首页
论坛
课程
招聘
[原创]看雪CTF 秋季赛 第二题 writeup
2017-10-26 22:13 1071

[原创]看雪CTF 秋季赛 第二题 writeup

2017-10-26 22:13
1071
这个题目思路极其独特,看似简单的题目,背后居然隐藏了怎么大的秘密。


刚开始打开IDA的时候,代码极其简单,很兴奋,感觉又好像是一道类似签到题。

void sub_401090(){  
  int v0; // [sp+4h] [bp-8h]@0  
  int v1; // [sp+8h] [bp-4h]@0  
  if ( v1 && v0 && v1 != v0 && 5 * (v1 - v0) + v1 == 0x8F503A42 && 13 * (v1 - v0) + v0 == 0xEF503A42 )    
      --checkcode;
}
以及
void sub_4010E0(){  
  int v0; // [sp+4h] [bp-8h]@0  
  int v1; // [sp+8h] [bp-4h]@0  
  if ( v1 && v0 && v1 != v0 && 17 * (v1 - v0) + v1 == 0xF3A94883 && 7 * (v1 - v0) + v0 == 0x33A94883 )    
      --checkcode;
}

只需要将两次的if语句都算正确即可。
6 * a - 5 * b = 0x8F503A42(s1)
13 * a - 12 * b = 0xEF503A42(s2)
18 * a - 17 * b = 0xF3A94883(s3)
7 * a - 6 * b = 0x33A94883(s4)

按照常规的数学运算,a和b是能够通过多个等式求出来的 即使求出来的解不是很准确,但是最多也就最高位上的值不是很准确

a = s4 * 2 - s2
a = s1 + s2 - s3
b = (s1 * 3 - s3) / 2
b = s1 + s4 - s2

通过两中方式求出来的a,b差距很大, 而且看 数值  0xF3A94883 ≈ 0x33A94883 ,  0x8F503A42 ≈ 0xEF503A42。

所以说可能是有诈,并且没有说明输入的字符长度为8。
后发现该程序存在栈溢出漏洞,作者可能利用这一点将真正的代码验证端放到之后。并且OD加载的初始位置和这段代码之间的间隔了很多的空数据。 找到空数据结束的位置  0x413131 。 推测可能为程序真正的代码验证块。

0018FF34   0041B08C  ASCII "%s"
0018FF38   0018FF3C  ASCII "aaaabbbbcccc11A"
0018FF3C   61616161
0018FF40   62626262
0018FF44   63636363
0018FF48   00413131  ctf2017_.004131310018FF4C   
00413E3E  返回到 ctf2017_.00413E3E 来自 ctf2017_.00401000

直接覆盖返回地址为00413131 即输入12个字符+11A

之后代码后很多花指令,乱跳转,但是目的都只有一个,是用来验证输入的code。

使用调试软件直接动调将一句一句代码扣下来, 因为全是跳转语句,刚开始在验证的跳转处没有识别出来,然后遇到了挫折。后来发现主要的跳转有一个特点就是跳转很长。


00413131 | 83 C4 F0                 | add esp,FFFFFFF0                        |
00413150 | 33 C0                    | xor eax,eax                             | eax:"aaaabbbbcccc11A"
00413184 | A3 34 B0 41 00           | mov dword ptr ds:[41B034],eax           |
004131BA | 58                       | pop eax                                 |
004131EB | 8B C8                    | mov ecx,eax                             | ecx:&"\n\n"
0041321F | 58                       | pop eax                                 |
00413254 | 8B D8                    | mov ebx,eax                             |
00413289 | 58                       | pop eax                                 |
004132B5 | 8B D0                    | mov edx,eax                             |
004132AD | 8B D0                    | mov edx,eax                             |
004132E2 | 8B C1                    | mov eax,ecx                             |
00413316 | 2B C3                    | sub eax,ebx                             |
00413349 | C1 E0 02                 | shl eax,2                               |
00413380 | 03 C1                    | add eax,ecx                             |
004133B5 | 03 C2                    | add eax,edx                             |
004133E9 | 2D E2 17 F9 EA           | sub eax,EAF917E2                        |
00413420 | 0F 85 DD 06 00 00        | jne ctf2017_fpc.413B03                  |
00413455 | 03 C1                    | add eax,ecx                             |
00413489 | 2B C3                    | sub eax,ebx                             |
004134BF | 8B D8                    | mov ebx,eax                             |
004134F3 | D1 E0                    | shl eax,1                               |
00413525 | 03 C3                    | add eax,ebx                             |
00413559 | 03 C1                    | add eax,ecx                             |
0041358F | 8B C8                    | mov ecx,eax                             |
004135C3 | 03 C2                    | add eax,edx                             |
004135F7 | 2D C8 08 F5 E8           | sub eax,E8F508C8                        |
0041362E | 0F 85 CF 04 00 00        | jne ctf2017_fpc.413B03                  |
00413665 | 8B C1                    | mov eax,ecx                             |
0041365D | 8B C1                    | mov eax,ecx                             |
004136A7 | 2B C2                    | sub eax,edx                             |
004136D8 | 2D 68 3C 0A 0C           | sub eax,C0A3C68                         |
00413710 | 0F 85 ED 03 00 00        | jne ctf2017_fpc.413B03                  |
00413747 | 58                       | pop eax                                 |
00413777 | 35 01 81 00 00           | xor eax,8101                            |
004137A9 | 8B F8                    | mov edi,eax                             |
004137E2 | 33 C0                    | xor eax,eax                             |
00413817 | AB                       | stosd dword ptr es:[edi],eax            |
0041385C | 58                       | pop eax                                 |
0041388E | 50                       | push eax                                |
004138BA | 8B F8                    | mov edi,eax                             |
004138B2 | 8B F8                    | mov edi,eax                             |
004138E6 | 68 69 09 00 4E           | push 4E000969                           |
0041391F | 58                       | pop eax                                 |
004139B5 | 35 3E 0A 01 00           | xor eax,10A3E                           |
004139EB | AB                       | stosd dword ptr es:[edi],eax            |
00413A1C | 33 C3                    | xor eax,ebx                             |
00413A4D | 35 14 1E 51 22           | xor eax,22511E14                        |
00413A82 | AB                       | stosd dword ptr es:[edi],eax            |
00413AB6 | 35 2D 64 61 00           | xor eax,61642D                          |
00413B83 | 33 05 34 B0 41 00        | xor eax,dword ptr ds:[41B034]           |
00413BBB | FF E0                    | jmp eax                                 |

核心的代码就是怎么一段, 最后是经过jmp eax 回到输出的位置的。

可以就只分析前面的三个等式,忽略后面的,总结就是怎么三个等式。求三个解。

5 * a -  4 * b + c = 0xEAF917E2(s1)
4 * a -  3 * b + c = 0xE8F508C8(s2)
5 * a -  3 * b - c = 0x0C0A3C68(s3)

先计算出大概值:

c = (s2 - s3) / 2;
a = (s2 - c) * 4 - (s1 - c) * 3;
b = (s2 - c) * 5 - (s1 - c) * 4;

a = 0xf473754a ; b = 0xf26f6630 ; c = 0xee756630;

高位在爆破一下:

for (int i1 = 0; i1 <= 0xff; i1++){
	for (int i2 = 0; i2 <= 0xff; i2++){
		for (int i3 = 0; i3 <= 0xff; i3++){
			int t1 = ((i1 << 24) & 0xff000000) + (0xf473754a & 0xffffffff);
			int t2 = ((i2 << 24) & 0xff000000) + (0xf26f6630 & 0xffffffff);
			int t3 = ((i3 << 24) & 0xff000000) + (0xee756630 & 0xffffffff);
			if ((5 * t1 - 4 * t2 + t3 == s1) && (4 * t1 - 3 * t2 + t3 == s2) && (4 * t1 - 3 * t2 - t3 == s3)){
				printf("%x %x %x \n", t1, t2, t3);
			}
		}
	}
}

//output: 7473754a 726f6630 6e756630

最后flag为 Just0for0fun11A 

出题人的思路真心可以,第一次遇到这种骚操作。

[培训]12月3日2020京麒网络安全大会《物联网安全攻防实战》训练营,正在火热报名中!地点:北京 · 新云南皇冠假日酒店

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回