(一)PHP命令执行:
1.string system
string system (string command,int &return_var)可以用来执行系统命令并将相应的执行结果输出
2. string exec
string exec(string command,array &outpub,int &return_var)
command是要执行的命令,output是获得执行命令输出的每一行字符串,return_var存放执行命令后的状态值。exec输出的是命令执行结果的最后一行内容。如果你需要获取未经处理的全部输出数据,请使用passthru()函数。
3. passthru
void passthru(string command, int &return_var)
command是要执行的命令,return_var存放执行命令后的状态值。
4.string shell_exec
string shell_exec (string command)command是要执行的命令。
5.反引号运算符
反引号运算符与shell_exec功能相同,执行shell命令并返回输出的字符串。
6.一些命令分隔符:
linux中:%0a 、%0d 、; 、& 、| 、&&、||
windows中:%0a、&、|、%1a(一个神奇的角色,作为.bat文件中的命令分隔符)。
空格被过滤:
< 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS等
7.花括号的别样用法:
在Linux bash中还可以使用{OS_COMMAND,ARGUMENT}执行系统命令
8.拼接绕过:
比如:a=l;b=s;$a$b,a=fl;b=ag;cat $a$b,即cat flag,长用于绕过黑名单检测。也可用编码的方式
9.内联执行:
内联,就是将反引号内命令的输出作为输入执行,类似的还有$(command)
10.长度限制:
长度限制可以用文件构造的方式来绕过。
linux下可以用 1>a创建文件名为a的空文件
ls -t>test则会将目录按时间排序后写进test文件中
sh命令可以从一个文件中读取命令来执行
(二)PHP常见函数漏洞总结:
1.三种函数
匿名函数(Anonymous functions)就是没有函数名的函数,也叫闭包函数(closures),是在 php5.3 中新增一个特性。定义格式:
function (参数列表) {
CODE//和普通函数一样可以有返回值
}
可变函数:PHP 中支持可变函数的概念(也叫变量函数),可以这样理解,如果一个变量名后有小括号( ),那么 PHP 就会寻找与变量值同名的函数并执行它。也就是说如果给一个变量赋不同的值,程序就会调用不同的函数。( ) 与调用函数时函数名后的小括号功能相同
回调函数:就是指调用函数时并不是向函数中传递一个标准的变量作为参数,而是将另一个函数作为参数传递到调用的函数中,这个作为参数的函数就是回调函数。通俗的来说,回调函数也是一个我们定义的函数,但是不是我们直接来调用的,而是通过另一个函数来调用的,这个函数通过接收回调函数的名字和参数来实现对它的调用。
魔法函数:magic函数命名是以符号__开头的,这些函数都会在某些特殊时候被自动调用。PHP 将所有以 __(两个下划线)开头的类方法保留为魔术方法。所以在定义类方法时,除了上述魔术方法,建议不要以 __ 为前缀。__sleep 方法会在一个对象被序列化的时候调用,对象被创建时__construct:当对象被销毁时:__destruct当对象被当作一个字符串使用时:to_string反序列化恢复对象前调用:__wakeup()当调用对象中不存在的方法时自动调用:__call从不可访问的属性读取数据:__get
2. import_request_variables全局变量
bool import_request_variables ( string types [, string prefix]) 函数可以在 register_global = off 时,把 GET/POST/Cookie 变量导入全局作用域中. 可以用字母'G'、'P'和'C'分别表示 GET、POST 和 Cookie。这些字母不区分大小写,所以你可以使用'g'、'p'和'c'的任何组合。POST 包含了通过 POST 方法上传的文件信息。注意这些字母的顺序,当使用“gp”时,POST 变量将使用相同的名字覆盖 GET 变量。任何 GPC 以外的字母都将被忽略。prefix 参数作为变量名的前缀,置于所有被导入到全局作用域的变量之前。所以如果你有个名为“userid”的 GET 变量,同时提供了“pref_”作为前缀,那么你将获得一个名为 $pref_userid 的全局变量
3.mixed preg_replace
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )用/e((PREG_REPLACE_EVAL)模式时如果这个修饰符设置了, preg_replace()在进行了对替换字符串的 后向引用替换之后, 将替换后的字符串作为php代码评估之行(eval函数方式), 并使用之行结果 作为实际参与替换的字符串. 单引号, 双引号, 反斜线(\)和NULL字符在 后向引用替换时会被用反斜线转义
4.string escapeshellarg
string escapeshellarg (string $arg)讲给字符串增加一个单引号或者转码已经存在的单引号,这样以确保能够直接将一个字符串传入shell参数并且还是确保安全的。Shell函数包含exec(),system(),执行运算符。 遇到不可见字符?
5. escapeshellcmd
string escapeshellcmd(string $command)对字符串种可能会欺骗shell命令执行任意命令的字符进行转义,此函数保证用户输入的数据在传入exec(),system(),执行操作符。反斜线会在下列字符前插入:&#;`/*?-<>(){}[]$\,\x0A和\xFF.’和”只在不配对时进行转义。
6. preg_match
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] ) 返回 pattern 的匹配次数。 它的值将是 0 次(不匹配)或 1 次,因为 preg_match() 在第一次匹配后 将会停止搜索。preg_match_all() 不同于此,它会一直搜索subject 直到到达结尾。 如果发生错误preg_match()返回 FALSE。绕过方法:
1.preg_match只能处理字符串,当传入的subject是数组时会返回false
2.PHP利用PCRE回溯次数限制绕过某些安全限制。pcre.backtrack_limit给pcre设定了一个回溯次数上限,默认为1000000,如果回溯次数超过这个数字,preg_match会返回false
3..不会匹配换行符
7.create_function
create_function (string $args,string $code) 根据传递的参数创建匿名函数,并为其返回唯一名称。create_function()会创建一个匿名函数(lambda样式)。create_function()函数会在内部执行 eval(),我们发现是执行了后面的return语句,属于create_function()中的第二个参数string $code位置。
string $args 声明的函数变量部分
string $code 执行的方法代码部分
8.in_array
9.array_search
array_search ( mixed $needle , array $haystack [, bool $strict = false ] ) : mixed,第三个参数 strict 默认为 false,如果可选的第三个参数 strict 为 TRUE,则 array_search() 将在 haystack 中检查完全相同的元素。 这意味着同样严格比较 haystack里 needle 的 类型,并且对象需是同一个实例。即默认为 false 时,会进行弱类型比较
10.base64_encode()、base64_decode()、sha1()、strcmp()传入数组会返回null
11.intval
intval (var)函数用于获取变量的整数值。在转换时,直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时(\0)结束转换
12. disable_function
命令执行函数一般都会被限制在disable_function当中,因此可以用system()等函数执行目录的相关操作。
13. symlink
bool symlink ( string $target , string $link ) 将建立一个指向target的名为link的符号链接,当然一般情况下这个target是受限于open_basedir的。symlink("c/d","tmplink");
symlink("tmplink/../../1.txt","exploit"); tmplink还是一个符号链接文件,它指向的路径是c/d,因此exploit指向的路径就变成了c/d/../../1.txt。有两个../是为了回到与C同级的目录下。
(三)php Complex (curly) syntax:
PHP的 Complex Syntax (Curly Syntax) 也能导致代码执行,它将执行花括号间的代码,并将结果替换回去。
(四)php 伪协议:
1.Think PHP5RCE漏洞:
/index.php/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
php://filter 的payload格式php://filter/read=convert.base64-encode/resource=index.php
2.data伪协议
data://伪协议 从php5.2.0起,数据流封装器开始有效,主要用于数据流的读取。如果传入的数据是PHP代码,就会执行代码
使用方法:data://text/plain;base64,xxxx(base64编码后的数据)
3.php://input
这个协议的利用方法是 将要执行的语法php代码写在post中提交,不用键与值的形式,只写代码即可
4.file://
与php:filter类似,访问本地文件,但是只能传入绝对路径。
绕过file_get_contents($text,‘r’)===“xxxx”,$text可以是url,可以是本地路径。可以用php://input、data://text/plain绕过
5.glob伪协议
glob是php自5.3.0版本起开始生效的一个用来筛选目录的伪协议,由于它在筛选目录时是不受open_basedir的制约的,可用它来绕过限制。例:"glob:///var/www/test/*.txt"
(五)文件包含
(六)弱类型
php把字母开头的转化为整型时,转化为0, 前面数字后面字母的话就只取到第一个字母出现的位置之前(如intval(''123abd45gf)结果为123)
(七)PHP溢出漏洞
对于一个2字节的Unsigned short int型变量,它的有效数据长度为两个字节,当它的数据长度超过两个字节时,就溢出,溢出的部分则直接忽略,使用相关变量时,使用的数据仅为最后2个字节,其他类型变量和数值与之类似。因此65537和1的值是相等的。
(八)PHP跨行符0a%(换行)绕过正则跨行匹配
正则表达式中,“.”(点符号)匹配的是除了换行符“/n”以外的所有字符
(九)绕过open_basedir
open_basedir是php.ini中的一个配置选项,它可将用户访问文件的活动范围限制在指定的区域. 但指定的限制实际上是前缀,而不是目录名。若"open_basedir = /dir/user", 那么目录 "/dir/user" 和 "/dir/user1"都是可以访问的。所以如果要将访问限制在仅为指定的目录,请用斜线结束路径名。
(十)正则回溯:
PHP为防止正则表达式的DDOS攻击设置了回溯次数上限(默认一百万字符)。就是说传入超过一百万字符匹配函数返回非0非1而为false.针对某些waf也可以采用这种方法。
(十一)PHP序列化与反序列化:
序列化:将变量转换为可保存或传输的字符串的过程。
serialize(mixed $value): string。字母含义如下:
a - array b - boolean d - double i - integer o - common object r - reference s - string C - custom object O - class N - null R - pointer reference U - unicode string
反序列化:在适当的的时候把这个字符串再转化成原来的变量使用。
unserialize()会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup() 方法. 序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过wakeup()的执行。