由於最近在學習binary,來拿幾道練練手,感受比國賽簡單多了(但願今年也這樣…)。大多都是工具的基礎使用。
寫了re部分的wp,若有錯誤和更簡單的解法歡迎大師傅們指點。linux
打開附件,先拖進Exeninfo看看是什麼類型。是一個32bit的ELF。
c++
因此拖進ida32,找到main函數,F5一下得到反彙編後的結果。數組
分析一下,程序用memset開闢了幾個連續的內存空間(能夠認爲是數組)v3,v4,v5.而後開始賦值。
一開始很懵。後來發現,問題在於賦的值真的只是數字嗎?咱們知道即便是字符串,在內存空間中存儲也是以數(ascii)的形式表示的。
因此咱們點一下v3第一塊空間的值,按R(轉爲字符)看看有什麼結果。
果不其然,GALF。看來程序實現的是一個反轉字符串的功能。直接把剩下的變量全轉爲字符。得到flag。
安全
FLAG-4092849uio2jfklsj4kl
(這是逆向題?)網絡
無語的題目。
拿到附件,首先發現他不是一個可執行文件。扔進ida顯示是一個二進制文件。也沒法反彙編。從題目得知應該是一個內存取證的題目(用linux掛載啥的,還沒太接觸過)。
而後無語的地方出現了,用ida按下shift+F12(查看字符串)。其中發現了:
行吧。(看來掛載以後,也是去找mnt/test/Flag.txt就能夠得到flag了)函數
flag{yc4pl0fvjs2k1t7T}
嚴格意義上的第一道逆向題。首先先分析:
一個win32程序。運行一下看看:
看來是要找出正確的輸入內容是什麼了,先用ida看下:
517個函數,附帶一個鬼畜的main函數反彙編結果:
字符串查找也沒有結果。靜態調試怕是要看死了,考慮用od動態調試。
先扔進od中,查看參考文本字符串,發現了輸入提示語:
雙擊,找到了在程序中對應的位置。按下F2下斷點:
運行程序到斷點處。這裏隨便輸入數據(111111),繼續執行程序:
按F8步進,注意觀察寄存器中內容的變化。終於發現步進到某個函數時,咱們剛纔輸入的數據被放進了ecx寄存器中:
繼續F8,能夠看到不遠處,有一條指令將main函數放入了eax寄存器中:
依舊F8,就能夠發現些眉目了。
首先,程序取出了main的首字母m,與輸入數據的頭位1,分別放到cl與al中:
以後將二者進行異或運算,保存在al中:
能夠看到結果是"":
接着步進,能夠看到程序往eax寄存中放入了一串疑似base64編碼的字符串:
同時咱們能夠看到,剛纔輸入的11111已經變成了"11111":
繼續步進,程序jb到了前面的內存地址,看來是一個循環:
因此咱們一路F8,看看這回cl與al中都放入了什麼,能夠看到cl中放入了a,al中放入了:
二者異或,和剛纔的操做相似,這回獲得了'=':
繼續F8下去,能夠發現程序的邏輯是:將輸入數據的每位與main的每位分別異或
例如咱們輸入了11111,那麼第一位1會先與m異或獲得符號,符號在與a異或獲得=符號……直到最後一次異或運算獲得了:符號,
接下來程序從剛纔輸入數據的第二位1開始,繼續上述操做,最後結果也獲得了:符號。
若是跑完整個流程,咱們輸入的111111應該變成了:::::
見圖,第二位運算完成後的結果以下:
最終結果以下:
這以後程序跳出了循環,繼續F8,能夠發現程序又在eax中放入了一串疑似base64的字符串:
再日後就回到了try again了:
這串base64能夠在參考文本字符串中看到:
解碼後結果爲:mgjlpO8F?Ts:R?T|?Ex^Bv工具
因此程序的邏輯大概能夠猜想出來了:輸入一串字符,將其每位與main每位分別異或,最後與串mgjlpO8F?Ts:R?T|?Ex^Bv對比,若不一樣則Try again
那麼咱們能夠本身寫一個exp:把mgjlpO8F?Ts:R?T|?Ex^Bv每位與niam每位分別異或,就能夠獲得咱們一開始應該輸入的串學習
exp沒啥難度,基本字符串操做,直接上代碼:ui
#include<bits/stdc++.h> using namespace std; int main() { char s1[100]="mgjlpO8F?Ts:R?T|?Ex^Bv"; char s2[100]="niam"; int i,j; for(i=0;i<strlen(s1);i++) for(j=0;j<strlen(s2);j++) { s1[i] = s1[i] ^ s2[j]; } puts(s1); return 0; }
獲得結果,看上去是個flag格式。編碼
輸入原程序中看看結果:
success,得解:
flag{D3M4_x1Y4_w4NsUI}
省賽的逆向題目貌似就這些了,仍是比較基礎的。但願能幫到你們。 順便吐槽一下網絡安全大賽竟然沒有Web題……