I'm currently trying to understand a peculiar behaviour with a shellcode. When reaching a MOV instruction just before an interrupt the shellcode get modified:

radare2 output

As you can see on the radare2 output, my shellcode is still there before the mov instruction, but once I step into it all the shellcode seems scrambled. I tried this shellcode on an ubuntu virtualbox VM.

The target binary is taken from RPISEC lab3B.

The shellcode come from pwntools, I tested it first directly from the lib and it works on the VM. I'm wondering how executing a mov instruction can have such an impact especially since I'm not getting any sigsev.

  • 1
    what version of radare2 do you use? Please share the output of r2 -v
    – Megabeets
    Jul 4 '18 at 5:04
  • 1
    Provide the shellcode with all the details how you inject it. Jul 4 '18 at 5:14
  • @Megabeets here is the output for r2 -v on my machine:
    – Kodoque
    Jul 4 '18 at 20:15
  • @Megabeets here is the output for r2 -v on my machine: radare2 2.7.0-git 18463 @ linux-x86-64 git.2.6.0-285-g535b685 commit: 535b6855d54d0359637c98dc9c6734e6d33d6d52 build: 2018-06-18__20:44:12
    – Kodoque
    Jul 4 '18 at 20:28

The shellcode you're using is this

 0:    6a 01                    push   0x1
 2:    5f                       pop    edi
 3:    68 01 01 01 01           push   0x1010101
 8:    81 34 24 75 79 75 01     xor    DWORD PTR [esp], 0x1757975
 f:    68 6f 61 64 2e           push   0x2e64616f
14:    68 70 61 79 6c           push   0x6c796170
19:    6a 05                    push   0x5
1b:    58                       pop    eax
1c:    89 e3                    mov    ebx, esp
1e:    31 c9                    xor    ecx, ecx
20:    cd 80                    int    0x80
22:    89 c5                    mov    ebp, eax
24:    89 c3                    mov    ebx, eax
26:    6a 6c                    push   0x6c
28:    58                       pop    eax
29:    89 e1                    mov    ecx, esp
2b:    cd 80                    int    0x80
2d:    83 c4 14                 add    esp, 0x14
30:    8b 34 24                 mov    esi, DWORD PTR [esp]
33:    31 c0                    xor    eax, eax
35:    b0 bb                    mov    al, 0xbb
37:    89 fb                    mov    ebx, edi
39:    89 e9                    mov    ecx, ebp
3b:    99                       cdq
3c:    cd 80                    int    0x80

This is from here in pwntools.

The first syscall is i386.syscall('SYS_open', 'esp', 'O_RDONLY') for payload.txt which will succeed if cwd has the file. The next is ${i386.syscall('SYS_fstat', 'eax', 'esp')} which has a signature like

int fstat(int fd, struct stat *statbuf);

According to the man page

These functions return information about a file, in the buffer pointed to by statbuf.

In your case statbuf is esp and hence the stack is overwritten. Always debug and read the shellcode you're using.

  • I don't know why r2 you are still on the mov instruction but judging by what's on your stack I'm pretty sure the syscall has been executed. In my case output
    – sudhackar
    Jul 5 '18 at 7:53
  • Oh thanks that would make sense, I tested it with run_disassembly from pwntools but thinking of it the shellcode must not be placed on the stack with this function (I'll look into the implementation) which might explain why it worked with the test.
    – Kodoque
    Jul 5 '18 at 9:58
  • Just make some space on the stack before executing your shellcode. sub esp,0x100 should work. Also, try to post as much details as you can. It took me quite sometime to manually copy the shellcode from the image and correlating with pwntools.
    – sudhackar
    Jul 5 '18 at 10:10
  • @sudhackar I was started to copy the shellcode too ;) Jul 5 '18 at 10:22
  • @Paweł Łukasik Sorry, it was indeed the readfile shellcode from pwntools :)
    – Kodoque
    Jul 8 '18 at 17:50

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.