本帖最后由 whklhh 于 2017-10-20 01:10 编辑
Reversing.kr是韩国的一个逆向题目网站
有分国度的排行榜,还是挺有意思的
本题即来自于第二十二关MetroApp
http://reversing.kr/challenge.php可以下载到文件
这次的逆向处理了很多麻烦,学到了不少关于MetroApp的东西,有没有用呢……囧
首先解压得到README,两个文件夹,一个ps1脚本,一个appx安装文件,一个cer证书
README中说明flag是全大写英文和数字,就没了
查了一下,用自带的PowerShell可以安装appx:
[Bash shell] 纯文本查看 复制代码 Add-AppxPackage F:\ctf\reversing.kr\MetroApp\MetroApp\MetroApp_1.0.0.5_Win32.appx
但是报错证书不可信任,看了一下证书的许可日期是2013-2014,很明显超出时间了
将本地的时间改到2013年后再次安装,又报错缺少依赖的包,查了得知是C#RunTime的库,但是我以前应该安装过╮(╯_╰)╭
ps1后缀名是PowerShell脚本,直接运行也会报错
到这里就没辙了,只好去查一下appx的相关知识,得知appx跟APK类似,实际上也是一个压缩包
通过RAR或者ZIP可以直接打开,解压后得到一堆配置文件和一个exe文件:
虽然这个exe不能直接运行,会报错要求容器上下文,必须依赖metro
但是还是个PE文件,可以直接拖IDA反编译呀~
查找字符串发现Correct和Wrong:
几个API稍微猜猜查查就能得到意思,只是要求MERONG出现在开头嘛~
很简单啊~
验证果然错误╮(╯_╰)╭
上下查了一下也没找到GetWindowText类型的API,不知道从哪里看起
而且由于有大量的虚函数,所以纯静态分析过于困难了
于是再回头研究如何安装吧_(:з」∠)_
后来发现,脚本运行需要先更改执行策略来执行不安全的脚本:
[Bash shell] 纯文本查看 复制代码 PS C:\Windows\system32> Set-ExecutionPolicy -ExecutionPolicy Unrestricted
执行策略更改
执行策略可帮助你防止执行不信任的脚本。更改执行策略可能会产生安全风险,如 http://go.microsoft.com/fwlink/?LinkID=135170
中的 about_Execution_Policies 帮助主题所述。是否要更改执行策略?
[Y] 是(Y) [A] 全是(A) [N] 否(N) [L] 全否(L) [S] 暂停(S) [?] 帮助 (默认值为“N”): y
PS C:\Windows\system32> F:\ctf\reversing.kr\MetroApp\MetroApp\Add-AppDevPackage.ps1
安全警告
请只运行你信任的脚本。虽然来自 Internet 的脚本会有一定的用处,但此脚本可能会损坏你的计算机。如果你信任此脚本,请使用
Unblock-File cmdlet 允许运行该脚本,而不显示此警告消息。是否要运行
F:\ctf\reversing.kr\MetroApp\MetroApp\Add-AppDevPackage.ps1?
[D] 不运行(D) [R] 运行一次(R) [S] 暂停(S) [?] 帮助 (默认值为“D”): r
Found package: F:\ctf\reversing.kr\MetroApp\MetroApp\MetroApp_1.0.0.5_Win32.appx
Before installing this package, you need to do the following:
- Acquire a developer license
A developer license was successfully acquired.
Installing package…
Found dependency package(s):
F:\ctf\reversing.kr\MetroApp\MetroApp\Dependencies\x86\Microsoft.VCLibs.x86.11.00.appx
Success: Your package was successfully installed.
按 Enter 键继续…:
可以看到,脚本自动地去Dependencies中安装了缺少的依赖库,然后安装就可以了
(注意本地时间要改哦,否则证书仍然是失效的)
安装完成以后在开始菜单中(M开头的程序)就可以找到MetroApp了,运行发现是一个文本框和按钮
由于它还是PE程序,因此可以用OD附加调试(不过不能以调试模式直接运行╮(╯_╰)╭)
附加以后要选择正确的模块,然后搜索字符串就可以跳到熟悉的地方了
首先测试一下,在刚才找到的关键跳处下断,点击按钮后爆破:
看到Correct被创建了引用以后F9,程序还是返回Wrong了
没什么好思路,大量的虚函数让我无从下手,只好从头到后面一直单步跟了
(后来发现其实之前就获取了输入字符串,只是没显示出来而已
参数都为结构体,第二个字节保存长度3,第五个字节保存真正的字符串地址。猜测是这种结构中的Object?)
中间有一些虚函数获取了输入字符
但是也没发现用在哪里了,继续往下跟发现它重复获取了很多很多次,意图应该是干扰吧
一直跟到最后,发现这里有使用:
按照地址,找到对应的反编译:
为了验证是否是循环处理输入字符串,在OD中下断F9发现果然又循环到这里了,并且ebx,即变量i自增了
代码中可以分析出来v1作为flag,如果不等于的话就会运行下边的大段代码
那大段代码我没明白是什么意思
也没找到再次校验的地方
粗暴的直接爆破,把OD中对应if(v1)的跳转改成了jmp,再F9发现程序就返回Correct了
于是结合之前MERONG的判断进行了多次实验,发现
1.MERONG的查找结果不影响结果
2.只要爆破了if(v1)就会显示Correct
3.MERONG只经过了一次(说明不是对输入字符串变换以后再次校验是否和MERONG相等的类型)
也就是说输入只要满足迭代关系式就行了,并且由于关系式的特性,每一个首字符都可以生长出任意长度的字符串
迭代关系式:
第n+1个字节==第n个字节循环右移(第n个字节的值&7) ^ byte_4307A8[i & 7]
正向运算非常容易,写出脚本随便生成一个字符串后输入,结果还是返回Wrong了
去OD中跟踪发现运算的字符串包括结尾的\0,也就是说生长出的字符串结尾必须为0,这就有些难度了
反求有些麻烦,因此就准备直接穷举了
这样的字符串应该不只一个,其他限定条件还有吗?
有啊!README中提示了要求只由大写字母和数字组成!
那么穷举范围就大大缩小了,从48-90即可(其实还可以刨去中间的几个符号,不过懒得搞啦~)
遍历首字符,以20为MAX长度,生成脚本:
[Python] 纯文本查看 复制代码 def rol(a, n):
for i in range(n):
p = a // (0x100 >> 1)
a = p + ((a << 1) & 0xff)
return a
d = [119, 173, 7, 2, 165, 0, 41, 153]
MAX = 20
flag = []
s = [0]
for j in range(48, 90):
s[0] = j
i = 0
for i in range(MAX):
k = d[i & 7] ^ rol(s, s & 7)
if (not k):
flag.append(s)
break
s.append(k)
j += 1
s = [0]
for j in flag:
for i in j:
print(chr(i), end='')
print()
得到两个字符串
第一个字符串存在小写字母,很明显就是第二个了,提交完成
其实这个脚本还有改善余地:
判断k非大写字母和数字时就停止生成,这样可以阻止MAX过大时的时间浪费,并且flag全部满足条件
当MAX需要更大时可以使用上述条件减少穷举的时间
我就懒得搞啦~
总的来说压根没搞懂整个程序,只是粗暴的通过爆破找到通过路径,然后找到答案而已……
最后也没有弄明白弹窗的Correct和Wrong是怎么分开的,以及if(v1)中的代码的flag是何处……希望懂的师傅能指点一下(:з」∠)
PS:话说MetroApp算Windows平台还是移动平台呀233
|