REVERSE-COMPETITION-GeekChallenge2021
REVERSE-COMPETITION-GeekChallenge2021
- Re0
- 劉壯桌面美化大師
- 買Activity
- Re1
- 調(diào)試
- 珍惜生命
- new_language
- easypyc
- Brute_force
- win32
- wasm
- 猜拳
- have_a_tea
Re0
64位exe,ida打開,main函數(shù)中沒發(fā)現(xiàn)什么重要的邏輯
Shift+F12打開字符串窗口,直接找到flag明文
劉壯桌面美化大師
apk文件,jadx-gui打開,MainActivity中什么都沒有,于是查看與MainActivity在同一目錄下的其它類
在DesktopbeautifierConfigureActivityKt類里面找到一個(gè)好像和flag相關(guān)的方法loadTitlePref
loadTitlePref要獲取R.string.flag,我們跟過去發(fā)現(xiàn)只是一個(gè)整型,實(shí)際上是一個(gè)資源id
在android中,一個(gè)資源id和一個(gè)實(shí)際的資源綁定,而這個(gè)實(shí)際的資源在資源文件res中
于是在如下位置找到flag
買Activity
apk文件,加載了buyactivity庫,MainActivity大概作用是保存輸入到一個(gè)msgList里,沒什么大用,于是Msg和MsgAdapter這兩個(gè)類就不用看了
查看ExportedActivity這個(gè)類,發(fā)現(xiàn)可以直接在一個(gè)文本框打印flag
來到Decode類,從本地獲取一個(gè)字符串,然后對這個(gè)字符串順序異或16即為flag
這個(gè)時(shí)候可以直接用jeb調(diào)試smali,指定啟動(dòng)ExportedActivity即可獲得flag
這里我們按照getDecodedFlag方法的邏輯計(jì)算flag
ida打開libbuyactivity.so,來到Java_com_sorrowrain_buyactivity_Decode_stringFromNative
可以看到兩個(gè)字符串和一些操作,下面的操作一時(shí)看不懂,直接將兩個(gè)字符串拼接,然后順序異或16
可以看到兩個(gè)字符串拼接順序異或16后,得到的字符串中含有"{}",說明這個(gè)字符串大概率就是flag,但是順序不對
看著像柵欄,直接用工具,欄數(shù)為2,得到flag
解柵欄前:
解柵欄后:
Re1
64位的exe,ida打開
主要的邏輯在main函數(shù)中,輸入的長度為44,輸入經(jīng)標(biāo)準(zhǔn)base64變換后與0x40異或,最后與data比較
取出data的數(shù)據(jù),寫逆腳本即可
調(diào)試
64位elf,反編譯main函數(shù)后就只有一個(gè)字符串拷貝
查看main函數(shù)的匯編代碼,在偏移0x144C處有一條jnz條件跳轉(zhuǎn)指令,如果[rbp+var_144]非零則跳轉(zhuǎn)到loc_1455,但是在偏移0x1382處給[rbp+var_144]賦值為0,所以ida反編譯到j(luò)nz就判定為不跳轉(zhuǎn),進(jìn)而jmp到loc_14A0即main函數(shù)結(jié)束處
我們看到loc_1455中偏移為0x146B處調(diào)用了sub_11C8函數(shù),根據(jù)函數(shù)調(diào)用約定可知上面拷貝來的字符串作為參數(shù)傳入了sub_11C8函數(shù)進(jìn)行處理
于是可以猜測出題人就是想通過上述不執(zhí)行jnz條件跳轉(zhuǎn)的方式來隱藏flag
這里我們先去看一下sub_11C8函數(shù),ida分析sub_11C8失敗,先在偏移0x11C8處右鍵->undefine
我們知道函數(shù)的開頭一般是push rbp,機(jī)器碼為0x55,于是在偏移0x11CD處,按c將數(shù)據(jù)轉(zhuǎn)為代碼,再按p創(chuàng)建函數(shù),反編譯后得到
sub_11CD沒看懂什么邏輯,實(shí)際上也不需要看懂
出題人通過不執(zhí)行sub_11CD的方式來隱藏flag,于是我們可以patch程序,將jnz改寫成jz,如圖
保存后,直接運(yùn)行elf,即可得到flag
或者不patch程序,根據(jù)題目的提示,用ida遠(yuǎn)程調(diào)試elf的時(shí)候,在執(zhí)行jnz之前將零標(biāo)志位的值修改為0即可將程序流引向執(zhí)行sub_11CD,進(jìn)而獲得flag
珍惜生命
.pyc文件,用uncompyle6來反編譯
輸入flag和key,flag長度為51,key長度為8
驗(yàn)證key經(jīng)過多元方程組運(yùn)算后是否與"Syclover"相同,然后輸入的flag中{}中包含的內(nèi)容與key做循環(huán)異或,結(jié)果與一個(gè)給定的flag元組比較,驗(yàn)證輸入的flag是否正確
核心在求解key,用z3解多元方程組即可,需要注意兩個(gè)地方
1、用BitVec定義變量時(shí)需要是16位,筆者開始用8位,一直解不出來
2、此方程組多解,要用while s.check()==sat來輸出多組解,需要的是key的8個(gè)值都小于128的一組解
最后key與flag循環(huán)異或即可得到flag
flag = [113, 74, 71, 35, 29, 91, 29, 12, 114, 73, 60, 52, 69, 5, 113, 35, 95, 38, 20, 112, 95, 7, 74, 12, 102, 23, 7, 31, 87, 5, 113, 98, 85, 38, 16, 112, 29, 6, 30, 12, 65, 73, 83, 36, 12, 23] key=[0]*8 key[6] = 54 key[1] = 38 key[3] = 99 key[0] = 83 key[7] = 46 key[2] = 121 key[5] = 45 key[4] = 64 for i in range(len(flag)):flag[i]^=key[(i+1)%len(key)] print("SYC{"+"".join(chr(i) for i in flag)+"}") # SYC{W3$c0m3_T0_th3_py_w0r1d_@nd_z3_1s_s0000_g00d!!}new_language
32位.Net程序,dnSpy打開,來到Main
text為輸入,長度為38,將輸入作為下標(biāo)從sbox中取值,保存到array中,然后array與已知的array2比較
取出sbox和array2,寫逆運(yùn)算腳本即可得到flag
easypyc
python打包成的exe,用pyinstxtractor腳本解包
uncompyle6反編譯easypyc.pyc失敗,原因是解包后的easypyc.pyc文件魔數(shù)被破壞,需要修正正確
此為被破壞的easypyc.pyc文件
想要修正easypyc.pyc需要對照同目錄下的struct.pyc進(jìn)行修正,如圖
此為修正后的easypyc.pyc文件
保存后再用uncompyle6反編譯
aaaaaaa和bbbbbbbbbb是魔改了一點(diǎn)的RC4,最后異或的時(shí)候多異或了一個(gè)102,解RC4的時(shí)候要加上,密鑰為"Geek2021"
ccccccccc對RC4加密后的密文進(jìn)行異或運(yùn)算,結(jié)果與tttttt比較
先逆ccccccccc解得正確的RC4密文
再解魔改RC4即可得到flag
#include<stdio.h> void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k) {int i = 0, j = 0;char k[256] = { 0 };unsigned char tmp = 0;for (i = 0; i < 256; i++) {s[i] = i;k[i] = key[i % Len_k];}for (i = 0; i < 256; i++) {j = (j + s[i] + k[i]) % 256;tmp = s[i];s[i] = s[j];s[j] = tmp;} }/* RC4加解密函數(shù) unsigned char* Data 加解密的數(shù)據(jù) unsigned long Len_D 加解密數(shù)據(jù)的長度 unsigned char* key 密鑰 unsigned long Len_k 密鑰長度 */ void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密 {unsigned char s[256];rc4_init(s, key, Len_k);int i = 0, j = 0, t = 0;unsigned long k = 0;unsigned char tmp;for (k = 0; k < Len_D; k++) {i = (i + 1) % 256;j = (j + s[i]) % 256;tmp = s[i];s[i] = s[j];s[j] = tmp;t = (s[i] + s[j]) % 256;Data[k] = Data[k] ^ s[t]^102; //這里加一個(gè)異或102} } void main() {//密鑰unsigned char key[] = "Geek2021";unsigned long key_len = sizeof(key) - 1;//密鑰//unsigned char key[] = {};//unsigned long key_len = sizeof(key);//密文unsigned char data[] = { 34, 87, 28, 210, 186, 225, 87, 69, 104, 210, 181, 143, 128, 51, 105, 175, 135, 170, 87, 83, 3, 64, 181, 140, 38, 18, 59, 220, 71, 155, 93, 161 };//解密rc4_crypt(data, sizeof(data), key, key_len);for (int i = 0; i < sizeof(data); i++){printf("%c", data[i]);}printf("\n");return; } //SYC{Just_a_Eeeeeeasy_Rc4_right?}Brute_force
64位exe,ida打開,go語言,左側(cè)函數(shù)窗找到main_main
要求運(yùn)行時(shí)加參數(shù),且參數(shù)的長度為24
進(jìn)入main_unnamed630函數(shù),第40行有一個(gè)main_encode函數(shù),做了md5散列,返回十六進(jìn)制摘要
直接在ida中調(diào)試一下,斷點(diǎn)下在main_unnamed630函數(shù)第49行調(diào)用runtime_memequal函數(shù)前
參數(shù)設(shè)置為一段長度為24的字符串,如圖
程序運(yùn)行后在此處斷下
v15指向我們的輸入經(jīng)main_encode函數(shù)處理返回的十六進(jìn)制摘要,此時(shí)為"e2fc714c4727ee9395f324cd2e7f331f"
v19指向要去比較的長度為32的md5十六進(jìn)制摘要,此時(shí)為"957a3926d4ff16d0d3bac4ed3044537b"
通過在線網(wǎng)站查詢到v15指向的字符串就是我們輸入的前四個(gè)字符"abcd"的md5十六進(jìn)制摘要
那么這題的流程就是將長度為24的輸入分成6組,每組4個(gè)字符,對每組進(jìn)行md5散列,返回散列值的十六進(jìn)制摘要,與已知的長度為32的md5十六進(jìn)制摘要比較,從而驗(yàn)證輸入
每組4個(gè)字符,每個(gè)字符的ascii碼范圍為[48,128),可爆破,和題目名稱呼應(yīng)
"957a3926d4ff16d0d3bac4ed3044537b"只是第1組要去比較的md5十六進(jìn)制摘要,其他5組可通過調(diào)試得到
最后全部6組md5十六進(jìn)制摘要和爆破腳本如下
win32
題目名為win32,實(shí)際是個(gè)64位的exe,upx脫殼,ida打開
題目描述中提到了base64,猜測可能是變表base64
交叉引用Str2來到sub_140011B80函數(shù),主要邏輯在case 0x111處
輸入傳入sub_1400110F5函數(shù)處理,結(jié)果放入變量Str1中,與已知的Str2比較,驗(yàn)證輸入
進(jìn)入sub_1400110F5->sub_140011F90
sub_140011F90函數(shù)構(gòu)造了一個(gè)表,和標(biāo)準(zhǔn)的base64表是一樣的,下面就是正常的base64算法
直接解Str2的base64即可得到flag
wasm
wasm逆向參考:一種Wasm逆向靜態(tài)分析方法
使用wasm2c將.wasm文件轉(zhuǎn)為.c文件,對.c文件用gcc只編譯不鏈接得到.o文件
ida分析.o文件,w2c_main->w2c_f11
大概的邏輯如下圖,判斷輸入的長度是否等于22,w2c_f10對輸入進(jìn)行變換,w2c_f9對變換后的輸入進(jìn)行比較驗(yàn)證
進(jìn)入w2c_f10函數(shù),唯一的參數(shù)就是我們的輸入
看到循環(huán)體里有一個(gè)異或0x66的運(yùn)算,結(jié)合題目文件名xorwasm,這個(gè)異或0x66的運(yùn)算可能有很大作用
之前猜測w2c_f9是對變換后的輸入進(jìn)行比較驗(yàn)證的函數(shù),但是跟進(jìn)去分析并沒有找到最后要去比較的數(shù)據(jù)
參考博客里寫道,“對于wasm,所有的字符串會(huì)被存放在二進(jìn)制文件的末尾,以此能獲取一些關(guān)鍵的信息”
而且在ida字符串窗口中也能找到一些明文字符串
在Hex View中找到這些明文字符串,可以看到在"infinity"這個(gè)有意義的單詞前正好有22個(gè)數(shù)據(jù),猜測這些數(shù)據(jù)就是最后要去比較的數(shù)據(jù)
直接取出這22個(gè)數(shù)據(jù),異或0x66后即可得到flag
猜拳
64位exe,加了upx殼,但是工具脫不掉殼
根據(jù)提示"API斷點(diǎn)"猜測可能是通過調(diào)試器對按鈕相關(guān)的API下斷點(diǎn),程序停下來后修改寄存器的值,從而改變程序執(zhí)行流,得到flag
程序直接扔進(jìn)x64dbg,然后F9會(huì)被程序檢測到調(diào)試器從而結(jié)束進(jìn)程
這時(shí)我們先運(yùn)行程序,然后讓x64dbg去附加(attach)到運(yùn)行中的程序
附加成功后,右鍵->搜索->所有模塊->字符串
可以發(fā)現(xiàn)一些明文字符串
雙擊字符串"Congratulations on getting the flag"(相當(dāng)于ida中的交叉引用),找到引用該字符串的指令
我們看到該字符串的上方有一條"Sycl0v3r"的字符串,還有一條"call re.7FF7A77E13D8"的指令
多次調(diào)試發(fā)現(xiàn),程序?qū)?#34;Sycl0v3r"作為密鑰傳入0x7FF7A77E13D8處的函數(shù),對密文進(jìn)行解密,返回flag
在上圖標(biāo)紅處,即"00007FF7A77E1567"處,右鍵->設(shè)置新的運(yùn)行點(diǎn),將rip設(shè)置到此處
隨后F8單步步過,在"call re.7FF7A77E13D8"這條指令執(zhí)行后即可得到flag
have_a_tea
64位ELF,start函數(shù)中存在SMC,在偏移0x1A2F處下斷點(diǎn)
啟動(dòng)調(diào)試,程序斷下來后,F8來到偏移0x0870處
再多按幾次F8,來到偏移0x1361處
之后可以不用按F8,往下走,來到偏移0x14C6處,可以看到"db 55h"
我們知道"push rbp"的機(jī)器碼為0x55,于是這里就是一個(gè)函數(shù)的起始地址
在偏移0x14C6處按c,將數(shù)據(jù)轉(zhuǎn)成代碼,再按p創(chuàng)建函數(shù),然后F5反編譯
sub_55C97B2014C6->sub_55C97B2012BD,可以看到程序正常運(yùn)行時(shí)會(huì)打印的字符串
進(jìn)入sub_55C97B2010B7函數(shù),分析可知
程序?qū)斎脒M(jìn)行CBC模式的TEA加密,已知iv和key,密文為res
筆者沒有CBC模式的TEA解密腳本,只能先對密文解TEA,然后按CBC模式加密思路來逆CBC
對密文解TEA:
按CBC模式加密思路來逆CBC
from Crypto.Util.number import long_to_bytes res=[0xc9fa3b95,0x7cfd0735,0x958c7c9f,0xc143b59e,0x61741e89,0xf47dcdc4,0xd6e2a1f2,0x6a38e9ad,0xc2c16feb,0x8c0ee999] iv=[0]*10 iv[0]=0x5f797274 iv[1]=0x64726168 for i in range(8):iv[i+2]=res[i] plain=[0x243a2b27,0x1d133211,0x8d945ac6,0x2393665c,0xfbbc14c5,0x9e22f9c1,0x3e1a2ff0,0xab1ca587,0xb883e88a,0x683ae9d0] flag="" for i in range(10):flag+=long_to_bytes(plain[i]^iv[i])[::-1] print(flag) # SYC{ySaySanDian_Zh0n_La_y1n_Cha_xIan}總結(jié)
以上是生活随笔為你收集整理的REVERSE-COMPETITION-GeekChallenge2021的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 法拉利告别内燃机
- 下一篇: 【JS 逆向百例】37网游登录接口参数逆