一道关于逆向的实战CTF题目分析

WriteUp 4个月前 admin
24 0 0

一道关于逆向的实战CTF题目分析

前言:本题自带call型花指令,考验选手对花指令的理解程度。加密属于基础的异或和左右移位加密。主要考察选手的基础能力,动态调试和写脚本的能力。在这篇文章,详细记录了我的分析过程,相信你会有很大收获。

花指令zip获取方式:后台回复 题目

1、查壳

一道关于逆向的实战CTF题目分析

PE64位,没壳程序

2、IDA分析去花指令

使用IDA打开时,发现一片红,很正常的CTF考点:花指令

sub_main

一道关于逆向的实战CTF题目分析

当务之急是如何去除花指令,继续向下分析,发现了一些端倪

一道关于逆向的实战CTF题目分析

花指令的形成是干扰编译器的分析,但又不会影响程序的正常运行。

那么显而易见,会将某个寄存器进行push(保存)然后对其进行复杂操作,最终pop(恢复)该寄存器的值,程序正常执行。

而在本程序中,可以发现该手法:

push ebx
.....
pop ebx

中间的过程均无需再看,直接NOP操作。

一道关于逆向的实战CTF题目分析

nop完记得保存修改。

一道关于逆向的实战CTF题目分析

接下来就可以分析main函数啦

一道关于逆向的实战CTF题目分析

而这两个函数恰好均为关键的函数。

sub_401040

一道关于逆向的实战CTF题目分析

此时,我们可以看到函数开头的位置存在多个push操作,不要急着nop。对照函数结束的部分,避免误杀友军。

一道关于逆向的实战CTF题目分析

可以看到pop和push是相互对应的,开头push,结束就要pop。

此时注意到:push、pop不是要nop的点,我们继续分析

一道关于逆向的实战CTF题目分析

熟悉混淆的朋友一定可以识别出这是一个call型混淆。

call一个地址,然后修改堆栈返回值,retn跳过混淆,相对之前的混淆需要对堆栈有一定的理解。

识别出来,进行nop即可

一道关于逆向的实战CTF题目分析

得到加密函数

一道关于逆向的实战CTF题目分析

int __cdecl sub_401040(char a1, int a2)
{
  return ((a2 ^ a1) << 8) - a2;
}

sub_401080

来分析另一个函数

相同的操作

一道关于逆向的实战CTF题目分析

一道关于逆向的实战CTF题目分析

得到加密算法

int __cdecl sub_401080(char a1, int a2)
{
  
  return a2 ^ (a1 << 8);
}

3、分析加密流程

一道关于逆向的实战CTF题目分析

那么现在的任务是获得加密函数的顺序,这里采用动态调试的方法来获得:

一道关于逆向的实战CTF题目分析

得到顺序

left
xor
xor
left
xor
left
left
xor
left
left
xor
xor
xor
left
left
left
xor
xor
xor
left
xor
xor
left
xor
left
left
left
left
xor
xor
xor
left

将left用1替代,xor用0替代,得到顺序:

int temp[32] = { 1,0,0,1,0,1,1,0,1,1,0,0,0,1,1,1,0,0,0,1,0,0,1,0,1,1,1,1,0,0,0,1 };

密文可以看到是:

dword_402120 数组
unsignedint dword_402120[32]={
0x00004408,0x000068D8,0x00007AD8,0x00004308,0x00007BD8,0x00004608,0x00007B08,0x000070D8,
0x00003308,0x00007308,0x000076D8,0x00005CD8,0x000076D8,0x00006608,0x00006908,0x00006E08,
0x00004BD8,0x000076D8,0x00003FD8,0x00006F08,0x00005ED8,0x000076D8,0x00007408,0x000046D8,
0x00005F08,0x00006308,0x00003408,0x00007408,0x000076D8,0x000044D8,0x00004CD8,0x00007D08
};
一道关于逆向的实战CTF题目分析

4、写出解密算法


#include <stdio.h>


void left(unsigned int a1, unsigned int a2) {
//  (a1>>8)^a2
printf("%c",((a1 ^ a2)>>8));
}
void xors(unsigned int a1, unsigned int a2) {
//(((a1+a2)>>8)^a2)
printf("%c",(((a1 + a2)>>8)^ a2));
}
int main()
{
unsignedint dword_402120[32]={
0x00004408,0x000068D8,0x00007AD8,0x00004308,0x00007BD8,0x00004608,0x00007B08,0x000070D8,
0x00003308,0x00007308,0x000076D8,0x00005CD8,0x000076D8,0x00006608,0x00006908,0x00006E08,
0x00004BD8,0x000076D8,0x00003FD8,0x00006F08,0x00005ED8,0x000076D8,0x00007408,0x000046D8,
0x00005F08,0x00006308,0x00003408,0x00007408,0x000076D8,0x000044D8,0x00004CD8,0x00007D08
};
int temp[32]={1,0,0,1,0,1,1,0,1,1,0,0,0,1,1,1,0,0,0,1,0,0,1,0,1,1,1,1,0,0,0,1};
for(size_t i =0; i <32; i++)
{
if(temp[i]){
//left
left(dword_402120[i],8);
}
else{
//xor
xors(dword_402120[i],40);

}
}



}

到此,恭喜你学会了分析一道CTF题目最基本的步骤。

一道关于逆向的实战CTF题目分析

原文始发于微信公众号(蚁景网安):一道关于逆向的实战CTF题目分析

版权声明:admin 发表于 2024年7月12日 下午5:32。
转载请注明:一道关于逆向的实战CTF题目分析 | CTF导航

相关文章