【WhaleCTF逆向題】第一期大骰子writeup & ebCTF 2013 BIN100writeup
阿新 • • 發佈:2018-12-10
題目資訊:
執行一下
出現
我們可以看出這是ebCTF 2013 BIN100的題目
dice 骰子的意思 提示我們要拿到flag就得輸入正確的數字(骰子要投出相應的數字)
但是骰子哪有7點???
那就得爆破了
查殼無殼 並且是Dev-C++編寫的
IDA載入 檢視字串或者直接檢視WinMain()也可以找到關鍵
雙擊進去 再雙擊引用
再F5一下
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { unsigned int v4; // eax int v5; // eax int v6; // eax std::ostream *v7; // eax int v8; // eax std::ostream *v9; // eax std::ostream *v10; // eax int v11; // eax std::ostream *v12; // eax int v13; // eax std::ostream *v14; // eax std::ostream *v15; // eax time_t v16; // eax std::ostream *v17; // eax std::ostream *v18; // eax int v19; // eax std::ostream *v20; // eax int v21; // eax std::ostream *v22; // eax std::ostream *v23; // eax time_t v24; // eax std::ostream *v25; // eax std::ostream *v26; // eax int v27; // eax std::ostream *v28; // eax int v29; // eax std::ostream *v30; // eax std::ostream *v31; // eax time_t v32; // eax std::ostream *v33; // eax std::ostream *v34; // eax int v35; // eax unsigned int v36; // eax _BYTE *v37; // eax std::ostream *v38; // eax int v39; // eax std::ostream *v40; // eax std::ostream *v41; // eax std::ostream *v42; // eax std::ostream *v43; // eax int v44; // eax std::ostream *v45; // eax int v46; // eax std::ostream *v47; // eax std::ostream *v48; // eax time_t v49; // eax unsigned int v50; // eax _BYTE *v51; // eax unsigned int v52; // eax _BYTE *v53; // eax unsigned int v54; // eax std::ostream *v55; // eax std::ostream *v56; // eax int v57; // eax int v58; // eax int v59; // eax std::ostream *v60; // eax int v61; // eax int v63; // [esp+0h] [ebp-188h] _BYTE *v64; // [esp+3Ch] [ebp-14Ch] int v65; // [esp+60h] [ebp-128h] struct SjLj_Function_Context fctx; // [esp+64h] [ebp-124h] void *v67; // [esp+88h] [ebp-100h] int *v68; // [esp+8Ch] [ebp-FCh] int j; // [esp+98h] [ebp-F0h] int i; // [esp+9Ch] [ebp-ECh] int v71; // [esp+A0h] [ebp-E8h] int v72; // [esp+B0h] [ebp-D8h] int v73; // [esp+C0h] [ebp-C8h] int v74; // [esp+D0h] [ebp-B8h] int v75; // [esp+E0h] [ebp-A8h] int v76; // [esp+F0h] [ebp-98h] int v77; // [esp+100h] [ebp-88h] int v78; // [esp+110h] [ebp-78h] time_t v79; // [esp+120h] [ebp-68h] time_t v80; // [esp+124h] [ebp-64h] int v81; // [esp+128h] [ebp-60h] int v82; // [esp+12Ch] [ebp-5Ch] char v83; // [esp+130h] [ebp-58h] char v84; // [esp+140h] [ebp-48h] int v85; // [esp+158h] [ebp-30h] int v86; // [esp+15Ch] [ebp-2Ch] char v87; // [esp+160h] [ebp-28h] char v88; // [esp+170h] [ebp-18h] fctx.personality = __gxx_personality_sj0; fctx.lsda = dword_44176C; fctx.jbuf[0] = &v88; v67 = &loc_402B5C; v68 = &v63; _Unwind_SjLj_Register(&fctx); fctx.call_site = -1; std::string::string(&v87); v85 = 6; fctx.call_site = 17; std::string::string(&v84); fctx.call_site = 16; std::string::string(&v83); v4 = time(0); srand(v4); std::allocator<char>::allocator(&v77); fctx.call_site = 14; std::string::string(&v78, " -------\n| |\n| O |\n| |\n -------\n\n", &v77); std::allocator<char>::~allocator(&v77); std::allocator<char>::allocator(&v76); fctx.call_site = 12; std::string::string(&v77, " -------\n| O |\n| |\n| O |\n -------\n\n", &v76); std::allocator<char>::~allocator(&v76); std::allocator<char>::allocator(&v75); fctx.call_site = 10; std::string::string(&v76, " -------\n| O |\n| O |\n| O |\n -------\n\n", &v75); std::allocator<char>::~allocator(&v75); std::allocator<char>::allocator(&v74); fctx.call_site = 8; std::string::string(&v75, " -------\n| O O |\n| |\n| O O |\n -------\n\n", &v74); std::allocator<char>::~allocator(&v74); std::allocator<char>::allocator(&v73); fctx.call_site = 6; std::string::string(&v74, " -------\n| O O |\n| O |\n| O O |\n -------\n\n", &v73); std::allocator<char>::~allocator(&v73); std::allocator<char>::allocator(&v72); fctx.call_site = 4; std::string::string(&v73, " -------\n| O O |\n| O O |\n| O O |\n -------\n\n", &v72); std::allocator<char>::~allocator(&v72); std::allocator<char>::allocator(&v71); fctx.call_site = 2; std::string::string(&v72, " -------\n| O O |\n| O O O |\n| O O |\n -------\n\n", &v71); std::allocator<char>::~allocator(&v71); fctx.call_site = 1; if ( isDebuggerPresent() ) v86 = 66; else v86 = 16; fctx.call_site = 1; v5 = std::ostream::operator<<(&std::cout, std::endl<char,std::char_traits<char>>); std::operator<<<std::char_traits<char>>(v5, "[*] ebCTF 2013 Teaser - BIN100 - Dice Game"); v6 = std::ostream::operator<<(&std::cout, std::endl<char,std::char_traits<char>>); v7 = std::operator<<<std::char_traits<char>>(v6, " To get the flag you will need to throw the correct numbers."); v8 = std::ostream::operator<<(v7, std::endl<char,std::char_traits<char>>); std::ostream::operator<<(v8, std::endl<char,std::char_traits<char>>); v9 = std::operator<<<std::char_traits<char>>( &std::cout, "[*] You will first need to throw a three, press enter to throw a dice!"); std::ostream::operator<<(v9, std::endl<char,std::char_traits<char>>); std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v83); v80 = time(0); v82 = rand() % 6 + 1; // 取隨機數除6取餘,然後逐個和1-6進行對比,再和目標數字(3-1-3-3-7)對比,如果不相同則退出 if ( v82 == 1 ) std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v78); if ( v82 == 2 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v77); } if ( v82 == 3 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v76); } if ( v82 == 4 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v75); } if ( v82 == 5 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v74); } if ( v82 == 6 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v73); } if ( v82 == 3 ) // 第一次投擲為3 { fctx.call_site = 1; v10 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] You rolled a three! Good!"); v11 = std::ostream::operator<<(v10, std::endl<char,std::char_traits<char>>); std::ostream::operator<<(v11, std::endl<char,std::char_traits<char>>); v85 *= 2; std::string::operator=(&v84, &byte_444240); v16 = time(0); v79 = v16; v81 = v16 - v80; if ( v16 - v80 > 2 ) // 第一次的時間減去第二次的時間 如果大於2 v85 *= 2; fctx.call_site = 1; v17 = std::operator<<<std::char_traits<char>>( &std::cout, "[*] Next you will need to throw a one, press enter to throw a dice!"); std::ostream::operator<<(v17, std::endl<char,std::char_traits<char>>); std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v83); v80 = time(0); v82 = rand() % 6 + 1; if ( v82 == 1 ) std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v78); if ( v82 == 2 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v77); } if ( v82 == 3 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v76); } if ( v82 == 4 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v75); } if ( v82 == 5 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v74); } if ( v82 == 6 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v73); } if ( v82 == 1 ) // 第二次投擲為1 { fctx.call_site = 1; v18 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] You rolled a one! Very nice!"); v19 = std::ostream::operator<<(v18, std::endl<char,std::char_traits<char>>); std::ostream::operator<<(v19, std::endl<char,std::char_traits<char>>); v85 += 4; std::string::operator=(&v87, &byte_444309); v24 = time(0); v79 = v24; v81 = v24 - v80; if ( v24 - v80 > 2 ) v85 *= 2; fctx.call_site = 1; v25 = std::operator<<<std::char_traits<char>>( &std::cout, "[*] Next you will need to throw another three, press enter to throw a dice!"); std::ostream::operator<<(v25, std::endl<char,std::char_traits<char>>); std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v83); v80 = time(0); v82 = rand() % 6 + 1; if ( v82 == 1 ) std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v78); if ( v82 == 2 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v77); } if ( v82 == 3 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v76); } if ( v82 == 4 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v75); } if ( v82 == 5 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v74); } if ( v82 == 6 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v73); } if ( v82 == 3 ) // 第三次投擲為3 { fctx.call_site = 1; v26 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] You rolled a three! Awesome!"); v27 = std::ostream::operator<<(v26, std::endl<char,std::char_traits<char>>); std::ostream::operator<<(v27, std::endl<char,std::char_traits<char>>); v85 *= 3; v32 = time(0); v79 = v32; v81 = v32 - v80; if ( v32 - v80 > 2 ) v85 *= 2; fctx.call_site = 1; v33 = std::operator<<<std::char_traits<char>>( &std::cout, "[*] Throw another three for me now, press enter to throw a dice!"); std::ostream::operator<<(v33, std::endl<char,std::char_traits<char>>); std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v83); v80 = time(0); v82 = rand() % 6 + 1; if ( v82 == 1 ) std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v78); if ( v82 == 2 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v77); } if ( v82 == 3 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v76); } if ( v82 == 4 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v75); } if ( v82 == 5 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v74); } if ( v82 == 6 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v73); } if ( v82 == 3 ) // 第四次投擲為3 { fctx.call_site = 1; v34 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] You rolled another three! Almost there now!"); v35 = std::ostream::operator<<(v34, std::endl<char,std::char_traits<char>>); std::ostream::operator<<(v35, std::endl<char,std::char_traits<char>>); v85 += 2; for ( i = 0; ; ++i ) { fctx.call_site = 1; v36 = std::string::size(&v87); if ( i >= v36 ) break; v37 = std::string::operator[](&v87, i); *v37 ^= v86; } v79 = time(0); v81 = v79 - v80; if ( v79 - v80 > 2 ) v85 *= 2; fctx.call_site = 1; v42 = std::operator<<<std::char_traits<char>>( &std::cout, "[*] The last character you need to roll is a seven.... (o_O) Press enter to throw a dice!"); std::ostream::operator<<(v42, std::endl<char,std::char_traits<char>>); std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v83); v80 = time(0); if ( v82 == 1 ) std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v78); if ( v82 == 2 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v77); } if ( v82 == 3 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v76); } if ( v82 == 4 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v75); } if ( v82 == 5 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v74); } if ( v82 == 6 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v73); } if ( v82 == 7 ) { fctx.call_site = 1; std::operator<<<char,std::char_traits<char>,std::allocator<char>>(&std::cout, &v72); } if ( v82 == 7 ) // 第五次投擲為7 { fctx.call_site = 1; v43 = std::operator<<<std::char_traits<char>>( &std::cout, "[*] You rolled a seven, with a six sided dice! How awesome are you?!"); v44 = std::ostream::operator<<(v43, std::endl<char,std::char_traits<char>>); std::ostream::operator<<(v44, std::endl<char,std::char_traits<char>>); v85 *= 2; v85 *= 50; v85 /= 50; v85 += 65; v85 -= 65; v85 *= 42; v85 /= 42; v49 = time(0); v79 = v49; v81 = v49 - v80; if ( v49 - v80 > 2 ) v85 *= 2; for ( i = 0; ; ++i ) { fctx.call_site = 1; v50 = std::string::size(&v87); if ( i >= v50 ) break; v51 = std::string::operator[](&v87, i); *v51 ^= v85; } i = 0; for ( j = 0; ; ++j ) { fctx.call_site = 1; v52 = std::string::size(&v84); if ( j >= v52 ) break; v64 = std::string::operator[](&v84, j); v53 = std::string::operator[](&v87, i); *v64 ^= *v53; ++i; v54 = std::string::length(&v87); if ( i >= v54 ) i = 0; } fctx.call_site = 1; if ( std::string::find(&v84, "ebCTF", 0) == -1 ) { fctx.call_site = 1; v59 = std::ostream::operator<<(&std::cout, std::endl<char,std::char_traits<char>>); v60 = std::operator<<<std::char_traits<char>>( v59, "[!] It seems yot did something wrong :( No flag for you."); v61 = std::ostream::operator<<(v60, std::endl<char,std::char_traits<char>>); std::ostream::operator<<(v61, std::endl<char,std::char_traits<char>>); fctx.call_site = 3; std::string::~string(&v72); fctx.call_site = 5; std::string::~string(&v73); fctx.call_site = 7; std::string::~string(&v74); fctx.call_site = 9; std::string::~string(&v75); fctx.call_site = 11; std::string::~string(&v76); fctx.call_site = 13; std::string::~string(&v77); fctx.call_site = 15; std::string::~string(&v78); fctx.call_site = 16; std::string::~string(&v83); fctx.call_site = 17; std::string::~string(&v84); fctx.call_site = -1; std::string::~string(&v87); v65 = 0; } else { v55 = std::operator<<<std::char_traits<char>>( &std::cout, "[*] You rolled 3-1-3-3-7, what does that make you? ELEET! \\o/"); std::ostream::operator<<(v55, std::endl<char,std::char_traits<char>>); v56 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] Nice job, here is the flag: "); v57 = std::operator<<<char,std::char_traits<char>,std::allocator<char>>(v56, &v84); v58 = std::ostream::operator<<(v57, std::endl<char,std::char_traits<char>>); std::ostream::operator<<(v58, std::endl<char,std::char_traits<char>>); fctx.call_site = 3; std::string::~string(&v72); fctx.call_site = 5; std::string::~string(&v73); fctx.call_site = 7; std::string::~string(&v74); fctx.call_site = 9; std::string::~string(&v75); fctx.call_site = 11; std::string::~string(&v76); fctx.call_site = 13; std::string::~string(&v77); fctx.call_site = 15; std::string::~string(&v78); fctx.call_site = 16; std::string::~string(&v83); fctx.call_site = 17; std::string::~string(&v84); fctx.call_site = -1; std::string::~string(&v87); } } else { fctx.call_site = 1; v45 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] You rolled a "); v46 = std::ostream::operator<<(v45, v82); v47 = std::operator<<<std::char_traits<char>>(v46, " That is not a seven :/"); std::ostream::operator<<(v47, std::endl<char,std::char_traits<char>>); v48 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] Game over!"); std::ostream::operator<<(v48, std::endl<char,std::char_traits<char>>); fctx.call_site = 3; std::string::~string(&v72); fctx.call_site = 5; std::string::~string(&v73); fctx.call_site = 7; std::string::~string(&v74); fctx.call_site = 9; std::string::~string(&v75); fctx.call_site = 11; std::string::~string(&v76); fctx.call_site = 13; std::string::~string(&v77); fctx.call_site = 15; std::string::~string(&v78); fctx.call_site = 16; std::string::~string(&v83); fctx.call_site = 17; std::string::~string(&v84); fctx.call_site = -1; std::string::~string(&v87); v65 = 0; } } else { fctx.call_site = 1; v38 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] You rolled a "); v39 = std::ostream::operator<<(v38, v82); v40 = std::operator<<<std::char_traits<char>>(v39, " That is not a three :/"); std::ostream::operator<<(v40, std::endl<char,std::char_traits<char>>); v41 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] Game over!"); std::ostream::operator<<(v41, std::endl<char,std::char_traits<char>>); fctx.call_site = 3; std::string::~string(&v72); fctx.call_site = 5; std::string::~string(&v73); fctx.call_site = 7; std::string::~string(&v74); fctx.call_site = 9; std::string::~string(&v75); fctx.call_site = 11; std::string::~string(&v76); fctx.call_site = 13; std::string::~string(&v77); fctx.call_site = 15; std::string::~string(&v78); fctx.call_site = 16; std::string::~string(&v83); fctx.call_site = 17; std::string::~string(&v84); fctx.call_site = -1; std::string::~string(&v87); v65 = 0; } } else { fctx.call_site = 1; v28 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] You rolled a "); v29 = std::ostream::operator<<(v28, v82); v30 = std::operator<<<std::char_traits<char>>(v29, " That is not a three :/"); std::ostream::operator<<(v30, std::endl<char,std::char_traits<char>>); v31 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] Game over!"); std::ostream::operator<<(v31, std::endl<char,std::char_traits<char>>); fctx.call_site = 3; std::string::~string(&v72); fctx.call_site = 5; std::string::~string(&v73); fctx.call_site = 7; std::string::~string(&v74); fctx.call_site = 9; std::string::~string(&v75); fctx.call_site = 11; std::string::~string(&v76); fctx.call_site = 13; std::string::~string(&v77); fctx.call_site = 15; std::string::~string(&v78); fctx.call_site = 16; std::string::~string(&v83); fctx.call_site = 17; std::string::~string(&v84); fctx.call_site = -1; std::string::~string(&v87); v65 = 0; } } else { fctx.call_site = 1; v20 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] You rolled a "); v21 = std::ostream::operator<<(v20, v82); v22 = std::operator<<<std::char_traits<char>>(v21, " That is not a one :/"); std::ostream::operator<<(v22, std::endl<char,std::char_traits<char>>); v23 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] Game over!"); std::ostream::operator<<(v23, std::endl<char,std::char_traits<char>>); fctx.call_site = 3; std::string::~string(&v72); fctx.call_site = 5; std::string::~string(&v73); fctx.call_site = 7; std::string::~string(&v74); fctx.call_site = 9; std::string::~string(&v75); fctx.call_site = 11; std::string::~string(&v76); fctx.call_site = 13; std::string::~string(&v77); fctx.call_site = 15; std::string::~string(&v78); fctx.call_site = 16; std::string::~string(&v83); fctx.call_site = 17; std::string::~string(&v84); fctx.call_site = -1; std::string::~string(&v87); v65 = 0; } } else { fctx.call_site = 1; v12 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] You rolled a "); v13 = std::ostream::operator<<(v12, v82); v14 = std::operator<<<std::char_traits<char>>(v13, " That is not a three :/"); std::ostream::operator<<(v14, std::endl<char,std::char_traits<char>>); v15 = std::operator<<<std::char_traits<char>>(&std::cout, "[*] Game over!"); std::ostream::operator<<(v15, std::endl<char,std::char_traits<char>>); fctx.call_site = 3; std::string::~string(&v72); fctx.call_site = 5; std::string::~string(&v73); fctx.call_site = 7; std::string::~string(&v74); fctx.call_site = 9; std::string::~string(&v75); fctx.call_site = 11; std::string::~string(&v76); fctx.call_site = 13; std::string::~string(&v77); fctx.call_site = 15; std::string::~string(&v78); fctx.call_site = 16; std::string::~string(&v83); fctx.call_site = 17; std::string::~string(&v84); fctx.call_site = -1; std::string::~string(&v87); v65 = 0; } _Unwind_SjLj_Unregister(&fctx); return v65; }
具體分析 上邊程式碼都有
可以看出程式是每次讀取我們的一個輸入
先與1~6進行比較
接著再與3-1-3-3-7盡心比較
判斷他們的跳轉都是jnz
我們只需要將他們都nop掉儲存即可
最簡單的方法就是直接在IDA中改位元組碼 (以後再補坑。)
最直接的就是OD搜尋ASCll碼 從字串向上找到關鍵調轉jnz nop
掉即可
需要注意的是還有一個je跳轉 也需要nop掉
最後儲存 執行 隨意輸入 即可得到flag
留個坑:裡邊還有time()這個東西 我還沒搞明白 。