X-CTF-no_string

文件地址:https://github.com/PIG-007/X-CTF

  1. 这是一个linux程序,先在Linux环境下跑一下,输出两串没用字符,其中一个是显示错误信息,不过这也代表了应该要输入东西之后,显示正确,然后打印flag,或者直接输入flag,打印正确。
  2. 载入IDA,发现关键函数在authenticate()中的decrypt(),函数decrypt()进行一堆算法,然后赋值给s2,再将s2与输入的字符串作比较,一样就打印成功,但是不打印其它字符串。这里就可以判定我们应该是得输入flag,然后程序判断后打印成功。那么我们需要的flag就应该在s2中。这里就可以分两种方法来获取flag。

★第一种:让程序跑起来,然后查看s2所在寄存器的的值

(1)打开linux的虚拟环境,打开终端,输入gdb no_string,开始使用gdb载入程序。

(2)输入命令b decrypt,表示在该函数处下断点,之后输入r让程序运行至断点处停止。

(3)这时候因为程序是停在decrypt这个函数上,并没有执行该函数,所以应该输入n来使得程序进行一步,运行该函数。

(4)此时eax寄存器中应该保存着s2,也就是我们需要的flag的值,所以输入命令:x/200wx$eax 来获取eax寄存器中的值:

img

从0x00000039一直到字符串结尾字符标志0x00000000,也就是对应flag的值,大家直接黏贴出来转ascii码就行。

▲200是代表查看多少个,wx是代表以word字节查看,$eax即是查看该寄存器的值。

(另外:可以通过IDApython来打印,也就是先在linux下远程动态调试,将断点停在decrypt上,然后运行一步,在右上角寄存器窗口栏右键eax-在数据窗口跟随,找到eax的首地址,运行如下py代码:

1
2
3
4
5
6
#注释头
addr=0x0965D800#eax首地址,或者点击eax首地址,然后换成here()
ans=""
for temp addr in range(addr,addr+50*4,4):
ans+=get_bytes(tempaddr,1)
print(ans)

这里addr+504代表从addr开始偏移量为504,因为可以看到eax中每四个字节存 储一个字符数据,也就是向下读取50个字符,然后后面的4是以4个字节为一个单位来翻译字符)

★第二种:

(1)在IDA中查看传入decrypt的两个数据,可以用Py脚本打印或者是点进去,然后选中整个数据段之后shift+E,可以转换为C类型或者是hex类型可得。

(2)然后编写逆推算法:利用十六进制来表示。