攻防世界中此题信息未给全,题目来源为[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


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

 
1
2
./reverse_box 0000
28282828

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

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

From Hex-Rays Decompiler

 
 
 
 
 
 

C

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax@7
  int v4; // ecx@7
  size_t i; // [sp+18h] [bp-10Ch]@4
  int v6; // [sp+1Ch] [bp-108h]@4
  int v7; // [sp+11Ch] [bp-8h]@1
 
  v7 = *MK_FP(__GS__, 20);
  if ( argc <= 1 )
  {
    printf("usage: %s flag\n", *argv);
    exit(1);
  }
  calculate((int)&v6);
  for ( i = 0; i < strlen(argv[1]); ++i )
    printf("%02x", *((_BYTE *)&v6 + argv[1][i]));
  putchar('\n');
  result = 0;
  v4 = *MK_FP(__GS__, 20) ^ v7;
  return result;
}

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

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

From Hex-Rays Decompiler

 
 
 
 
 
 

C

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
int __cdecl calculate(int a1)
{
  unsigned int seed; // eax@1
  int v2; // edx@4
  char v3; // al@5
  char v4; // ST1B_1@7
  char v5; // al@8
  int v6; // eax@10
  int v7; // ecx@10
  int v8; // eax@10
  int v9; // ecx@10
  int v10; // eax@10
  int v11; // ecx@10
  int v12; // eax@10
  int v13; // ecx@10
  int result; // eax@10
  char v15; // [sp+1Ah] [bp-Eh]@3
  char v16; // [sp+1Bh] [bp-Dh]@3
  char v17; // [sp+1Bh] [bp-Dh]@7
  int randomNum; // [sp+1Ch] [bp-Ch]@2
 
  seed = time(0);
  srand(seed);
  do
    randomNum = (unsigned __int8)rand();
  while ( !randomNum );
  *(_BYTE *)a1 = randomNum;
  v15 = 1;
  v16 = 1;
  do
  {
    v2 = (unsigned __int8)v15 ^ 2 * (unsigned __int8)v15;
    if ( v15 >= 0 )
      v3 = 0;
    else
      v3 = 27;
    v15 = v2 ^ v3;
    v4 = 4 * (2 * v16 ^ v16) ^ 2 * v16 ^ v16;
    v17 = 16 * v4 ^ v4;
    if ( v17 >= 0 )
      v5 = 0;
    else
      v5 = 9;
    v16 = v17 ^ v5;
    v6 = *(_BYTE *)a1;
    LOBYTE(v6) = v16 ^ v6;
    v7 = (unsigned __int8)v16;
    LOBYTE(v7) = __ROR1__(v16, 7);
    v8 = v7 ^ v6;
    v9 = (unsigned __int8)v16;
    LOBYTE(v9) = __ROR1__(v16, 6);
    v10 = v9 ^ v8;
    v11 = (unsigned __int8)v16;
    LOBYTE(v11) = __ROR1__(v16, 5);
    v12 = v11 ^ v10;
    v13 = (unsigned __int8)v16;
    LOBYTE(v13) = __ROR1__(v16, 4);
    result = v13 ^ v12;
    *(_BYTE *)(a1 + (unsigned __int8)v15) = result;
  }
  while ( v15 != 1 );
  return result;
}

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

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

 
1
2
3
4
5
movzx   eax, byte ptr [esp+eax+1Ch]
movzx   eax, al
mov     [esp+4], eax
mov     dword ptr [esp], offset a02x ; "%02x"
call    _printf

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

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

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#! /usr/bin/python
f = open(r"c:\megabeets\array", "rb")
buff = f.read(268)
random_value = 0x66
base_array = []
 
#Claculate the base array
for i in buff:
base_array.append(ord(i) ^ random value)
 
#The given output from the flag run, each value is seperated by -
flag_output = "95-ee-af-95-ef-94-23-49-99-58-2f-72-2f-49-2f-72-b1-9a-7a-af-72-e6-e7-76-b5-7a-ee-72-2f-e7-7a-b5-ad-9a-ae-b1-56-72-96-76-ae-7a-23-6d-99-b1-df-4a"
flag = ''
for c in flag_output:
flag.append(int('0x' + c , 16))
 
T_location = ord('T')
#XORing the T_location element in the base array with the output result in order to get the random value
flag_random_value = base_array[T_location] ^ flag[0]
 
#Manipulate the base array to create the array for the flag binary run
flag_array = []
for b in base_array:
flag_array.append(ord(b) ^ flag_random_value)
 
# Create a dictionary which maps an output hex value to an input character
dic{}
for i in range(0, 268):
dic[flag_array[i]] = chr(i)
 
#
for i in xrange(len(flag)):
print dic[flag[i]],

该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)]))

攻防世界 reverse 进阶 10 Reverse Box的更多相关文章

  1. 攻防世界 web进阶练习 NewsCenter

    攻防世界 web进阶练习 NewsCenter   题目是NewsCenter,没有提示信息.打开题目,有一处搜索框,搜索新闻.考虑xss或sql注入,随便输入一个abc,没有任何搜索结果,页面也没有 ...

  2. 攻防世界_MISC进阶区_Get-the-key.txt(详细)

    攻防世界MISC进阶之Get-the-key.txt 啥话也不说,咱们直接看题吧! 首先下载附件看到一个压缩包: 我们直接解压,看到一个文件,也没有后缀名,先用 file 看一下文件属性: 发现是是L ...

  3. XCTF攻防世界web进阶练习—mfw

    XCTF攻防世界web进阶练习-mfw题目为mfw,没有任何提示.直接打开题目,是一个网站 大概浏览一下其中的内容,看到其中url变化其实只是get的参数的变化查看它的源码,看到有一个?page=fl ...

  4. 攻防世界MISC进阶之签到题

    攻防世界MISC进阶之签到题    第一步:分析    第二步:实操    第三步:答案第一步:分析难度系数:1星题目来源: SSCTF-2017题目描述:SSCTF线上选举美男大赛开始了,泰迪拿着他 ...

  5. 攻防世界web进阶题—unfinish

    攻防世界web进阶题-unfinish 1.看一下题目提示SQL 2.打开题目看一下源码,没有问题 3.查一下网站的组成:php+Apache/2.4.7+Ubuntu 4.扫一下目录,扫到一个注册页 ...

  6. 攻防世界web进阶题—bug

    攻防世界web进阶题-bug 1.打开题目看一下源码,没有问题 2.扫一下目录,没有问题 3.查一下网站的组成:php+Apache+Ubuntu 只有登录界面 这里可以可以想到:爆破.万能密码.进行 ...

  7. 攻防世界 web进阶区 ics-06

    攻防世界 ics-06 涉及知识点: (1)php://filter协议 (2)php中preg_replace()函数的漏洞 解析: 进入题目的界面,一通乱点点出了唯一一个可以进入的界面. 观察ur ...

  8. 攻防世界 web进阶区 lottery

    首先进入题目的页面. 按其要求登录.然后看到以下界面. 御剑扫描目录,发现了robots.txt (robots协议) ,进入查看 进入.git/目录,用神器 GitHack 下载文件. 然后查看源码 ...

  9. 攻防世界MISC—进阶区1-10

    1.something_in_image zip中的文件用010 Editor打开后直接搜索flag,即可找到flag 2.wireshark-1 zip内是pcap文件,打开后根据题目知道要寻找登录 ...

随机推荐

  1. Front End Frameworks Trending 2021

    Front End Frameworks Trending 2021 Front End Frameworks https://2019.stateofjs.com/front-end-framewo ...

  2. iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug

    iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug iOS 14.1 Bug 弹窗 UI 非常丑 弹窗屏占太高了 屏幕使用时间 https://support.apple ...

  3. React Slingshot

    React Slingshot React 弹弓 https://github.com/coryhouse/react-slingshot https://decoupledkit-react.rea ...

  4. VirtualBox All in One

    VirtualBox All in One 虚拟机 / VM / Virtual Machine x86 and AMD64/Intel64 VirtualBox is a powerful x86 ...

  5. TypeScript with React

    TypeScript with React # Make a new directory $ mkdir react-typescript # Change to this directory wit ...

  6. css delete line text & html del

    css delete line text & html del html <del>¥720</del> demo <span class="ticke ...

  7. Baccarat凭什么能成为DeFi后时代火爆新趋势?

    在各币种经历涨涨跌跌以后,DeFi后时代已然来临.那么,当前DeFi市场中哪个项目更被市场生态建设者看好呢?毫无疑问,Baccarat会成为最被看好的DeFi项目. Baccarat采用了独特的共识算 ...

  8. [转]【视觉 SLAM-2】 视觉SLAM- ORB 源码详解 2

    转载地址:https://blog.csdn.net/kyjl888/article/details/72942209 1 ORB-SLAM2源码详解 by 吴博 2 https://github.c ...

  9. 14_MySQL条件查询

    本节所涉及的sql语句: -- 去除结果集中的重复记录 SELECT job FROM t_emp; SELECT DISTINCT job FROM t_emp; SELECT DISTINCT j ...

  10. java基础第12期——反射、注解

    一. 反射 反射: 将类的各个组成部分封装为其他对象. 1.1 获取class对象的方式 Class.forName("全类名"): 将字节码文件加载进内存,返回class对象 多 ...