日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

REVERSE-PRACTICE-BUUCTF-17

發布時間:2023/12/10 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 REVERSE-PRACTICE-BUUCTF-17 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

REVERSE-PRACTICE-BUUCTF-17

    • [網鼎杯 2020 青龍組]jocker
    • [2019紅帽杯]childRE
    • [MRCTF2020]PixelShooter
    • [ACTF新生賽2020]SoulLike

[網鼎杯 2020 青龍組]jocker

exe程序,運行后提示輸入flag,無殼,用ida分析
main函數平衡棧后,F5反匯編
主要邏輯為
讀取輸入,檢驗輸入長度是否為24,對輸入進行變換,與已知數組比較,執行一段從encrypt函數起始地址開始的SMC,分析可知,finally函數也會完全被SMC,未經變換的輸入作為參數,調用encrypt函數和finally函數

先寫input經過wrong變換和omg驗證的逆運算腳本,得到的是假flag

往下走,在ida中使用idapython腳本完成SMC自修改代碼

from idaapi import * from idautils import * start_addr = 0x401500 key = 0x41 for i in range(start_addr,start_addr+187):PatchByte(i,Byte(i)^key)

SMC前,encrypt函數和finally函數各自包含了一大段數據

SMC后,encrypt函數和finally函數的指令間都有一些db指令,實際上為花指令
encrypt函數:

finally函數:

手動nop掉多余的db指令,讓ida能夠自動分析成代碼
完成nop后,發現encrypt函數,在兩端黑色代碼中間插有一段紅色代碼

這時的處理方法是,在encrypt函數起始地址0x401500處,右鍵->undefine,變成黃色的數據,再按c轉成代碼,這時,encrypt函數起始地址與finally函數起始地址之間的代碼全部為紅色,再在encrypt函數起始地址0x401500處,右鍵->create function,平衡棧后,F5反匯編
這里encrypt函數反匯編后,好像沒有用到未經變換的input,可能是patch代碼的時候出錯了,不過可以猜測為input和字符串“hahahaha_do_you_find_me?”異或,再與已知的unk_403040數組比較

寫encrypt函數的逆運算腳本,得到部分flag,之所以是部分flag,是因為長度為24的unk_403040的最后5個元素為0,“d_me?”與0異或不變,或者v6=19說明了只異或了19次,而且提交失敗

同encrypt函數的解析步驟,對finally函數,先nop掉多余的db指令,undefine掉黑色代碼,轉成數據,按c再轉成代碼,右鍵->create function,F5反匯編
沒看懂這個函數,看了其他師傅的wp,說這里也是異或,能看到的5個值[37,116,112,38,58]是異或后要比較的值,由于input的最后一位一定是“}”,它異或一個值(“71”)后與58相等,而且它之前的四位也是和這個值(“71”)異或,結果是58之前的四個值

寫finally函數的逆運算腳本得到后半部分的flag,替換掉“flag{d07abccf8a410cd_me?”的后5位,flag即為“flag{d07abccf8a410cb37a}”

[2019紅帽杯]childRE

exe程序,運行后直接輸入,無殼,ida分析
交叉引用字符串“flag{MD5(your input)}”來到sub_140001610函數
sub_140001610函數主要的邏輯為
讀取輸入,驗證輸入的長度是否為31,對輸入進行位置變換處理,位置變換的結果放到v2(name),經調試可知,輸入為abcdefghijklmnopqrstuvwxyz12345時,v2(name)的內容為pqhrsidtujvwkebxylz1mf23n45ogca
對v2(name)調用UnDecorateSymbolName函數處理,結果放到outputstring,驗證outputstring的長度62及其內容

signed __int64 sub_7FF6DC281610() {signed __int64 input_len; // rax_QWORD *v1; // raxconst CHAR *v2; // r11__int64 v3; // r10__int64 v4; // r9const CHAR *v5; // r10signed __int64 outputstring_len; // rcx__int64 v7; // raxsigned __int64 result; // raxunsigned int v9; // ecx__int64 v10; // r9int v11; // er10__int64 v12; // r8__int128 input; // [rsp+20h] [rbp-38h]__int128 v14; // [rsp+30h] [rbp-28h]input = 0i64;v14 = 0i64;sub_7FF6DC281080((__int64)"%s", &input); // 讀取輸入input_len = -1i64;do++input_len;while ( *((_BYTE *)&input + input_len) );if ( input_len != 31 ) // 輸入的長度為31{while ( 1 )Sleep(0x3E8u);}v1 = sub_7FF6DC281280(&input); // 對input的處理,通過調試可知,從31行到41行,是對input的位置變換,變換后的結果放入v2,也就是name// 例如,輸入abcdefghijklmnopqrstuvwxyz12345,name=“pqhrsidtujvwkebxylz1mf23n45ogca”v2 = name; // v2==nameif ( v1 ){sub_7FF6DC2815C0((unsigned __int8 *)v1[1]);sub_7FF6DC2815C0(*(unsigned __int8 **)(v3 + 16));v4 = dword_7FF6DC2857E0;v2[v4] = *v5;dword_7FF6DC2857E0 = v4 + 1;}UnDecorateSymbolName(v2, outputString, 0x100u, 0);// v2,也就是name,經過UnDecorateSymbolName函數處理,結果放到outputstring中outputstring_len = -1i64;do++outputstring_len;while ( outputString[outputstring_len] );if ( outputstring_len == 62 ) // outputstring的長度為62{v9 = 0;v10 = 0i64;do // do循環體在驗證outputstring的內容{v11 = outputString[v10];v12 = v11 % 23;if ( table[v12] != *(_BYTE *)(v10 + 0x7FF6DC283478i64) )// (_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&_exit(v9);if ( table[v11 / 23] != *(_BYTE *)(v10 + 0x7FF6DC283438i64) )// 55565653255552225565565555243466334653663544426565555525555222_exit(v9 * v9);++v9;++v10;}while ( v9 < 0x3E );sub_7FF6DC281020("flag{MD5(your input)}\n", v11 / 23, v12, v10);result = 0i64;}else{v7 = sub_7FF6DC2818A0(std::cout);std::basic_ostream<char,std::char_traits<char>>::operator<<(v7, sub_7FF6DC281A60);result = 0xFFFFFFFFi64;}return result; }

先寫驗證outputstring的長度62及其內容的逆運算腳本,得到outputstring,為一個未修飾的C++符號名

UnDecorateSymbolName函數反修飾指定已修飾的 C++ 符號名,參考:UnDecorateSymbolName
第1個參數為已修飾的 C++ 符號名,此名稱能以始終為問號 (?) 的首字符鑒別,本題中為v2(name),第2個參數指向字符串緩沖區的指針,該緩沖區接收未修飾的名字,本題中為outputstring
可知需要對outputstring符號名修飾才能得到v2(name),參考:c/c++函數名修飾規則
或者通過寫C++代碼,調用__FUNCDNAME__宏(FUNCDNAME:只有在函數內部才有效,返回該函數經編譯器修飾后的名字。如果編譯器選項中設定了/EP或/P,則__FUNCDNAME__是未定義。)直接得到函數經編譯器修飾后的符號名,需要注意的是函數所在的類,域,返回類型,函數名,參數類型都必須和已知完全相同

#include<iostream> using namespace std; class R0Pxx {//函數所在的類 public:R0Pxx() {//該類的構造函數unsigned char a;My_Aut0_PWN(&a);}private://函數屬于私有域//函數的返回類型 函數名 以及參數類型char * My_Aut0_PWN(unsigned char*) {char * ret = NULL;//調用宏 輸出該函數經編譯器修飾后的符號名printf("%s", __FUNCDNAME__);return ret;} }; int main() {new R0Pxx();getchar();return 0; }

運行結果即為v2(name),注意是在x86架構下運行的結果

寫逆位置變換腳本即可得到輸入,對輸入進行md5散列即可得到flag

[MRCTF2020]PixelShooter

apk文件,jadx-gui打開,什么都沒發現
用Apktool Box反編譯apk后,在PixelShooter->lib->armeabi-v7a目錄下發現3個.so文件,依次分析,同樣什么都沒發現
突然想到這是個安卓unity游戲,而安卓unity游戲的核心邏輯一般位于assets\bin\Data\Managed\Assembly-CSharp.dll
用dnSpy打開,在類UIController的GameOver方法中找到flag

[ACTF新生賽2020]SoulLike

elf文件,無殼,ida分析
main函數,讀取輸入,驗證輸入的前5個字符是否為“actf{”,將輸入{}內的字符放入v8,可知輸入{}內的長度為12,調用sub_83A函數驗證v8,且輸入的最后一個字符為“}”

分析sub_83A函數,可以看到是對input{}內12個字符的超多異或運算

在sub_83A函數的最后,是input{}內的12個字符經過超多異或運算后的值與已知的v4到v15比較,因為會有類似input[3]^=input[2]的情況,所以不能通過調試得到每個字符最后等效的異或值是什么
不過當比較為不相同時,程序會打印輸入是哪個位置的字符錯了,于是可以寫腳本爆破出flag

爆破腳本

#coding:utf-8 from itertools import * import subprocessflag="" t="" for i in range(12):for j in range(32,126):flag ="actf{"+t+chr(j)+"}" p = subprocess.Popen(["./SoulLike"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)p.stdin.write(flag)p.stdin.close()out=p.stdout.read()p.stdout.close()if "#"+str(i) not in out:t+=chr(j)breakprint(flag)

運行結果

總結

以上是生活随笔為你收集整理的REVERSE-PRACTICE-BUUCTF-17的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。