XDCTF2013大会期间注册了账户,看了两个题实在不会做,看来和牛人差距还是很明显的。现在答案出来了,跟着牛人学习一下思路。
basic部分
一、第一关Welcome XDCTF 2013
该题点击进去后,是在文本框中有很多字符,由于字符是0-F,所以感觉应该是16进制字符,虽然认识到了是十六进制字符。但当时不知怎么来将其转换成为明文所以放弃了。今天看了答案,才知道编辑十六进制文件的工具linux下有hexedit(可能需要通过apt-get来进行安装),windows下有WinHex。
(1)linux下处理16进制字符的过程
即先用touch命令创建一个新文件,然后用hexedit命令进行编辑,然后将题目中的那些字符拷进去,然后使用Ctrl+w保存,然后使用Ctrl+x退出。详细使用方法输入man hexedit
(2)windows下处理十六进制字符的过程
windows下使用WinHex工具来进行处理。打开WinHex后,随便打开一个文件。复制比赛中的十六进制字符后,在WinHex中右键点“edit”,然后选择“Cliboard Data”—>”Paste Into New File”后,选择文件类型为”ASCII Hex”后就把复制的字符填充到新文件中了。
然后将文件保存即可。
通过linux或windows方式保存十六进制字符为文件后,可以通过file命令来查看文件类型(linux下可以直接使用file命令,windows下需要安装相关程序)。
可以看到文件是rar类型,将其重命名为.rar文件后进行解压,解压后发现里面存有一张图片。用文本编辑器将其打开,发现在最下面有提示这是一张图片后门,根据文章“一种隐藏在JPG图片EXIF中的后门”(http://www.freebuf.com/articles/web/11403.html)可以知道后门信息在图片的EXIF中。找到后是base64_decode(“V2UxYzBtZVhEY1NjMjAxMz==”);,进行base64解码后为:We1c0meXDcSc2013
—————————————————————————————————————————————————————–
第二关:BlackHat
第二关点击进去后,显示“Make sure that you are from Vatican”,看来只有梵蒂冈的IP地址才能访问了,但怎么才能让服务器认为我们的IP地址是梵蒂冈的呢?我的第一想法是挂VPN,但是梵蒂冈的代理不好找呀。看了答案后才豁然开朗,可以将请求的X-FORWARDED-FOR改为梵蒂冈的IP地址就行了(一般也用此方法来突破后台对IP地址的限制)。百度到一个梵蒂冈的IP地址212.77.1.243,然后用burp抓包修改就行了。
可以看到,添加X-FORWARDED-FOR头后可以正常访问了,但是返回的结果显示访问的页面并不存在,但查看burp后发现返回的状态码是200,因而说明这个页面是伪造的。同时返回的几个页面中一直包含www.blackhat.com,说明访问的信息与www.blackhat.com有关系。想到同一IP地址可以有多个不同的网站,收到请求时是根据host信息来确定到底在请求哪个网站的页面,因此,只要我们把请求中的host改为www.blackhat.com来看看情况,返回了key
不过参考答案上说,上面的key并不是最终结果,需要进行base64解码后才是最后的key。$4W8DerGHXlD@N
ps:总结,上面中修改host为www.blackhat.com与直接访问www.blackhat.com是不同的,因为两个访问的IP地址不同。在使用burp抓的包中目的IP地址已经确定(ctf.xdsec.org对应的IP地址),此时修改host只是修改了该IP地址上对应的其他站点;而如果直接访问www.blackhat.com则会解析到www.blackhat.com的IP地址上,因而结果不同。即burp抓取的是http包,http协议是TCP协议的上层协议,即抓到包前已经完成TCP的三次握手了,因而目的IP地址也都已经确定了。
可以通过以下方式测试:即访问www.google.cn,用burp抓包,将host由www.google.cn改为www.baidu.com,提交后返回的页面还是google的,并没有变为baidu的。如何设置同一IP地址,相同端口有多个网站,可以参考http://www.cnblogs.com/Jimmy009/archive/2012/11/22/2782666.html。
———————————————————————————————————————————————————–
第三关 click
网址:http://ctf.xdsec.org:2222/basic/click/
访问页面后,在中间有一个“GET KEY!”按钮,应该是通过点击该按钮来获取key,但是在该页面中无法点击该按钮。所以先看下源代码了。
源代码如下:
<html> <head> <title>Click</title> <SCRIPT LANGUAGE="JavaScript"> function uncompile(code) { code=unescape(code); var c=String.fromCharCode(code.charCodeAt(0)-code.length); for(var i=1;i<code.length;i++){ c+=String.fromCharCode(code.charCodeAt(i)-c.charCodeAt(i-1)); } return c; } document.write(uncompile("%9E%AF%D6%D5%DB%D9%E4%B2Hp%DB%E3%D1%D7%DD%D8%DD%8E%81%C3%C5%8BQ3%85%85%17r%D1%D1%D2%D2%D3%E2%B1%A1%D3%D2%D8%E2%D2%D3%E2%A2%95%CC%D9%B9%B1%D1%D2%D2%D3%E2%B6%BB%C2%AD%8CO%90%D6%D4%8EPW%A1%E5%D5%A0dU%5D%98%D6%D4%96%9A%D0%DE%A7%95%D0%CF%8DbE%87%87Fk%A2%D6%D5%DB%D9%E4%B2")); </SCRIPT> <style> iframe { width: 450px; height: 950px; /* Use absolute positioning to line up update button with fake button */ position: absolute; top: -388px; left: 452px; z-index: 2; /* Hide from view */ -moz-opacity: 0.5; opacity: 0.0; filter: alpha(opacity=0.5); } button1 { position: absolute; top: 10px; left: 10px; z-index: 1; width: 120px; } button1 { position: absolute; top: 10px; left: 10px; z-index: 1; width: 120px; } </style> </head> <body> <center> <br> <iframe src="#" scrolling="no"></iframe> 不要被你的眼睛欺骗^0^<br><br><br><br><br><br><br><br><br> <button onclick = "abc()">GET KEY!</button> <br><br><br><br><br><br><br><br><br><br><br> <br><img id="img" /> <br><br><br><br><br><br><br><br><br> <a href="http://www.baidu.com" target="_parent"><button type="button">         EXIT         </button></a> </center> </script> </body> </html>
通过上面的源代码可以看到,按钮之所以不能点击,是因为上面有一个隐形的iframe框架。去掉iframe后,可以点击,但是点击后没反应,所以只能通过源代码看看点击后发生了什么。点击按钮后执行了函数abc(),但是查看源代码没有发现abc()函数,开来是通过DOM动态添加的,向上看源码发现执行了uncompile函数,说明是执行的uncompile()函数动态添加了abc()函数。为了查看uncompile()函数的执行结果,修改一下班uncompile()函数来讲执行结果alert出来
function uncompile(code) { code=unescape(code); var c=String.fromCharCode(code.charCodeAt(0)-code.length); for(var i=1;i<code.length;i++){ c+=String.fromCharCode(code.charCodeAt(i)-c.charCodeAt(i-1)); } alert(c); return c; }
修改后执行一下,结果如下:
可以看到动态的添加了一段javascript脚本,脚本中有abc()函数。abc()函数很简单,只是修改了img元素的src属性。看来key和这个图片有关系,将这个图片下载出来用文本文件打开。
可以看到key就在其中,为key:T4hAnw5eRi5ke7
——————————————————————————————————————————-
第四关 Hide
网址:http://ctf.xdsec.org:2222/basic/hide/
访问该页面可以看到只有一张图片,key应该在源代码中或在这张图片中。查看网站的源代码,如下:
<html> <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> <head> <title>Hide</title> </head> <center> <h1>慧眼识珠</h1> <!--%2E%2E%2F%73%72%63%2F%38%61%37%39%32%31%34%62%38%30%30%32%34%38%65%35%34%30%39%30%64%36%33%64%30%63%5F%35%36%30%2E%72%61%72----> <img src="src/20110308191107-1060136018.jpg"> <br/><hr><span style="font:11px Verdana;">XDCTF2013</span><br/> </center> <!--by Dorothy--> </html>
可以看到源代码中有一段注释,应该key和这段注释有关,注意到这段字符是url编码,解码后为:../src/8a79214b800248e54090d63d0c_560.rar
下载该压缩文件,解压后中有一个key.txt但是说不是key,看来还要继续找key了。
用winhex或文本文件打开该rar文件,在最后看到了提示:key:58694469406E5A game is not over
由于提示game is not over,说明这不是最终的key,还得继续寻找。我没有思路了,看看答案怎么弄的。看完答案才豁然开朗,我竟然将图片忘了。用文本文件打开那个图片,在最后找到另一半key:key:304933534543 game is over
现在将两个key连在一起就获得了最后的key了。
———————————————————————————————————————————————————–
第五关 Jother
地址:http://ctf.xdsec.org:2222/basic/jother/
点开上面的那个超链接,结果如下,根据上面页面中Encode的提示,这应该是某种编码后的字符串,但是不知道编码类型。
现在只能看看答案怎么写的了,答案中说是Jother编码(妈的,我怎么没想到,这一关的题目就是Jother)。在百度和谷歌中搜索Jother编码,只找到编码的网址,没有找到解码的地址,看来需要自己研究研究了。通过介绍了解Jother编码就是将正常的javascript代码编码为有{}[]!+~组成的表达式
Jother编码的原理:http://tmxk.org/thread-637-1-1.html。通过原理了解Jother编码只是javascript代码的另外一种编码表示,即本质上还是javascript代码。虽然,我还没能搞懂原理来找到解码的方法,不过可以将他们放入<script></script>中来执行看一下,结果如下:
所以获取到key了。
ps:要注意,将文件保存为htm后,直接用浏览器打开和在放在网站目录下访问结果是不一样的,可能是使用的协议不同吧,直接用浏览器打开url是:file:///C:/Users/Administrator/Desktop/a.html,用的是file协议,与http协议不同。直接用浏览器打开时<script>alert(1)</script>会弹窗,用Jother编码后就不会弹窗;而如果放到网站目录下通过http访问,则编码之后也会弹窗。因此,今后在测试js代码时,务必将其放到网站目录下通过http访问,而不是直接用浏览器打开。
—————————————————————————————————————————————-
第六关 Js
网址:http://ctf.xdsec.org:2222/basic/js/
查看源代码如下:
<html> <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> <head> <title>Js</title> </head> <center> <h1>JavaScript</h1> <span style="font:15px Verdana;">小陈刚做web开发,写了个js还搞得乱糟糟,不知道你能否看的明白</span><br> <script> var _0x4e9d=["\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65","\x77\x72\x69\x74\x65"];document[_0x4e9d[0x1]](String[_0x4e9d[0x0]]( 0x3C,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x74,0x79,0x70,0x65,0x3D,0x22,0x74,0x65,0x78,0x74,0x2F,0x6A,0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70,0x74,0x22,0x20,0x73,0x72,0x63,0x3D,0x22,0x2E,0x2F,0x63,0x68,0x65,0x63,0x6B,0x70,0x61,0x73,0x73,0x22,0x3E,0x3C,0x2F,0x73,0x63,0x72,0x69,0x70,0x74,0x3E,0xD,0xA,0x3C,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x6C,0x61,0x6E,0x67,0x75,0x61,0x67,0x65,0x3D,0x22,0x6A,0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70,0x74,0x22,0x3E,0xD,0xA,0x68,0x61,0x63,0x6B,0x78,0x20,0x3D,0x20,0x22,0x75,0x70,0x6B,0x65,0x72,0x22,0x3B,0xD,0xA,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x20,0x63,0x68,0x65,0x63,0x6B,0x28,0x78,0x29,0xD,0xA,0x7B,0xD,0xA,0x22,0x2B,0x68,0x61,0x63,0x6B,0x78,0x2B,0x22,0x20,0x3D,0x3D,0x20,0x22,0x78,0x64,0x73,0x65,0x63,0x2E,0x6F,0x72,0x67,0x22,0xD,0xA,0x69,0x66,0x20,0x28,0x78,0x20,0x3D,0x3D,0x20,0x22,0x22,0x2B,0x68,0x61,0x63,0x6B,0x78,0x2B,0x22,0x22,0x29,0xD,0xA,0x7B,0xD,0xA,0x61,0x6C,0x65,0x72,0x74,0x28,0x22,0x77,0x69,0x6E,0x21,0x22,0x29,0x3B,0xD,0xA,0x7D,0x20,0x65,0x6C,0x73,0x65,0x20,0x7B,0xD,0xA,0x61,0x6C,0x65,0x72,0x74,0x28,0x22,0x54,0x72,0x79,0x20,0x61,0x67,0x61,0x69,0x6E,0x21,0x22,0x29,0x3B,0xD,0xA,0x7D,0xD,0xA,0x7D,0xD,0xA,0xD,0xA,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x20,0x63,0x68,0x65,0x63,0x6B,0x70,0x61,0x73,0x73,0x77,0x28,0x75,0x70,0x6B,0x65,0x72,0x29,0xD,0xA,0x7B,0xD,0xA,0x68,0x61,0x63,0x6B,0x78,0x20,0x3D,0x20,0x75,0x70,0x6B,0x65,0x72,0x3B,0xD,0xA,0x63,0x68,0x65,0x63,0x6B,0x73,0x28,0x68,0x61,0x63,0x6B,0x78,0x29,0x3B,0xD,0xA,0x7D,0xD,0xA,0x3C,0x2F,0x73,0x63,0x72,0x69,0x70,0x74,0x3E)); </script> <h2 align="center">Find the Key!</h2> <p align="center"><input type="password" id="pass" name="password" value=""><br /> <button onclick="javascript:checks(document.getElementById('pass').value)">Check Password</button></p> <br/><hr><span style="font:11px Verdana;">XDCTF2013</span><br/> </form> </center> <!--by upker.net--> </html>
看来获取key的关键是中间的那段js代码。现分析如下:
首先通过alert(_0x4e9d);来将_0x4e9d变量的值打印出来为: fromCharCode,write。_0x4e9d[0x1]为:write,所以后面document[_0x4e9d[0x1]]变为document[‘write’],因此为了获取最终结果,将document[‘write’]()换为alert()即可。
<script> var _0x4e9d=["\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65","\x77\x72\x69\x74\x65"]; alert(String[_0x4e9d[0x0]]( 0x3C,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x74,0x79,0x70,0x65,0x3D,0x22,0x74,0x65,0x78,0x74,0x2F,0x6A,0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70,0x74,0x22,0x20,0x73,0x72,0x63,0x3D,0x22,0x2E,0x2F,0x63,0x68,0x65,0x63,0x6B,0x70,0x61,0x73,0x73,0x22,0x3E,0x3C,0x2F,0x73,0x63,0x72,0x69,0x70,0x74,0x3E,0xD,0xA,0x3C,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x6C,0x61,0x6E,0x67,0x75,0x61,0x67,0x65,0x3D,0x22,0x6A,0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70,0x74,0x22,0x3E,0xD,0xA,0x68,0x61,0x63,0x6B,0x78,0x20,0x3D,0x20,0x22,0x75,0x70,0x6B,0x65,0x72,0x22,0x3B,0xD,0xA,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x20,0x63,0x68,0x65,0x63,0x6B,0x28,0x78,0x29,0xD,0xA,0x7B,0xD,0xA,0x22,0x2B,0x68,0x61,0x63,0x6B,0x78,0x2B,0x22,0x20,0x3D,0x3D,0x20,0x22,0x78,0x64,0x73,0x65,0x63,0x2E,0x6F,0x72,0x67,0x22,0xD,0xA,0x69,0x66,0x20,0x28,0x78,0x20,0x3D,0x3D,0x20,0x22,0x22,0x2B,0x68,0x61,0x63,0x6B,0x78,0x2B,0x22,0x22,0x29,0xD,0xA,0x7B,0xD,0xA,0x61,0x6C,0x65,0x72,0x74,0x28,0x22,0x77,0x69,0x6E,0x21,0x22,0x29,0x3B,0xD,0xA,0x7D,0x20,0x65,0x6C,0x73,0x65,0x20,0x7B,0xD,0xA,0x61,0x6C,0x65,0x72,0x74,0x28,0x22,0x54,0x72,0x79,0x20,0x61,0x67,0x61,0x69,0x6E,0x21,0x22,0x29,0x3B,0xD,0xA,0x7D,0xD,0xA,0x7D,0xD,0xA,0xD,0xA,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x20,0x63,0x68,0x65,0x63,0x6B,0x70,0x61,0x73,0x73,0x77,0x28,0x75,0x70,0x6B,0x65,0x72,0x29,0xD,0xA,0x7B,0xD,0xA,0x68,0x61,0x63,0x6B,0x78,0x20,0x3D,0x20,0x75,0x70,0x6B,0x65,0x72,0x3B,0xD,0xA,0x63,0x68,0x65,0x63,0x6B,0x73,0x28,0x68,0x61,0x63,0x6B,0x78,0x29,0x3B,0xD,0xA,0x7D,0xD,0xA,0x3C,0x2F,0x73,0x63,0x72,0x69,0x70,0x74,0x3E)); </script>
其中文件checkpass中的代码为:
dairy="hello"; upker = "hero"; hackx = "upker"; function checks(pass) { if(pass == hackx+"is"+upker) { alert("Good job!"); } else { alert("Try again"); } }
总的js代码为:
<script type="text/javascript" src="./checkpass"></script> <script language="javascript"> hackx = "upker"; function check(x) { "+hackx+" == "xdsec.org" if (x == ""+hackx+"") { alert("win!"); } else { alert("Try again!"); } }
而其中过关页面中检测输入是否正确使用的是函数checks(),因而pass为“upkerishero”
ps:这一关学到在javascript中,document.write还可以写成document[‘write’],String.fromCharCode可以写成String[‘fromCharCode’].
————————————————————————————————————————————————————
第七关 Login
地址:http://ctf.xdsec.org:2222/basic/login/
查看网页源代码,没有发现什么有用的东西。源代码如下:
<html> <form action="login.php" method="post"> <input type="password" name="Password"> <input type="submit" name="submit" value="login"> </form> </html>
没有思路了,查看答案怎么说的。原来答案是根据访问时返回的头部信息来获取key的,即破解key的关键隐藏在返回的头部的字段中。
可以看到请求后返回的响应头部有PASSWORD: DONtTrY,将此输入到框中再次看返回的头部信息。可以看到返回了加密后的key
现在有加密后的key了,没有密钥呀,原来密钥藏在http://ctf.xdsec.org:2222/basic/login/页面的响应的头部中(访问http://ctf.xdsec.org:2222/basic/login/时会自动跳转到http://ctf.xdsec.org:2222/basic/login/login.php页面上,所以导致我没有注意到http://ctf.xdsec.org:2222/basic/login/页面)
有了DES KEY了(D0nptTrY),进行解密就可以了。
ps:答案中是在linux系统中利用curl -I http://ctf.xdsec.org:2222/basic/login/来获取页面的头部信息。
—————————————————————————————————————————————
第八关 Rot13
网址:http://ctf.xdsec.org:2222/basic/rot/
根据提示,这一关应该和cmd有关。下载页面上的那个zip文件,解压后有两个cmd文件
不管是用文本文件打开查看,还是查看文件属性都没有发现文件的不同之处。查看答案后发现网站给出的提示是:diff命令查看文件的不同,rot13编码。
执行diff -a cmd.exe cmd-origin.exe来比较文件的不同(注意diff默认只比较文本文件因此需要-a参数),diff命令的使用参考:http://www.cnblogs.com/peida/archive/2012/12/12/2814048.html
可以看出cmd.exe多了字符串Xrl:E0g13rApeLcgrQ 进行rot13解密即可。解码地址:http://www.mxcz.net/tools/rot13.aspx,解码结果:Key:R0t13eNcrYpteD。
ps:在windoes下可以使用文件比较工具,如UltraCompare等来进行比较。可以更直观的显示出连个文件的不同
——————————————————————————————————————————————————
第九关 vi
地址:http://ctf.xdsec.org:2222/basic/vi/
查看了一下,只是一篇介绍vi的文章,查看源代码也没有发现隐藏信息。 查看答案后才明白,作者说看完第四条就去上课去了,说明他没有看第五条,也就是说作者没有关闭vi的自动保存功能,即会生成带~的备份文件,因此我们访问ctf.xdsec.org:2222/basic/vi/second-vi-editor.php~来将备份文件下载下来。
打开下载的备份文件,在其中找到泄露的源代码
通过泄露的源代码可以看到只要修改一下请求,就可以泄露$password变量的信息。
使用火狐的hackbar插件,成功获取到key
不知为什么,用burp将GET包修改为POST包没有成功。比较了一下找到原因,由于将GET修改为POST后没有加Content-Length头部,因而服务器没有接收POST的数据。
————————————————————————————————-
第十关 Visit
地址:http://ctf.xdsec.org:2222/basic/visit/
可以看到访问的页面上没有任何有用信息,查看源代码看是否有隐藏信息:
<HTML> <HEAD> <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> <title>Visit Here</title> <script LANGUAGE="Javascript">document.write(unescape("%3C%21DOCTYPE%20html%20PUBLIC%20%22-//W3C//DTD%20XHTML%201.0%20Transitional//EN%22%20/red.php%20%22http%3A//www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd%22%3E%20%0A%3Chtml%3E%0A%3Cmeta%20http-equiv%3D%27Content-Type%27%20content%3D%27text/html%3B%20charset%3Dutf-8%27%20/%3E%0A%3Chead%3E%0A%3Ctitle%3Evisit%3C/title%3E%0A%3C/head%3E%0A%3Ccenter%3E%0A%3Ch2%3E%u6B22%u8FCE%u8BBF%u95EE%3C/h2%3E%0A%3Cbr/%3E%3Chr%3E%3Cspan%20style%3D%22font%3A11px%20Verdana%3B%22%3EXDCTF2013%3C/span%3E%3Cbr/%3E%0A%3C/center%3E%0A%3C/html%3E"))</SCRIPT> </HEAD> <BODY> </BODY> </HTML>
可以看到确实通过javascript隐藏了一些信息,将document.cookie替换为alert来看一下后面是什么信息:
可以看到这段js脚本只是输出了一个普通的html页面,不过要注意到第一行有一个很明显的/red.php,说明key就隐藏在该页面中。访问该页面:
被拒绝访问了,并且显示了提示信息。通过提示信息,我们可以知道网站对访问来源进行了限制。要突破限制可以通过修改请求中的Referer(注意是Referer)头来达到。
可以看到返回的页面不同了。查看其源代码:
在注释中有16个数字应该就和key有关了:49 56 52 48 54 100 101 52 54 101 97 54 53 57 54 100。看这些数字应该是字符对应的10进制的数字,按照ascii表将其转换为字符后为:18406de46ea6596d,由于是16位,可知是md5值,进行破解得:iverson3.
—————————————————————————————————————————————
HackGame部分
第一关Complex
网址:http://ctf.xdsec.org:2222/hackgame/complex/
首先用御剑猜得管理目录manager,但是不知密码
打算用burp来暴力跑密码,但是没跑到。查看答案发现,原来思路错了。网站提示“创建的一堆凌乱的目录”,所以猜测简单的字母目录,最终猜得:http://ctf.xdsec.org:2222/hackgame/complex/a/s/l/y/ 因为是nginx服务器,猜测目录下面存在.htaccess文件,访问之
在文件中有answer关键字,猜测可能存在与answer有关的文,测试后发现http://ctf.xdsec.org:2222/hackgame/complex/a/s/l/y/answer 获取到登陆密码为not here
ps:此题的蛋疼之处在于猜密码。学到的东西是nginx服务器的目录之下可能存在.htaccess文件。
————————————————————————————————————————————————
第二关 Guess
网址:http://ctf.xdsec.org:2222/hackgame/guess/
查看网页的源代码,看是否泄露信息。源代码如下:
<html> <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> <head> <title>猜猜看</title> </head> <body> <h1>Guessing!</h1> <p> 猜一猜下面的密码,如果猜对了,你将获得key! </p> <form action="#" method="GET"> <p><input type="text" name="attempt"></p> <p><input type="submit" value="猜猜更健康"></p> </form> </body> <!--by upker.net--> </html> <!--白盒审计 $filename = 'x'; extract($_GET); if (isset($attempt)) { $combination = trim(file_get_contents($filename)); if ($attempt === $combination) { echo "<p>文件内容:" . " $combination!?</p>"; $next = file_get_contents('y'); echo "<p>Congratulation.Key is:" . " $next</p>"; } else { echo "<p>Incorrect!</p>"; } } -->
可以看到源代码在注释中泄露了网站的php源代码。从源码上可以看出可以通过输入来覆盖$filename变量,从而绕过限制输出key。但是我犯了一个错误:由于我不能控制本网站的内容,所以我选取了一个远程地址:http://webnews.freetzi.com/a.php(该地址输出的内容为aa),但是忽略了网站可能限制了远程文件的获取从而使获取的内容为空,所以在http://ctf.xdsec.org:2222/hackgame/guess/?attempt=aa&filename=http://webnews.freetzi.com/a.php没有成功时,尝试http://ctf.xdsec.org:2222/hackgame/guess/?attempt=&filename=http://webnews.freetzi.com/a.php。当然,可以选择不存在的文件,并让aa为空,这样就可以突破了。
———————————————————————————————————————————————
第三关 Injection
http://ctf.xdsec.org:2013/hackgame/injection/
这一关考的应该是考察的是注入。猜测page参数存在注入,但是试了GET/POST/COOKIE方式都没有测试出来,不知怎么绕过。看答案原来是order参数存在注入.
但是,在order参数后加’和and 1=1都提醒不能注入,/*!and*/1=1 %0a/*!aNd*/1=1 order by 1#等都不行,看来是过滤了关键词,看来还得看看答案。答案说order参数存在盲注,原来将order参数设为abs(id-某一数字)的结果和数字有关系,如下:
这样就可以通过不断修改order by的参数来达到注入的效果。
由于在abs函数中,可能不能通过工具来获取到注入内容,只能写一个中转程序了。但是写的中转程序没有检测出注入,看来写的还有问题,以后研究一下。
<?php $id=$_GET['order']; $url="http://ctf.xdsec.org:2013/hackgame/injection/index.php?page=2&order=abs(id-".$id.")"; $ch=curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回 curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回 echo $output = curl_exec($ch); ?>
———————————————————————————————————————————————
第四关 Love
网址:http://ctf.xdsec.org:2222/hackgame/love/
Tips: 账号为ghost&wdxl,密码请自行猜测;密码16位以上,不区分大小写,请充分利用题中信息。
昵称改为舞动旋律忽悠人的请参赛队伍自行辨别
看来这一关是利用提供的信息进行社工,猜测出password。
猜测:ghostlovewdxl0812 ghostandwdxl0812 ghostlovewdxlat0812都猜错了。答案中说使用社工字典工具来根据题目中的信息来生成字典。工具可以采用BT5中集成的cupp工具(参考:通用密码分析神器—Cup:phttp://www.2cto.com/Article/201308/238431.html)。
————————————————————————————————————————————
第五关 mail
http://ctf.xdsec.org:2013/hackgame/mail/
查看源代码,没有发现什么有用的信息,只能从界面上的三个按钮想办法了。由于现在不知管理员admin的账号,所以不能研究“登陆”和“忘记密码”,所以先注册一个账号来研究一下了。
先注册一个账号,用户名:jing,口令:ling
现在有账号了,点击“忘记密码”。在找回密码界面上,未验证用户的合法性,只要求输入用户名即可生成重置密码的链接。
重置密码的链接中的p参数amluZy43MTdlMjUxNGIzMGRjNGM5MjIzMWMwZDBiOWMzY2Y4ZA==感觉是经过base64编码过了,将其解码得:jing.717e2514b30dc4c92231c0d0b9c3cf8d 可以看出解码后前面为用户名jing,后面为某一字符串的md5值,破解后为:jing+ling,即用户名+密码。
现在用此链接重置一下密码看一下
可以看到重置时只要输入一下新密码就可以了。现在尝试重置admin的密码(成功的关键是希望系统没有记录重置链接,并且不会提取重置链接中的用户名和md5中的用户名进行对比)。构造admin用户的重置链接,md5中的用户名和口令就使用注册时的,因为网站必须用户名和口令正确来能通过验证。因为网站只验证了后面md5值得正确,而没有验证前面的用户名是验证成功的用户名,即base64(admin.md5(jing+ling))=base64(admin.717e2514b30dc4c92231c0d0b9c3cf8d)=YWRtaW4uNzE3ZTI1MTRiMzBkYzRjOTIyMzFjMGQwYjljM2NmOGQ=。
所以重置链接为:http://ctf.xdsec.org:2013/hackgame/mail/resetUserPass.php?p=YWRtaW4uNzE3ZTI1MTRiMzBkYzRjOTIyMzFjMGQwYjljM2NmOGQ=
但是访问该链接什么也没反应,说明思路是错的。看了一下答案,原来是对正确的重置密码数据包的修改来达到重置admin密码的目的。
访问:http://ctf.xdsec.org:2013/hackgame/mail/resetUserPass.php?p=amluZy43MTdlMjUxNGIzMGRjNGM5MjIzMWMwZDBiOWMzY2Y4ZA==
结果失败,没有重置成功,看来得配合p参数来成功重置。即修改访问url为http://ctf.xdsec.org:2013/hackgame/mail/resetUserPass.php?p=YWRtaW4uNzE3ZTI1MTRiMzBkYzRjOTIyMzFjMGQwYjljM2NmOGQ=,并且将数据包中POST数据中的username改为admin,这样可通过burp修改,当然,可以通过hackbar来实现。
———————————————————————————————————————————————
第六关 upload
网址:http://ctf.xdsec.org:2222/hackgame/upload/
上传一个jpg文件,成功上传,提示显示这关要上传一个php文件来过关。
上传php文件,结果显示“文件类型出错或者大小过大!请重新上传!”,看来得抓包看一下怎样突破。将Content-Type修改后没有成功,答案说要利用%00截断并且要修改php的大小,由于文件名是在post数据中,因此截断需要先将%00进行url解码为00,即进行00截断。
————————————————————————————————————————
第七关 wordpress
Link To: http://ctf.xdsec.org:2013/hackgame/wordpress/
请注意获取wordpress有哪些账户,后台登陆即可得到key。
我没有做出来的原因是只知道通过/?author=1这样的形式来获取用户列表,不知道可通过/index.php?author=1。因为这关的wordpress限制了通过/?author=1这样的方式获取用户,导致我没有获取到用户列表。
通过/index.php?author=1这样的方式获取到两个用户名admin和test
现在看看登陆界面,登陆界面经过作者修改了,其中验证码要用手机号来接收,没办法来突破呀。
由于用户是test,猜测这一关test用户存在弱口令test,点击登陆提示输入四位数字验证码,所以可以用burp进行暴力破解。
转载请注明:jinglingshu的博客 » 西电网络攻防大赛Basic学习