首页
社区
课程
招聘
[原创]看雪CTF.TSRC 2018 第十题 侠义双雄 WP
2018-12-21 10:47 7147

[原创]看雪CTF.TSRC 2018 第十题 侠义双雄 WP

2018-12-21 10:47
7147

第一部分:解题

先看一眼界面:
图片描述

 

于是查PEiD,发现是Delphi编译的,直接用DeDe找到窗口过程:
图片描述
图片描述

 

其中 Button1Click 函数响应的是右上角的关闭按钮,就把目光转到了 Button2Click 函数上。但无奈调试时发现在 Button2Click 中的断点一直没有断到过,只能再看看 FormCreate 和 FormShow 中有没有猫腻了。在 FormShow 中发现了如下代码信息:
图片描述
图片描述
图片描述

 

哈哈,竟然用HTML画界面,用vbscript弹窗口,那验证代码肯定在ckpswd()中了!
毫无疑问,ckpswd()函数肯定是js代码了,而且根据上面的HTML代码来看,中间部分数据是加密的,那他肯定要解密这段数据交给HTML解析函数去处理,这时候直接观察这段数据解密过程(我直接F9运行起来后内存搜索了),最终发现解密完后的HTML代码如下:

< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > 
<script>
    eval(function(s, p, a, c, k, e, d) {
        for (i = 0; i < k.length; i++) k[i] = k[i].replace(s, '');
        e = function(c) {
            eval(document.write(String.fromCharCode(13)));
            return (eval(c < a) ? '': e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
        };
        if (!''.replace(/^/, String)) {
            while (c--) d[e(c)] = k[c] || e(c);
            k = [function(e) {
                return d[e]
            }];
            e = function() {
                return '\\w+'
            };
            c = 1
        };
        while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
        return p
    } ( '$$$',
        '8 4() {    1 = 6.3.e.f;    9 (1 == "b") {        2("5!")    } 7 {        2("g!<" + 1 + "> a d c 0 ;-)")    }}',
        62,
        17, 
        'GUID$$$@a$$$@alert$$$@all$$$@ckpswd$$$@congratulations$$$@document$$$@else$$$@function$$$@if$$$@is$$$@kanxueCTF2018bySimpower91$$$@my$$$@not$$$@pswd$$$@value$$$@wrong$$$'.split('@'),
        0,
        {} )
    )
</script>
CTF 2018&reg;
<script language="vbscript">
    function alert(msg_str)
        MsgBox msg_str,vbOKOnly + vbExclamation + vbApplicationModal,""
    End Function
</script>
<center> <br> <br> <br>
    <input value = "" id = "pswd" size = 39></input><br><br><br>
    <input type = button value = "checkMyFlag" onclick="ckpswd();">
</center>

发现解密出的js代码还有一次解密操作,于是解密最终的js代码:

function ckpswd() {
    a = document.all.pswd.value;
    if (a == "kanxueCTF2018bySimpower91") {
        alert("congratulations!")
    } else {
        alert("wrong!<" + a + "> is not my GUID ;-)")
    }
}

发现Key:kanxueCTF2018bySimpower91,这个key竟然在最终cklswd()代码解密之前就存在了(震惊)!

第二部分:尝试分析作者思路

直接用内存搜索的方法找到了解密后的js代码,感觉有些过意不去啊,作者的解密逻辑都没有分析,回头来看看作者是怎么解密的吧。

 

用IDR导出分析后的Map文件,使用开源的IDA插件 ida-pro-loadmap 导入MAP文件,这样就可以识别这些库函数了(插件在库函数头的注释中写上了函数名,就方便手动修改函数名了),修好函数名了再用IDA导出MAP文件给OD使用:
图片描述

 

看下部分代码:
图片描述

 

这代码逻辑肯定是作者构造的,于是开始调试分析。

 

重点在sub_467ACC -> sub_467878 -> sub_46750C -> sub_467938中,sub_467878函数结尾为jmp [esp-4+var_3C]sub_46750C中有一句call dword ptr [ebx+1030h]sub_467938中有一句call dword ptr [ebx+1060h],这些都是疑点。

 

调试后发现作者在利用栈来布局数据和ShellCode,而作者对栈的使用也是比较夸张的,直接承包了整个栈空间:
图片描述

 

sub_467938call dword ptr [ebx+1060h]是进入函数sub_467974,而该函数会根据 4691AF 位置的数据解密出如下ShellCode,这段ShellCode会作为sub_46750Ccall dword ptr [ebx+1030h]的参数:

0018F658    8D4D 8C         lea ecx,dword ptr ss:[ebp-0x74]
0018F65B    8B55 FC         mov edx,dword ptr ss:[ebp-0x4]
0018F65E    A1 C8CC4600     mov eax,dword ptr ds:[0x46CCC8]
0018F663    E8 2DE6FFFF     call 0018DC95

sub_46750Ccall dword ptr [ebx+1030h]是执行在堆中释放的代码:

00811300    55              push ebp
00811301    8BEC            mov ebp,esp
00811303    33C0            xor eax,eax
00811305    C705 84A78200 0>mov dword ptr ds:[0x82A784],0x1
0081130F    8B55 18         mov edx,dword ptr ss:[ebp+0x18]
00811312    A3 88A78200     mov dword ptr ds:[0x82A788],eax
00811317    52              push edx
00811318    C705 94A78200 0>mov dword ptr ds:[0x82A794],0x1
00811322    8B4D 14         mov ecx,dword ptr ss:[ebp+0x14]
00811325    51              push ecx
00811326    8B45 10         mov eax,dword ptr ss:[ebp+0x10]   ; enc0_cra.00467B10
00811329    50              push eax
0081132A    8B55 0C         mov edx,dword ptr ss:[ebp+0xC]    ; enc0_cra.004691AF
0081132D    52              push edx
0081132E    8B4D 08         mov ecx,dword ptr ss:[ebp+0x8]
00811331    51              push ecx
00811332    E8 6D5F0000     call 008172A4
00811337    83C4 14         add esp,0x14
0081133A    5D              pop ebp                  ; enc0_cra.00467578
0081133B    C2 1400         retn 0x14

sub_467878函数结尾的jmp [esp-4+var_3C]是跳转执行一句代码再返回到指定位置,这句代码就是上面解密出的ShellCode中的,例如:

00094038    8D4D 8C         lea ecx,dword ptr ss:[ebp-0x74]
0009403B    68 107B4600     push 0x467B10
00094040    C3              retn

时间问题,没有调完,有空以后再填坑吧。直接写出目前我调试后发现的代码逻辑吧:

  1. sub_467938call dword ptr [ebx+1060h]进入函数sub_467974解密一段ShellCode
  2. sub_46750Ccall dword ptr [ebx+1030h]根据上一步的ShellCode构造sub_467878函数结尾jmp [esp-4+var_3C]跳转位置的代码,执行完之后调用sub_464518将代码写到跳转位置去
  3. 在调试过程中还发现sub_46750C中的代码将上面解密出的ShellCode翻译成了汇编语句字符串,之后再对这段汇编字符串进行操作,难道是先反汇编然后再将汇编语句编译成二进制?如果是的话就很符合题目“侠义双雄”了

目前不能下结论,由于作者忽略了HTML代码在内存中很容易搜到的问题,导致题目很快被破解了,不然完整分析解密过程还是需要比较长的时间~


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2018-12-21 10:51 被KevinsBobo编辑 ,原因:
收藏
点赞5
打赏
分享
最新回复 (5)
雪    币: 22979
活跃值: (3337)
能力值: (RANK:648 )
在线值:
发帖
回帖
粉丝
KevinsBobo 8 2018-12-21 12:27
2
0

后续见大佬 ODPan 的文章 https://bbs.pediy.com/thread-248550.htm
sub_467878函数结尾jmp [esp-4+var_3C]跳转后的位置,逐条收集解密、修复过的ShellCode就能找到解密js脚本的函数:sub_4677EC

雪    币: 7839
活跃值: (944)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
点中你的心 2018-12-21 13:29
3
0
感谢分享,支持分享
雪    币: 1470
活跃值: (74)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
新月之铭 2018-12-21 14:37
4
0
本来有非预期解,大佬非得按作者思路解~大佬就是大佬
雪    币: 22979
活跃值: (3337)
能力值: (RANK:648 )
在线值:
发帖
回帖
粉丝
KevinsBobo 8 2018-12-21 15:14
5
0
新月之铭 本来有非预期解,大佬非得按作者思路解~大佬就是大佬
我是直接搜内存得到解的,但是看到作者构造的代码,感觉不调一遍对不起作者啊
雪    币: 1470
活跃值: (74)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
新月之铭 2018-12-21 17:49
6
0
KevinsBobo 我是直接搜内存得到解的,但是看到作者构造的代码,感觉不调一遍对不起作者啊
其实也不是~分析了大半天没结果,最后内存里搜到了。是作者戏弄了我们
游客
登录 | 注册 方可回帖
返回