攻防世界RE练习区题目总结(1-10)
前言
這篇文章是我做完攻防世界練習區的題目后對這十道題做的總結。emmm,其實這幾道題我幾個月前就做完了,這幾天又回去試著再做一遍發現還是有一些地方存在疑惑,并且速度也沒有太大的提升。所以決定把之前做過的題目整理一下都寫在博客里,便于以后復習順便把一些我沒搞懂的地方也記錄在這里,希望以后可以解決。也希望能有大佬有緣看到我這個小菜鳥的文章,可以幫我指點迷津。
這一篇只寫攻防世界新手區的幾道題,之后我還會把BUUCTF做的題也做個總結,寫一篇博客,希望可以把這個習慣保持下去。說了這么多廢話,下面開始正文。
第一題:open-source
首先把附件下載下來,在exeinfope里查殼(雖然第一道題基本上沒有加殼的可能性,但我覺得這是個很好的習慣) 可見這個文件沒有加殼。這個文件的后綴是.c,所以直接在IDE里打開,這里我用的是DEVC++
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc != 4) {
printf(“what?\n”);
exit(1);
}
}`
由最后的兩個printf語句可以看出flag就是hash,由%x可以看出是十六進制表示。
所以向上看對hash進行運算的只有
可知hash的值與first,second,argv[3]的值有關,從上面的3個if語句可以判斷出:當if()里的條件為真時,都會提示錯誤并退出程序,所以3個if()里的條件都為假,所以可以推測出下列條件;first=0xcafe,second % 5 != 3&&second % 17 == 8(最小的second是25),argv[3]=h4cky0u(所以strlen(argv[3])=7)。將上述條件帶入計算hash的那段代碼可以得出hash,下面是我寫的代碼`#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int first=0xcafe;
int second=25;
int a=7;
}`
結果是
所以flag就是c0ffee。
第一題拿下!
第二題:simple-unpack
由題目描述可以看出這是一個加殼的文件,所以先拖到exeinfope里查殼
可以看出加了UPX這一類殼。所謂加殼就是為了隱藏程序真正的OEP(入口點),所以為了正常地打開程序使程序正常運行,我們必須脫殼。我選擇的是用upx脫殼。
脫殼成功!關于upx脫殼我之前看到一篇博客講得挺詳細的,我把超鏈接放在下面。
使用upx脫殼工具脫殼
脫殼結束后再把脫殼后的文件放在exeinfope里看一下。
可以看到現在已經沒有UPX殼了,之后把文件拉到IDA里打開。
按F5反匯編后發現flag相當可疑,雙擊flag追蹤過去看到
發現了flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}。
第二題拿下!
第三題:logmein
下載附件后老規矩拿到exeinfope里查殼,
發現沒殼,而且是64位的文件,所以放到IDA64里靜態分析。ctrl+f搜索main函數,再按F5反匯編,如圖
雙擊sub_4007F0看到
說明輸入正確的flag會讓程序輸出上述printf的一句話并退出。
再雙擊sub_4007C0看到
所以當輸入錯誤的flag時會使程序輸出上述一句話并退出。
所以不能讓程序運行sub_4007C0這個函數,所以*s[i] = (char)(*((_BYTE )&v7 + i % v6) ^ v8[i])
必須成立。去上面的代碼找到v7,v6,v8[]
看出v6=7 , v8[]=:"AL_RT^L*.?+6/46 , v7=28537194573619560LL,將28537194573619560LL轉換成字符,如圖
因為IDA是小段法存儲,所以真正的v7應該是ebmarah倒過來變成harambe。下面是我寫的解題代碼
結果為
第三題拿下!
第四題:insanity
老規矩先把附件下載后放在exeinfope里查殼
看出文件無殼且是32位的,用IDA打開
發現整段代碼沒有什么運算,感覺&strs有點可疑,雙擊進去
發現9447{This_is_a_flag}…感覺簡單得有點過分
又去字符串窗口看了一下
flag確實就是這個了(難道這才是第一題?)
第五題:python-trade
老規矩查殼
無殼是用python寫的。發現IDA打開之后無法反匯編,所以當時我去找了一些博客,發現是要用python反匯編,這里我用的是在線Python反匯編,超鏈接我放在下面。
在線Python反編譯工具
推測出當flag在encode函數中加密后與correct相等就成功。
由這一段看出將correct通過base64解碼后,經過xor異或可以再得出原來的flag。
下面是我寫的解題代碼
得出結果nctf{d3c0mpil1n9_PyC}
第五題拿下!
第六題:re1
老規矩先查殼
無殼且是32位,拉到IDA里反匯編
雙擊aFlag_0進去
發現aFlag_0意思是flag錯誤,雙擊unk_413E90進去
發現顯示的是flag get,所以正確的flag會使程序進行unk_413E90
所以if()里的條件要為假才可以不進行aFlag_0,所以v3要為0
因為v3是由 *v3 = strcmp((const char )&v5, &v9) 決定的,當v5=v9時v3才=0,發現v9由 **_mm_storeu_si128((__m128i )&v5, _mm_loadu_si128((const __m128i )&xmmword_413E34))決定,
發現xmmword_413E34有點可疑,雙擊進去
猜測v9就等于xmmword的值,將3074656D30633165577B465443545544h轉換成字符
因為IDA是小端法,所以這一串字符應該反過來輸出,即為DUTCTF{We1c0met0}
一看就知道這就是flag
第六題拿下!
第七題:game
老規矩下載之后放到exeinfope里查殼
發現無殼且是32位的exe文件,發現是exe可執行文件,直接雙擊打開
這一看我就樂了,經典點燈小游戲,簡單地說就是12345678分別控制1234578這8盞燈及其相鄰的燈的滅亮(1和8也算作相鄰的),了解過這個游戲的都知道直接按12345678的順序點一遍就可以全部點亮了。全點亮后如下圖
……發現flag真的出來了。
下面放在IDA里看一下,發現下面這一段很明顯是判斷燈是否全亮的
雙擊sub_457AB4()進去,最后發現一段循環異或,猜測這就是flag的算法
寫一段代碼把v2到v58,v59到v115的值分別放在2個數組里,再進行異或運算,最后輸出結果。
(把這些數據拿到數組里真是太麻煩了,本人太菜,一個個復制粘貼過去的,有大佬知道什么快速的方法希望能告訴我 (~ ̄▽ ̄)~)
有個地方我想說一下,本來我的代碼是把printf放到for循環之外的,我打算一次性輸出整個字符串,但是控制臺老是顯示NULL,我到現在也不清楚是為什么,最后只能一個一個字符輸出了,有大佬知道為什么的話希望能告知 o(@)o。
最后結果如下圖
第七題拿下!
第八題:Hello,CTF
老規矩下載附件拖到exeinfope查殼
發現無殼且是32位的exe文件,嘖嘖,一看又是exe我想不會又可以不寫代碼直接玩出flag吧,結果我雙擊進去發現只有一句話:please input your serial:……emmm還是老老實實的IDA打開吧。ctrl+F查找main之后按F5反匯編,然后直接去找判斷成功的代碼如下
看出v3要大于等于17,并且v10與v13要相同才可以進行aSuccess。繼續往上看
要輸入v9,并且v9的長度要小于等于17,然后在do循環里把v9[v3]賦給v4,發現sprintf很像printf,猜測是輸出函數,感覺asc_408044可疑,雙擊進去發現
有%x表示十六進制,猜測sprintf就是把v4用十六進制表示,再往上看
發現v13=437261636b4d654a757374466f7246756e,所以flag應該就是把437261636b4d654a757374466f7246756e用十六進制表示出來,為了方便我就直接用在線轉換工具把它轉換成16進制了,結果如下。
flag就是CrackMeJustForFun
第八題拿下!
第九題:no-strings-attached
老規矩下載附件拉到exeinfope查殼。
發現無殼且是32位的,拉到IDA里去反匯編,發現main函數反匯編后只有這些東西
發現authenticate是證實的意思,所以猜測flag與authenticate有關系,雙擊進去看見
發現最后的if-else與判斷勝負的函數很像,雙擊unk_8048B44進去
發現有Success,估計正確的flag就可以進入unk_8048B44
發現wcscmp和strcmp很像估計作用也是一樣的,就是當ws=s2的時候就可以進入if了,再往上看發現decrypt函數,decrypt是翻譯的意思,猜測是加密函數,雙擊進去。
發現這段代碼先把s的值復制給dest,然后將dest的每個值減去a2的每個值,然后返回值是dest,從原函數可知dest的值就是之前的s2。接下來就是要找出傳入的s和a2的值,即原來的s和dword_8048A90,雙擊原來的dword_8048A90進去,看見了s和dword_8048A90的值,分別選中它們的值后按Shift+E,選擇C無符號字符數組(十進制),將值復制下來準備寫解題代碼時用。記得最后的4個0不要復制,因為字符串默認結尾為0。
下面是我寫的解題代碼。
最后刪去空格的結果如下
第九題拿下!
第十題:maze
l老規矩拿到附件之后查殼
發現無殼且是64位的文件,根據題目描述這應該是一道迷宮題。關于迷宮題,我當時做完這道題之后專門去找了一些資料學習,其中有一篇博客講的很好,由題目也有解析,我把超鏈接和網址放在下面。
逆向迷宮題總結
網址:https://blog.csdn.net/weixin_50549897/article/details/110633105
用IDA打開文件,ctrl+F查找main函數,F5反匯編之后,看了看發現有4個if語句,因為是迷宮題,所以推測這四個if就是用來判斷上下左右的,把if()里的數字都換成字符,發現4個方向鍵是 ‘O’ , ‘o’ , ‘.’ , ‘0’ 。發現四個if語句最后都會到LABEL_14,一直追蹤下去,發現如下代碼
發現**if ( asc_601060[8 * (signed int)v10 + SHIDWORD(v10)] != ‘#’ )**應該就是判斷是否到達終點的函數,雙擊asc_601060進去發現如下圖
數了數空格,*,#一共有64個字符,推測應該是8x8的迷宮
四個if語句進行的函數代碼如下
可以看出上下和左右應該分別由 ‘O’,‘o’ 和 ‘.’ ,'0’控制,并且發現有>0和<8來控制邊界所以可以確定這個迷宮就是8x8的迷宮了。
因為O和o傳入的參數是+1的,4個方向函數傳入的參數都是4個字節的,所以O和o應該是高位4字節,而.和0應該是低位4字節,推測高位決定行低位決定列,所以推測O和o應該決定左右,.和0應該決定上下,所以上下左右分別為 ‘.’ , ‘0’ , ‘O’,‘o’ .方向搞定。。再往上看發現如下代碼
可以看出輸入的s1就是flag,并且flag的長度等于24,并且開頭前5個字符就是 “nctf{”,并且結尾的字符是 ‘}’。所以能夠操作的步數是并且只能是24-6=18步,下面是我寫的打印迷宮的代碼。
#include <stdio.h> #include <stdlib.h> #include <string.h>int main() {char v[100]=" ******* * **** * **** * *** *# *** *** *** *********";printf("%d\n",strlen(v));for(int i=0;i<64;i++){printf("%c",v[i]);if((i+1)%8==0){printf("\n");}}return 0; }打印出來為
其中*為墻壁,空格為可走的路徑。走幾次迷宮就可以判斷出來走法了,走法為:右下右右下下左下下下右右右右上上左左,所以flag=nctf{o0oo00O000oooo…OO}。
第十題拿下!
總結
首先當時做題時遇到的最大問題就是見過的題目太少,基本每一道題都是新的題型,媒體都要去查資料。所以我認為,想要提高自己的技術,最重要的就是要都做題,關鍵是做不同類型的題,不然很容易遇到無從下手的情況。
還有兩道題我還要再琢磨一下,這次再次回顧做題的時候發現那兩道題思路還是不太清晰,所以我這次沒有寫進來。等之后有空我就會寫出來的。
后續要學習的東西,在此立個flag
1.脫殼方法與技術
目前脫殼我只會用upx脫殼,但我之前在找資料的時候看到很多大佬都是用的ollydbg動態調試來脫殼的,之后我肯定是要重點學習一下的。
2.相關匯編基礎打牢
沒有系統地專門學習過匯編,只是在網上找資料學會了一些皮毛,對于堆棧的理解還是不夠深刻,之后也要找時間打打牢。
3.做題做題再做題
果然做題才是積累經驗的好方法,之后題目肯定不能斷
4.博客繼續寫
這次回顧攻防世界的題目讓我再次對自己的記性產生了懷疑,果然好記性不如爛筆頭,之后每做完一些題我都要寫一下博客。
總結
以上是生活随笔為你收集整理的攻防世界RE练习区题目总结(1-10)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AI时代下,如何打造一个具有情感化属性的
- 下一篇: L1-078 吉老师的回归 (15 分)