Ciscn2017出题总结与分享

不吐槽赛制,不吐槽别人,每个在场的都属于既得利益的一方,没必要吐槽别人了

题目灵感来自某次渗透测试吧,当时也是差不多这个配置环境搞了好几天。总的来说是一个思路比较简单的题

漏洞列表

  • sql时间盲注 ( 全局magic_quotes_gpc=On
    无法直接写入shell
  • 文件包含

配置环境

centos 6.5 PHP 5.2.17

mysql  Ver 14.14 Distrib 5.1.73

Server version: Apache/2.2.15 (Unix)

Linux localhost.localdomain 3.10.107-1.el6.elrepo.x86_64 #1 SMP Tue Jun 27 10:57:54 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux
  • 网站后台
admin

8YDMGYqkpHt5waTpEC

  • mysql用户
bertram@localhost

123456b

bertram权限

| GRANT FILE ON *.* TO 'bertram'@'localhost' IDENTIFIED BY PASSWORD '*EF7EFAEE2A2C696B3DFBCE2A6DD653098ECD4CE2' |
| GRANT SELECT, INSERT ON `typecho`.* TO 'bertram'@'localhost'                                                  |
| GRANT UPDATE ON `typecho`.`typecho_users` TO 'bertram'@'localhost'                                            |
| GRANT UPDATE ON `typecho`.`typecho_metas` TO 'bertram'@'localhost'                                            |
| GRANT UPDATE ON `typecho`.`typecho_options` TO 'bertram'@'localhost'                                          |
| GRANT UPDATE ON `typecho`.`typecho_contents` TO 'bertram'@'localhost'                                         |
| GRANT UPDATE ON `typecho`.`typecho_relationships` TO 'bertram'@'localhost'                                    |
| GRANT UPDATE ON `typecho`.`typecho_fields` TO 'bertram'@'localhost'                                           |
| GRANT UPDATE ON `typecho`.`typecho_comments` TO 'bertram'@'localhost'
  • phpmyadmin 认证
passw0rd
  • 文件权限 /var/www/html/ 744 | /tmp/ 777 | /home/apache/flag 744

  • phpmyadmin 登陆401 普通用户权限管理问题

  • /var/www/目录结构

.
├── 8080
│   ├── hook_it.apk
│   └── index.html
├── cgi-bin
├── error
│   ├── contact.html.var
│   ├── HTTP_BAD_GATEWAY.html.var
│   ├── HTTP_BAD_REQUEST.html.var
│   ├── HTTP_FORBIDDEN.html.var
│   ├── HTTP_GONE.html.var
│   ├── HTTP_INTERNAL_SERVER_ERROR.html.var
│   ├── HTTP_LENGTH_REQUIRED.html.var
│   ├── HTTP_METHOD_NOT_ALLOWED.html.var
│   ├── HTTP_NOT_FOUND.html.var
│   ├── HTTP_NOT_IMPLEMENTED.html.var
│   ├── HTTP_PRECONDITION_FAILED.html.var
│   ├── HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
│   ├── HTTP_REQUEST_TIME_OUT.html.var
│   ├── HTTP_REQUEST_URI_TOO_LARGE.html.var
│   ├── HTTP_SERVICE_UNAVAILABLE.html.var
│   ├── HTTP_UNAUTHORIZED.html.var
│   ├── HTTP_UNSUPPORTED_MEDIA_TYPE.html.var
│   ├── HTTP_VARIANT_ALSO_VARIES.html.var
│   ├── include
│   │   ├── bottom.html
│   │   ├── spacer.html
│   │   └── top.html
│   ├── noindex.html
│   └── README
├── html
│   ├── admin
│   │   ├── config.php
│   │   ├── css
│   │   ├── .git
│   │   ├── index.php
│   │   ├── js
│   │   ├── linux-3.12.16.tar.xz
│   │   └── phpmyadmin
│   ├── config.inc.php
│   ├── .htaccess
│   ├── index.php
│   ├── info.php
│   ├── license.txt
│   ├── test
│   │   ├── index.php
│   │   └── templates
│   ├── usr
│   │   ├── plugins
│   │   ├── themes
│   │   └── uploads
│   └── var
│       ├── CommonMark
│       ├── Helper.php
│       ├── IXR
│       ├── Json.php
│       ├── Markdown.php
│       ├── PasswordHash.php
│       ├── Typecho
│       ├── Upgrade.php
│       └── Widget
├── .htpasswd
└── .htpasswd2

其中phpmyadmin文件夹下还有一个.htaccess 用于401验证

源码

  • index.php
<?php
##############################
#   Author:berTrAM.          #
#   Only Use For Ciscn2017   #
#   flag is in /home/apache/flag#
##############################
error_reporting(0);

include 'config.php';


function safe_check($string){
    $string=filter_invisible($string); 
    if(preg_match("/insert\b|update\b|drop\b|delete\b|dumpfile\b|outfile\b|rename\b|floor\(|extractvalue|updatexml|name_const|multipoint\(/i", $string)){
        die("<script>alert(\"Be a Good Man :)\")</script>");
    }
    return $string;
}

function filter_invisible($str){
    for($i=0;$i<strlen($str);$i++){
        $ascii = ord($str[$i]);
        if($ascii>126 || $ascii < 32){ 
            if(!in_array($ascii, array(9,10,13))){
                die("<script>alert(\"param error\");</script>");
            }else{
                $str = str_replace($ascii, " ", $str);
            }
        }
    }
    return $str;
}

function dologin($username,$password){
    GLOBAL $db;
    if(empty($username)||empty($password)){
        die("<script>alert(\"Check Your Input ^..^\");</script>");
    }
    else{
        $query = "SELECT * FROM user where username='{$username}'";
        $res = $db->kick_query($query);
        
        if(mysql_num_rows($res)===0){
            die("<script>alert('User Don\'t exists!');</script>");
        }

        $rows = mysql_fetch_assoc($res);
        if($rows['password']!==$password){
            die("<script>alert(\"You Password is Wrong!\");</script>");
        }

        $query = "SELECT * FROM isadmin where username='{$username}'";
        $res = $db->kick_query($query);
        if(mysql_num_rows($res)){
            die("<script>alert(\"You cAn't Login.  XD\");</script>");
        }
        else{
            $_SESSION['username'] = $rows['username'];
            echo "<script>alert('Login Success~ have Fun!');</script>";
        }

        if ($username ==='berTrAM'){
            $_SESSION['isadmin']='True';
            //var_dump($_SESSION);
        }
    }
}

function doregister($username,$password){
    echo $username.$password;
    GLOBAL $db;
    if(empty($username)||empty($password)){
        die("<script>alert('Check Your Input ^..^');</script>");
    }
    else{
        $query = "SELECT * FROM user Where username='{$username}'";
        $res = $db->kick_query($query);
        if(mysql_num_rows($res)>0){
            die("<script>alert('Some One has Used this username');</script>");
        }
        $query = "INSERT INTO user(username,password) VALUES('{$username}','{$password}')";
        $res = $db->kick_query($query);
        $query = "INSERT INTO isadmin(username,`is`) VALUES('{$username}',0)";
        $res = $db->kick_query($query);
        echo "<script>alert(\"register Ok\");</script>";
    }
}

function islogin(){
    //var_dump($_SESSION);
    if(!isset($_SESSION['username']))
        die("<script>alert(\"please Login first\");</script>");
}

function dosend($username,$header,$description){
    GLOBAL $db;
    if(empty($header)||empty($description)){
        die("<script>alert(\"Rubbish string. :(\");</script>");
    }

    if(strlen($header)>20)
        $header = substr($header,0,20);
    if(strlen($description)>255)
        $description = substr($description,0,255);
    $host = $_SERVER['REMOTE_ADDR'];
    $query = "INSERT INTO messagebox(username,header,description,host) VALUES('{$username}','{$header}','{$description}','{$host}')";
    $db->kick_query($query);
}

foreach ($_GET as $key => $value) {
    $_GET[$key] = trim(safe_check($value));
}
foreach ($_POST as $key => $value) {
    $_POST[$key] = trim(safe_check($value));
}

$db = new db();

$action = $_GET['action'];
if($action === 'phpinfo'){
    phpinfo();
}elseif($action === 'register'){
    //var_dump($_POST);
    $username = isset($_POST['username'])?$_POST['username']:'';
    $password = isset($_POST['password'])?md5($_POST['password']):'';
    doregister($username,$password);
}elseif($action === 'login'){
    $username = isset($_POST['username'])?$_POST['username']:'';
    $password = isset($_POST['password'])?md5($_POST['password']):'';
    dologin($username,$password);
    $query = "SELECT * FROM messagebox WHERE username = 'berTrAM' limit 0,1";
    $res = $db->kick_query($query);
    $rows = mysql_fetch_assoc($res);
    echo $rows['username'];
    echo $rows['header'];
    echo $rows['description'];
    //var_dump($_SESSION);
}elseif($action === 'admin'){
    islogin();
    if($_SESSION['isadmin']!=='True'){
        die("<script>alert('You Are Not Admin');</script>");
    }
    echo $_POST['shell'].".bertram.php";