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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

攻防世界逆向高手题之crazy

發(fā)布時間:2023/12/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 攻防世界逆向高手题之crazy 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

攻防世界逆向高手題之crazy

繼續(xù)開啟全棧夢想之逆向之旅~
這題是攻防世界逆向高手題的crazy

下載附件,照例扔入exeinfope中查看信息:

64位ELF文件,扔入對應(yīng)IDA中查看信息,有main函數(shù)看main函數(shù):

可以看到,一堆眼花繚亂的系統(tǒng)函數(shù),有些則是用類名調(diào)用的普通C++函數(shù)。
這里積累第一個經(jīng)驗:(別人博客的一句話)

代碼看著很亂,有很多很長的命令,解決辦法:依據(jù)英文意思去猜測。
找關(guān)鍵變量的方法:從后往前找,看flag和輸入關(guān)系。復(fù)雜代碼本質(zhì)應(yīng)該是簡潔的,這樣才叫出題。

但是從后往前找與flag的有關(guān)變量還是很麻煩,所以我們用運行程序方法不斷查看顯示信息,鎖定關(guān)鍵位置。(調(diào)試的話不知道斷點下在那里可能要遍歷很長時間)



第一次亂輸入:

.
.
可以看到運行到checking…后顯示too short or too long處,還有就是用戶輸入在字符串輸出之前。返回IDA查看代碼:

這里有個cin,也是主函數(shù)中在其它字符串之前的,cin是c++的輸入函數(shù),從這里積累第二個經(jīng)驗:該程序的長字符傳命令中最后一個才是我們要關(guān)注的命令,比如這里的cin函數(shù),像下面截圖中字符串前面也有cout函數(shù)。

.
.
.
看check…字符串之后的函數(shù):

可以看到checking到if判斷語句之間還是有很多函數(shù)的,可以用前面的依據(jù)英文意思猜測的方法去看函數(shù),也可以在strings窗口查找too short or too long處的函數(shù)位置:(我選擇后者)

這里跟蹤到HighTemplar::calculate函數(shù),根據(jù)英文名是計算函數(shù),但是我看不懂這里的this+16,憑借意思我推測是我們輸入flag的地址,把我們輸入的flag經(jīng)過兩個簡單的循環(huán)異或加密后輸出:

bool __fastcall HighTemplar::calculate(HighTemplar *this) {__int64 v1; // rax_BYTE *v2; // rbxbool result; // al_BYTE *v4; // rbxint i; // [rsp+18h] [rbp-18h]int j; // [rsp+1Ch] [rbp-14h]if ( std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length((char *)this + 16) != 32 ){v1 = std::operator<<<std::char_traits<char>>(&std::cout, "Too short or too long");std::ostream::operator<<(v1, std::endl<char,std::char_traits<char>>);exit(-1);}for ( i = 0;i <= (unsigned __int64)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length((char *)this + 16);++i ){v2 = (_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16, // 這里積累第三個經(jīng)驗:這是一個兩步操作,v2取的是對應(yīng)字符的地址,*v2是指在原v2地址上修改。把修改input_flag字符分成了兩步做,讓不熟悉的我載了跟頭。i);*v2 = (*(_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16,i) ^ 80)+ 23;}for ( j = 0; ; ++j ){result = j <= (unsigned __int64)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length((char *)this + 16);if ( !result )break;v4 = (_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16,j);*v4 = (*(_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16,j) ^ 19)+ 11;}return result; }

.
.
.然后由于HighTemplar::calculate函數(shù)的下一個就是if判斷函數(shù),所以我們只能跟蹤if判斷函數(shù)的HighTemplar::getSerial了。

.
.
前面this+16我推測是我們輸入flag的地方,但是這個this+80存了什么東西我是真不知道了。雙擊跟蹤堆棧也是未賦值的狀態(tài)。這里積累第四個經(jīng)驗,逆向中不符合預(yù)期帶份運算結(jié)果基本都是中間做了其它操作,如之前遇到的HOOK,這里很多函數(shù)我還沒跟蹤,那說明的確會有未發(fā)現(xiàn)的操作。
.
.
回到一開始cin函數(shù)的地方,表黃輸入變量,看哪里還引用過該變量:

可以看到在checking前面還引用了一下,而該函數(shù)我們并沒有分析,雙擊跟蹤分析:

unsigned __int64 __fastcall HighTemplar::HighTemplar(DarkTemplar *a1, __int64 input_flag) {char v3; // [rsp+17h] [rbp-19h] BYREFunsigned __int64 v4; // [rsp+18h] [rbp-18h]v4 = __readfsqword(0x28u);DarkTemplar::DarkTemplar(a1);*(_QWORD *)a1 = &off_401EA0;*((_DWORD *)a1 + 3) = 0;std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string((char *)a1 + 16, // C++函數(shù),basic_string(字符串類模板),不是復(fù)制就是比較,這里是復(fù)制輸入字符串給a1+16開始的地址的數(shù)組中input_flag);std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string((char *)a1 + 48, // C++函數(shù),basic_string(字符串類模板),不是復(fù)制就是比較,這里是復(fù)制輸入字符串給a1+48開始的地址的數(shù)組中,與前面隔了32個字符input_flag);std::allocator<char>::allocator(&v3);std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string((char *)a1 + 80,"327a6c4304ad5938eaf0efb6cc3e53dc", // C++函數(shù),basic_string(字符串類模板),不是復(fù)制就是比較,這里是復(fù)制輸入字符串給a1+80開始的地址的數(shù)組中,與前面還是隔了32個字符,這個v3不清楚&v3);std::allocator<char>::~allocator(&v3);return __readfsqword(0x28u) ^ v4; }

這里我們可以看到把輸入的flag分別給了this+16和this+48地址處,在this+80地址處給了327a6c4304ad5938eaf0efb6cc3e53dc這個字符串,那么前面對this+80的疑惑就解釋得通了。
.
.
回過頭去看this+80的那個HighTemplar::calculate函數(shù):

__int64 __fastcall HighTemplar::getSerial(HighTemplar *this) {char v1; // bl__int64 v2; // rax__int64 v3; // rax__int64 v4; // rax__int64 v5; // raxunsigned int i; // [rsp+1Ch] [rbp-14h]for ( i = 0;(int)i < (unsigned __int64)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length((char *)this + 16);++i ){v1 = *(_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 80, // this+80地址處是327a6c4304ad5938eaf0efb6cc3e53dc的字符串(int)i);if ( v1 != *(_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16, // this+80處如果不等于this+16處就不通過(int)i) ){v4 = std::operator<<<std::char_traits<char>>(&std::cout, "You did not pass ");v5 = std::ostream::operator<<(v4, i);std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>);*((_DWORD *)this + 3) = 1;return *((unsigned int *)this + 3);}v2 = std::operator<<<std::char_traits<char>>(&std::cout, "Pass ");v3 = std::ostream::operator<<(v2, i);std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);}return *((unsigned int *)this + 3); }

.
.
簡單的加密邏輯,直接寫腳本逆向邏輯即可:

key1="327a6c4304ad5938eaf0efb6cc3e53dc" flag1="" flag="" print(len(key1)) for i in range(len(key1)):flag1+=chr((ord(key1[i])-11)^19) for i in range(len(flag1)):flag+=chr((ord(flag1[i])-23)^80) print(flag)

.
.
結(jié)果:(這里積累第5個經(jīng)驗:現(xiàn)在的flag真的是越來越古靈精怪了,還有花括號,我一開始都以為我寫錯腳本了,現(xiàn)在看來,什么類型的flag都可以!一次不行就修改再交幾次)

.
.
.
最后,下面這三個函數(shù)有什么用呢,我判斷它是沒什么用的,因為參數(shù)沒有傳入我輸入的flag,跟蹤里面也沒有我輸入的flag地址,除非是偏移地址間接引用我輸入的flag,不過那樣的話題就很難了!

.
.
.
總結(jié):

1:這里積累第一個經(jīng)驗:(別人博客的一句話)
代碼看著很亂,有很多很長的命令,解決辦法:依據(jù)英文意思去猜測。
找關(guān)鍵變量的方法:從后往前找,看flag和輸入關(guān)系。復(fù)雜代碼本質(zhì)應(yīng)該是簡潔的,這樣才叫出題。

但是從后往前找與flag的有關(guān)變量還是很麻煩,所以我們用運行程序方法不斷查看顯示信息,鎖定關(guān)鍵位置。(調(diào)試的話不知道斷點下在那里可能要遍歷很長時間)

2:
這里積累第二個經(jīng)驗:該程序的長字符傳命令中最后一個才是我們要關(guān)注的命令,比如這里的cin函數(shù),像下面截圖中字符串前面也有cout函數(shù)。

3:
這里積累第三個經(jīng)驗:這是一個兩步操作,v2取的是對應(yīng)字符的地址,*v2是指在原v2地址上修改。把修改input_flag字符分成了兩步做,讓不熟悉的我載了跟頭。

4:
這里積累第四個經(jīng)驗,逆向中不符合預(yù)期帶份運算結(jié)果基本都是中間做了其它操作,如之前遇到的HOOK,這里很多函數(shù)我還沒跟蹤,那說明的確會有未發(fā)現(xiàn)的操作。

5:
這里積累第5個經(jīng)驗:現(xiàn)在的flag真的是越來越古靈精怪了,還有花括號,我一開始都以為我寫錯腳本了,現(xiàn)在看來,什么類型的flag都可以!一次不行就修改再交幾次

解畢!敬禮!

總結(jié)

以上是生活随笔為你收集整理的攻防世界逆向高手题之crazy的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。