In multi-stage shellcode, rsi keeps becoming "" (empty string)

Skip to first unread message

Martin Petkov

May 10, 2021, 8:39:11 AM5/10/21
I'm currently trying to reproduce a multi-stage shellcode, as described in the slides. I'm executing a simple read and piping more shellcode into it. When I run the ELF directly, it performs as expected and executes the second stage.

However, when I try to run it against babyshell_level8 (which is supposed to sort the bytes), I get a really bizarre result. Basically, if I set rdi to 0, it overwrites my rsi with "" (empty string), no matter what else I do around it. I've tried multiple ways of setting rdi to 0 (shift left/right, xor, mov 1 then shift or do math), but every time that register becomes 0, rsi becomes "".

I assume this has something to do with the sorting. However, when the teaching exercise prints the code it's about to execute, it looks right. It doesn't look like the sorting mangled it at all. It shows lea rsi, mov rdi, mov rax, mov rdx, syscall, as expected and in the right order.

I'm not sure what I'm missing here. Either the teaching binary isn't showing the actual bytes after they were sorted, or somehow rdi is affecting rsi.

Martin Petkov

May 10, 2021, 10:54:14 AM5/10/21
I tried with babyshell1 and I'm getting the same behavior. strace shows the following:
$ cat ../stage2/shellcode-raw | strace /babyshell_level1_teaching1 <shellcode-raw
write(1, "Executing shellcode!\n", 21) = 21
write (1, "\n", 1) = 1
read(0, "", 1000) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPPER, si_addr=NULL} ---
+++ killed by SIGSEV (core dumped) +++
Segmentation fault

I really don't see why it would read 0 bytes and promptly segfault.

Martin Petkov

May 10, 2021, 11:53:16 AM5/10/21
I think I actually figured it out.

I now create a named pipe using mkfifo, and run like this:
(cat stage1/shellcode-raw ; cat pipe) | babyshell_level1_teaching1

And in a different terminal:
cat stage2/shellcode-raw >pipe

Which does actually run!
Reply all
Reply to author
0 new messages