当前位置: 代码迷 >> 综合 >> 攻防世界 re5-packed-movement WP
  详细解决方案

攻防世界 re5-packed-movement WP

热度:54   发布时间:2024-01-26 16:15:23.0

这道题真的难搞,我现在还不知道正解,不过我这搞法也可以做出来。
拿到题目之后,直接IDA打开,发现代码看不了
可以看到有大段的数据,代码却很少,可以推测加了壳。

打开string,找到了upx。。所以是upx壳,直接脱壳
运行upx自动脱壳

upx -d elf -o output

再用IDA打开output,发现恶心的死,全部都是mov指令,连跳转都没有

这里我分析了一下,程序开头调用了signaction函数,这个是用来注册异常处理程序的。
这个程序总得让人输入flag,再来验证吧,肯定得调用read和write,发现其中有一段

这里显然动调运行到这eax时等于0,这里就触发了异常,让后就会根据external的内容运行相应的函数,这大概就是这个程序调用函数的方式,其实我也只搞懂了这部分
我当时就在思考,这程序没用别的指令,而数据区段中没有一点与flag有关的数据,那么flag肯定存在于某个mov指令中(由于指令种类少,很复杂的加密肯定难的搞出来的)。
可以猜测就是mov XX,'f’之类的指令
之后有了解到有idc脚本,直接拿来全程序段搜索一下满足条件的立即数(可能是属于flag的字符)

#include<idc.idc>
static isAscii(p)  //判断符合条件的字符
{if(Byte(p)<='9' && Byte(p)>='0')return 1;if(Byte(p)<='z' && Byte(p)>='a')return 1;if(Byte(p)<='Z' && Byte(p)>='A')return 1;if(Byte(p)=='}' || Byte(p)=='{' || Byte(p)=='_' || Byte(p)=='@' || Byte(p)=='!' || Byte(p)=='#' || Byte(p)=='&' || Byte(p)=='*')return 1;return 0;
}
static main()
{auto start=0x0804829C,end=0x08060B32;  //代码段起止地址auto point=start;auto str="";while(point<=end){if(isAscii(point) && Byte(point+1)==0 && Byte(point+2)==0 && Byte(point+3)==0)  {   //汇编中立即数一般都是DWORDMessage("%X %c\n",point,Byte(point));str=str+Byte(point);}point=point+1;}Message("%s\n",str);   //可能是flag
}

接下来直接在ida下运行这个脚本,果不其然flag就在这个里面
flagflag->ALEXCTF{M0Vfusc4t0r_w0rk5_l1ke_m4g1c}
前面那个2显然是有问题的字符,舍弃掉,直接交上去发现就过了

这种做法属实憨批。。。。
不过这种变态的代码,我是真的不想去一行行看