首页
社区
课程
招聘
[原创]看雪.TSRC 2017CTF秋季赛第三题 crackMe
2017-10-29 20:28 2859

[原创]看雪.TSRC 2017CTF秋季赛第三题 crackMe

2017-10-29 20:28
2859
 

目录

 

对于这道题,服气。做的时候遇到思维定势,想着输入要符合base64解码和莫尔斯解码的规则,然而这题的关键就在与在解码时遇到不符合规则的情况就退出了,只解码符合规则的部分。

结果

这题很精彩,但是出现了多解。先上代码

#!/usr/bin/env python
# -*- coding: utf8 -*-

import subprocess
import base64
import random
import string

# 需要安装https://github.com/guanzhi/GmSSL
# 计算 SM3 哈希
def get_sm3(data):
    cmd = 'echo -n "{}" | gmssl sm3'.format(data)
    r = subprocess.check_output(cmd, shell=True)
    sm3 = r[-65:-1]

    return sm3

# 生成指定长度的随机字符串
def get_rand_str(length):
    r = ''
    candidate = string.ascii_letters + string.digits

    for i in range(length):
        r += random.choice(candidate)
    return r


if __name__ == '__main__':
    for i in range(32):
        # data长度为9的倍数,保证两次base64编码后没有 '='
        # 开头的 '/' 用于莫尔斯解码时产生一个空格
        data = '/' + get_rand_str(8)
        b64b64 = base64.b64encode(base64.b64encode(data))
        # 判断base64中是否包含 '/' 或 '+'
        if '/' in b64b64 or '+' in b64b64:
            continue
        sm3 = get_sm3(data[:3])
        print(b64b64+sm3)

然后再给一组flag。

THpKWlkyeEtNRTA16818125a17a0a98a3c0a014bc0e978c3acdf71432e1e597afd6c487c4d182221
TDB4SVoweExjbXB59cd2d73624a93aababf3404b290ba7fcd8d8c4ecc8a15b8f1cd11de29b33b755
TDNoU2FIVlpiSGcyfda40f2c80d024eaab84558a237aa9200a3b3ae9f921cbeeaf598d249f79a6a7
TDNaaVNFZ3lkMDlR734eb4d95b85812c9bd401558e426d0d9fe93275f304df3dc42149bd85b764a9
TDJ0UVJVUkJUbkYye224b0ddc81dcaf802c9d31222cf84f4225d77e90ed652f53308f1f8489e36ab
TDA1WVMxbzVjemhX87f0e5fa985af4492f4be21f12012129d1b3521ae44521c1d96822c724adee41
TDJSRWVtRlFhMFZ2174cd39924afa2fc8969c32be32aa4ea3ff170c3c633e897e3d8288282e7e95b
TDNCT2IxbEdTSE5U151f04656fff01be882fd049d5ed9395c095d67c0237c03fff438ed8a8c763fe
TDFkeVFUVjFZMjky44a0b5a26336988f7fbed52d8ffda04084446114ab6676892d27e7e939d9d33b
TDJGeFVISnpPRWhJ5015ef13da10b5b2826719280e32b87e0732ffd367944ff1d5a31c754215f449
THpKVmVGUlJlWFZNe805f6d6360a74e82bd021470437770764c08bc4668eaf57ec6010e730bb805a
TDJsUVpubE9aMHhQ3b5274917f8cdbb8c689d260271cbd8fb3137c4a68e3cb3b2fa8fd0db30ad3dd
TDBZd2NYVTJSRWRC13706034fdb5d5f405a04d1814940b15da438f1bb4038ad1d12a2a9277217749
TDFwdE9VVTBOR1owccff9ad893ef112f473bc2a38c90b0e9a16058ac0ebfe26169eb12a8c73c2fbb
TDNGT1IwZHlTSFJX0237b8a434f9f32c9dbc27d9e63e20d9977501de09d2c22cb18ce1ea988092c2
TDNveFpsZzNjRkpMdebd2e8137274def64b61d058f254074c04680d5ec9b3d4d030789ba4a8c344b

分析

首先,整个校验的总流程如下
image_1btjmtpdi1h871rih2bg1rtgpl69.png-45.8kB

 

首先对输入进行两次base64解码,然后再进行一次莫尔斯解码,对第二次base64解码的结果的前3个字节计算SM3哈希。哈希结果和输入的最后64个字节进行比较,比较通过后,再调用check函数对莫尔斯解码的结果进行检查。这个检查很迷,基本没用。

base64

image_1btjumoi61vadbeh6ruk5u1st25v.png-94.2kB
如果逆向过base64还是能意识到这是什么的。

morse code

image_1btjqdc6oqdr1i4ep4816cs2ou13.png-53.3kB
这个函数比较长,只截取了关键的一段,其实这个解码没有多大用,只要知道/是单词的间隔,也就是/会被替换成空格

SM3 Hash

image_1btjqhbpeik61cn210a1ac21ab51g.png-15.2kB
识别出这个主要是因为sm3_init这个函数里面的初始值。
image_1btjqln1f155n3fc1b2iuofs282a.png-28.7kB
知道了算法之后就不用详细分析了。

关于反调试

这个题的一大亮点就是反调试,其实patch掉反调试之后,不用分析那么多也能搞出一个flag,就是三个0字节的SM3哈希183920f00e15a0433ee3a8fc90dd9ac164c4142ccf63ca189a8f645ec96ff8de。原理就是这个哈希值进行两次base64解码后为空字符串,缓冲里面全是0,取前三个字节也是0,正好符合。可能这才是作者的意图?

 

下面来看一下这个程序是怎么反调试的。

isDebuggerPresent

image_1btjr3dc8gviv9015jh1b7p1m6e34.png-31.6kB
首先加载模块,然后得到函数地址,判断一下函数地址处是否有软中断,最后调用isDebuggerPresent

BeingDebugged

image_1btjsb6tn71p1l46gu4dou1tc83h.png-59.2kB
这里涉及到PEB结构和TEB结构,详情请参考《加密与解密》第三版401页15.1.1 BeingDebugged。(请把广告费打到我账户上)。

checkHeap

image_1btjt5pckhekbab2rg15km1eso3u.png-35kB
不详述了,参考《加密与解密》第三版407页15.1.3 Heap Magic。

FindWindow

image_1btjtf7fjd9b19qe134h10631j3m4b.png-68.1kB
调试器的主窗口,也有标题和类名。使用这个API可以判断各种调试器的窗口是否打开。参考《加密与解密》第三版435页15.3.2 OllyDbg检测方法。

Process32Next

image_1btju3b83pd21ves17na1k6g2s54o.png-34.5kB
image_1btju3r57sbv1jn25m3klk3g955.png-45.9kB
与查找窗口类似,查找进程。

NTICE FILEM

image_1btjugkc614m1cm67bkreg5rq5i.png-32.2kB
通过句柄检测SoftICE和Filemon,参考《加密与解密》第三版433页15.3.1。

checkRemoteDebuggerPresent

image_1btjv2p831r0rfg9cli51ofs6c.png-41.7kB
这里的反汇编出来的伪代码不太对,参考《加密与解密》第三版413页15.2.1。

ZwQueryInformationProcess

image_1btjv7ohq761hi11vem1rtk1gsq76.png-50.7kB
参考《加密与解密》第三版415页。

ZwQuerySystemInformation

image_1btjvgdlb1khr1sl416lr9s917bg7j.png-34.1kB
参考《加密与解密》第三版423页。

SeDebugPrivilege

image.png-19.8kB
参考《加密与解密》第三版436页。

检查父进程

image_1btk08csvm5j8bj1qeg19o0i6190.png-66.1kB
参考《加密与解密》第三版440页15.3.5。

int3

image_1btk6qjrb13jaumso14ia5t0o9.png-134.9kB
原理就是如果没有调试器,就利用int 3设置四个硬件断点,这四个硬件断点都会inc eax,最后eax的值就是4。如果调试器处理的int 3,那么最后eax就是0。

太多了,还是把书看一遍

以前没怎么逆向过Windows,一下搞了这么多反调试,太凶残。


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

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回