前言

GKCTF 2021所以题目均以开源,下面所说的一切思路可以自行通过源码对比IDA进行验证。

Github项目地址:https://github.com/w4nd3r-0/GKCTF2021

出题及解题思路

QQQQT

Enigma Virtual Box打包的QT程序,可以解包其实也可以不解包,因为这里并没有对字符串做隐藏,按钮事件函数可以很块通过flag字符串定位,按根据钮事件的逻辑也十分好猜,base系列加密特征明显,对base系列算法稍有了解的即可识别。若还是无法识别,建议查看一些base系列算法C实现,自行积累一些识别特征的方法。

最终是用了一个base58进行加密,加密字符串也是写脸上,可以直接百度或谷歌在线网站解密即可。

flag: flag{12t4tww3r5e77}

PS:学弟出的这个题目没有对字符串做隐藏,使得选手不用了解QT任何机制就能解出来。

Crash

可根据字符串信息也可根据段gopclntab判别是golang elf程序。符号表可以在IDA7.5中通过IDAGolanHelper(该插件近一个月有更新,可以支持高版本go符号还原)还原符号。

有了符号信息后静态审代码就非常清晰明了,用了3DES CBC, SHA256, SHA512, MD5,对四部分数据进行验证,而对应的密文也都可以简单的提取出来。

3DES CBC的密钥为一个txt文件,利用golang新版特性附加到来了二进制文件中,可以方便的找到,因此直接解密即可。

hash系列函数都是4字节爆破,用python的itertools可以快速爆破。

from Crypto.Cipher import DES3
import base64
import itertools
import string
import hashlib def des3_cbc_decrypt(secret_key, secret_value, iv):
unpad = lambda s: s[0:-ord(s[-1])]
res = DES3.new(secret_key.encode("utf-8"), DES3.MODE_CBC, iv)
base64_decrypted = base64.b64decode(secret_value.encode("utf-8"))
encrypt_text = res.decrypt(base64_decrypted)
result = unpad(encrypt_text.decode())
return result def sha256crash(sha256enc):
code = ''
strlist = itertools.product(string.ascii_letters + string.digits, repeat=4) for i in strlist:
code = i[0] + i[1] + i[2] + i[3]
encinfo = hashlib.sha256(code.encode()).hexdigest()
if encinfo == sha256enc:
return code
break def sha512crash(sha256enc):
code = ''
strlist = itertools.product(string.ascii_letters + string.digits, repeat=4) for i in strlist:
code = i[0] + i[1] + i[2] + i[3]
encinfo = hashlib.sha512(code.encode()).hexdigest()
if encinfo == sha256enc:
return code
break def md5crash(sha256enc):
code = ''
strlist = itertools.product(string.ascii_letters + string.digits, repeat=4) for i in strlist:
code = i[0] + i[1] + i[2] + i[3]
encinfo = hashlib.md5(code.encode()).hexdigest()
if encinfo == sha256enc:
return code
break if __name__ == '__main__':
key = "WelcomeToTheGKCTF2021XXX"
iv = b"1Ssecret"
cipher = "o/aWPjNNxMPZDnJlNp0zK5+NLPC4Tv6kqdJqjkL0XkA=" part1 = des3_cbc_decrypt(key,cipher,iv)
part2 = sha256crash("6e2b55c78937d63490b4b26ab3ac3cb54df4c5ca7d60012c13d2d1234a732b74")
part3 = sha512crash("6500fe72abcab63d87f213d2218b0ee086a1828188439ca485a1a40968fd272865d5ca4d5ef5a651270a52ff952d955c9b757caae1ecce804582ae78f87fa3c9")
part4 = md5crash("ff6e2fd78aca4736037258f0ede4ecf0") flag = "GKCTF{" + part1 + part2 + part3 + part4 + "}"
# GKCTF{87f645e9-b628-412f-9d7a-e402f20af940}
print (flag)

app-debug

这个题目比赛过程中出来一些情况,这里对造成不便的师傅说一声道歉。

安卓逆向题目,主要验证逻辑在native层,因此直接进入native层即可。对输入进行tea加密验证,delta是0x458BCD42,并且有利用TracerPid的反调试,当发现调试器时,会使用假的key,只要没有检测到调试器才会使用真key。

因为key是一个全局变量可以通过引用找到在哪里替换为了真key,再找到比对的密文后即可进行解密函数的编写。

#include <stdio.h>
#include <stdint.h> void TeaDecode(uint32_t* v, uint32_t* k) {
uint32_t delta=0x458BCD42;
uint32_t v0=v[0], v1=v[1], sum=delta*32, i; uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
for (i=0; i<32; i++) {
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
}
v[0]=v0; v[1]=v1;
} int main()
{
uint32_t enc[]={4121530355,2719511459, 0};
uint32_t key[] = {9, 7, 8, 6}; TeaDecode(enc, key);
puts(enc); //GKcTFg0 return 0;
}

KillerAid

程序结构分为两部分,一个C# 前端GUI,用于获取ID和Code,并将ID用Code进行循环异或处理,最后比对ID。需要获得ID的前提必须有正确的Code,因此必须先解出Code。

Code的验证逻辑在一个用C++编写的KillerAid.Core.dll中。Core.dll中主要由两部分组成,一部分是用于反调试的检测代码,一部分是基于AES-CBC的一个简单对称加密体系算法。

反调试检测代码主要有三部分,一部分是利用WIN32 API以及一些Windows下比较常规的反调试技巧;另一部分是通过便于隐藏特征的动态CRC32算法对ntdll、Core.dll、exe的代码段进行冗余码校验;最后一部分是,基于xd4d大佬一篇解析Net内核调试机制的C++代码实现方案,用于切断.net 内核调试线程(即杀死调试线程实例)与dnSpy和IDA这类托管调试器的通信。

调试启动的手段通过C++ 语言机制,用于一个全局委托类进行构造,它会在dll被加载时,十分早的调用委托类的构造函数,而所以反调试手段都是通过调用win32 API创建一个反调试线程进行检测。

这期为了实现这些功能所调用的所有Win 32 api以及一些native api都是定义成为函数指针集成到一个代理类中,调用进行动态函数地址获取,可以比较有效隐藏win32 api的调用以及一部分抗静态分析的效果。

由于反调试比较多,虽然可找到一个反调试的主调用函数,进行文件patch但最简单的方法仍然是将反调试线程挂起。但没有做好的一点是动态crc32的调用时机相对于exe的运行时机来说还是太滞后了,后面想考虑加一个隐蔽的使用文件CRC32进行检测,但由于时间原因并没有加上。

至于加密函数的设计,是一个基于AES-CBC模式设计的简单对称加密体系,具体设计如下图所示:



具体的解密部分并没有写多少,但可以参照AES的解密思路,一个道理,这里不多做赘述。

AES算法的初始key和iv向量都是定义为全局变量,并使用rand函数动态获取。由于iv向量是定位全局变量,dll一加载即有数据了,所以这里即便没过反调试,也可通过实际加载的ImageBase计算偏移获得key和iv向量的地址(PE的知识),提取数据即可。

至于解密函数,可在源码中dllmain.cpp中找到,当然这里也贴出来了。

#ifdef _DEBUG
uint8_t* AES_DecryptPro(uint8_t* encData, size_t sizeofData, uint8_t* key, uint8_t* iv, uint32_t rounds)
{
uint8_t* Ivs = nullptr;
uint8_t* Keys = nullptr; struct AES_ctx ctx; Ivs = new uint8_t[rounds * AES_BLOCKLEN]();
Keys = new uint8_t[rounds * AES_BLOCKLEN](); // 迭代出所有 k 与 iv
for (size_t i = 0; i < rounds; i++)
{
memcpy(Ivs + i * AES_BLOCKLEN, iv, AES_BLOCKLEN);
memcpy(Keys + i * AES_BLOCKLEN, key, AES_BLOCKLEN); // 对 iv 进行 sbox 替代 后 k 用 iv 异或更新
SubBytes((state_t*)iv);
XorWithIv(key, iv);
// 对 k 进行 sbox 替代 后 iv 用 k 异或更新
SubBytes((state_t*)key);
XorWithKey(iv, key);
} // 解密流
for (size_t i = 1; i <= rounds; i++)
{
key = (uint8_t*)(Keys + (rounds - i) * AES_BLOCKLEN);
iv = (uint8_t*)(Ivs + (rounds - i) * AES_BLOCKLEN);
AES_init_ctx_iv(&ctx, key, iv);
AES_CBC_decrypt_buffer(&ctx, encData, sizeofData);
}
delete[] Ivs;
delete[] Keys; return encData;
}
#define DecryptPro(encData, sizeofData, key, iv, rounds) AES_DecryptPro(encData, sizeofData, key, iv, rounds)
#else
#define DecryptPro(encData, sizeofData, key, iv, rounds)
#endif // _DEBUG

SoMuchCode

这个题目的混淆思路十分简单,,即再真实逻辑中插入大量的有引用的垃圾代码,用来将真实的逻辑变得更加复杂难看,其实从CFG图中可以看出,并没有任何复杂分支,基本是一条流程走到底,而具体垃圾代码的插入的实现思路是使用编译器预处理的宏展开机制进行的。

程序的原始逻辑十分简单,获取输入,进行xxtea加密,与密文比较。

本题希望选手能够在大量的垃圾逻辑中抓住关键部分进行逆向,因此xxtea加密函数中进行一部分混淆,但关键特征并没有进行混淆,只要通过长长的程序流程追踪到了加密函数,即可识别出是xxtea加密,后续解题思路也会明了起来。

具体解密函数可参考源码给出的实现。

GKCTF 2021 Reverse Writeup的更多相关文章

  1. BUGKU-逆向(reverse)-writeup

    目录 入门逆向 Easy_vb Easy_Re 游戏过关 Timer(阿里CTF) 逆向入门 love LoopAndLoop(阿里CTF) easy-100(LCTF) SafeBox(NJCTF) ...

  2. BUU [GKCTF 2021]签到

    BUU [GKCTF 2021]签到 1.题目概述 2.解题过程 追踪HTTP流 在下面发现了一串可疑字符 Base16转base64 放到010里看看 复制下来,去转字符 好像不是,再回去找找其他的 ...

  3. NEEPU-CTF 2021公开赛 writeup

    没打这场比赛,但是题目质量挺高的.赛后赶紧学习一波. RUSH B Linux入门 考linux指令的. cat hint.txt 提示让访问根目录. ls / 发现flag cat flag 提示说 ...

  4. 2021 羊城杯WriteUP

    比赛感受 题目质量挺不错的,不知道题目会不会上buu有机会复现一下,躺了个三等奖,发下队伍的wp Team BinX from GZHU web Checkin_Go 源码下载下来发现是go语言写的 ...

  5. (未完成)catalyst-system WriteUp(2019暑假CTF第一周reverse)

    目录 预备学习--Linux实践:ELF文件格式分析 一.概述 二.分析ELF文件头(ELF header) 三.通过文件头找到section header table,理解其内容 四.通过secti ...

  6. ISCC2018 Reverse & Pwn writeup

    Reference:L1B0 Re RSA256 春秋欢乐赛原题..flag都不变的 给了三个加密文件和公钥证书public.key,可以使用openssl进行处理 $openssl rsa -pub ...

  7. 2021广东省强网杯WriteUp

    个人赛 网络诈骗 参考 https://github.com/Heyxk/notes/issues/1 先把EnMicroMsg.db提出来 CompatibleInfo.cfg是0kb,用第一种方法 ...

  8. 2021 数字四川创新大赛WriteUp

    数字四川初赛+复赛wp Web easyphp http://111.9.220.114:50006/.index.php.swp 备份文件泄漏 <?php #error_reporting(0 ...

  9. 虎符2021线下赛pwn writeup

    jdt 一个图书管理系统,但并不是常规的堆题.edit和show函数可以越界.edit函数和show函数相互配合泄露libc基地址,将main函数的返回地址覆盖成onegadgets拿shell. f ...

随机推荐

  1. java中jre\bin目录和jdk\bin目录下的工具功能介绍

    转自:https://blog.csdn.net/eclipse_yin/article/details/51051096 jre/bin目录下面工具说明 javac:Java编译器,将Java源代码 ...

  2. ARP:地址解析协议

    我们假设这样一个场景:你需要和你网络中的一个设备进行通信,这个设备可能是某种服务器.你用来创建这个通信的应用已经得到了这个远程主机的ip地址,也意味着系统已经有了用来构建它想要在第三层到第7层传递数据 ...

  3. Servlet体系及方法

    时间:2016-11-11 15:07 --Servlet体系Servlet(interface):    实现类:GenericServlet.HttpServletServletConfig(in ...

  4. win7上帝模式详解

    最近,Windows7"GodMode"(上帝模式)被国内各大网站和论坛炒得沸沸扬扬."GodMode"始见于国外网站"GeekInDisguise& ...

  5. linux 查看用户密码

    2021-07-26 1.查看前三个密码 head -3 / etc / passwd # 注解 /etc/passwd 中一行记录对应着一个用户,每行记录又被冒号 (:) 分隔为 7 个字段,其格式 ...

  6. Linux系统的日志管理、时间同步、延迟命令at

    方便查看和管理 /var/log/messages ?系统服务及日志,包括服务的信息,报错等等 /var/log/secure ? ? ? ? 系统认证信息日志 /var/log/maillog ? ...

  7. Java动态代理底层实现

    Java实现源码 上一节我们提到了Java动态代理的使用,接下来我们看一下他的具体实现. HelloInterface proxyHello = (HelloInterface) Proxy.newP ...

  8. Jenkins手动下载并安装插件

    最近遇到Jenkins插件无法自动安装的问题,在插件管理页面的[升级站点]使用镜像url也无法解决.于是决定手动下载并安装Jenkins插件,具体步骤如下. Step1:进入Jenkins官网的插件下 ...

  9. 20210819 Emotional Flutter,Medium Counting,Huge Counting,字符消除2

    考场 T1 一下想到了这题,将白块缩短 \(s\) 后维护类似的区间即可. T2 T3 俩计数,直接跳了. T4 的可行 \(t\) 集合相同相当与从 \(n\) 往前跳 kmp 数组,途径点相同,从 ...

  10. 20210816 你相信引力吗,marshland,party?,半夜

    考场 第一眼都不可做 T1 长得就像单调栈/单调队列,推了推性质发现优弧.劣弧都合法的点对很好处理,其他情况只在一种情况合法,那么开两个单调队列分别统计距离 \(\le\frac2n,>\fra ...