首页
论坛
课程
招聘
[原创]2019看雪CTF 团队赛 第三题 影分身之术WP
2019-3-21 02:38 3954

[原创]2019看雪CTF 团队赛 第三题 影分身之术WP

2019-3-21 02:38
3954
先运行cm,用窗口工具查看主窗体类名,发现是Internet Explorer_Server,从内存中搜索html相关的代码,发现了
<input type=button value="checkMyFlag" onclick="ckpswd();">
尝试在内存中搜索 ckpswd,找到了这段js代码:
function sptWBCallback(spt_wb_id,spt_wb_name,optionstr){url='#sptWBCallback:id=';url=url+spt_wb_id+';eventName='+spt_wb_name;if(optionstr) url=url+';params=optionstr';location=url;}eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('a 6() {    f="n";    3 = 8.5.l.q;    c (3.d(f) ==0) {        g=3.h;        b=f.h;        o(3.p(b,g));    } 9 {        4("r!<" + 3 + "> e j i 2 ;-)");        m "1";    }}a k(){  4("7!");}',62,28,'|1234|GUID|a|alert|all|ckpswd|congratulations|document|else|function|i|if|indexOf|is|key|l|length|my|not|ok|pswd|return|simpower91|sptWBCallback|substring|value|wrong'.split('|'),0,{}))
可以写个html加载这个脚本,然后用chrome调试得到解密后的代码,解密后的代码为:
function ckpswd() {
    key="simpower91";  
  a = document.all.pswd.value;
    if (a.indexOf(key) ==0) {     
   l=a.length;   
     i=key.length;    
    sptWBCallback(a.substring(i,l)); 
   } else {    
    alert("wrong!<" + a + "> is not my GUID ;-)");  
      return "1234";    }}


function ok(){  alert("congratulations!");}
很明显,flag前面的字符串是simpower91,再调用sptWBCallback, 参数是flag的后几位字符。
在内存中搜索 sptWBCallback,找到了这段代码:
function sptWBCallback(spt_wb_id, spt_wb_name, optionstr) {
    url = '#sptWBCallback:id=';
    url = url + spt_wb_id + ';eventName=' + spt_wb_name;
    if (optionstr)
        url = url + ';params=optionstr';
    location = url;
}
应该是回调了某个函数,在OD里搜索#sptWBCallback,定位到004920C1处下断。输入" simpower91"加上其他的一些字符,按按钮后程序停下。

单步时发现了这个

走过这个函数后,继续单步就retn了,没有其他调用,用IDA看看493F70这个函数,部分伪代码如下:
 if ( sub_404734(v15) == 4 )                   // 末尾长度不是4则返回
  {
    if ( Sysutils::FileExists((const int)&str_data_txt_1[1]) )
    {
      v6 = (Classes::TStream *)unknown_libname_1109((int)&off_416694, 1);
      Ibsql::TIBXSQLVAR::LoadFromFile(v6, (int)&str_data_txt_1[1]);
    }
    else
    {
      v6 = sub_4677DC(*(_DWORD *)(v5 + 816), (int)&str_data_txt_1[1], -1, v5, esi0);// 读取自身的附加数据段
    }
    v16 = &byte_494045;
    sub_473A04(dword_498F3C, *((_DWORD *)v6 + 1), &byte_494045);// 动态解密汇编指令并执行
    JUMPOUT(0);
  }
得知flag还有4位,sub_473A04则是解密指令并执行,解密具体实现在sub_472EAC。个人能力不足,无法分析出来。
解密完之后的代码会由004734F1的jmp跳转过去

那么只要在这里下断点,就能收集到每次执行的指令了,验证后四位的部分的指令如下:
add eax,0x7F //第一位字符
xor edx,edx
cmp eax,edx //前面将edx置0了,但代码执行到这里时edx等于0xE0,应该是解密指令的时候修改了edx的值
jnz 0x52 //不相等则跳
add eax,0x7F //第二位字符
xor edx,edx
cmp eax,edx //edx=0xB0
jnz 0x3F
add eax,0x7F //第三位字符
xor edx,edx
cmp eax,edx //edx=0xB1
jnz 0x2C
add eax,0x7F //第四位字符
xor edx,edx
cmp eax,edx //edx=0xB2
jnz 0x19
lea eax,dword ptr ss:[ebp-0x420]
push eax
xor ecx,ecx
call 00491DEC //显示成功信息框
我们可以算出后四位是"a123",拼接两段字符串得到flag:simpower91a123

[培训]12月3日2020京麒网络安全大会《物联网安全攻防实战》训练营,正在火热报名中!地点:北京 · 新云南皇冠假日酒店

最后于 2019-3-21 02:40 被梦游枪手编辑 ,原因:
收藏
点赞0
打赏
分享
最新回复 (1)
雪    币: 2420
活跃值: 活跃值 (17)
能力值: ( LV11,RANK:198 )
在线值:
发帖
回帖
粉丝
simpower 活跃值 2019-3-27 17:01
2
0
游客
登录 | 注册 方可回帖
返回