Tuesday, March 22, 2011
Let's Get Started!
Hey everyone, just got back from spring break, so if anyone was wondering why I hadn't posted anything that's why! Yes, I have a life away from computers haha. It was one crazy break, but I'm ready to dive into things again. Hopefully I can keep myself motivated enough to learn everyday. I've started playing Smash The Stack (www.smashthestack.org). I'm doing IO, it's a lot of fun and gives me something to practice all the things I've been reading about. If you haven't already I suggest that you check out STS. This is going to be a short post I just wanted to say hi and motivate myself (haha) to start working.
Tuesday, March 8, 2011
Ryan's Bomb
Hey guys! What's up?
I have a few things I'd like to talk about. First off I was part of a team for CodeGate which is a Korean hacking competition and oh man was it fun. There were a about 6 sections if I recall correctly, Vunerab, Crypto, Bin, Networking, Issues and Forensics. I worked on the Issues, Forensics and Bin ones with my team and man were some of them tough! The team I was apart of ended up getting 1600 points and ended in 47th place so not too shabby.
Okay now on to today's topic. I'm going to be talking about Ryan's bomb! This is a fun little program that has 4 wires and you have to figure out the passwords for each to defuse the bomb. You can get the program here http://www.cs.rpi.edu/academics/courses/spring10/csci4971/rev2/bomb The wires are relatively simple in retro-spec but still fun to figure out and it's good practice.
The tools I used for this program is mainly GDB (Gnu Debugger) It's a simple debugger to use and it's all you really need for this program. I was also testing out HT editor, because a friend had suggested it to me. I found it useful but I'm more comfortable with gdb. You can find HT Editor here if you're interested http://hte.sourceforge.net/doc.html.
Protip: Run through the program to see what it does, see what type of input it takes, and to see if there's anyway to make any type of overflow.
USEFUL LINKS:
www.google.com
I'll be going through how I accomplished each wire so if you're wanting to figure this out by yourself STOP READING HERE!
YELLOW:
Okay, Yellow is really easy! If you couldn't get this one on yourself, you might want to give up for the rest of your life. Haha just kidding never give up! It really is simple though. So let's check it out in gdb.
##############################################################################
Breakpoint 1, 0x0804971f in yellow ()
(gdb) disass
Dump of assembler code for function yellow:
0x08049719 <+0>: push ebp
0x0804971a <+1>: mov ebp,esp
0x0804971c <+3>: sub esp,0x8
=> 0x0804971f <+6>: call 0x80496e8
0x08049724 <+11>: movzx eax,BYTE PTR ds:0x804c24c
0x0804972b <+18>: cmp al,0x38
0x0804972d <+20>: jne 0x804977c
0x0804972f <+22>: movzx eax,BYTE PTR ds:0x804c24d
0x08049736 <+29>: cmp al,0x34
0x08049738 <+31>: jne 0x804977c
0x0804973a <+33>: movzx eax,BYTE PTR ds:0x804c24e
0x08049741 <+40>: cmp al,0x33
0x08049743 <+42>: jne 0x804977c
0x08049745 <+44>: movzx eax,BYTE PTR ds:0x804c24f
0x0804974c <+51>: cmp al,0x37
0x0804974e <+53>: jne 0x804977c
0x08049750 <+55>: movzx eax,BYTE PTR ds:0x804c250
0x08049757 <+62>: cmp al,0x31
0x08049759 <+64>: jne 0x804977c
0x0804975b <+66>: movzx eax,BYTE PTR ds:0x804c251
0x08049762 <+73>: cmp al,0x30
0x08049764 <+75>: jne 0x804977c
0x08049766 <+77>: movzx eax,BYTE PTR ds:0x804c252
0x0804976d <+84>: cmp al,0x36
0x0804976f <+86>: jne 0x804977c
0x08049771 <+88>: movzx eax,BYTE PTR ds:0x804c253
0x08049778 <+95>: cmp al,0x35
0x0804977a <+97>: je 0x804978b
0x0804977c <+99>: mov eax,ds:0x804c124
0x08049781 <+104>: shl eax,0xa
0x08049784 <+107>: mov ds:0x804c124,eax
0x08049789 <+112>: jmp 0x80497a1
0x0804978b <+114>: mov DWORD PTR [esp],0x804a1f4
0x08049792 <+121>: call 0x80487b4
0x08049797 <+126>: mov DWORD PTR ds:0x804c124,0x0
0x080497a1 <+136>: leave
0x080497a2 <+137>: ret
End of assembler dump.
(gdb)
##############################################################################
This one is extremely straight forward! Just check what things are being compared to and you have the key. I'm not going to give the answer to this one since it's so simple you should honestly be able to figure it out just by looking at it.
GREEN:
##############################################################################
(gdb) disass
Dump of assembler code for function green:
0x08049904 <+0>: push ebp
0x08049905 <+1>: mov ebp,esp
0x08049907 <+3>: sub esp,0x38
=> 0x0804990a <+6>: mov eax,gs:0x14
0x08049910 <+12>: mov DWORD PTR [ebp-0x4],eax
0x08049913 <+15>: xor eax,eax
0x08049915 <+17>: mov DWORD PTR [ebp-0x8],0x1
0x0804991c <+24>: lea eax,[ebp-0x14]
0x0804991f <+27>: mov DWORD PTR [esp],eax
0x08049922 <+30>: call 0x80498d4
0x08049927 <+35>: mov DWORD PTR [esp+0x8],0x8
0x0804992f <+43>: lea eax,[ebp-0x14]
0x08049932 <+46>: mov DWORD PTR [esp+0x4],eax
0x08049936 <+50>: mov DWORD PTR [esp],0x804a2c0
0x0804993d <+57>: call 0x80487d4
0x08049942 <+62>: test eax,eax
0x08049944 <+64>: jne 0x804998e
0x08049946 <+66>: mov DWORD PTR [esp],0x804a2fc
0x0804994d <+73>: call 0x80487b4
0x08049952 <+78>: mov eax,DWORD PTR [ebp-0x8]
0x08049955 <+81>: and eax,0x1
0x08049958 <+84>: test eax,eax
0x0804995a <+86>: sete al
0x0804995d <+89>: movzx eax,al
0x08049960 <+92>: mov DWORD PTR [ebp-0x8],eax
0x08049963 <+95>: mov DWORD PTR [esp],0x7a120
0x0804996a <+102>: call 0x8048724
0x0804996f <+107>: mov DWORD PTR [esp],0x804a33c
0x08049976 <+114>: call 0x80487b4
0x0804997b <+119>: mov eax,DWORD PTR [ebp-0x8]
0x0804997e <+122>: and eax,0x1
0x08049981 <+125>: test eax,eax
0x08049983 <+127>: sete al
0x08049986 <+130>: movzx eax,al
0x08049989 <+133>: mov DWORD PTR [ebp-0x8],eax
0x0804998c <+136>: jmp 0x804999a
0x0804998e <+138>: mov eax,ds:0x804c12c
0x08049993 <+143>: add eax,eax
0x08049995 <+145>: mov ds:0x804c12c,eax
0x0804999a <+150>: mov eax,DWORD PTR [ebp-0x8]
---Type to continue, or q to quit---
0x0804999d <+153>: test eax,eax
0x0804999f <+155>: jne 0x80499ad
0x080499a1 <+157>: mov eax,ds:0x804c12c
0x080499a6 <+162>: sar eax,1
0x080499a8 <+164>: mov ds:0x804c12c,eax
0x080499ad <+169>: mov eax,DWORD PTR [ebp-0x4]
0x080499b0 <+172>: xor eax,DWORD PTR gs:0x14
0x080499b7 <+179>: je 0x80499be
0x080499b9 <+181>: call 0x8048784 <__stack_chk_fail@plt>
0x080499be <+186>: leave
0x080499bf <+187>: ret
End of assembler dump.
(gdb)
##############################################################################
Okay, so let's see this thing. So the first thing I did was check out what strncmp was doing. Well I did x/s on 0x804a2c0 and found it was dcaotdae so I re ran the program using that password and it ended up accepting it but locking it again. I can see that there is more things that it's comparing and what not but I had a hard time figuring it out. I tried appending things to dcaotdae and ended up finding out if something made $ebp-0x8 0xa or 0x0 then it would accept it as a password. So all I really did on this was try numbers until I found some that worked.
BLUE:
##############################################################################
Dump of assembler code for function blue:
0x080499f1 <+0>: push ebp
0x080499f2 <+1>: mov ebp,esp
0x080499f4 <+3>: sub esp,0x18
=> 0x080499f7 <+6>: call 0x80499c0
0x080499fc <+11>: mov DWORD PTR [ebp-0x4],0x804c160
0x08049a03 <+18>: mov eax,DWORD PTR [ebp-0x4]
0x08049a06 <+21>: mov eax,DWORD PTR [eax+0x4]
0x08049a09 <+24>: mov DWORD PTR [ebp-0x8],eax
0x08049a0c <+27>: mov DWORD PTR [ebp-0xc],0x0
0x08049a13 <+34>: jmp 0x8049a84
0x08049a15 <+36>: mov DWORD PTR [ebp-0x10],0x0
0x08049a1c <+43>: mov eax,DWORD PTR [ebp-0xc]
0x08049a1f <+46>: movzx eax,BYTE PTR [eax+0x804c24c]
0x08049a26 <+53>: movsx eax,al
0x08049a29 <+56>: mov DWORD PTR [ebp-0x14],eax
0x08049a2c <+59>: cmp DWORD PTR [ebp-0x14],0x4c
0x08049a30 <+63>: je 0x8049a40
0x08049a32 <+65>: cmp DWORD PTR [ebp-0x14],0x52
0x08049a36 <+69>: je 0x8049a4a
0x08049a38 <+71>: cmp DWORD PTR [ebp-0x14],0xa
0x08049a3c <+75>: je 0x8049a55
0x08049a3e <+77>: jmp 0x8049a5e
0x08049a40 <+79>: mov eax,DWORD PTR [ebp-0x4]
0x08049a43 <+82>: mov eax,DWORD PTR [eax]
0x08049a45 <+84>: mov DWORD PTR [ebp-0x4],eax
0x08049a48 <+87>: jmp 0x8049a71
0x08049a4a <+89>: mov eax,DWORD PTR [ebp-0x4]
0x08049a4d <+92>: mov eax,DWORD PTR [eax+0x8]
0x08049a50 <+95>: mov DWORD PTR [ebp-0x4],eax
0x08049a53 <+98>: jmp 0x8049a71
0x08049a55 <+100>: mov DWORD PTR [ebp-0x10],0x1
0x08049a5c <+107>: jmp 0x8049a71
0x08049a5e <+109>: mov DWORD PTR [ebp-0x10],0x1
0x08049a65 <+116>: mov DWORD PTR [esp],0x804a3bb
0x08049a6c <+123>: call 0x80487b4
0x08049a71 <+128>: cmp DWORD PTR [ebp-0x10],0x0
0x08049a75 <+132>: jne 0x8049a8a
0x08049a77 <+134>: mov eax,DWORD PTR [ebp-0x4]
0x08049a7a <+137>: mov eax,DWORD PTR [eax+0x4]
0x08049a7d <+140>: xor DWORD PTR [ebp-0x8],eax
---Type to continue, or q to quit---
0x08049a80 <+143>: add DWORD PTR [ebp-0xc],0x1
0x08049a84 <+147>: cmp DWORD PTR [ebp-0xc],0xe
0x08049a88 <+151>: jle 0x8049a15
0x08049a8a <+153>: mov DWORD PTR [esp],0x804a3c0
0x08049a91 <+160>: call 0x8048744
0x08049a96 <+165>: mov eax,ds:0x804c240
0x08049a9b <+170>: mov DWORD PTR [esp],eax
0x08049a9e <+173>: call 0x8048734
0x08049aa3 <+178>: mov DWORD PTR [esp],0x1
0x08049aaa <+185>: call 0x80487a4
0x08049aaf <+190>: mov DWORD PTR [esp],0x804a3eb
0x08049ab6 <+197>: call 0x80487b4
0x08049abb <+202>: mov DWORD PTR [esp],0x7a120
0x08049ac2 <+209>: call 0x8048724
0x08049ac7 <+214>: mov eax,ds:0x804a384
0x08049acc <+219>: cmp DWORD PTR [ebp-0x8],eax
0x08049acf <+222>: jne 0x8049aec
0x08049ad1 <+224>: mov DWORD PTR [esp],0x804a3fc
0x08049ad8 <+231>: call 0x80487b4
0x08049add <+236>: mov eax,ds:0x804c140
0x08049ae2 <+241>: sub eax,0x1
0x08049ae5 <+244>: mov ds:0x804c140,eax
0x08049aea <+249>: jmp 0x8049af9
0x08049aec <+251>: mov eax,ds:0x804c140
0x08049af1 <+256>: add eax,0x1
0x08049af4 <+259>: mov ds:0x804c140,eax
0x08049af9 <+264>: leave
0x08049afa <+265>: ret
End of assembler dump.
(gdb)
##############################################################################
This one is a bitch. So I started off like I usually did and checked out the cmps I see that they're comparing my input with L, R and ctrl+j. I also see that $ebp-0xc is a counter which gains one every time an acceptable input is taken and when it's greater than 15 it's cut off. What this program does pretty much is XOR a bunch of hex until your input is done then compares it to 0x40475194. Now XORing hex is a fuckin' bitch, there's an array in there that you'll find if you mess around with. I was able to just guess the password by looking at it, but I would suggest you write a script that tries all the combinations and returns the answer. That seems to be the proper way to do it.
RED:
##############################################################################
0x08049831 in red ()
(gdb) disass
Dump of assembler code for function red:
=> 0x08049831 <+0>: push ebp
0x08049832 <+1>: mov ebp,esp
0x08049834 <+3>: sub esp,0x18
0x08049837 <+6>: call 0x80497a4
0x0804983c <+11>: mov DWORD PTR [ebp-0x4],0x804a29c
0x08049843 <+18>: mov DWORD PTR [ebp-0x8],0x0
0x0804984a <+25>: jmp 0x80498ba
0x0804984c <+27>: mov eax,DWORD PTR [ebp-0x8]
0x0804984f <+30>: movzx edx,BYTE PTR [eax+0x804c24c]
0x08049856 <+37>: mov eax,ds:0x804c26c
0x0804985b <+42>: and eax,0x1f
0x0804985e <+45>: add eax,DWORD PTR [ebp-0x4]
0x08049861 <+48>: movzx eax,BYTE PTR [eax]
0x08049864 <+51>: cmp dl,al
0x08049866 <+53>: je 0x8049877
0x08049868 <+55>: mov eax,ds:0x804c128
0x0804986d <+60>: add eax,0x1
0x08049870 <+63>: mov ds:0x804c128,eax
0x08049875 <+68>: jmp 0x80498ca
0x08049877 <+70>: mov eax,ds:0x804c26c
0x0804987c <+75>: mov edx,eax
0x0804987e <+77>: shr edx,0x5
0x08049881 <+80>: mov eax,ds:0x804c268
0x08049886 <+85>: shl eax,0x1b
0x08049889 <+88>: or eax,edx
0x0804988b <+90>: mov ds:0x804c26c,eax
0x08049890 <+95>: mov eax,ds:0x804c268
0x08049895 <+100>: mov edx,eax
0x08049897 <+102>: shr edx,0x5
0x0804989a <+105>: mov eax,ds:0x804c264
0x0804989f <+110>: shl eax,0x1b
0x080498a2 <+113>: or eax,edx
0x080498a4 <+115>: mov ds:0x804c268,eax
0x080498a9 <+120>: mov eax,ds:0x804c264
0x080498ae <+125>: shr eax,0x5
0x080498b1 <+128>: mov ds:0x804c264,eax
0x080498b6 <+133>: add DWORD PTR [ebp-0x8],0x1
0x080498ba <+137>: cmp DWORD PTR [ebp-0x8],0x12
0x080498be <+141>: jle 0x804984c
0x080498c0 <+143>: mov DWORD PTR ds:0x804c128,0x0
---Type to continue, or q to quit---
0x080498ca <+153>: leave
0x080498cb <+154>: ret
End of assembler dump.
(gdb)
##############################################################################
There is nothing hard about Red at all, the only thing that is new is that the bomb will explode if you try to debug it using breakpoints. So what I did was break main, then break the address before Red is called then stepped into it. Be careful in here ONE WRONG MOVE AND IT'LL BLOW haha. This is how I did this one. It's really tedious but it worked. All I did was input some garbage then stepped until 0x08049864 then I checked $al and that happens to be the correct input. So then I would restart, put in the first right code then step to 0x08049864 again and I repeated this 17 times haha. That's all there is to it.
After you have all the codes you put them in and you disarm the bomb yay! I know my explonations kinda suck, didn't go in very much detail and seemed like lucky guesses. Well that's because some of they were, well I mean I had a hunch on a few of them since like Blue I guessed it was LLRR just because I figured it would be 4 characters long since there was 4 wires and it happened that L was the first letter to be compared to. I honestly don't know in Green how $ebp-0x8 changes its values with the appended characters. I tried to step through it but I couldn't disassemble it.
If you did things another way, have comments, have tips for me or anything please let me know. I'm thirsting for knowledge. I hope you enjoyed reading this and if you were stuck hope it helped you out. I'll be trying to find new things to work on. Thanks and have a great day!
P.S.
I'm trying to find HTML code that will hide all the text until the user clicks a button. Does anyone know how to do this?
Labels:
bomb,
by-passing,
code,
engineering,
example,
fun,
hacking,
reverse,
reverse engineering,
ryan's,
ryan's bomb
Sunday, February 27, 2011
Heap Overflow
DISCLAIMER: I am not experienced in anyway, anything I say might be wrong! If you do not agree with something please leave me a comment, I'd love to learn more.
Hey everyone!
I recently started to get into Hacking: The Art of Exploitation by Jon Erickson. If you're curious about this type of stuff and need a good start I would suggest going and getting a copy of this! The second edition has improved a lot from the first, and the examples really help out. If you're going to get this book used; make sure it has the CD. The CD is a live-CD of Ubuntu that's been tailored for the book. It has all of the examples, and by using their OS you are more likely to get results that follow the results from the book. If you have a x86_64 system you will not be able to follow this book line for line.
Alright, so while I was reading this I found something that I found really interesting and thought I'd give you a little taste of what this book is about. If you haven't guessed already (from the title) it's heap overflows! This will be following an example from 0x340 from the book. A heap over flow can occur if there is an important variable after a vulnerable, exploiting this can cause "the program's control flow to be altered".
"
3.4.1.1. Excerpt from notetaker.c
buffer = (char *) ec_malloc(100);
datafile = (char *) ec_malloc(20);
strcpy(datafile, "/var/notes");
if(argc < 2) // If there aren't command-line arguments,
usage(argv[0], datafile); // display usage message and exit.
strcpy(buffer, argv[1]); // Copy into buffer.
printf("[DEBUG] buffer @ %p: \'%s\'\n", buffer, buffer);
printf("[DEBUG] datafile @ %p: \'%s\'\n", datafile, datafile);
" (Taken from Jon Erickson's book)
Okay, so if you're not familiar with C you probably don't know what's going on. I would suggest you go read up on some C before you continue since this book is C heavy. C is a fun language and I think most programmers who want to get into this type of field should study it.
Alright, so some things I should probably clear up. Whenever you evoke malloc() you are reserving blocks of memory in the heap dynamically. If you're coming from other languages such as C++, this is similar to "new". So here's the basics of why this is snippet of code is vulnerable.
We've declared a buffer and reserved 100 bytes, and right after it we declared datafile which will end up copying the location /var/notes. Nothing wrong with that, the part which makes this a mess is "strcpy(buffer,argv[1]". You might be asking 'Well... why does that mess things up?' Well because, we declared buffer to be 100 bytes yet we didn't make sure that whatever is in argv[1] is less than or equal to 100 bytes. Meaning we could overflow this buffer and cause something to be written into datafile, since we declared it after we declared buffer.
So, in the example they use this vulnerability, to cause this little note taking program to write into /tmp/etc/passwd, which is a symlink to /etc/passwd and they append a new root shell called myroot. They do this by overflowing the buffer with filling up the buffer with the name of the new user, and 0 for u/gids a fixed amount of A's and the path to the shell, the by making sure datafile is /etc/passwd.
In the end the program crashes, but if we check the /etc/passwd we can see that the new user and root shell has been written. You can then test it out by doing su myroot, putting in the password, then once you're in type whoami and you will see that you are now a root user!
So this is a cool way to get a new root shell onto a linux box. The only problem is that this has limited application, since of the requirements needed to apply it effectively.
Hey everyone!
I recently started to get into Hacking: The Art of Exploitation by Jon Erickson. If you're curious about this type of stuff and need a good start I would suggest going and getting a copy of this! The second edition has improved a lot from the first, and the examples really help out. If you're going to get this book used; make sure it has the CD. The CD is a live-CD of Ubuntu that's been tailored for the book. It has all of the examples, and by using their OS you are more likely to get results that follow the results from the book. If you have a x86_64 system you will not be able to follow this book line for line.
Alright, so while I was reading this I found something that I found really interesting and thought I'd give you a little taste of what this book is about. If you haven't guessed already (from the title) it's heap overflows! This will be following an example from 0x340 from the book. A heap over flow can occur if there is an important variable after a vulnerable, exploiting this can cause "the program's control flow to be altered".
"
3.4.1.1. Excerpt from notetaker.c
buffer = (char *) ec_malloc(100);
datafile = (char *) ec_malloc(20);
strcpy(datafile, "/var/notes");
if(argc < 2) // If there aren't command-line arguments,
usage(argv[0], datafile); // display usage message and exit.
strcpy(buffer, argv[1]); // Copy into buffer.
printf("[DEBUG] buffer @ %p: \'%s\'\n", buffer, buffer);
printf("[DEBUG] datafile @ %p: \'%s\'\n", datafile, datafile);
" (Taken from Jon Erickson's book)
Okay, so if you're not familiar with C you probably don't know what's going on. I would suggest you go read up on some C before you continue since this book is C heavy. C is a fun language and I think most programmers who want to get into this type of field should study it.
Alright, so some things I should probably clear up. Whenever you evoke malloc() you are reserving blocks of memory in the heap dynamically. If you're coming from other languages such as C++, this is similar to "new". So here's the basics of why this is snippet of code is vulnerable.
We've declared a buffer and reserved 100 bytes, and right after it we declared datafile which will end up copying the location /var/notes. Nothing wrong with that, the part which makes this a mess is "strcpy(buffer,argv[1]". You might be asking 'Well... why does that mess things up?' Well because, we declared buffer to be 100 bytes yet we didn't make sure that whatever is in argv[1] is less than or equal to 100 bytes. Meaning we could overflow this buffer and cause something to be written into datafile, since we declared it after we declared buffer.
So, in the example they use this vulnerability, to cause this little note taking program to write into /tmp/etc/passwd, which is a symlink to /etc/passwd and they append a new root shell called myroot. They do this by overflowing the buffer with filling up the buffer with the name of the new user, and 0 for u/gids a fixed amount of A's and the path to the shell, the by making sure datafile is /etc/passwd.
In the end the program crashes, but if we check the /etc/passwd we can see that the new user and root shell has been written. You can then test it out by doing su myroot, putting in the password, then once you're in type whoami and you will see that you are now a root user!
So this is a cool way to get a new root shell onto a linux box. The only problem is that this has limited application, since of the requirements needed to apply it effectively.
Subscribe to:
Posts (Atom)