攻防世界 reverse 进阶 10 Reverse Box

攻防世界中此题信息未给全,题目来源为[TWCTF-2016:Reverse] Reverse Box

网上有很多wp是使用gdb脚本,这里找到一个本地还原关键算法,然后再爆破的

https://www.megabeets.net/twctf-2016-reverse-reverse-box/

[TWCTF-2016:Reverse] Reverse Box Writeup

标准

Shak的客座文章。

挑战描述
$ ./reverse_box $ {FLAG} 
95eeaf95ef94234999582f722f492f72b19a7aaf72e6e776b57aee722fe77ab5ad9aaeb156729676ae7a236d99b1df4a reverse_box.7z


这个挑战是一个二进制文件,它需要一个参数然后吐出一个字符串。我们得到二进制文件的输出,用于运行它。让我们开始这一点。

二进制可能会打印替换每个字符的十六进制值。同样清楚的是,它是每个角色的唯一值。我们必须处理某种替代密码。在使用完全相同的参数再次运行它之后,我们得到不同的输出,因此替换也以某种方式随机化。

跳转到二进制文件,我们有两个重要的函数,我命名为main和calculate。

主要功能非常简单。它负责检查我们是否使用参数运行二进制文件,调用calculate函数,最后打印结果。查看结果打印格式,我们可以看到结果是十六进制格式。

接下来我们将处理计算功能。

扫描二维码关注公众号,回复: 7146946 查看本文章

它根本不像我们的主要直接,但基本上它随机化一个变量,做一些内存操作并返回一些随机值。现在,让我们尝试调试二进制文件而不完全理解计算。

二进制文件迭代输入中的字符并执行以下程序集以打印结果。

到达这组指令后,eax寄存器保存了我们输入的字符。然后为printf函数传递的是来自eax位置(第1行)的[esp + 1Ch]中的数组的元素。所以这个数组保存我们的结果。让我们进一步研究它,看看它是什么。跳转到堆栈上的那个位置我们会遇到一个268 Bytes的十六进制数组,我们将把数组保存到一个名为array的二进制文件中供以后使用。

在运行二进制文件几次之后,我们可以理解该数组也是以某种方式随机化的。也许它与计算函数返回的随机值有关。再运行二进制文件几次,我们看到数组的第二个元素总是等于计算中的随机数。所以,二进制文件必须有一个基本数组,然后用随机值以某种方式进行操作。如果每次操作发生时,基本数组中的第二个元素必须为零,我们得到随机数。让我们试着理解二进制执行什么样的操作。我们将通过将二进制数组加载到python脚本来实现这一点,然后我们将通过对我们保存的数组元素执行假定操作来获取基数组,并使用我们执行二进制文件时的已知随机值,最后将该过程与另一个具有不同随机值的二进制运行进行比较以进行验证。第一个选项是将随机值添加到基础数组值。它适用于第二个元素,但将此过程与另一个二进制运行进行比较不起作用。第二个猜测是二进制文件使用基本数组元素对随机值进行异或运算,这也将允许第二个数组元素等于随机值。宾果,这个有效。现在我们所要做的就是使用我们保存的数组和该二进制运行的随机值来获取基数组。接下来我们要考虑的是标志结构,即TWCTF {...}。

该flag为  TWCTF {5UBS717U710N_C1PH3R_W17H_R4ND0M123D_5-B0X}

python3

 1 ror = lambda val, r_bits, max_bits: \
 2     ((val & (2**max_bits-1)) >> r_bits%max_bits) | \
 3     (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
 4 
 5 all_s_boxes = {}
 6 for randomValue in range(256):
 7   results = [0 for i in range(256)]
 8   position_index = 3;
 9   some_value = 1;
10   while position_index != 1:
11     # Used to generate some_value
12     v1 = 2 * some_value ^ some_value & 0xff
13     v2 = (v1 ^ v1 * 4) &0xff
14     v3 = (v2 ^ v2 * 16) & 0xff
15     if ( v3 < 128 ):
16       v5 = 0;
17     else:
18       v5 = 9;
19     some_value = (v3 ^ v5) & 0xff;
20 
21     factor1 = some_value & 0xff
22     factor2 = some_value ^ randomValue
23     factor1_rotate_7bits = ror(factor1, 7,8)
24     factor1_rotate_6bits = ror(factor1, 6,8)
25     factor1_rotate_5bits = ror(factor1, 5,8)
26     factor1_rotate_4bits = ror(factor1,4,8)
27     result = factor2 ^ factor1_rotate_7bits ^ factor1_rotate_6bits ^ factor1_rotate_5bits ^ factor1_rotate_4bits
28 
29     results[position_index] = (result & 0xff)
30 
31     some_value = factor1
32     v2 = (position_index ^ (2 * position_index));
33     if position_index < 128:
34       v3 = 0;
35     else:
36       v3 = 27;
37     position_index = (v2 ^ v3) & 0xff
38   all_s_boxes[randomValue] = results
39 
40 startingFlag = "TWCTF"
41 startingTarget = "\x95\xee\xaf\x95\xef"
42 sbox_to_use = None
43 
44 for key,sbox in all_s_boxes.items():
45   for index,char in enumerate(startingFlag):
46     if sbox[ord(char)] == ord(startingTarget[index]):
47       sbox_to_use = sbox
48       print("Found sbox at random value %d" % key)
49       break
50 
51 target = "95eeaf95ef94234999582f722f492f72b19a7aaf72e6e776b57aee722fe77ab5ad9aaeb156729676ae7a236d99b1df4a"
52 print(''.join([chr(sbox_to_use.index(i)) for i in bytes.fromhex(target)]))
View Code

猜你喜欢

转载自www.cnblogs.com/DirWang/p/11441963.html