堆棧里的秘密行動:劫持執行流

  • 2020 年 3 月 11 日
  • 筆記

前情回顧

執行緒老哥執行memcpy越界訪問溢出,堆棧里的一眾對象難逃噩運。

詳情參見:堆棧里的悄悄話——智慧指針

1

神秘的0xCC

「去吧,為了首領的偉大理想出發」

我是一段二進位程式碼shellcode,0xCC大人精心創造了我,一同誕生的還有一個HTML表單文件小P,我就棲身在小P的身上,隨著一個POST請求,我們朝著目標奔去。

很快我們就抵達目的地,這是一個Linux帝國,無數的數據包在這裡來來往往。

「這裡可真熱鬧」

「噓,先別說話,馬上要經過防火牆,藏好了,可別被發現了」,小P一把捂住了我的嘴。

說完我們就來到了防火牆面前,當差的守衛查看了我們的源IP和埠,又看了目的IP和目的埠,接著瞟了一眼負載數據,當他望向我這邊時,我緊張的大氣都不敢出一聲,把頭深深的埋著。

守衛凶神惡煞的問到:「你是去80埠的?這裡面裝的是什麼?」

「回大人的話,這裡面是個HTML表單,這單業務比較急,還望大爺行個方便」,小P一邊說一邊悄悄給守衛的衣袖裡塞了一些銀兩。

「走吧,放行!」,總算等來了守衛的這句話。

通過了安檢,我倆被安排到了一個隊列等待,一會兒,一個自稱是Apache公司的執行緒大哥把我們取走了。

2

棧溢出 & Stack Cannary

執行緒大哥把我倆放到了一片陌生的區域。

「你等我一下,我去打聽下情況」,小P叮囑完我後,和隔壁一個對象聊了起來。

「我打聽清楚了,這裡是進程的堆區,你可還記得主人交代的任務嗎?」,小P問我。

「當然記得,我是shellcode,我要獲得執行機會,潛伏起來,和主人取得聯繫,等待下一步指示」

「嗯,很好,一會我會找機會讓你獲得執行機會,先等等」

「你要怎麼辦到啊?」,我有點好奇。

「你看到那個執行緒的棧沒?」,小P一邊說一邊給我指。

順著小P指的方向望去,我看到了他口中所說的棧,執行緒大哥正在旁邊忙碌,一會push,一會兒pop。

「我看到了,你猜你是想用棧溢出攻擊覆蓋返回地址,劫持指令暫存器,讓我獲得執行機會吧?」,我轉頭看著小P。

「小子,知道的不少嘛!不過你只回答對了一半,咱這次沒法覆蓋返回地址來獲得執行機會」

「哦,這卻是為何」

小P又指向了執行緒棧,「你看,返回地址前面有個8位元組數字,那個叫Stack Cannary,是Linux帝國抵禦棧溢出攻擊的手段」

「不就是8個位元組的數字,有什麼可怕的?」,我不屑一顧。

「可不要小瞧了它,當棧溢出數據被修改後,函數return時,在從棧中取出返回地址之前會檢查它有沒有被修改,一旦被發現修改過,進程就會終止,咱們的計劃不就泡湯了嗎?」

「這程式設計師還挺聰明的嘛!居然還做了檢查」

「這可不是程式設計師做的,這是GCC編譯器乾的,只要編譯的時候添加了-fstack-protector標記就會自動添加,對原來的程式程式碼是透明的」

聽著小P的話,我陷入了沉思。

3

C++虛函數表

「如此一來,那豈不是不能使用棧溢出了?」

「也不盡然。直接覆蓋返回地址是基本不太可能了,過不了函數返回時的檢查。但可以在它做檢查之前就動手,搶先一步劫持執行流程,就沒有機會做檢查了。」,說完小P朝我眨了眨眼睛。

還有這種操作,我還是第一次聽說,「不覆蓋返回地址怎麼能劫持到執行流程呢?你打算怎麼做?」

「噓!執行緒大哥來了!」

我一下趴著不敢動彈,余光中瞥見執行緒大哥取出了隔壁對象的前面8個位元組後就離開了。

「好險,差點被發現,你呀,說話別那麼大聲,計劃敗露那就全完了,知道嗎!」,小P把我訓了一頓。

「好啦,我知道了。我剛才問你的問題你還沒回答我呢」,這一次我壓低了音量。

「你猜剛剛執行緒大哥過來讀取的是什麼?」小P神秘地說。

「不是取的隔壁對象的內容嗎?你也看到了啊還問我」

「這我當然知道,我是問你那內容是什麼?」

「這我怎麼知道,我又不知道那是個什麼對象」

小P用手臂把我的頭挽在胸前,在我耳邊輕輕說到:「他讀取的應該是對象的虛函數表指針,你看執行緒大哥讀完內容後,又去這內容指向的地方了,你再看那裡有一個表格,表格里每一項都是一個函數的地址」

我按他說的看過去,果如他所言,只見執行緒大哥讀取了表格中的一項後轉身就去執行那裡的程式碼了。

「你饒了半天,還沒告訴我你打算怎麼讓我獲得執行機會呢」,我又一次提出了我的疑問。

「你別著急啊,這秘訣就在這虛函數表指針上。你再看看執行緒棧,瞧見沒有,那裡也有一個對象,咱只要把它的虛函數表指針覆蓋,待會兒執行緒大哥調用它的方法時,來讀取的地址,我就安排成你的地址,就能讓你有機會執行了」

我腦子飛速運轉想像了一下這幅畫面:

「果然是妙招!不過你怎麼知道對象的虛函數表指針在哪裡呢?」,我向小P提出了疑問。

「虛表指針一般都是在對象的頭部,也就是最前面8個位元組」

「所有對象都是嗎?」

小P搖搖頭,「那倒也不是,有些對象所屬的類根本沒有虛函數,那也就沒有虛函數表,虛表指針更是無從談起了。不過這個對象是有的,主人在創造我們時已經都提前研究好了。咱們只需靜待時機,按計划行事即可。」

4

DNS隱蔽通訊

「快醒醒,該我們上了」,小P把我叫醒,不知過了多少時間, 我竟然睡著了。

只見執行緒大哥執行了memcpy,把我和小P一起複制到了棧里。

我昏沉的腦袋一下子清醒了過來,下意識的看了一下之前那對象,現在他就在我上面不遠處,已經被小P的身體覆蓋掉了,再仔細一看這對象的前8個位元組,指向的函數表就在我的頭頂,而表中每一項都指向了我所在的地址,0xCC大人果然安排的天衣無縫。

果不出乎所料,按照周密的計劃,我終於等來了執行的機會,潛伏這麼久,總算是可以活動活動了。

「你在幹嘛?」,小P大聲喝住了我。

「按照計劃,我在和0xCC大人聯繫啊」

「你就這樣直接建立網路連接嗎?一會兒防火牆就會發現了」,小P面色凝重。

我有點不解,「那要怎麼辦?我怎麼和大人聯繫上?」

「臨行前大人叮囑我了,用DNS請求把數據帶出去,把數據編碼後作為請求的域名,分多片發出去」

按照小P的策略,我把通訊內容先進行了一次加密,然後再使用base64編碼後,拆成了三段,準備用三個DNS請求給發出去。

….JXU0RTAwJXU1MjA3JXU2QjYzJXU1RTM4JXVGRjBDJXU3QjQ5JXU1Rjg1JXU2MzA3JXU3OTNB.com

「等一下,你不能使用0xCC大人的IP作為目的IP地址,會被防火牆發現的,就使用這裡默認的DNS伺服器地址就好了」,小P又一次喝止了我。

「使用這裡默認的DNS伺服器地址,那大人怎麼能收到消息呢?」,我有點納悶。

「放心,路由器那裡已經安排好了!」

未完待續·······

彩蛋

「咦,DNS數據包發送失敗了!」

「應該是沒有許可權,快翻一下大人給你準備的Linux提權指南」

欲知後事如何,請關注後續精彩……

原創不容易,快轉發分享給更多人看啊