pcfx Posted August 1, 2016 Posted August 1, 2016 (edited) Hi, I'm reading about some egg hunter shellcode and noticed a weird thing. If I remove the 'egg tag' in front of my actual payload i'm getting wrong strlen sizes? Why so? The shellcode isn't working in the second example without the egg tag (of course) but this has nothing to do with the strlen function, has it? shellcode1.c (Egg-tag is "Egg-Mark" without "", correct strlen of array) #include <stdio.h> #include <string.h> unsigned char egg[] = { 0x40, 0x81, 0x78, 0xf8, 0x45, 0x67, 0x67, 0x2d, 0x75, 0xf6, 0x81, 0x78, 0xfc, 0x4d, 0x61, 0x72, 0x6b, 0x75, 0xed, 0xff, 0xd0 }; unsigned char payload[] = { 0x45, 0x67, 0x67, 0x2d, 0x4d, 0x61, 0x72, 0x6b, 0x31, 0xc0, 0xb0, 0x04, 0x31, 0xdb, 0x53, 0x68, 0x41, 0x41, 0x41, 0x41, 0xb3, 0x01, 0x89, 0xe1, 0x31, 0xd2, 0xb2, 0x04, 0xcd, 0x80, 0xb0, 0x01, 0x31, 0xdb, 0xcd, 0x80 }; int main() { printf("length: %d\n", strlen(egg)); printf("length: %d\n", strlen(payload)); int (*ret)() = (int(*)())egg; ret(); } Output pcfx@pcfx-VirtualBox:~/Code/shellcodes/egg_hunter_1$ ./shellcode1 length: 21 length: 36 shellcode2.c (removed "Egg-Mark" in front of payload, getting wrong strlen of array) #include <stdio.h> #include <string.h> unsigned char egg[] = { 0x40, 0x81, 0x78, 0xf8, 0x45, 0x67, 0x67, 0x2d, 0x75, 0xf6, 0x81, 0x78, 0xfc, 0x4d, 0x61, 0x72, 0x6b, 0x75, 0xed, 0xff, 0xd0 }; unsigned char payload[] = { 0x31, 0xc0, 0xb0, 0x04, 0x31, 0xdb, 0x53, 0x68, 0x41, 0x41, 0x41, 0x41, 0xb3, 0x01, 0x89, 0xe1, 0x31, 0xd2, 0xb2, 0x04, 0xcd, 0x80, 0xb0, 0x01, 0x31, 0xdb, 0xcd, 0x80 }; int main() { printf("length: %d\n", strlen(egg)); printf("length: %d\n", strlen(payload)); int (*ret)() = (int(*)())egg; ret(); } Output: pcfx@pcfx-VirtualBox:~/Code/shellcodes/egg_hunter_1$ ./shellcode2 length: 49 length: 28 Segmentation fault (core dumped) Here is the assembler code: BITS 32 global _start section .text _start: ; searching for Egg marker next: inc eax isEgg: cmp dword [eax-8], egg1 ; checking for egg1 jne next ; if not continue searching cmp dword [eax-4], egg2 ; checking for egg2 jne next call eax section .data egg1 equ "Egg-" egg2 equ "Mark" My second question would be, why is eax pointing to current memory address: (gdb) run Hunter Length: 21 Payload Length: 36 Dump of assembler code from 0x8049700 to 0x8049719: => 0x08049700 <hunter+0>: inc eax 0x08049701 <hunter+1>: cmp DWORD PTR [eax-0x8],0x6d6d7559 0x08049708 <hunter+8>: jne 0x8049700 0x0804970a <hunter+10>: cmp DWORD PTR [eax-0x4],0x67674579 0x08049711 <hunter+17>: jne 0x8049700 0x08049713 <hunter+19>: call eax 0x08049715 <hunter+21>: add BYTE PTR [edx+0x75],cl 0x08049718 <garbage1+2>: jae 0x804978e 1: x/xw $eax 0x8049700 : 0xf8788140 1: x/xw $eax 0x8049701 <hunter+1>: 0x59f87881 1: x/xw $eax 0x8049702 <hunter+2>: 0x7559f878 Hope someone can help me, feeling a bit helpless with it. Edited August 1, 2016 by pcfx
evlncrn8 Posted August 2, 2016 Posted August 2, 2016 (edited) umm.. doesnt strlen look for a null terminator ? and what the hell are you using strlen for in the first place ? printf("length: %d\n", (sizeof(egg))); printf("length: %d\n", (sizeof(payload))); int (*ret)() = (int(*)())egg; ret(); Edited August 2, 2016 by evlncrn8
kao Posted August 2, 2016 Posted August 2, 2016 You're trying to run before you've learned to walk. Start by learning basics of assembler and C library functions. Only then move to shellcodes and advanced stuff. Otherwise you'll be posting one beginner question after next one for a year or two. 1) strlen takes string and scans it until it finds terminating \0 character. Passing binary data to strlen is a fornicating stupid idea to begin with. Apparently shellcode1.c is compiled with data structure alignments and uses \0 for padding, so strlen works as expected. On the contrary shellcode2.c is compiled without alignments, or uses another character, like 0xCC for padding. Therefore strlen cannot find calculate lengths of buffers correctly. It's not a problem of strlen, it's a problem of coder who wrote that code. Simple disassembly or hex editor would tell you that. 2) For some reason it assumes that EAX will be pointing to code or data start. Why? No idea. Ask the moron who wrote that shitcode. As far as I can find, it's not Linux standard behavior, nor Windows.. 1
pcfx Posted August 2, 2016 Author Posted August 2, 2016 1. Why is nearly every shellcode snippet using strlen()? I opened shellcode2.c in hex editor and the length of 49 and 28 matched the length of the two shellcode parts until the first 0x00. How do you know the file has data structure alignment or how to check that? I compiled both with. gcc -fno-stack-protector -z execstack shellcode2.c -o shellcode2
evlncrn8 Posted August 2, 2016 Posted August 2, 2016 they shouldnt... strlen as its name implies is for strings... stringlength -> strlen... they should use sizeof instead, considering you're building the byte array... and also if you built it you should know damn well how to find / calculate its displacment
kao Posted August 3, 2016 Posted August 3, 2016 1. Long long time ago the most common exploit was buffer overflow in string operation. Therefore shellcodes were limited to printable characters (or anything but \0). So, shellcodes and examples for 1990s could use strlen. Anything more recent would use sizeof. 2. Neither of your screenshots show compiled shellcode1.c. Since strlen worked fine there, I must conclude that there was '\0' after egg data. The only reasonable explanation I can think of - there was some sort data alignment involved. 1
pcfx Posted August 3, 2016 Author Posted August 3, 2016 (edited) 1. If I look at 5 most recent shellcode exploits on exploit-db, 3 of 5 use strlen(). Seems to be a bad habit even now a days but I know better now, thanks. 2. The upper two screenshots show the compiled shellcode, which didn't work. Here are egg and payload of shellcode1.c. Although payload (second screenshot) doesn't end with 0x00, strlen() gets the right payload size? My question still: How can I determine a data alignment is involved. The only thing I changed from shellcode1 to shellcode2 was removing the first 8 bytes of payload[]. 0x45, 0x67, 0x67, 0x2d, 0x4d, 0x61, 0x72, 0x6b, Edited August 3, 2016 by pcfx
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now