CTF-攻防世界 Reverse新手練習解析

博主也是CTF小白,入門ing。。。方向是RE + PWN。文章可能多有紕漏,但會持續更新更正。希望大家多多指出不足之處。

0x1. re1

解析:
這道題很簡單:
打開.exe隨便輸點東西進去,發現不對,退出。
用IDA打開,點到十六進制視圖
點IDA視圖–打開子視圖–字符串(英文版IDA應該就是view這種常見的單詞)。或者直接按shift+F12。然後在一大堆東西中找到這個:flag get
在這裏插入圖片描述
英文應該都能看懂吧······這就是關鍵
雙擊,跳到十六進制視圖窗口就可輕鬆獲得flag:DUTCTF{We1c0met0DUTCTF}

0x2.game

n是燈的序列號,m是燈的狀態
如果第N個燈的m爲1,則它打開,如果不是,則關閉
起初所有的燈都關閉了
現在您可以輸入n來更改其狀態
但是你應該注意一件事,如果改變第N盞燈的狀態,第(N-1)和第(N + 1)的狀態也會改變
當所有燈都亮起時,將出現標誌
現在,輸入n
(來自谷歌翻譯·······QAQ)

解析:
依舊什麼都不用管,直接拖到IDA打開
shift+F12
Alt+T(搜索字符串),搜索: flag
直接跳出來:done!!!the flag is
雙擊,跳到IDA View-A(這裏說一下,字符串窗口雙擊跳轉的窗口是打開字符串窗口時停留的窗口。也就是說,當你頁面停在IDA View-A時,你打開了字符串窗口,那在字符串窗口雙擊,就跳轉到IDA View-A)
Ctrl+X(交叉引用)
F5(生成僞代碼)
如下圖
在這裏插入圖片描述
在這裏插入圖片描述

這裏我們就初步接觸到了逆向的加解密,加解密其實也就是算法的使用。這裏加密比較簡單,甚至都不能稱爲加密。*(&v2 + i)的值練起來就是flag的值
所以得到解密代碼:(博主使用python,其他語言均可)

#v2:原代碼v2-v58的值
v2 = [123,32,18,98,119,108,65,41,124,80,125,38,124,111,74,49,83,108,94,108,84,6,96,83,44,121,104,110,32,95,117,101,99,123,127,119,96,48,107,71,92,29,81,107,90,85,64,12,43,76,86,13,114,1,117,126,0]

#v59:原代碼v59-v115的值
v59 = [18,64,98,5,2,4,6,3,6,48,49,65,32,12,48,65,31,78,62,32,49,32,1,57,96,3,21,9,4,62,3,5,4,1,2,3,44,65,78,32,16,97,54,16,44,52,32,64,89,45,32,65,15,34,18,16,0]

s = ""

for i in range(57):
    v2[i] = v2[i] ^ v59[i]
    v2[i] = v2[i] ^ 19
    s += chr(v2[i])
    
print(s)

得到flag:zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}

0x3.Hello,CTF

解析:
老辦法,遇到.exe直接打開看看是啥玩意兒。隨便輸,發現會彈出來wrong,輸出巨長字符串後會直接退出
拖到IDA打開,shift+F12
發現和我們的程序中有一個東西是匹配的:“wrong!\n”,關鍵點get到!
雙擊進IDA View-A,Ctrl+X,F5
在這裏插入圖片描述

簡單的邏輯推理:
v9爲我們的輸入,長度≤0x11(10進制的17)
v10儲存的就是v9,和v13進行比較。相同就success
到這裏我們就知道輸入必須就是v13這個字符串相同。但是發現引號中字符數>17,所以判斷這是個16進制數表示的字符串(ASCII碼),用網上16進制轉字符串得到flag:CrackMeJustForFun

0x4.open-source

拿到源碼了嚶嚶嚶,就直接IDE打開不解釋!
源碼如下圖:
在這裏插入圖片描述
解析:
這個題不用逆向也能做,純源碼分析就能得到答案。
逆向做法:
隨便輸入幾個參數編譯鏈接執行發現wrong
拖IDA,shift+F12,發現“Get your key:”,雙擊,Ctrl+X+確定,F5
發現v3就是key,寫出代碼求得v3

v3 = 11 * (25 % 17) + 1628458542 + len("h4cky0u") - 1615810207
print(v3)

得到12648430,轉16進製得到flag:c0ffee

0x5.simple-unpack

解析:
從題目就知道需要脫殼,但是讓我們假裝不知道QAQ!依舊還是拖到IDA裏面看看,果然!
什麼都看不懂······那還是老步驟:shift+F12,發現了一個關鍵字:upx,說明他是upx壓縮的文件,所以就需要upx解壓

這裏博主還是推薦大家裝一個kali,雙系統或者虛擬機都可以。如果原本就用的Ubuntu等Linux可以忽略這句話QWQ

upx -d filename脫殼
在這裏插入圖片描述

拖到IDA,shift+F12直接得到flag:flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}

0x6.logmein

解析:
日常拖IDA,shift+F12
第一次經驗性進You entered the correct password!\nGreat job!\n,發現反編譯出來的函數沒啥用,所以第二次選擇進輸入點Enter your guess(類似於找OEP時先找PUSHAD和POPAD)
在這裏插入圖片描述
邏輯分析:
v8是給定的字符串,v7是long long的數據類型
s是輸入,v3是s的長度,v3必須≥v8的長度17,否則會進入提示輸入錯誤的函數sub_4007C0()
重點是:(_BYTE *)&v7的意思是,把longlong型的v7強制轉化爲byte型的地址,簡單的說,就是把它看成字符串(C語言字符串本質都是指針首地址+偏移)。
所以我們用先用v7的值10進制轉16進制,然後16進制轉文本得到:ebmarah
重點來了!爲什麼直接套這個字符串不對,根本原因是因爲在機器虛擬化內存後,規定地址排列規則時使用了小端法(最低有效字節在前面)。因此我們真正的解碼文本應該是把上面的答案倒過來寫:harambe

v8 = ":\"AL_RT^L*.?+6/46"
v7 = 'harambe'

for i in range(len(v8)):
    char = ord(v7[i % 7]) ^ ord(v8[i])
    print(chr(char),end='')
    

得到flag:RC3-2016-XORISGUD

當然個人感覺最簡單的辦法還是C++重現一遍。。。就不用考慮這麼多

#include <iostream>
using namespace std;

int main(){
	long long v7 = 28537194573619560;
	char *p = (char*)&v7;
	char v8[] = ":\"AL_RT^L*.?+6/46";
	for(int i = 0;v8[i]!=0;i++){
		v8[i] = v8[i]^p[i%7];
	}
	cout<<v8<<endl;
	return 0;
}

0x7. insanity

解析:
這個真的不知道咋解析······至於爲啥放這裏,也許就和題目所言一樣吧,希望大家身心愉悅繼續肝吧·······
拖IDA,shift+F12直接拿到flag:9447{This_is_a_flag}

0x8.no-strings-attached

這個題是真的有難度QAQ

解析:
正常步驟拖到IDA靜態分析,shfit+F12,發現第一行赫然出現:/lib/ld-linux.so.2。看見這個大家心裏應該都有數了,和linux有關沒跑了。同時也說明這是個ELF文件
字符串沒有關鍵字,就從IDA左邊函數列表找到main函數雙擊進去,F5反彙編,再進到authenticate函數看看(有的東西做多了就知道了),如下:
在這裏插入圖片描述
此時就真的看英語了······計算s2的函數decrypt正是非常專業的術語:解密。
粗略的看一下下面的僞碼,得出:ws是輸入,ws==s2時就是正確的flag
此時我們需要轉變一下思維:之前我們都是各種找、各種邏輯推斷正確輸入。但是我們忽略了一件事,那個與輸入的比較的正確答案,一定是加載到內存裏面之後,才與輸入比較。要是我們能跟蹤到這個正確答案儲存在內存的位置然後把他拿出來,這不也行嘛!!!(Reverse!)

思路有了,還需要實際的操作。這裏就不能用靜態分析了。這裏插一句,我們逆向分析分爲靜態分析和動態分析,直接拖到IDA反彙編看僞代碼,邏輯推斷等等都屬於靜態分析。換言之,在沒有執行程序或程序是靜態時的分析。
所以要用IDA動態調試ELF—IDA remote linux debugger

環境配置參考IDA動態調試ELF寫的非常清楚

爲了檢驗連通性,可以看看kali的命令行,如下圖
kali檢驗

首先我們進入authenticate,F5,點左邊設置斷點,如下圖(在s2剛被賦值完畢後停止,找s2的值)
在這裏插入圖片描述
然後按F9,編譯鏈接運行到斷點停止,如下圖
在這裏插入圖片描述
這個時候,我們看到了s2就儲存在寄存器eax中,所以我們在下面的Hex View窗口中右鍵,synchronized with,選eax,就能看到值啦,這就是flag,如下圖
在這裏插入圖片描述
至此拿到flag:9447{you_are_an_international_mystery}

0x9.csaw2013reversing2

解析:拖到IDA中分析發現有重要的函數IsDebuggerPresent(),這個函數目的就是反調試(檢測是否處於調試環境中)。既然如此千方百計阻止我們調試,那就直接OD動態走起。
我們拖到OD中,ctrl+n找到IsDebuggerPresent(),確定他的位置之後下斷點開始調試程序,發現底下有兩個對話框的代碼(能看見註釋那裏有Flag,Text字樣就ok),手動F8看一次,發現00C61000那裏的函數沒有執行。本着現在是“你不讓乾的事我偏要搞一次”的思想,我們修改程序跳轉代碼,發現flag赫然出現!
由於這樣的方法強行改彙編跳轉也存在“試”的成分,所以直接給修改完成的代碼(修改了4處),如下圖:
在這裏插入圖片描述

所以直接能拿flag啦:flag{reversing_is_not_that_hard!}

0xa.getit

解析:依舊老套路,拖IDA,shift+F12看字符串發現linux和一個很像flag形式的字符串"SharifCTF{???}",雙擊點進去,然後在左邊的框找到主函數,反彙編成僞代碼。如下圖:在這裏插入圖片描述
簡單分析代碼:(重點是11~20行)s長度限定,v5條件選擇,v3偏移量,用參數操作s,t爲最終存放數組,最後用流寫入tmp文件夾下的flag.txt中。但是/tmp是linux主目錄下一個存放臨時文件的文件夾,程序return後寫入的臨時文件也一併丟棄。

這裏額外說一下,這道題可以用在linux環境下運行,然後設置斷點去/tmp文件夾下找,或者直接更改流寫入的目標文件夾都是可以的。這裏我們使用windows純代碼分析的方法。

通過分析我們發現v3,v5已知,需要知道s和t。我們在IDA的IDA View-A的窗口中找到s的值,如下圖

在這裏插入圖片描述
找t的值,代碼如下:(注意這裏是題目有bug!!!t的值是SharifCTF{???},可在16進制視圖窗口查看)
在這裏插入圖片描述

最後寫出代碼

v5 = 0
s = 'c61b68366edeb7bdce3c6820314b7498'
t = ['S','h','a','r','i','f','C','T','F','{','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','}']
v3 = 0
l = len(s)
while(v5 < l):
    if( v5 & 1 ):
        v3 = 1
    else:
        v3 = -1
    t[10+v5] = chr(ord(s[v5])+v3)
    v5 += 1
flag = ''
for x in t:
    flag+=x
print(flag)

得到flag:SharifCTF{b70c59275fcfa8aebf2d5911223c6589}

0xB.python-trade

解析:
下載完文件發現是一個.pyc文件,百度得知.pyc文件其實是PyCodeObject的一種持久化保存方式(感興趣可自行搜索學習)。所以思路就比較清晰了:用python反編譯在線工具反編譯這個.pyc文件得到源碼,如下圖
在這裏插入圖片描述
關鍵點:encode(flag) == correct
所以就很容易寫出逆向解碼的代碼:

# encoding: utf-8
import base64
s = "XlNkVmtUI1MgXWBZXCFeKY+AaXNt"
flag = ""

#base64
b = base64.b64decode(s)# print(b)

#encode
for i in b:
    i -= 16
    i ^= 32
    flag += chr(i)
print(flag)

拿到flag:nctf{d3c0mpil1n9_PyC}

0xC.maze

解析:ELF文件,日常拖到IDA,查找字符串,交叉引用,F5大法好。
分析代碼,s1儲存輸入對象,比較前5位是不是"nctf{",第25位最後一位是不是"}"。之後發現asc_601060中儲存的是一個8*8的迷宮,迷宮如下:

  ******
*   *  *
*** * **
**  * **
**  * **
*  *#  *
** *** *
**     *
********

通過分析,發現v4是玩家輸入的方向:‘O’–左,‘o’–右,’.’–上,‘0’–下,由迷宮得到軌跡:右下右右下下左下下下右右右右上上左左
所以flag就是:nctf{o0oo00O000oooo…OO}


到這裏,整個攻防世界Reverse的Exercise area就解答完畢了,希望大家能多多交【pi】流【ping】!
RE真好玩~強顏歡笑.jpg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章