2019看雪CTF 晋级赛Q2第四题wp
上次参加2019看雪CTF 晋级赛Q2卡在了这道题上,虽然逆出算法,但是方程不会解,哈哈哈哈,果然数学知识很重要呀,现在记录一下。
首先根据关键信息,根据错误提示字符串定位到这里:
1 int __thiscall guanjian_401EA0(CWnd *this)
2 {
3 CWnd *v1; // esi
4 int index; // eax
5 WCHAR String; // [esp+Ch] [ebp-310h]
6 char v5; // [esp+Eh] [ebp-30Eh]
7 char ptr; // [esp+20Ch] [ebp-110h]
8 char v7; // [esp+20Dh] [ebp-10Fh]
9 DWORD v8; // [esp+30Ch] [ebp-10h]
10 CWnd *v9; // [esp+310h] [ebp-Ch]
11 int v10; // [esp+314h] [ebp-8h]
12 DWORD flOldProtect; // [esp+318h] [ebp-4h]
13
14 v1 = this;
15 v9 = this;
16 String = 0;
17 memset(&v5, 0, 0x1FEu);
18 ptr = 0;
19 memset(&v7, 0, 0xFFu);
20 CWnd::GetDlgItemTextW(v1, 1000, &String, 20);
21 if ( wcslen(&String) == 16 )
22 {
23 index = 0;
24 while ( !(*(&String + index) & 0xFF00) )
25 {
26 *(&ptr + index) = *((_BYTE *)&String + 2 * index);
27 if ( ++index >= 16 )
28 {
29 v8 = 64;
30 flOldProtect = 0;
31 VirtualProtect(sub_9D10E0, 0xD17u, 0x40u, &flOldProtect);// BOOL VirtualProtect(
32 // LPVOID lpAddress,
33 // DWORD dwSize,
34 // DWORD flNewProtect,
35 // PDWORD lpflOldProtect
36 // lpAddress,要改变属性的内存起始地址。
37 //
38 // dwSize,要改变属性的内存区域大小。
39 //
40 // flNewProtect,内存新的属性类型,设置为PAGE_EXECUTE_READWRITE(0x40)时该内存页为可读可写可执行。
41 //
42 // pflOldProtect,内存原始属性类型保存地址。
43 //
44 //
45 GetLastError();
46 qmemcpy(sub_9D10E0, byte_B347B8, 0x330u);
47 VirtualProtect(sub_9D10E0, 0xD17u, flOldProtect, &v8);
48 if ( !GetLastError() )
49 {
50 v10 = 0;
51 v10 = sub_9D10E0();
52 if ( v10 == 1 )
53 return CWnd::MessageBoxW(v9, L"Congratulations! You are right!", 0, 0);
54 }
55 v1 = v9;
56 return CWnd::MessageBoxW(v1, L"Wrong!", 0, 0);
57 }
58 }
59 }
60 return CWnd::MessageBoxW(v1, L"Wrong!", 0, 0);
61 }
注意到运行时先修改sub_9D10E0()代码段,然后再运行sub_9D10E0(),我们动态调试,dump出修改完成的sub_9D10E0()代码段
1 int __cdecl sub_9D10E0(char *input)
2 {
3 signed int i; // eax
4 char v2; // cl
5 signed int v3; // ecx
6 signed int v4; // eax
7 signed int low_index; // eax
8 signed int j; // esi
9 signed int k; // ecx
10 __int16 v8; // dx
11 char *buffer_ptr_; // edi
12 __int16 v10; // ax
13 signed int temp_1; // eax
14 signed int m_1; // ecx
15 unsigned __int16 t_3; // bx
16 signed int j_1; // esi
17 signed int k_1; // ecx
18 __int16 v16; // dx
19 char *buffer_ptr; // edi
20 __int16 t_4; // ax
21 signed int t; // eax
22 signed int m; // ecx
23 unsigned __int16 temp; // bx
24 unsigned int t_1; // eax
25 signed int i_2; // ecx
26 unsigned __int16 temp_2; // dx
27 char f; // dl
28 signed int i_1; // eax
29 __int16 t_2; // si
30 int index; // eax
31 char s_xor[17]; // [esp+8h] [ebp-90h]
32 int v31; // [esp+1Ch] [ebp-7Ch]
33 int v32; // [esp+20h] [ebp-78h]
34 int v33; // [esp+24h] [ebp-74h]
35 char x[8]; // [esp+28h] [ebp-70h]
36 char buffer[16]; // [esp+30h] [ebp-68h]
37 char y[8]; // [esp+40h] [ebp-58h]
38 char yy7_result[17]; // [esp+48h] [ebp-50h]
39 char result[17]; // [esp+5Ch] [ebp-3Ch]
40 char xx_result[17]; // [esp+70h] [ebp-28h]
41 char yy_result[17]; // [esp+84h] [ebp-14h]
42
43 s_xor[4] = 0x81u;
44 s_xor[11] = 0x81u;
45 i = 0;
46 s_xor[0] = 0x16;
47 s_xor[1] = -106;
48 s_xor[2] = -116;
49 s_xor[3] = -29;
50 s_xor[5] = -104;
51 s_xor[6] = 110;
52 s_xor[7] = 100;
53 s_xor[8] = 0x84u;
54 s_xor[9] = 8;
55 s_xor[10] = -36;
56 s_xor[12] = 0xBEu;
57 s_xor[13] = 77;
58 s_xor[14] = 72;
59 s_xor[15] = 79;
60 *(_DWORD *)&s_xor[16] = 0;
61 v31 = 0;
62 v32 = 0;
63 v33 = 0;
64 *(_DWORD *)x = 0;
65 *(_DWORD *)&x[4] = 0;
66 *(_DWORD *)y = 0;
67 *(_DWORD *)&y[4] = 0;
68 do
69 { // 先将输入分成两部分,记为x,y,然后进行异或操作,
70 v2 = s_xor[i + 8] ^ input[i + 8]; // 从输入的第9位开始处理,索引8-15
71 // 异或
72 x[i] = s_xor[i] ^ s_xor[i + input - s_xor]; // 输入的前8位
73 // 异或
74 y[i++] = v2;
75 }
76 while ( i < 8 );
77 *(_DWORD *)s_xor = 0;
78 *(_DWORD *)xx_result = 0;
79 *(_DWORD *)&xx_result[4] = 0;
80 *(_DWORD *)&xx_result[8] = 0;
81 *(_DWORD *)&xx_result[12] = 0;
82 xx_result[16] = 0;
83 *(_DWORD *)yy_result = 0;
84 *(_DWORD *)&yy_result[4] = 0;
85 *(_DWORD *)&yy_result[8] = 0;
86 *(_DWORD *)&yy_result[12] = 0;
87 yy_result[16] = 0;
88 *(_DWORD *)yy7_result = 0;
89 *(_DWORD *)&yy7_result[4] = 0;
90 *(_DWORD *)&yy7_result[8] = 0;
91 *(_DWORD *)&yy7_result[12] = 0;
92 yy7_result[16] = 0;
93 *(_DWORD *)result = 0;
94 *(_DWORD *)&result[4] = 0;
95 *(_DWORD *)&result[8] = 0;
96 *(_DWORD *)&result[12] = 0;
97 result[16] = 0;
98 *(_DWORD *)&s_xor[4] = 0;
99 *(_DWORD *)&s_xor[8] = 0;
100 *(_DWORD *)&s_xor[12] = 0;
101 s_xor[16] = 0;
102 v3 = 8;
103 s_xor[0] = 8;
104 v4 = 7;
105 do
106 {
107 if ( x[v4] ) // x[7]!=0
108 break;
109 --v3;
110 --v4;
111 }
112 while ( v4 >= 0 );
113 if ( v3 == 8 )
114 {
115 low_index = 7;
116 do
117 {
118 if ( y[low_index] ) // y[7]!=0
119 break;
120 --v3;
121 --low_index;
122 }
123 while ( low_index >= 0 ); // 输入为16位
124 if ( v3 == 8 && !(x[7] & 0xF0) ) // 第8位<0x10
125 {
126 j = 0;
127 do
128 {
129 *(_DWORD *)buffer = 0;
130 *(_DWORD *)&buffer[4] = 0;
131 *(_DWORD *)&buffer[8] = 0;
132 *(_DWORD *)&buffer[12] = 0;
133 k = 0;
134 v8 = (unsigned __int8)x[j];
135 buffer_ptr_ = &buffer[j];
136 do
137 {
138 v10 = (unsigned __int8)buffer[j + 8] + v8 * (unsigned __int8)x[k];
139 buffer_ptr_[k] = buffer[j + 8] + v8 * x[k];
140 ++k;
141 buffer[j + 8] = HIBYTE(v10);
142 }
143 while ( k < 8 );
144 LOBYTE(temp_1) = 0;
145 m_1 = 0;
146 do
147 {
148 t_3 = (char)temp_1 + (unsigned __int8)xx_result[m_1 + j] + (unsigned __int8)buffer_ptr_[m_1];
149 xx_result[m_1++ + j] = t_3;
150 temp_1 = (signed int)t_3 >> 8;
151 }
152 while ( m_1 < 9 );
153 ++j; // 先按字节乘,再加进位,和手算乘法原理一致
154 }
155 while ( j < 8 ); // 通过两层循环其实是为了计算大数相乘,这里算出x^2
156 j_1 = 0;
157 do
158 {
159 *(_DWORD *)buffer = 0;
160 *(_DWORD *)&buffer[4] = 0;
161 *(_DWORD *)&buffer[8] = 0;
162 *(_DWORD *)&buffer[12] = 0;
163 k_1 = 0;
164 v16 = (unsigned __int8)y[j_1];
165 buffer_ptr = &buffer[j_1];
166 do
167 {
168 t_4 = (unsigned __int8)buffer[j_1 + 8] + v16 * (unsigned __int8)y[k_1];
169 buffer_ptr[k_1] = buffer[j_1 + 8] + v16 * y[k_1];
170 ++k_1;
171 buffer[j_1 + 8] = HIBYTE(t_4);
172 }
173 while ( k_1 < 8 );
174 LOBYTE(t) = 0;
175 m = 0;
176 do
177 {
178 temp = (char)t + (unsigned __int8)yy_result[m + j_1] + (unsigned __int8)buffer_ptr[m];
179 yy_result[m++ + j_1] = temp;
180 t = (signed int)temp >> 8;
181 }
182 while ( m < 9 );
183 ++j_1; // 这里计算出y^2
184 }
185 while ( j_1 < 8 );
186 LOBYTE(t_1) = yy7_result[16];
187 i_2 = 0;
188 do
189 { // 这里计算7*y^2
190 temp_2 = (unsigned __int8)t_1 + 7 * (unsigned __int8)yy_result[i_2];
191 yy7_result[i_2++] = temp_2;
192 t_1 = (unsigned int)temp_2 >> 8;
193 }
194 while ( i_2 < 17 );
195 yy7_result[16] = HIBYTE(temp_2);
196 f = 0;
197 i_1 = 0;
198 do
199 {
200 t_2 = (unsigned __int8)xx_result[i_1] - (unsigned __int8)yy7_result[i_1] - f;
201 result[i_1] = t_2;
202 if ( t_2 < 0 )
203 f = 1;
204 ++i_1;
205 }
206 while ( i_1 < 17 );
207 if ( !f )
208 {
209 index = 0;
210 while ( result[index] == s_xor[index] ) // 这里相当于验证x^2-7*y^2==8
211 {
212 if ( ++index >= 17 )
213 return 1;
214 }
215 }
216 }
217 }
218 return 0;
219 }
到这里思路已经很明确了,16位输入,分成两部分进行异或操作,验证x^2-7*y^2=8
限定条件为
0x100000000000000<x < 0x1000000000000000,(x为8字节,且第8字节<0x10)
0x100000000000000<y<x (y为8字节,)
在进行一步异或即可得到原输入
x^2-7*y^2=8为非标准佩尔方程,求解使用了wolframalpha
https://www.wolframalpha.com/input/?i=x%5E2-7y%5E2%3D8,72057594037927936%3Cx+%3C+1152921504606846976,72057594037927936%3Cy%3Cx
1 x=385044246406735194
2 y=145533045678356702
3
4 s_xor1=0x646e9881e38c9616
5 s_xor2=0x4f484dbe81dc0884
6
7 t1=hex(x^s_xor1)[2:]
8 t2=hex(y^s_xor2)[2:]
9
10 m1=[]
11 m2=[]
12 for i in range(0,16,2):
13 m1.append(int(t1[i:i+2],16))
14 m2.append(int(t2[i:i+2],16))
15 a=''.join(map(chr,m1))
16 b=''.join(map(chr,m2))
17 print(a[-1::-1]+b[-1::-1])
18 # L3mZ2k9aZ0a36DMM
链接:https://pan.baidu.com/s/1ZpzCus2BdlSujkVRBQZZxQ
提取码:qrlz
复制这段内容后打开百度网盘手机App,操作更方便哦
2019看雪CTF 晋级赛Q2第四题wp的更多相关文章
- off-by-one&doublefree. 看雪10月ctf2017 TSRC 第四题赛后学习
off-by-one 0x00 发现漏洞 1.off-by-one 在massage函数中,如图所示,可以修改的字节数比原内存大小多了一个字节 2.悬挂指针 可以看到,在free堆块的时候,没有清空指 ...
- 看雪.TSRC 2017CTF秋季赛第三题
看雪.TSRC 2017CTF秋季赛第三题 wp 这是一道很简单的题,反调试的坑略多.这道题采用了很多常用的反调试手段,比如调用IsDebuggerPresent.进程名检查等等.另外也有利用SEH的 ...
- 看雪CTF第十题
__int64 sub_140006F50() { __int64 v0; // r8@1 __int64 v1; // r9@1 signed __int64 len; // rax@1 __int ...
- 看雪CTF第八题
IDA查看Exports有3个TlsCallback 只有TlsCallback_2有用 其中创建6个线程用于代码动态解码smc 只有前三个线程有用 分别对check_part1,check_part ...
- 看雪CTF第十四题
from z3 import * dest=[] s = Solver() data = [, , , , , , , , , , , , , , , , , , , , , , , , , , , ...
- 看雪CTF第十五题
1.直接运行起来,再用OD附加 在此处luajit加载并调用main函数 004021C7 E8 64FE0000 call CrackMe. ; luaL_newstate 004021CC 8BF ...
- 2019牛客多校赛第一场 补题 I题
I题 Points Division 题意: 给你n个点,每个点有坐标(xi,yi)和属性(ai,bi),将点集划分为两个集合, 任意 A 集合的点 i 和 B 集合点 j, 不允许 xi > ...
- 发现环——第八届蓝桥杯C语言B组(国赛)第四题
原创 标题:发现环 小明的实验室有N台电脑,编号1~N.原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络.在树形网络上,任意两台 电脑之间有唯一的路径相连. 不过在最近一次维护网络时,管 ...
- 『2019/4/9 TGDay2模拟赛 反思与总结』
2019/4/9 TGDay2模拟赛 今天是\(TG\)模拟赛的第二天了,试题难度也是相应地增加了一些,老师也说过,这就是提高组的难度了.刚开始学难的内容,一道正解也没想出来,不过基本的思路也都是对了 ...
随机推荐
- 谈一谈phar 反序列化
前言 来自Secarma的安全研究员Sam Thomas发现了一种新的漏洞利用方式,可以在不使用php函数unserialize()的前提下,引起严重的php对象注入漏洞.这个新的攻击方式被他公开在了 ...
- spring boot集成mybatis只剩两个sql 并提示 Cannot obtain primary key information from the database, generated objects may be incomplete
前言 spring boot集成mybatis时只生成两个sql, 搞了一个早上,终于找到原因了 找了很多办法都没有解决, 最后注意到生成sql的时候打印了一句话: Cannot obtain pri ...
- NGK与AOFEX交易所达成战略合作,BGV即将上线A网!
据NGK官方消息,NGK官方已经与英国伦敦知名交易所AOFEX交易所达成战略合作,将于12月2日全球首发BGV,现已开启充值服务.同时,在12月3日15:00,用户可以参与BGV交易:在12月4日15 ...
- 快速读懂 HTTP/3 协议
在 深入浅出:HTTP/2 一文中详细介绍了 HTTP/2 新的特性,比如头部压缩.二进制分帧.虚拟的"流"与多路复用,性能方面比 HTTP/1 有了很大的提升.与所有性能优化过程 ...
- django学习-26.admin管理后台里:修改登录页面标题,修改登录框标题,修改首页标题
目录结构 1.前言 2.完整的操作步骤 2.1.第一步:查看[site.py]的源码 2.2.第二步:在应用[hello]所在目录里的[admin.py]里重写三个属性的属性值 2.3.第三步:重启服 ...
- idea没有错误提示的解决方法(一直处于错误分析中)
仅作记录,以防再次发生却不记得. 原文链接:https://blog.csdn.net/a755199443/article/details/90084316 问题描述:idea没有自动报错.例如随便 ...
- 痞子衡嵌入式:系统时钟配置不当会导致i.MXRT1xxx系列下OTFAD加密启动失败
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是系统时钟配置不当会导致i.MXRT1xxx系列下OTFAD加密启动失败问题. 我们知道,i.MXRT1xxx家族早期型号(RT1050/ ...
- Markdown(2)基本语法
Markdown 是一种轻量级标记语言 , 通过简单的标记语法,使文本内容具有一定的格式 . 一.段落 1. 标题 语法格式: 符号 "#" 可以标记 1~6级标题.一级标题对 ...
- hive中更改表impala中不能生效
hive中的更新或者新建表impala 不能实时更新 Impala是基于Hive的大数据实时分析查询引擎,直接使用Hive的元数据库Metadata,意味着impala元数据都存储在Hive的meta ...
- 大数据实战-Hive-技巧实战
1.union 和 union all 前者可以去重 select sex,address from test where dt='20210218' union all select sex,add ...