19,Hack-you-2014_Newbie_calculations
在main有很多运算(极慢无法实现)调用三个函数,通过垃圾运算实现 加、减、乘(调用加)三个功能。手动手柄main更改内函数的名称方便看:
for ( i = 0; i < 32; i ) v120[i] = 1; v121 = 0; puts("Your flag is:"); v3 = mul(v120, 1000000000); v4 = sub(v3, 999999950); mul(v4, 2); v5 = add(&v120[1], 5000000); v6 = sub(v5, 6666666); v7 = add(v6, 1666666); v8 = add(v7, 45); v9 = mul(v8, 2); add(v9, 5); v10 = mul(&v120[2], 1000000000); v11 = sub(v10, 999999950); v12 = mul(v11, 2); add(v12, 2); v13 = add(&v120[3], 55); v14 = sub(v13, 3); v15 = add(v14, 4); sub(v15, 1); v16 = mul(&v120[4], 100000000); v17 = sub(v16, 99999950); v18 = mul(v17, 2); add(v18, 2); v19 = sub(&v120[5], 1); v20 = mul(v19, 1000000000); v21 = add(v20, 55); sub(v21, 3); v22 = mul(&v120[6], 1000000); v23 = sub(v22, 999975); mul(v23, 4); v24 = add(&v120[7], 55); v25 = sub(v24, 33); v26 = add(v25, 44); sub(v26, 11); v27 = mul(&v120[8], 10); v28 = sub(v27, 5); v29 = mul(v28, 8); add(v29, 9); v30 = add(&v120[9], 0); v31 = sub(v30, 0); v32 = add(v31, 11); v33 = sub(v32, 11); add(v33, 53); v34 = add(&v120[10], 49); v35 = sub(v34, 2); v36 = add(v35, 4); sub(v36, 2); v37 = mul(&v120[11], 1000000); v38 = sub(v37, 999999); v39 = mul(v38, 4); add(v39, 50); v40 = add(&v120[12], 1); v41 = add(v40, 1); v42 = add(v41, 1); v43 = add(v42, 1); v44 = add(v43, 1); v45 = add(v44, 1); v46 = add(v45, 10); add(v46, 32); v47 = mul(&v120[13], 10); v48 = sub(v47, 5); v49 = mul(v48, 8); v50 = add(v49, 9); add(v50, 48); v51 = sub(&v120[14], 1); v52 = mul(v51, -294967296); v53 = add(v52, 55); sub(v53, 3); v54 = add(&v120[15], 1); v55 = add(v54, 2); v56 = add(v55, 3); v57 = add(v56, 4); v58 = add(v57, 5); v59 = add(v58, 6); v60 = add(v59, 7); add(v60, 20); v61 = mul(&v120[16], 10); v62 = sub(v61, 5); v63 = mul(v62, 8); v64 = add(v63, 9); add(v64, 48); v65 = add(&v120[17], 7); v66 = add(v65, 6); v67 = add(v66, 5); v68 = add(v67, 4); v69 = add(v68, 3); v70 = add(v69, 2); v71 = add(v70, 1); add(v71, 20); v72 = add(&v120[18], 7); v73 = add(v72, 2); v74 = add(v73, 4); v75 = add(v74, 3); v76 = add(v75, 6); v77 = add(v76, 5); v78 = add(v77, 1); add(v78, 20); v79 = mul(&v120[19], 1000000); v80 = sub(v79, 999999); v81 = mul(v80, 4); v82 = add(v81, 50); sub(v82, 1); v83 = sub(&v120[20], 1); v84 = mul(v83, -294967296); v85 = add(v84, 49); sub(v85, 1); v86 = sub(&v120[21], 1); v87 = mul(v86, 1000000000); v88 = add(v87, 54); v89 = sub(v88, 1); v90 = add(v89, 1000000000); sub(v90, 1000000000); v91 = add(&v120[22], 49); v92 = sub(v91, 1); v93 = add(v92, 2); sub(v93, 1); v94 = mul(&v120[23], 10); v95 = sub(v94, 5); v96 = mul(v95, 8); v97 = add(v96, 9); add(v97, 48); v98 = add(&v120[24], 1); v99 = add(v98, 3); v100 = add(v99, 3); v101 = add(v100, 3); v102 = add(v101, 6); v103 = add(v102, 6); v104 = add(v103, 6); add(v104, 20); v105 = add(&v120[25], 55); v106 = sub(v105, 33); v107 = add(v106, 44); v108 = sub(v107, 11); add(v108, 42); add(&v120[26], v120[25]); add(&v120[27], v120[12]); v109 = v120[27]; v110 = sub(&v120[28], 1); v111 = add(v110, v109); sub(v111, 1); v112 = v120[23]; v113 = sub(&v120[29], 1); v114 = mul(v113, 1000000); add(v114, v112); v115 = v120[27]; v116 = add(&v120[30], 1); mul(v116, v115); add(&v120[31], v120[30]);
内容很简单,就是操作每个字符。手工操作得到结果
s = [ (1000000000-999999950)*2, (1 5000000-6666666 1666666 45)*2 5, (1000000000-999999950)*2 2, 1 55-3 4-1, (1000000000-999999950)*2 2, 55-3, (1000000-999975)*4, 1 55-33 44-11, (10-5)*8 9, 1 53, 1 49-2 4-2, (1000000-999999)*4 50, 7 10 32, (10-5)*8 9 48, 55-3, 1 1 2 3 4 5 6 7 20, (10-5)*8 9 48, 1 7 6 5 4 3 2 1 20, 1 7 2 4 3 6 5 1 20, (1000000-999999)*4 50-1, 49-1, 54-1, 1 49-1 2-1, (10-5)*8 9 48, 2 3 3 3 6 6 6 20, 1 55-33 44-11 42, 1 1 55-33 44-11 42, 1 7 10 32, 1-1 1 7 10 32-1, (10-5)*8 9 48, 2*(1 7 10 32), 1 2*(1 7 10 32) ] [print(chr(i), end='') for i in s] #CTF{daf8f4d816261a41a115052O1bb23Ode}
20,re1-100
main直接给出比较串,但顺序变了,在confuseKey里给了排法
bool __cdecl confuseKey(char *szKey, int iKeyLength) { ... strncpy(szPart1, szKey 1, 0xAuLL); strncpy(szPart2, szKey 11, 0xAuLL); strncpy(szPart3, szKey 21, 0xAuLL); strncpy(szPart4, szKey 31, 0xAuLL); memset(szKey, 0, iKeyLength); *szKey = 123; strcat(szKey, szPart3)
strcat(szKey, szPart4);
strcat(szKey, szPart1);
strcat(szKey, szPart2);
szKey[41] = 125;
return 1;
}
排好序,然后把没皮的包裹去掉
正确的排法
daf29f5903 3
4938ae4efd 4
53fc275d81 1
053ed5be8c 2
#{53fc275d81053ed5be8cdaf29f59034938ae4efd}
#53fc275d81053ed5be8cdaf29f59034938ae4efd
21,XCTF 3rd-RCTF-2017_easyre-153
一打开发现什么都没有,怀疑加壳,用upx先去壳。
在main里有比较的串,在lol里有一些算法
v2 = 2 * a1[1];
v3 = a1[4] + a1[5];
v4 = a1[8] + a1[9];
v5 = 2 * a1[12];
v6 = a1[18] + a1[17];
v7 = a1[10] + a1[21];
v8 = a1[9] + a1[25];
return printf("flag_is_not_here"); // "69800876143568214356928753"
还原串。有了前边的经验rctf这个用大写RCTF{}包
a1 = b"69800876143568214356928753"
b = [2 * a1[1], a1[4] + a1[5], a1[8] + a1[9], 2 * a1[12], a1[18] + a1[17], a1[10] + a1[21], a1[9] + a1[25]]
print(bytes(b))
#rhelheg
#RCTF{rhelheg}
22,百越杯2018_crazy
C++写的面向对象的程序。ida翻译得不好。在对象初始化时有比较串,在calculate里有运算方法:两次异或和加
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,i);
*v2 = (*(_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16, i) ^ 0x50) + 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) ^ 0x13) + 11;
}
解码(这个很坑,一眼感觉就不对,里边有半个大括号,可是他真是这样):
a = b'327a6c4304ad5938eaf0efb6cc3e53dc'
b = [0]*32
for i,v in enumerate(a):
b[i] = (((v-11)^0x13)-23)^0x50
print(bytes(b))
#flag{tMx~qdstOs~crvtwb~aOba}qddtbrtcd}
23,2019-ISCC_answer_to_everything
程序巨短,是个脑筋急转弯的题。not_the_flag里有几个字母,然后提法里说sha1
__int64 __fastcall not_the_flag(int a1)
{
if ( a1 == 42 )
puts("Cipher from Bill \nSubmit without any tags\n#kdudpeh");
else
puts("YOUSUCK");
return 0LL;
}
算这几个字符的sha1
'''
sha1 得到了一个神秘的二进制文件。寻找文件中的flag,解锁宇宙的秘密。注意:将得到的flag变为flag{XXX}形式提交。
kdudpeh
sha1(kdudpeh)
flag{80ee2a3fe31da904c596d993f7f1de4827c1450a}
'''
24,csaw-ctf-2016-quals_gametime
这个很乱,网上搜了下,发现确实是逆向不了,直接把出错时的跳转nop等他自己出flag
'''
sub_401260
return 后的两个不相符时退出的jz,jnz nop掉
然后运行程序,不要有任何输入
经过一段时间输出后会输出
key is (no5c30416d6cf52638460377995c6a8cf5)
'''
#no5c30416d6cf52638460377995c6a8cf5