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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

REVERSE-PRACTICE-BUUCTF-15

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

REVERSE-PRACTICE-BUUCTF-15

    • [2019紅帽杯]xx
    • [ACTF新生賽2020]Universe_final_answer
    • [WUSTCTF2020]level4
    • findKey

[2019紅帽杯]xx

exe程序,運行后直接輸入,無殼,ida分析
交叉引用字符串“You win!”來到sub_1400011A0函數
主要的邏輯為
讀取輸入,驗證輸入長度是否為19,且均為小寫字母或0~9的數字
對輸入進行TEA加密,加密密鑰通過調試可知是輸入的前4個字符,即“flag”
TEA加密的密文變換位置
變換位置后的密文循環異或
循環異或后的密文與已知字節比較

__int64 __fastcall sub_1400011A0(__int64 a1, __int64 a2) {unsigned __int64 input_len_; // rbxsigned __int64 input_len; // rax__int128 *v4; // rax__int64 Code; // r11__int128 *v6; // r14int v7; // edi__int128 *v8; // rsichar v9; // r10int v10; // edx__int64 v11; // r8unsigned __int64 Code_len; // rcxsigned __int64 Code_len_; // rcxunsigned __int64 v14; // raxunsigned __int64 i; // rax_BYTE *cipher; // raxsize_t v17; // rsi_BYTE *cipher_; // rbx_BYTE *v19; // r9signed int v20; // er11char *v21; // r8signed __int64 v22; // rcxchar v23; // alsigned __int64 v24; // r9signed __int64 v25; // rdx__int64 v26; // raxsize_t Size; // [rsp+20h] [rbp-48h]__int128 v29; // [rsp+28h] [rbp-40h]int v30; // [rsp+38h] [rbp-30h]int v31; // [rsp+3Ch] [rbp-2Ch]int input[4]; // [rsp+40h] [rbp-28h]int v33; // [rsp+50h] [rbp-18h]*(_OWORD *)input = 0i64;v33 = 0;sub_1400018C0(std::cin, a2, input); // 讀取輸入input_len_ = -1i64;input_len = -1i64;do // do循環計算輸入的長度++input_len;while ( *((_BYTE *)input + input_len) );if ( input_len != 19 ) // 驗證輸入的長度是否為19{sub_140001620(std::cout, "error\n");_exit((unsigned __int64)input);}v4 = (__int128 *)sub_140001E5C(5ui64);Code = *(_QWORD *)&::Code; // Code=="qwertyuiopasdfghjklzxcvbnm1234567890"v6 = v4;v7 = 0;v8 = v4; // v4==v6==v8do{v9 = *((_BYTE *)v8 + (char *)input - (char *)v4);v10 = 0;*(_BYTE *)v8 = v9;v11 = 0i64;Code_len = -1i64;do++Code_len;while ( *(_BYTE *)(Code + Code_len) );if ( Code_len ){do{if ( v9 == *(_BYTE *)(Code + v11) )break;++v10;++v11;}while ( v10 < Code_len );}Code_len_ = -1i64;do++Code_len_;while ( *(_BYTE *)(Code + Code_len_) );if ( v10 == Code_len_ ) // 驗證輸入的內容是否在Code范圍內,即輸入的內容均為小寫字母或0~9的數字_exit(Code);v8 = (__int128 *)((char *)v8 + 1);}while ( (char *)v8 - (char *)v4 < 4 );*((_BYTE *)v4 + 4) = 0;do++input_len_;while ( *((_BYTE *)input + input_len_) );v14 = 0i64;v29 = *v6;while ( *((_BYTE *)&v29 + v14) ){if ( !*((_BYTE *)&v29 + v14 + 1) ){++v14;break;}if ( !*((_BYTE *)&v29 + v14 + 2) ){v14 += 2i64;break;}if ( !*((_BYTE *)&v29 + v14 + 3) ){v14 += 3i64;break;}v14 += 4i64;if ( v14 >= 0x10 )break;}for ( i = v14 + 1; i < 16; ++i )*((_BYTE *)&v29 + i) = 0;cipher = sub_140001AB0((__int64)input, input_len_, (unsigned __int8 *)&v29, &Size);// 在sub_140001Ab0函數中發現一常數0x61C88647,判斷為TEA加密算法// v29為密鑰,調試可知為輸入的前4個字符,即“flag”v17 = Size;cipher_ = cipher;v19 = sub_140001E5C(Size);v20 = 1;*v19 = cipher_[2]; // 輸入經TEA加密后的密文cipher,變換位置,存儲到v19v21 = v19 + 1;v19[1] = *cipher_;v19[2] = cipher_[3];v19[3] = cipher_[1];v19[4] = cipher_[6];v19[5] = cipher_[4];v19[6] = cipher_[7];v19[7] = cipher_[5];v19[8] = cipher_[10];v19[9] = cipher_[8];v19[10] = cipher_[11];v19[11] = cipher_[9];v19[12] = cipher_[14];v19[13] = cipher_[12];v19[14] = cipher_[15];v19[15] = cipher_[13];v19[16] = cipher_[18];v19[17] = cipher_[16];v19[18] = cipher_[19];v19[19] = cipher_[17];v19[20] = cipher_[22];v19[21] = cipher_[20];v19[22] = cipher_[23];for ( v19[23] = cipher_[21]; v20 < v17; ++v21 )// v20初始值為1,v17==Size==24,v21初始值為&(v19[1]),v20和v21是同時加1的{v22 = 0i64;if ( v20 / 3 > 0 ) // 決定下面異或運算的次數{v23 = *v21; // 取指針v21指向的值do{v23 ^= v19[v22++]; // 實際上為 *v21^=v19[v22++],而v21是指向v19的,意味著當v20大于等于3時,v19[v20]從v19[0]異或到v19[v20/3-1]// 即v19會變化,不再是簡單的TEA加密的密文*v21 = v23;}while ( v22 < v20 / 3 );}++v20;}*(_QWORD *)&v29 = 0xC0953A7C6B40BCCEi64; // v29是最后要去比較的結果,提取時注意小端序v24 = v19 - (_BYTE *)&v29;*((_QWORD *)&v29 + 1) = 0x3502F79120209BEFi64;v25 = 0i64;v30 = 0xC8021823;v31 = 0xFA5656E7;do{if ( *((_BYTE *)&v29 + v25) != *((_BYTE *)&v29 + v25 + v24) )// v19和v29比較驗證_exit(v7 * v7);++v7;++v25;}while ( v25 < 24 );v26 = sub_140001620(std::cout, "You win!");std::basic_ostream<char,std::char_traits<char>>::operator<<(v26, sub_1400017F0);return 0i64; }

先寫逆循環異或和逆位置變換得到TEA加密的密文腳本

網上找的xxtea的python代碼,參考:XXTEA 加解密 as3 和 Python 分別實現
密鑰為“flag”需要加長到16,寫解xxtea腳本即可得到flag

# encoding: utf-8 import struct_DELTA = 0x9E3779B9def _long2str(v, w):n = (len(v) - 1) << 2if w:m = v[-1]if (m < n - 3) or (m > n): return ''n = ms = struct.pack('<%iL' % len(v), *v)return s[0:n] if w else sdef _str2long(s, w):n = len(s)m = (4 - (n & 3) & 3) + ns = s.ljust(m, "\0")v = list(struct.unpack('<%iL' % (m >> 2), s))if w: v.append(n)return vdef encrypt(str, key):if str == '': return strv = _str2long(str, True)k = _str2long(key.ljust(16, "\0"), False)n = len(v) - 1z = v[n]y = v[0]sum = 0q = 6 + 52 // (n + 1)while q > 0:sum = (sum + _DELTA) & 0xffffffffe = sum >> 2 & 3for p in range(n):y = v[p + 1]v[p] = (v[p] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffffz = v[p]y = v[0]v[n] = (v[n] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[n & 3 ^ e] ^ z))) & 0xffffffffz = v[n]q -= 1return _long2str(v, False)def decrypt(str, key):if str == '': return strv = _str2long(str, False)k = _str2long(key.ljust(16, "\0"), False)n = len(v) - 1z = v[n]y = v[0]q = 6 + 52 // (n + 1)sum = (q * _DELTA) & 0xffffffffwhile (sum != 0):e = sum >> 2 & 3for p in range(n, 0, -1):z = v[p - 1]v[p] = (v[p] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffffy = v[p]z = v[n]v[0] = (v[0] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[0 & 3 ^ e] ^ z))) & 0xffffffffy = v[0]sum = (sum - _DELTA) & 0xffffffffreturn _long2str(v, True)def xor(x ,y):return ord(x) ^ ord(y)key="flag"+'\x00'*12 cipher_data=['\xbc','\xa5','\xce','\x40','\xf4','\xb2','\xb2','\xe7','\xa9','\x12','\x9d','\x12','\xae','\x10','\xc8','\x5b','\x3d','\xd7','\x06','\x1d','\xdc','\x70','\xf8','\xdc'] cipher=''.join(cipher_data) print(decrypt(cipher,key)) #flag{CXX_and_++tea}

[ACTF新生賽2020]Universe_final_answer

elf文件,無殼,ida分析
main函數,讀取輸入,check函數驗證輸入的字符,輸入驗證成功,程序調用sub_C50,最后輸出flag

重要的是check函數,分析可知,驗證input的字符,就是驗證方程組是否成立

利用python的z3庫寫腳本得到input

from z3 import * flag=[Int('flag[%d]' %i ) for i in range(10)] s=Solver() s.add(-85 * flag[8] + 58 * flag[7] + 97 * flag[6] + flag[5] + -45 * flag[4] + 84 * flag[3] + 95 * flag[0] - 20 * flag[1] + 12 * flag[2] == 12613) s.add(30 * flag[9] + -70 * flag[8] + -122 * flag[6] + -81 * flag[5] + -66 * flag[4] + -115 * flag[3] + -41 * flag[2] + -86 * flag[1] - 15 * flag[0] - 30 * flag[7] == -54400) s.add(-103 * flag[9] + 120 * flag[7] + 108 * flag[5] + 48 * flag[3] + -89 * flag[2] + 78 * flag[1] - 41 * flag[0] + 31 * flag[4] - (flag[6]*64) - 120 * flag[8] == -10283) s.add(71 * flag[6] + (flag[5] *128) + 99 * flag[4] + -111 * flag[2] + 85 * flag[1] + 79 * flag[0] - 30 * flag[3] - 119 * flag[7] + 48 * flag[8] - 16 * flag[9] == 22855) s.add(5 * flag[9] + 23 * flag[8] + 122 * flag[7] + -19 * flag[6] + 99 * flag[5] + -117 * flag[4] + -69 * flag[2] + 22 * flag[1] - 98 * flag[0] + 10 * flag[3] == -2944) s.add(-54 * flag[9] + -23 * flag[7] + -82 * flag[2] + -85 * flag[0] + 124 * flag[1] - 11 * flag[3] - 8 * flag[4] - 60 * flag[5] + 95 * flag[6] + 100 * flag[8] == -2222) s.add(-83 * flag[9] + -111 * flag[5] + -57 * flag[0] + 41 * flag[1] + 73 * flag[2] - 18 * flag[3] + 26 * flag[4] + 16 * flag[6] + 77 * flag[7] - 63 * flag[8] == -13258) s.add(81 * flag[9] + -48 * flag[8] + 66 * flag[7] + -104 * flag[6] + -121 * flag[5] + 95 * flag[4] + 85 * flag[3] + 60 * flag[2] + -85 * flag[0] + 80 * flag[1] == -1559) s.add(101 * flag[9] + -85 * flag[8] + 7 * flag[6] + 117 * flag[5] + -83 * flag[4] + -101 * flag[3] + 90 * flag[2] + -28 * flag[1] + 18 * flag[0] - flag[7] == 6308 ) s.add(99 * flag[9] + -28 * flag[8] + 5 * flag[7] + 93 * flag[6] + -18 * flag[5] + -127 * flag[4] + 6 * flag[3] + -9 * flag[2] + -93 * flag[1] + 58 * flag[0] == -1697) if s.check()==sat:print(s.model())

運行結果

轉成字符串,運行elf文件,輸入,得到flag

[WUSTCTF2020]level4

elf文件,運行后輸出了幾段字符串,可知是二叉樹的遍歷,無殼,ida分析
main函數,程序輸出的type1為中序遍歷,type2為后序遍歷,type3被注釋掉,應該是先序遍歷

中序遍歷:2f0t02T{hcsiI_SwA__r7Ee}
后序遍歷:20f0Th{2tsIS_icArE}e7__w
由中序遍歷和后序遍歷的字符串確定二叉樹,再先序遍歷二叉樹,即為flag
代碼參考:已知后序序遍歷序列和中序遍歷序列建立二叉樹

#include <stdio.h> #include <stdlib.h> #include <string.h> typedef char ElementType; typedef struct BiTNode {ElementType data;struct BiTNode* lchild;struct BiTNode* rchild; }BiTNode, *BiTree;BiTree CreatBinTree(char* post, char* in, int n); void preorder(BiTree T);int main() {BiTree T;char postlist[100] = "20f0Th{2tsIS_icArE}e7__w";char inlist[100] = "2f0t02T{hcsiI_SwA__r7Ee}";int length;length = strlen(postlist);T = CreatBinTree(postlist, inlist, length);preorder(T);return 0; } void preorder(BiTree T) {if (T){printf("%c", T->data);preorder(T->lchild);preorder(T->rchild);} } BiTree CreatBinTree(char* post, char* in, int n) {BiTree T;int i;if (n <= 0) return NULL;T = (BiTree)malloc(sizeof(BiTNode));T->data = post[n - 1];for (i = 0; in[i] != post[n - 1]; i++);T->lchild = CreatBinTree(post, in, i);T->rchild = CreatBinTree(post + i, in + i + 1, n - 1 - i);return T; }

運行結果即為flag

findKey

exe程序,無殼,ida分析
交叉引用字符串“flag{}”,發現從地址0x00401640開始,代碼就沒有被ida識別,應該是加了花指令
在地址0x00401918和地址0x0040191D處,兩條一樣的指令,放在了一起,nop掉第二條push指令

在地址0x00401640處右鍵->create function,或者選中全部的紅色地址代碼,按p創建函數,F5反匯編
主要的邏輯為
v20的字符串和v16的字符串循環異或,結果和pbData的md5散列值比較
比較相等時,md5散列前的pbData和unk_423030循環異或,結果即為flag

LRESULT __stdcall sub_401640(HWND hWndParent, UINT Msg, WPARAM wParam, LPARAM lParam) {int v5; // eaxsize_t v6; // eaxDWORD v7; // eaxint v8; // eaxint v9; // eaxconst char *v10; // [esp-4h] [ebp-450h]CHAR *v11; // [esp+0h] [ebp-44Ch]int v12; // [esp+4h] [ebp-448h]int v13; // [esp+4Ch] [ebp-400h]UINT v14; // [esp+50h] [ebp-3FCh]CHAR v15; // [esp+54h] [ebp-3F8h]CHAR v16[2]; // [esp+154h] [ebp-2F8h]int v17; // [esp+157h] [ebp-2F5h]__int16 v18; // [esp+15Bh] [ebp-2F1h]char v19; // [esp+15Dh] [ebp-2EFh]char v20; // [esp+160h] [ebp-2ECh]char v21; // [esp+181h] [ebp-2CBh]__int16 v22; // [esp+25Dh] [ebp-1EFh]char v23; // [esp+25Fh] [ebp-1EDh]CHAR v24; // [esp+260h] [ebp-1ECh]CHAR String[4]; // [esp+360h] [ebp-ECh]int v26; // [esp+364h] [ebp-E8h]__int16 v27; // [esp+368h] [ebp-E4h]CHAR Text; // [esp+36Ch] [ebp-E0h]struct tagRECT Rect; // [esp+38Ch] [ebp-C0h]CHAR Buffer; // [esp+39Ch] [ebp-B0h]HDC hdc; // [esp+400h] [ebp-4Ch]struct tagPAINTSTRUCT Paint; // [esp+404h] [ebp-48h]WPARAM v33; // [esp+444h] [ebp-8h]int v34; // [esp+448h] [ebp-4h]LoadStringA(hInstance, 0x6Au, &Buffer, 100);v14 = Msg;if ( Msg > 0x111 ){if ( v14 == 517 ){if ( strlen((const char *)&pbData) > 6 )ExitProcess(0);if ( strlen((const char *)&pbData) ){memset(&v24, 0, 0x100u);v6 = strlen((const char *)&pbData);memcpy(&v24, &pbData, v6); // pbData拷貝到v24v10 = (const char *)&pbData;do{v7 = strlen(v10);sub_40101E(&pbData, v7, v11); // CryptCreateHash函數,第二個參數為0x8003u,對pbData進行md5散列}while ( &v12 && !&v12 );strcpy(&v20, "0kk`d1a`55k222k2a776jbfgd`06cjjb");// v20="0kk`d1a`55k222k2a776jbfgd`06cjjb"memset(&v21, 0, 0xDCu);v22 = 0;v23 = 0;strcpy(v16, "SS"); // v16="SS"v17 = 0;v18 = 0;v19 = 0;v8 = strlen(&v20);sub_401005(v16, (int)&v20, v8); // v20^=v16if ( _strcmpi((const char *)&pbData, &v20) )// v20和md5散列后的pbData比較,求出v20,解md5散列,可得到散列前的pbData{SetWindowTextA(hWndParent, "flag{}");MessageBoxA(hWndParent, "Are you kidding me?", "^_^", 0);ExitProcess(0);}memcpy(&v15, &unk_423030, 0x32u); // unk_423030已知,拷貝到v15v9 = strlen(&v15);sub_401005(&v24, (int)&v15, v9); // v24和md5散列前的pbData相同,v24^=v15MessageBoxA(hWndParent, &v15, 0, 0x32u);}++dword_428D54;}else{if ( v14 != 520 )return DefWindowProcA(hWndParent, Msg, wParam, lParam);if ( dword_428D54 == 16 ){strcpy(String, "ctf");v26 = 0;v27 = 0;SetWindowTextA(hWndParent, String);strcpy(&Text, "Are you kidding me?");MessageBoxA(hWndParent, &Text, &Buffer, 0);}++dword_428D54;}}else{switch ( v14 ){case 0x111u:v34 = (unsigned __int16)wParam;v33 = wParam >> 16;v13 = (unsigned __int16)wParam;if ( (unsigned __int16)wParam == 104 ){DialogBoxParamA(hInstance, (LPCSTR)0x67, hWndParent, (DLGPROC)DialogFunc, 0);}else{if ( v13 != 105 )return DefWindowProcA(hWndParent, Msg, wParam, lParam);DestroyWindow(hWndParent);}break;case 2u:PostQuitMessage(0);break;case 0xFu:hdc = BeginPaint(hWndParent, &Paint);GetClientRect(hWndParent, &Rect);v5 = strlen(&Buffer);DrawTextA(hdc, &Buffer, v5, &Rect, 1u);EndPaint(hWndParent, &Paint);break;default:return DefWindowProcA(hWndParent, Msg, wParam, lParam);}}return 0; }

先寫腳本得到pbData的md5散列值,通過在線網站求逆


再寫md5散列前的pbData(v24)和unk_unk_423030(v15)循環異或的腳本,得到flag

總結

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

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