[XCTF-Reverse] 19-24

19,Hack-you-2014_Newbie_calculations

在main里边有一大堆运算(极慢不可实现的)调用3个函数,这3个函数通过垃圾运算实现了 加、减、乘(调用加)三个功能。手工把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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值