1

I have the following shellcode:

xor  eax, eax   ; eax = 0
push eax        ; 0 (end of the string)
push 0x68732f2f ; //sh
push 0x6e69622f ; /bin
mov  ebx, esp   ; ebx = &(/bin//sh)
xor  ecx, ecx   ; ecx = 0
mov  al, 0xb    ; execve
int  0x80

Which, converted into hex is used in the following C program:

const char shellcode[] =
     "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xb0\x0b\xcd\x80";

int main(){
    (*(void(*)()) shellcode)();
    return 0;
}

This works just fine, but when I step through the payload with gdb I see an extra instruction added to the shellcode:

$ gdb shellcode
(gdb) disass main
Dump of assembler code for function main:
   0x080483ed <+0>:     push   %ebp
   0x080483ee <+1>:     mov    %esp,%ebp
   0x080483f0 <+3>:     and    $0xfffffff0,%esp
   0x080483f3 <+6>:     mov    $0x80484a0,%eax
   0x080483f8 <+11>:    call   *%eax
   0x080483fa <+13>:    mov    $0x0,%eax
   0x080483ff <+18>:    leave
   0x08048400 <+19>:    ret
End of assembler dump.
(gdb)  x/14i 0x80484a0
   0x80484a0 <shellcode>:       xor    %eax,%eax
   0x80484a2 <shellcode+2>:     push   %eax
   0x80484a3 <shellcode+3>:     push   $0x68732f2f
   0x80484a8 <shellcode+8>:     push   $0x6e69622f
   0x80484ad <shellcode+13>:    mov    %esp,%ebx
   0x80484af <shellcode+15>:    xor    %ecx,%ecx
   0x80484b1 <shellcode+17>:    mov    $0xb,%al
   0x80484b3 <shellcode+19>:    int    $0x80
   0x80484b7 <shellcode+21>:    add    %al,(%ecx)
   ... (gibberish)

You can see the shellcode+23 is an extra line, added to the shellcode. While searching for an answer here I discovered that it was making the shellcode to crash, and I had to clear the ecx register before calling the interrupt.

Do you know what is this extra command?

3

The original shellcode contains only eight instructions, but because you asked gdb to disassemble 14 instructions, it went ahead and did just what you asked. Since you asked to disassemble more than there actually are, it disassembled whatever bytes happened to be present after the variable (likely zero padding but maybe also other parts of the executable).

So no instructions were "added", you're just disassembling some junk that happens to be in the memory after it.

| improve this answer | |
  • I see, but the instruction +21 is considere part of the shellcode, whereas the next one (which I should have provided, my bad) doesn't have the <shellcode+XX>. – nobe4 Sep 4 '17 at 9:30
  • how did you compile it? normally there should be ret after int 0x80 – Igor Skochinsky Sep 4 '17 at 9:40
  • gcc -o shellcode shellcode.c, is there anywhere I can look for more settings? – nobe4 Sep 4 '17 at 9:42
  • are you sure you compiled the same source you mention in this question and not the previous version? (without \xc3) – Igor Skochinsky Sep 4 '17 at 9:43
  • yeah, sorry it was a bad copy/paste. There is no \xc3 at the end of the shellcode – nobe4 Sep 4 '17 at 9:46
1

Igor is right... The original shellcode does not include any ret (0xc3), so there are none in the decompiled asm. The thing is that when you ask gdb to disassemble 14 instructions, it disassembles 14 instructions interpreting the content of the memory as if it was instructions.

As a proof of what I say, here is a disassembly of the instruction add %al,(%ecx):

$ rasm2 -a x86 -C 'add %al,(%ecx)'
"\xc0\x00"

Which is, in fact, "\x00\xc0" (because of the endianness) and where the first "\x00" is, in fact, the final character of the shellcode string.

The following characters are very likely the code of the main function or whatever is in the memory at this place.

Anyway, reread more carefully the answer of Igor (he's right!).

| improve this answer | |
  • Got it now, thanks for insisting on Igor's answer. Should I also not believe gdb when he tells me that an instruction is part of the shellcode? – nobe4 Sep 4 '17 at 12:07
  • 1
    gdb never told you that it was part of the shellcode. You asked for 14 instructions after the address you set, and voilà, you have 14 instructions... But, there is absolutely nothing that tells you if you are within or outside the bounds of the shellcode. You have to understand that the securing frontiers that you have at a high-level totally disappear when you are at the asm level. :-) – perror Sep 4 '17 at 17:00
  • Hehe thanks, I feel like going down the rabbit hole makes you more responsible for your actions! – nobe4 Sep 4 '17 at 17:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.