RCTF绕过方法

极客

RCTF绕过方法详解:那些年我们一起踩过的坑

嘿,兄弟们!今天咱不聊虚的,就来唠唠 RCTF绕过方法 这个老生常谈但又永远绕不开的话题,说真的,每次打CTF比赛,遇到RCTF相关的题目,我都又爱又恨——爱的是它确实能考验基本功,恨的是有些绕过姿势你要是没见过,那真是抓耳挠腮半天憋不出一个flag来。

RCTF绕过方法

先说说啥是RCTF吧,简单讲,就是Reverse + CTF,逆向工程类的题目,这类题目的核心往往不是让你硬肛整个二进制文件,而是找到那个“校验逻辑”然后想办法绕过它,注意啊,我这里说的RCTF绕过方法,不是教你作弊,而是教你在逆向分析中找到程序的逻辑漏洞,用巧劲儿拿到该拿的东西。

最经典的:条件跳转Patch

这个可以说是RCTF绕过方法里的“祖传手艺”了,你用IDA或者Ghidra打开一个binary,F5一看,哎,有个if ( check_flag() ),里面打印success,else打印wrong,那还等啥?直接找到对应的jz/jnz,改成jmp或者nop掉不就行了嘛!

我印象特别深,有一次比赛题目叫“baby_re”,我一看,好家伙,验证函数里居然是个简单的异或比较,但问题在于,它把正确flag的每个字符都异或了一个动态值……这时候你硬逆推也不是不行,但太费劲了,我直接掏出x64dbg,跑到比较那一步,改ZF标志位,flag到手,爽!这就是RCTF绕过方法的魅力——不一定要算出来,能让它“以为”你算对了就行。

反调试的绕过,别被吓住

很多RCTF题目会加反调试,什么ptrace检测、IsDebuggerPresent、时间差检测……新手一看就懵了,但其实RCTF绕过方法对付反调试,核心思路就两个:要么patch掉检测函数,要么在调试器里把返回值改了。

比如ptrace(PTRACE_TRACEME, 0, 0, 0),正常返回0,被调试时返回-1,你直接在IDA里把test eax, eax后面的跳转改了,或者用Frida hook一下ptrace让它永远返回0,我跟你说,有一次我遇到一个用rdtsc做时间检测的,单步调试必崩,后来咋办的?我直接找到那个计算时间差的函数,把它返回值改成固定的小数值,完美绕过,这种RCTF绕过方法,说白了就是“你检测你的,我改我的”。

花指令和混淆?别慌,慢慢来

有些RCTF题目会加花指令,就是一堆jz+jnz跳来跳去,或者插入垃圾字节让反汇编出错,这时候RCTF绕过方法就讲究一个“耐心”了,我一般先用IDA的“Make Code”强制重新分析,不行就手动nop掉花指令,或者用脚本去花。

还有那种OLLVM混淆的,控制流扁平化,看得人头大,但说实话,大部分比赛题不会上太变态的混淆,因为出题人也知道选手时间有限,你只要找到关键的比较指令,前面的混淆都可以忽略。RCTF绕过方法的核心是“找关键点”,不是“读懂每一行”。

动态调试才是王道

说句掏心窝子的话,静态分析再强,也不如动态跑一遍,很多RCTF绕过方法都是在动态调试中发现的,比如你发现程序在某个循环里不断比较你的输入和某个内存值,那你直接在内存里把那个值dump出来不就完了?或者用ltrace/strace看看它调用了啥库函数。

我常用的组合是:IDA看逻辑 + x64dbg下断点 + Python写脚本自动化,有一次比赛,题目是个VM类逆向,我静态看了半天没看懂指令集,后来动态跟了一遍,发现它其实就是在逐字符比较,只不过用了个简单的替换表,我直接把替换表抠出来,写个逆变换,flag秒出,所以说,RCTF绕过方法不是死板的,是灵活的。

别忽略那些“非技术”的绕过

RCTF绕过方法还包括一些“歪门邪道”,比如题目给的附件里有个flag.txt但是加密了,你发现加密密钥硬编码在程序里;或者题目服务器端有逻辑漏洞,你可以直接构造请求绕过验证,甚至有一次,我发现题目把flag写在了程序的内存里,只是没打印出来,我直接用strings就找到了……虽然那次被出题人骂了,但规则没说不让用啊哈哈。

我可不是鼓励你投机取巧,我的意思是,逆向思维要开阔,别只盯着反汇编代码。RCTF绕过方法的“绕过”二字,本身就意味着你要找到一条出题人没堵死的路。

最后唠两句

好了,关于RCTF绕过方法今天就扯这么多,其实说到底,这些方法都是熟能生巧,你打得多了,自然就知道看到什么特征该用什么姿势,别怕踩坑,我当年第一次打RCTF,连jzjnz都分不清,现在不也过来了嘛。

如果你也有啥奇葩的RCTF绕过方法经历,欢迎在评论区分享,咱们一起乐呵乐呵,下次比赛,记得别硬肛,多想想有没有巧劲儿——毕竟,能绕过去,谁愿意正面刚啊,对吧?

冲冲冲,flag就在前方!

文章版权声明:除非注明,否则均为极客网安-咸鱼原创文章,转载或复制请以超链接形式并注明出处。

目录[+]