暑假打了挺多线上的CTF,NepCTF的RE题质量一如既往的高。
realme
通过字符串定位法定位到主函数,初次分析发现是RC4魔改,置换S盒时异或0X66且最后的异或改为模除。后续发现有反调试,这里给出ScyllaHide插件dump和patch反调试两种做法。

ScyllaHide插件dump
通过ScyllaHide自动过反调试,结合程序不直接退出猜测有自修改,在输出时dump,发现实际魔改。


patch反调试
通过栈回溯法定位到第一次反调试处,HOOK了scanf函数,修改了魔改RC4的逻辑并通过异或激活第二次反调试。


第二次再次修改魔改RC4逻辑。

最后的两处魔改


#include<iostream>
#include<string>
#include<string.h>
using namespace std;
void rc4init(unsigned char K[],unsigned char key[])
{
unsigned char S[256];
unsigned char T[256];
int Len=strlen((char*)(key));
for(int i=0;i<256;i++)
{
S[i]=i^0xCF;
T[i]=key[i%Len];
}
int j=0;
int temp=0;
for(int i=0;i<256;i++)
{
j=(j+S[i]+T[i])%256;
temp=S[i];
S[i]=S[j];
S[j]=temp^0xAD;
}
//生成密钥流
int i = 0;
j=0;
int t = 0;
unsigned long k = 0;
for(int time=0;time<256;time++)
{
i=(i+1)%256;
j=(j+i*S[i])%256;
temp=S[i];
S[i]=S[j];
S[j]=temp;
t=(S[i]+S[j])%256;
K[time]=S[t];
}
}
int main()
{
unsigned char K[256]={0};
unsigned char key[]="Y0u_Can't_F1nd_Me!";
rc4init(K,key);
unsigned char flag[]={ 0x50, 0x59, 0xA2, 0x94, 0x2E, 0x8E, 0x5C, 0x95, 0x79, 0x16,
0xE5, 0x36, 0x60, 0xC7, 0xE8, 0x06, 0x33, 0x78, 0xF0, 0xD0,
0x36, 0xC8, 0x73, 0x1B, 0x65, 0x40, 0xB5, 0xD4, 0xE8, 0x9C,
0x65, 0xF4, 0xBA, 0x62, 0xD0};
for(int i=0;i<sizeof(flag)/sizeof(flag[0]);i++)
{
if(i%2==0)
{
flag[i]+=K[i];
}
else
{
flag[i]-=K[i];
}
cout<<flag[i];
}
}
Crackme
待续
qrs
待续

Comments NOTHING