Jump to content
Tuts 4 You

[C] Wrong strlen of array


pcfx

Recommended Posts

 

 

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 by pcfx
Link to comment

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 by evlncrn8
Link to comment

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..

 

  • Like 1
Link to comment

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

 

45.PNG

48.PNG

Link to comment

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

Link to comment

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.

  • Like 1
Link to comment

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,

egg.PNG

payload.PNG

Edited by pcfx
Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...