首页
论坛
课程
招聘
[原创]第三题 影分身之术 WP
2019-3-15 14:23 1368

[原创]第三题 影分身之术 WP

2019-3-15 14:23
1368

1.       运行。

随便输入报错。

wrong!<12345> is not my GUID ;-)


2.   X64DBG查看程序,发现为dephi. 程序界面为webbrower控件。而且该题应在上次CTF中出现过。右键被屏蔽了。IDA打开。可以发现很多函数。

_Tfrmcrackme_FormShow 主要是网页的初始化

_Tfrmcrackme_ApplicationEvents1Message 是网页邮件事件屏蔽。(网上可以搜到)

修改代码中1为0.可以右键菜单。

CODE:00493A28 014                 call    IsChild
CODE:00493A2D 00C                 test    eax, eax
CODE:00493A2F 00C                 jz      short loc_493A34
CODE:00493A31 00C                 mov     byte ptr [edi], 1

另外一种查看源代码的方式:

v9 = &str_<center><br>_br[1];
  v8 = dword_4935FC;
  v7 = dword_493608;
  Olectrls::TOleControl::GetOleObject(*(Olectrls::TOleControl **)(v34 + 760));
  Variants::__linkproc__ DispInvoke((VARIANTARG *)&v14, &v13, v7, v8);
  Variants::__linkproc__ DispInvoke(0, &v14, v8, v9);

我的内容是:

<script> alert(document.getElementsByTagName('html')[0].innerHTML); </script>

注意构造字符串的时候,需要修改字符串前8个字节。FF FF FF FF XX XX 00 00.

这些是字符串的头信息。FF FF FF FF 好像是引用计数还是什么?不太清楚。XX XX 00 00是字符串的长度。这样代码就被提示框弹出。Ctrl+c可复制。


3.       右键可以查看到源代码。其中感兴趣的代码如下,加密了

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,{}))
将eval 改为 alert,运行可以看到

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!");}

可以看到判断密码包含simpower91。 Function ok()为成功函数。

但输入后无法simpower91 无提示正确,但也不报错了。重点在sptWBCallback函数。


4.       找了很多都没找到其他的处理过程,一度怀疑程序错了。后来发现#sptWBCallback在程序中引用。八九不离十了。在004920C1断点,提交后成功断下。下面剩下分析处理代码了。

004920C1	B8 E8214900	mov eax,crackme2019d7.4921E8	4921E8:"#sptWBCallback:"
004920C6	E8 BD3BFDFF	call crackme2019d7.465C88	
004920CB	8BF0	mov esi,eax	esi:EntryPoint
004920CD	85F6	test esi,esi	esi:EntryPoint
004920CF	0F8E B6000000	jle crackme2019d7.49218B	
004920D5	8B45 08	mov eax,dword ptr ss:[ebp+8]	
004920D8	66:C700 FFFF	mov word ptr ds:[eax],FFFF	
004920DD	8D45 F4	lea eax,dword ptr ss:[ebp-C]	

分析到其中处理函数发现代码被处理过。分析很久也没出结果。只知道simpower91后面必须是4位。

换一个思路,可以爆破。假设输入a~Za~Z0~9.共4位,计算量还是比较大。实验了一下,中间出问题了,没达到效果。爆破代码不提供了,与后边另一种方法类似。

再换思路,其中一个处理函数的输入包含了我们输入的字符串,可以在字符串下硬件断点。输入”abcd”,发现程序读取了’a’, ‘b’.然后就结束了。处理过程中包含了大量的脚本,第一个指令是ADD EAX, -F7。Teengine引擎。资料也没找到。

但是读取了a,b 没读取c。是不是表示b不正确。测试修改为bcde。发现只读取了‘b’。所以验证是按照位验证,失败就退出?多次测试发现该规律,一直第一个是‘a’。

不会每个都输入验证吧。还是脚本,javascript脚本和x64dbg脚本。Javascript脚本负责循环填充验证字符串调用接口,x64dbg脚本负责判断输入字符串对应位是否正确。

Javascript脚本思路,一个按钮点击后触发定时器,循环构造4字节。

<CENTER><BR><BR><BR><INPUT id=pswd size=39></INPUT><BR><INPUT onclick=cls(); type=button value=cls><INPUT onclick=doit(); type=button value=test> <BR><BR><INPUT onclick=ckpswd(); type=button value=checkMyFlag></CENTER>
<SCRIPT>
	var arr = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
	var nIdx=-1;
	var bIn = false;
	var test;
	function doit1()
	{	
		if ( bIn ) return;
		nIdx=nIdx+1;
		if(nIdx > 64) return;
		i0 = parseInt(nIdx % 64);
		test ='a1'+arr[i0]+ 'd';
		document.all.pswd.value = test;
		sptWBCallback( test );
	}
	function ok()
	{
		bIn = true;
		alert( nIdx + test );
		bIn = false;
	}
	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;
	}
	function doit()
	{
		setInterval(doit1, 50 );
	}
	function cls()
	{
		nIdx=-1;
		bIn = false;
	}
</SCRIPT>
log "Jay script"
mov REIP,  00471701 // 读取输入的断点

bp 00492188    // 进入验证流程的断点,该位置可以取得输入的内存地址
bp 0049218B    // 验证结束的 断点

@xh:

Bphwc    // 清除 硬件断点

Run      // 运行到 验证流程开始位置 00492188   

cmp eip, 00492188 // 比较是否到了 验证开始
jne @xh

MOV TAG, [esp+18]  // 获取输入的内存地址

bphws TAG, "r", 4    //  设置硬件断点

run               // 运行到硬件断点或者验证结束
cmp eip, REIP
jne @xh

mov val, EBX        // 第一次硬件断点,取得本次验证的字符出地址

run               //  运行第二次硬件断点或其他

cmp eip ,REIP       // 判断是否硬件断点
jne @xh 

run               //  运行到第三次硬件断点或其他

cmp eip ,REIP       
jne @xh

run               // 运行到第四次硬件断点

cmp eip ,REIP
jne @xh

log #####{s:val}      // 第四次硬件断点,打印字符说明,前三个字符正确了
run                // 运行验证结束位置

jmp @end          // 跳转到结束
jmp @xh

@end:
pause
log endddd          
pause

前三次验证出来为’a12’。最后一个只需要循环构造64个,到正确时,会弹出提示框。

所以结果为simpower91a123。


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

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回