[攻防世界 XCTF 4th-WHCTF-2017] BABYRE

本文介绍了如何使用逆向工程工具IDA分析64位Linux程序,通过查看伪代码找出关键函数`judge`,并利用Python脚本在IDA中修改内存数据。在分析过程中,解密了一个字符串校验逻辑,最终揭示了隐藏的字符串`flag{n1c3_j0b}

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 下载附件,用Exeinfo看一下信息先

 64位Linux程序,跑一下先看看

丢进IDA,F5看伪代码

 看到main中的关键代码

  scanf("%20s", s); //最多不读入20个字符
  v5 = strlen(s);
  if ( v5 == 14 && (*(unsigned int (__fastcall **)(char *))judge)(s) )
    puts("Right!");

 输入字符的长度需要是14,并且要和judge不知道什么鬼操作

且judge还是已函数调用的形式使用的。judge为数据,作为函数使用,有点神奇

(*(unsigned int (__fastcall **)(char *))judge)

fastcall 一个char*,返回int。 

找到judge数据位置

 这里judge 已经放了一些初始数据,然后这些数据会经过^0xc后再被使用

  for ( i = 0; i <= 181; ++i )
    judge[i] ^= 0xCu;

我们在ida中再走一遍亦或流程,把ida中的数据改为亦或后的数据,才能在ida中做进一步分析处理。

众所周知,在ida中我们可以修补程序, 对汇编代码和数据段都可以随意改动。

 比如修改某个地址的byte数据可以如上操作,不过,,手动一个个点开改还是太麻烦了

所以我们可以在IDA中使用脚本语言处理

 

然后写上代码run就好了。 

不过由于网上的脚本版本都有些久远,可能已经不再兼容ida7.5以上版本,可能会报一些NameError: name Byte is not defined,之类的错误,我们想写用新一点ida写使用脚本方法咋办呢。

这告诉我们学习照抄是不行的,要自己掌握解决问题的思路和方法。

 看这里,点开Help,API文档,选择你想看的API,我对py比较熟,就写py好了。点开py文档

(如果你恰巧线下比赛没网,也可以参考ida主目录下的idahelp.chm文件)

 由于我们是要对byte进行操作,点开ida_bytes模块看看。

点开后,看到get_byte函数,

作用就是 Get the specified number of bytes of the program

传入地址,返回一个byte

再看到patch_byte函数,

看作用,就是我们要干的 Patch a byte of the program.

传入一个地址,一个uint64,返回bool值

 最终代码

from ida_bytes import *
addr=0x600b00
for i in range(182):
    patch_byte(addr+i,get_byte(addr+i)^0xC)

运行,然后可以看到此时的judge的值已经被我们的脚本修改完了

还是这个位置

重新生成汇编代码看看(按c)

之后就可以看到judge这玩意被重新处理成了代码

 光标还是在public judg的位置

重新生成函数(按p)

然后你就可以按f5看到judge的反汇编代码了

 唉,到这步就简单了。首先

v2 = "fmcd" + 0x7F
v3 = "k7d;V`;np"

先对我们的输入a1每一位进行本身亦或i

  for ( i = 0; i <= 13; ++i )
    *(_BYTE *)(i + a1) ^= i;

再对处理之后的每一位if校验,不等于v2[i]则return 0

  for ( i = 0; i <= 13; ++i )
  {
    if ( *(_BYTE *)(i + a1) != v2[i] )
      return 0LL;
  }
  return 1LL;

不过这个v2看起来好像有点问题,,v2最大才5位长度,而这里有14轮循环,恰巧v2+v3是14的长度。。。小小猜测一下,其实应该是亦或之后要等于v2+v3。

已知亦或完了之后要等于"fmcd" +0x7F+"k7d;V`;np",很容易推出原字符串

代码

input = "fmcd" + chr(0x7f) + "k7d;V`;np"
res = ''
for i, c in enumerate(input):
    res += chr(ord(c) ^ i)
print(res)

"""output
flag{n1c3_j0b}
"""

flag{n1c3_j0b}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值