BUUCTF [GUET-CTF2019]re

将文件拖入IDA 发现函数极少 应该是加壳了

利用upx脱壳

upx -d 文件地址

脱壳成功 再次拖入IDA shift+F12查看可疑字符串 这里发现了flag 双击点进去

继续跟进函数

进入sub_400E28函数

这里发现输出correct函数的是sub_4009AE函数 跟进sub_4009AE函数 发现以下伪c代码

BOOL8 __fastcall sub_4009AE(char *a1)
{
  if ( 1629056 * *a1 != 166163712 )
    return 0LL;
  if ( 6771600 * a1[1] != 731332800 )
    return 0LL;
  if ( 3682944 * a1[2] != 357245568 )
    return 0LL;
  if ( 10431000 * a1[3] != 1074393000 )
    return 0LL;
  if ( 3977328 * a1[4] != 489211344 )
    return 0LL;
  if ( 5138336 * a1[5] != 518971936 )
    return 0LL;
  if ( 7532250 * a1[7] != 406741500 )
    return 0LL;
  if ( 5551632 * a1[8] != 294236496 )
    return 0LL;
  if ( 3409728 * a1[9] != 177305856 )
    return 0LL;
  if ( 13013670 * a1[10] != 650683500 )
    return 0LL;
  if ( 6088797 * a1[11] != 298351053 )
    return 0LL;
  if ( 7884663 * a1[12] != 386348487 )
    return 0LL;
  if ( 8944053 * a1[13] != 438258597 )
    return 0LL;
  if ( 5198490 * a1[14] != 249527520 )
    return 0LL;
  if ( 4544518 * a1[15] != 445362764 )
    return 0LL;
  if ( 3645600 * a1[17] != 174988800 )
    return 0LL;
  if ( 10115280 * a1[16] != 981182160 )
    return 0LL;
  if ( 9667504 * a1[18] != 493042704 )
    return 0LL;
  if ( 5364450 * a1[19] != 257493600 )
    return 0LL;
  if ( 13464540 * a1[20] != 767478780 )
    return 0LL;
  if ( 5488432 * a1[21] != 312840624 )
    return 0LL;
  if ( 14479500 * a1[22] != 1404511500 )
    return 0LL;
  if ( 6451830 * a1[23] != 316139670 )
    return 0LL;
  if ( 6252576 * a1[24] != 619005024 )
    return 0LL;
  if ( 7763364 * a1[25] != 372641472 )
    return 0LL;
  if ( 7327320 * a1[26] != 373693320 )
    return 0LL;
  if ( 8741520 * a1[27] != 498266640 )
    return 0LL;
  if ( 8871876 * a1[28] != 452465676 )
    return 0LL;
  if ( 4086720 * a1[29] != 208422720 )
    return 0LL;
  if ( 9374400 * a1[30] == 515592000 )
    return 5759124 * a1[31] == 719890500;
  return 0LL;
}

这里进行的运算是X*a1[n]!=Y 我们给它进行逆操作 就是a1[n]=Y//X

编写反脚本


Y_values = [  
    166163712, 731332800, 357245568, 1074393000, 489211344, 518971936,  
    406741500, 294236496, 177305856, 650683500, 298351053, 386348487,  
    438258597, 249527520, 445362764, 981182160, 174988800, 493042704,  
    257493600, 767478780, 312840624, 1404511500, 316139670, 619005024,  
    372641472, 373693320, 498266640, 452465676, 208422720, 515592000,  
    719890500  
]  
  
X_values = [  
    1629056, 6771600, 3682944, 10431000, 3977328, 5138336,  
    7532250, 5551632, 3409728, 13013670, 6088797, 7884663,  
    8944053, 5198490, 4544518, 10115280, 3645600, 9667504,  
    5364450, 13464540, 5488432, 14479500, 6451830, 6252576,  
    7763364, 7327320, 8741520, 8871876, 4086720, 9374400,  
    5759124 
]  
  
a = [chr(y // x) for y, x in zip(Y_values, X_values)]  
    
print(''.join(a)) 


​

得到flag

但是因为a7不存在 我们需要0-9一个一个试值 最后试出来a7=1

故flag为flag{e165421110ba03099a1c039337}

但是到这里还没有结束 我去学习了其他师傅的解法 学到了新的东西 Z3求解器

CTF-reverse中有一类题目是通过约束方程求解变量的值,然后转化为对应的ASCII码,最终获得flag,约束方程以及要求解的未知数往往非常多,因此手算十分不现实,借助python中的z3模块可以很快完成求解。

Z3求解器给我们提供了一个非常便利求解方式,我们只需要定义未知量(x,y等),然后为这些未知量添加约束方式即可求解。Z3求解器能够求解任意多项式

利用Z3求解器编写代码

代码是这位师傅的

https://blog.csdn.net/Henlenl/article/details/115933792

from z3 import *
s = Solver()
a1 = [0]*32
for i in range(32):
    a1[i] = Int('a1['+str(i)+']')

s.add( 1629056 * a1[0] == 166163712 )
s.add( 6771600 * a1[1] == 731332800 )
s.add( 3682944 * a1[2] == 357245568 )
s.add( 10431000 * a1[3] == 1074393000 )
s.add( 3977328 * a1[4] == 489211344 )
s.add( 5138336 * a1[5] == 518971936 )
s.add( 7532250 * a1[7] == 406741500 )
s.add( 5551632 * a1[8] == 294236496 )
s.add( 3409728 * a1[9] == 177305856 )
s.add( 13013670 * a1[10] == 650683500 )
s.add( 6088797 * a1[11] == 298351053 )
s.add( 7884663 * a1[12] == 386348487 )
s.add( 8944053 * a1[13] == 438258597 )
s.add( 5198490 * a1[14] == 249527520 )
s.add( 4544518 * a1[15] == 445362764 )
s.add( 3645600 * a1[17] == 174988800 )
s.add( 10115280 * a1[16] == 981182160 )
s.add( 9667504 * a1[18] == 493042704 )
s.add( 5364450 * a1[19] == 257493600 )
s.add( 13464540 * a1[20] == 767478780 )
s.add( 5488432 * a1[21] == 312840624 )
s.add( 14479500 * a1[22] == 1404511500 )
s.add( 6451830 * a1[23] == 316139670 )
s.add( 6252576 * a1[24] == 619005024 )
s.add( 7763364 * a1[25] == 372641472 )
s.add( 7327320 * a1[26] == 373693320 )
s.add( 8741520 * a1[27] == 498266640 )
s.add( 8871876 * a1[28] == 452465676 )
s.add( 4086720 * a1[29] == 208422720 )
s.add( 9374400 * a1[30] == 515592000 )
s.add(5759124 * a1[31] == 719890500)
s.check()
print(s.model())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值