Uncrackable Programs? Key validation with Algorithm and creating a Keygen - Part 1/2 - bin 0x07

LiveOverflow · Intermediate ·🛡️ AI Safety & Ethics ·10y ago

Key Takeaways

The video demonstrates key validation with an algorithm and creating a keygen, showcasing reverse engineering and static analysis techniques to defeat a simple license key validation algorithm.

Full Transcript

[Music] Let's say you work for a company and your manager is mad that there are pirated versions of your product out there. He tells you to secure their intellectual property and make the program uncrackable. Is that even possible? Last video I claimed that every program is crackable, but that was old me. Maybe I learned more in the meantime. So, let's try it out. First problem is that the license key was inside the binary. The simple technique we had was to extract all strings and we found the key. Our first attempt to make it secure would be not to have the key inside. We can do this by writing an algorithm that scramles the key. You can come up with very creative ideas and then you can give the secured binary to your friend and ask them to crack it or write a key again. That can be really fun. The first idea I have is to simply sum up the as key values of the key and compare it to a magic value. So let's modify the original program. First we have to define a new integer value that will store our calculated sum. So int sum and set it to zero. Then we will add a for loop with the counter variable i which starts at zero with the loop condition that it continues to repeat this loop as long as i is smaller than the string length of the key that we can supply with arc v1 and in each repetition we will increment i by one. Now we want to sum up the value of each character. So sum plus equal argu one and then the index i. As you know a computer understands only numbers. So each character as you know from the aski table is a number. But the compiler knows that argu is defined as a character sequence. So to not get any complaints we cast this value to an integer like that. Now we want to find out what the sum of our original key is. So let's add a print f with percentage d in the format string and the sum as the parameter. Now we can compile it and execute it with the original key. So here's the sum of all character values for this key. Let's go to the code again and change the key check. Remove the string compare and replace it with the check that the sum has to be that number. remove the debug print f and try it. So here it says that it's a wrong key and here it says that it is a correct key. Now try strings and you will not find this key anymore. But how can we crack this? Now let's open it with radar 2 analyze all seek to the main function and print the disassembly. So let's look for the success or fail message. Here it is. And then we can check where the branches are coming from to find the check if the license was correct or not. Okay, so this compare and jump decides if we print access granted or if we follow it wrong. You can also see this hex value that is used for the compare. I like to use Python to convert between hex and decimal. So that's exactly what we have in our C code. So open the file again in debug mode and add a wrong license key. If you start the program, it says it's wrong. Great. Now let's set a break point with DB at this one compare and reopen the file in debug mode. Now DC to continue. Now we hit the break point with DR. You can see that RIP is at the jump with DR. RIP equals to we can set the RP address we want to execute next. And obviously we want to print the success. So we have cracked it again. Okay. Okay, so we have found out that if you can find this one compare where it decides if you have a valid license or not, you can simply bypass it. But we are hackers. We love challenges and patching a jump is just boring. So let's write a key again. So first we have to reverse the algorithm. I will open the source code next to it so we can compare a little bit. I seek to the main function and enter visual mode. Okay, so we already know a little bit about this program from the other video. So here we can see the compare if we supply the license key. Then comes the print f like in our C code. After this print f, we set sum to zero and also the for loop is initialized with the index counter i to zero. And you can see that in the assembler code to the left, two addresses are set to zero with a move. And the address is calculated with the base pointer address. Uh that's just another fancy register. And then the first variable is at offset minus hex 18. And the other one well radar replaced the number with a name and calls it local to 4 variable. But behind this name is just another number. Now when we look closely we find a branch that loops back up. So those blocks here are our for loop. And at the end of the for loop is a add instruction that adds one to this local variable that was set to zero earlier. So that is the increment of i and this local variable that radar identified is i. We can rename this variable with a fvn the previous name local 24 and i. In this block we have a string land call and afterwards we compare two registers and it either continues with this main block or it leaves. So this is the follow condition here. Now comes an ugly part if you have never seen this before but if you practiced it it's easy to see. Don't worry if you get lost uh for the next minute. This just requires some practice. So first it loads a value from an address which radar assigned a name to. This name came up before near the string len. And if you compare these two assembler blocks they are a bit similar. You can see that it adds a to the loaded value. So usually that means the value that was loaded is an address because we have 64 bit and we often divide memory in 8 byt chunks. Imagine an array in memory. It might use multiple 8 byt chunks. The first chunk which is the first value in the array is simply there where the address points to. This means that if you want to get a second value in the array, you have to add 8 to the address. Now it points to the second array entry. So this arg v1 remember we start counting at zero. So arv 0 would be the first array entry. ARV is basically a variable that contains the address with points to an array in memory and this address is loaded into rax and then we add a to it to move it to the second entry in that array. Now the second entry is another address which points to a string in our assembly code. We can see that the address of the string is loaded from the location raix is pointing to. Remember that the brackets around the register means that the register contains an address and we access the value that is stored at this address. Okay, so RDX down here now has the address where our string begins. Now we know that the next line loads the index counter I into EAX. Each ASK character is one bite big. So similar how we can move an address to point to the next array entry by adding eight, we can move the string point to the next character by adding one. So when we take the counter I which might for example have the value three and add it to the address that points to the start of the string, it will then point to the third character. Now next we load one bite from the current address in raix. This is the value of this particular character and we add this value in E X to a local variable at offset minus hex 18 which we earlier set to zero. So this is our sum. Well, I know it seems tedious and confusing and a bit crazy, but if you do this a couple of times and also debug this step by step with GDB and look at your registers in each step and inspect the memory addresses, it becomes clear. So now we know that this is a loop and that goes over each character of the string and adds the character value to a variable. Now when the string line compare branch goes the other way, we leave the loop and the sum is compared to hex 394. Cool. If your brain turned off during the previous part, turn it on again. Let's do this again, but this time you can ignore most of the stuff and work backwards with educated guesses. So you see that this address gets compared with a certain value. So look where this value came from. Ah so it has to do something with this ad. Now you can reload this binary in debug mode with OD. I will use ABCD as an example key. Press P to display the addresses and place a break point here. Then use V exclamation mark to switch to a more fancier mode and then execute it. Now always continue with colon DZ and look at the register raix that gets added. So in the first loop it's hex 41. If you know your ASKI table you know that this is a capital A. You can also use Python as a handy tool to convert back and forth and next time it's hex 42 that is a capital B and then it's hex 43. So clearly it just iterates over the supplied string. See, now you know what happens without having to read assembler line by line. Let's recreate this in Python. Let's write a function called check key. It takes a key as a parameter. Now we define a character sum and set it to zero. Then we loop over all characters with 4 C and key. And then we add the SQ value to the sum with ORD of C. Then we print the current key and its sum and we return the sum. Now let's do some example keys. With y you can copy a line and with p you can paste it again. I deliberately use ABCD because there are numerical values always increases by one. Cool. You can see how the sum is always one bigger than the previous one. Now let's use a very naive randomized key again to try to different keys until we find one. This can be obviously made much more intelligently because of the linear behavior of this function, but it will still look cool. So, import random module and create an endless loop. Our key starts with an empty string. Then, we select a random character from an alphabet with random choice and append it to the key. Now, we check this key. If this key sum is already too big, we reset the key and start fresh. And if we hit the correct value, we print that key. I will modify the print and check key function to make it a bit more cooler. Now save it and run. Oops, something is wrong. Ah, I had the compare the wrong way. We obviously have to reset the key when it's already too big. Okay, now damn, that's fast. Even though it's very bad algorithm, we quickly find many, many keys. Let's see if they work. Oh, yes, they work. That's cool, huh? So, we have learned now that we can hide license keys by using an algorithm to verify if a key is valid. This whole algorithm becomes useless when we find the assemble code that decides if it was valid or not. In our case, it's a simple compare jump that we can patch. Obviously you can make that a bit more complex for example doing a license check in different places but generally this is how you can defeat it. Now if we like a challenge or we don't want to patch a binary because whatever uh there are many reasons why you might want a valid key we can use static analysis and reverse engineer the license check algorithm and write a key gain to generate valid keys. Obviously this algorithm also can become very complex but generally if you put a lot of work in it you can figure it out. Now you tell that your manager but he's a smartass and tells you then you should stop people from being able to reverse engineer the binary. Uh then you direct yourself back to the desk and you come up with a new creative way how to stop somebody from debugging and reversing it. [Music]

Original Description

InfoSec clickbait title by BuzzSec! Key validation with Algorithm and creating a Keygen - Part 1/2 -=[ 🔴 Stuff I use ]=- → Microphone:* https://geni.us/ntg3b → Graphics tablet:* https://geni.us/wacom-intuos → Camera#1 for streaming:* https://geni.us/sony-camera → Lens for streaming:* https://geni.us/sony-lense → Connect Camera#1 to PC:* https://geni.us/cam-link → Keyboard:* https://geni.us/mech-keyboard → Old Microphone:* https://geni.us/mic-at2020usb US Store Front:* https://www.amazon.com/shop/liveoverflow -=[ ❤️ Support ]=- → per Video: https://www.patreon.com/join/liveoverflow → per Month: https://www.youtube.com/channel/UClcE-kVhqyiHCcjYwcpfj9w/join -=[ 🐕 Social ]=- → Twitter: https://twitter.com/LiveOverflow/ → Website: https://liveoverflow.com/ → Subreddit: https://www.reddit.com/r/LiveOverflow/ → Facebook: https://www.facebook.com/LiveOverflow/ -=[ 📄 P.S. ]=- All links with "*" are affiliate links. LiveOverflow / Security Flag GmbH is part of the Amazon Affiliate Partner Programm. #ReverseEngineering
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from LiveOverflow · LiveOverflow · 9 of 60

1 LiveOverflow - Trailer
LiveOverflow - Trailer
LiveOverflow
2 Introduction to Linux - Installation and the Terminal - bin 0x01
Introduction to Linux - Installation and the Terminal - bin 0x01
LiveOverflow
3 Writing a simple Program in C
Writing a simple Program in C
LiveOverflow
4 Writing a simple Program in Python - bin 0x03
Writing a simple Program in Python - bin 0x03
LiveOverflow
5 Live Hacking - Twitch Recording overthewire.org - Vortex 0x01-0x03 (3h)
Live Hacking - Twitch Recording overthewire.org - Vortex 0x01-0x03 (3h)
LiveOverflow
6 Reversing and Cracking first simple Program - bin 0x05
Reversing and Cracking first simple Program - bin 0x05
LiveOverflow
7 Abusing the exception handler to leak flag - 32C3CTF readme (pwnable 200)
Abusing the exception handler to leak flag - 32C3CTF readme (pwnable 200)
LiveOverflow
8 ROP with a very small stack - 32C3CTF teufel (pwnable 200)
ROP with a very small stack - 32C3CTF teufel (pwnable 200)
LiveOverflow
Uncrackable Programs? Key validation with Algorithm and creating a Keygen - Part 1/2 - bin 0x07
Uncrackable Programs? Key validation with Algorithm and creating a Keygen - Part 1/2 - bin 0x07
LiveOverflow
10 Uncrackable Program? Finding a Parser Differential in loading ELF - Part 2/2 - bin 0x08
Uncrackable Program? Finding a Parser Differential in loading ELF - Part 2/2 - bin 0x08
LiveOverflow
11 Syscalls, Kernel vs. User Mode and Linux Kernel Source Code - bin 0x09
Syscalls, Kernel vs. User Mode and Linux Kernel Source Code - bin 0x09
LiveOverflow
12 Smashing the Stack for Fun and Profit - setuid, ssh and exploit.education - bin 0x0B
Smashing the Stack for Fun and Profit - setuid, ssh and exploit.education - bin 0x0B
LiveOverflow
13 Live Hacking - EFF-CTF 2016 - Level 0-4 (Enigma Conference)
Live Hacking - EFF-CTF 2016 - Level 0-4 (Enigma Conference)
LiveOverflow
14 First Stack Buffer Overflow to modify Variable - bin 0x0C
First Stack Buffer Overflow to modify Variable - bin 0x0C
LiveOverflow
15 First Exploit! Buffer Overflow with Shellcode - bin 0x0E
First Exploit! Buffer Overflow with Shellcode - bin 0x0E
LiveOverflow
16 Buffer Overflows can Redirect Program Execution - bin 0x0D
Buffer Overflows can Redirect Program Execution - bin 0x0D
LiveOverflow
17 Doing ret2libc with a Buffer Overflow because of restricted return pointer - bin 0x0F
Doing ret2libc with a Buffer Overflow because of restricted return pointer - bin 0x0F
LiveOverflow
18 Reverse engineering C programs (64bit vs 32bit) - bin 0x10
Reverse engineering C programs (64bit vs 32bit) - bin 0x10
LiveOverflow
19 pwnable.kr - Levels: fd, collision, bof, flag
pwnable.kr - Levels: fd, collision, bof, flag
LiveOverflow
20 Reverse Engineering and identifying Bugs - BKPCTF cookbook (pwn 6) part 1
Reverse Engineering and identifying Bugs - BKPCTF cookbook (pwn 6) part 1
LiveOverflow
21 Leaking Heap and Libc address - BKPCTF cookbook (pwn 6) part 2
Leaking Heap and Libc address - BKPCTF cookbook (pwn 6) part 2
LiveOverflow
22 Arbitrary write with House of Force (heap exploit) - BKPCTF cookbook (pwn 6) part 3
Arbitrary write with House of Force (heap exploit) - BKPCTF cookbook (pwn 6) part 3
LiveOverflow
23 Live Hacking - Internetwache CTF 2016 - web50, web60, web80
Live Hacking - Internetwache CTF 2016 - web50, web60, web80
LiveOverflow
24 Live Hacking - Internetwache CTF 2016 - crypto60, crypto70, crypto90
Live Hacking - Internetwache CTF 2016 - crypto60, crypto70, crypto90
LiveOverflow
25 A simple Format String exploit example - bin 0x11
A simple Format String exploit example - bin 0x11
LiveOverflow
26 NEW VIDEOS ARE COMING - loopback 0x00
NEW VIDEOS ARE COMING - loopback 0x00
LiveOverflow
27 HTML + CSS + JavaScript introduction - web 0x00
HTML + CSS + JavaScript introduction - web 0x00
LiveOverflow
28 The HTTP Protocol: GET /test.html - web 0x01
The HTTP Protocol: GET /test.html - web 0x01
LiveOverflow
29 Building Poor Man's Logic Analyzer with an Arduino - Reverse Engineering A/C Remote part 1
Building Poor Man's Logic Analyzer with an Arduino - Reverse Engineering A/C Remote part 1
LiveOverflow
30 What is PHP and why is XSS so common there? - web 0x02
What is PHP and why is XSS so common there? - web 0x02
LiveOverflow
31 Introducing the AngularJS Javascript Framework - XSS with AngularJS 0x00
Introducing the AngularJS Javascript Framework - XSS with AngularJS 0x00
LiveOverflow
32 Sandbox Bypass in Version 1.0.8 - XSS with AngularJS 0x1
Sandbox Bypass in Version 1.0.8 - XSS with AngularJS 0x1
LiveOverflow
33 Capturing & Analyzing Packets with Saleae Logic Pro 8 - Reverse Engineering A/C Remote part 2
Capturing & Analyzing Packets with Saleae Logic Pro 8 - Reverse Engineering A/C Remote part 2
LiveOverflow
34 XSS Contexts and some Chrome XSS Auditor tricks - web 0x03
XSS Contexts and some Chrome XSS Auditor tricks - web 0x03
LiveOverflow
35 Previous Bypass is now fixed in version 1.4.7 - XSS with AngularJS 0x2
Previous Bypass is now fixed in version 1.4.7 - XSS with AngularJS 0x2
LiveOverflow
36 New Sandbox Bypass in 1.4.7 - XSS with AngularJS 0x3
New Sandbox Bypass in 1.4.7 - XSS with AngularJS 0x3
LiveOverflow
37 The Heap: what does malloc() do? - bin 0x14
The Heap: what does malloc() do? - bin 0x14
LiveOverflow
38 The Heap: How to exploit a Heap Overflow - bin 0x15
The Heap: How to exploit a Heap Overflow - bin 0x15
LiveOverflow
39 Reverse Engineering with Binary Ninja and gdb a key checking algorithm - TUMCTF 2016 Zwiebel part 1
Reverse Engineering with Binary Ninja and gdb a key checking algorithm - TUMCTF 2016 Zwiebel part 1
LiveOverflow
40 Scripting radare2 with python for dynamic analysis - TUMCTF 2016 Zwiebel part 2
Scripting radare2 with python for dynamic analysis - TUMCTF 2016 Zwiebel part 2
LiveOverflow
41 Live Hacking - Internetwache CTF 2016 - exp50, exp70, exp80
Live Hacking - Internetwache CTF 2016 - exp50, exp70, exp80
LiveOverflow
42 Sandbox bypass for the latest AngularJS version 1.5.8 - XSS with AngularJS 0x4
Sandbox bypass for the latest AngularJS version 1.5.8 - XSS with AngularJS 0x4
LiveOverflow
43 Channel is growing and Riscure hardware CTF starting soon - loopback 0x01
Channel is growing and Riscure hardware CTF starting soon - loopback 0x01
LiveOverflow
44 Explaining Dirty COW local root exploit - CVE-2016-5195
Explaining Dirty COW local root exploit - CVE-2016-5195
LiveOverflow
45 What is CTF? An introduction to security Capture The Flag competitions
What is CTF? An introduction to security Capture The Flag competitions
LiveOverflow
46 The Heap: How do use-after-free exploits work? - bin 0x16
The Heap: How do use-after-free exploits work? - bin 0x16
LiveOverflow
47 The Browser is a very Confused Deputy - web 0x05
The Browser is a very Confused Deputy - web 0x05
LiveOverflow
48 The Heap: Once upon a free() - bin 0x17
The Heap: Once upon a free() - bin 0x17
LiveOverflow
49 Simple reversing challenge and gaming the system - BruCON CTF part 1
Simple reversing challenge and gaming the system - BruCON CTF part 1
LiveOverflow
50 int0x80 from DualCore lent me his lockpicking set and I'm a horse - BruCON CTF part 2
int0x80 from DualCore lent me his lockpicking set and I'm a horse - BruCON CTF part 2
LiveOverflow
51 The Heap: dlmalloc unlink() exploit - bin 0x18
The Heap: dlmalloc unlink() exploit - bin 0x18
LiveOverflow
52 MD5 Length Extension and Blind SQL Injection - BruCON CTF part 3
MD5 Length Extension and Blind SQL Injection - BruCON CTF part 3
LiveOverflow
53 TCP Protocol introduction - bin 0x1A
TCP Protocol introduction - bin 0x1A
LiveOverflow
54 Socket programming in python and Integer Overflow - bin 0x1B
Socket programming in python and Integer Overflow - bin 0x1B
LiveOverflow
55 Linux signals and core dumps - bin 0x1C
Linux signals and core dumps - bin 0x1C
LiveOverflow
56 [Live] Remote oldschool dlmalloc Heap exploit - bin 0x1F
[Live] Remote oldschool dlmalloc Heap exploit - bin 0x1F
LiveOverflow
57 Riscure Embedded Hardware CTF setup and introduction - rhme2 Soldering
Riscure Embedded Hardware CTF setup and introduction - rhme2 Soldering
LiveOverflow
58 Rooting a CTF server to get all the flags with Dirty COW - CVE-2016-5195
Rooting a CTF server to get all the flags with Dirty COW - CVE-2016-5195
LiveOverflow
59 How to learn hacking? ft. Rubber Ducky
How to learn hacking? ft. Rubber Ducky
LiveOverflow
60 Format String to dump binary and gain RCE - 33c3ctf ESPR (pwn 150)
Format String to dump binary and gain RCE - 33c3ctf ESPR (pwn 150)
LiveOverflow

The video teaches how to use reverse engineering and static analysis to defeat a simple license key validation algorithm, and how to create a keygen to generate valid keys. It covers topics such as key validation, algorithmic security, and assembly language programming.

Key Takeaways
  1. Write an algorithm that scrambles the key
  2. Sum up the ASCII values of the key and compare it to a magic value
  3. Modify the key check to compare the sum to the magic value instead of the original string
  4. Analyze the code using a disassembler to find the compare and jump instructions
  5. Set a breakpoint at the compare instruction and run the program with a wrong license key
  6. Run GDB on the binary
  7. Use OD to debug the binary
  8. Write a function in Python to recreate the license check algorithm
  9. Use a brute force attack to find valid keys
💡 The algorithm's linearity makes it vulnerable to brute force attacks, and static analysis and reverse engineering can be used to write a keygen to generate valid keys.

Related Reads

📰
The 4-Step Test That Catches AI Errors Before They Shape Your Strategy via @sejournal, @alexanderkesler
Learn a 4-step test to verify AI conclusions and avoid costly errors in your strategy
Search Engine Journal
📰
Bank Statement Fraud in Lending: What Gets Altered and How to Catch It
Learn to detect bank statement fraud in lending by identifying altered balances, deposits, and overdrafts using structural signals
Dev.to · Iurii Rogulia
📰
GuardFall: When Decades-Old Shell Injection Tricks Beat Modern AI Safety Guardrails
Decades-old shell injection tricks can bypass modern AI safety guardrails, highlighting the need for more robust security measures
Dev.to · Cor E
📰
What 116 court judgments taught me about the limits of AI
Learn about the limitations of AI in professional settings through an analysis of 116 court judgments and a personal project using consumer AI tools
Medium · AI
Up next
Containers Don't Make Your AI Agent Safe
Web Dev Simplified
Watch →