firefox执行linux脚本,如何利用Mozilla Firefox的合法功能执行操作系统命令

在软件环境中,用户只能执行有限数量的任务,通常使用 Kiosk 应用程序来减少用户与系统交互的机会。在许多环境中,只有少数预定义的应用程序发布给用户,比如 web 浏览器或 POS 软件,这取决于用户需要做什么。

攻击这种受限环境的攻击者通常试图找到一种绕过已发布应用程序边界的方法,以便在底层操作系统上执行命令。攻击者的总体目标通常是在系统上建立一个立足点,再感染与之相连的其他系统。根据被攻击系统的目的不同,操作和财务损失 ( 包括敏感数据的丢失 ) 也可能有所不同。

在 Windows 中,攻击者有许多众所周知的方法来创建交互式 shell,例如粘滞键、" 打开文件 " 对话框、在地址栏输入命令、帮助菜单等。在 Linux 环境中,这个过程更复杂,不是只在浏览器的地址栏中输入命令即可。

本文我会给大家介绍一种技术,通过在 Mozilla Firefox 中包含一个用于基于智能卡的身份验证 ( PKCS11 ) 的定制模块,可以在底层操作系统上执行代码。本文主要关注 Linux 环境,但是当底层操作系统是 Microsoft Windows 时,本文所讲的操作方法也一样适用。

目标侦察

在执行安全评估时,第一步便是侦察,以便尽可能多的发现目标系统。如果 Firefox 是唯一可用的应用程序,那么侦察将更加困难,但并非不可能。" 文件打开 " 对话框有助于确定文件系统的结构。在某些情况下,可以锁定文件打开或文件保存的对话框,使目录和文件都隐藏起来。但是,Firefox 允许任何用户通过使用 "file:" 协议处理程序来遍历文件系统。下面的屏幕截图显示了调用 file:/// 之后底层操作系统的根目录

我们感兴趣的目录的是 /etc 目录,它可以包含关于系统配置的有价值的信息,或可以全局写入的 / tmp 目录,攻击者可以利用这个目录在系统上删除文件。我们不仅可以浏览目录,还可以浏览当前用户可读的 /etc/os-release 等文件。

收集一些关于操作系统的信息对于后续操作都很重要,通过 " 帮助 " 菜单和 " 关于 Firefox" 视图进行的进一步搜索,可以发现 Firefox 是作为一个 32 位进程运行的。这个信息很有用,因为模块的目标架构必须与流程的架构相匹配。

使用自定义 PKCS11 模块

生成交互式 shell 的选项是有限的,但是 Mozilla Firefox 中的 " 安全设备 " 功能允许加载本地存储的 * .so 或 * .dll 文件。此功能主要用于设置基于智能卡的身份验证,例如,当 web 服务器需要客户端证书时。该实现会基于 PKCS11 标准,该标准还定义了与智能卡通信的 API。

现在我们已经确定了要下载文件的架构和位置,创建一个功能 PKCS11 库需要以下三个步骤,它会生成一个 shell 并与 Mozilla Firefox 兼容 :

1. 找到一个合适的 PKCS11 库;

2. 编译 PKCS11 库;

3. 调整生成的库的动态依赖关系;

找到一个合适的 PKCS11 库

这样一个模块的基础是开源中间件 "OpenSC",可以在Github上找到。

能够与 PKCS11 API 实现通信的库需要实现以下功能 :

C_Initialize ( ) C_GetInfo ( ) C_GetSlotList ( ) C_GetTokenInfo ( ) C_OpenSession ( ) C_GetMechanismList ( )

从头实现这样一个模块将非常耗时,但是可以利用现有的 OpenSC 代码库进行必要的自定义改编。

编译 PKCS11 库

为了理解代码流,首先找到某种类型的 " 入口点 " 是很重要的。特别有趣的是 src/pkcs11/pkcs11-global.c 文件 :

CK_RV C_Initialize ( CK_VOID_PTR pInitArgs ) { CK_RV rv; #if !defined ( _WIN32 ) pid_t current_pid = getpid ( ) ; #endif int rc; unsigned int i; sc_context_param_t ctx_opts;

上面的代码段显示了浏览器加载 PKCS11 模块后自动调用的函数 C_Initialize,对于一些生成的额外的代码行来说,这是一个好的开始。

CK_RV C_Initialize ( CK_VOID_PTR pInitArgs ) { int res = system ( "/usr/bin/xterm" ) ; printf ( "%d", res ) ; CK_RV rv; #if !defined ( _WIN32 ) pid_t current_pid = getpid ( ) ; #endif int rc; unsigned int i; sc_context_param_t ctx_opts;

插入了对 system ( ) 命令的调用,,该命令调用外部应用程序(本文为 /usr/bin/xterm)来生成交互式终端。请注意,代码中的 "system()" 调用会阻止 Firefox 进程的主线程,并在 xterm 关闭之前保持停止响应。然而,对于我们的这次概念证明来说已经足够了。

对于简单的概念验证,这种修改就足够了。OpenSC 项目现在需要为 32 位架构进行编译,因为 Firefox 实例是作为 32 位进程启动的。编译项目之后,Firefox 可以打开的共享库以 "opensc-pkcs11" 的名称创建,可以在 src/pkcs11/.libs/ 中找到。在可访问的 web 服务器上托管文件后,需要将其下载到目标系统,例如使用浏览器的 "Save link as" 功能。将这个文件加载到 Firefox 中后,通常初始加载会失败,并显示错误消息 " 模块加载失败 "。这与一个 opensc-pkcs11 依赖的库(不过该库已经删除)有关,且意味着需要调整动态依赖关系。

调整结果库的动态依赖关系

要找出哪些库已经被删除,可以使用 "ldd" 命令 :

root@debian:~/OpenSC/src/pkcs11/.libs# ldd opensc-pkcs11.so linux-gate.so.1 ( 0xb774b000 ) libopensc.so.6 => /root/OpenSC/src/libopensc/.libs/libopensc.so.6 ( 0xb75a4000 ) libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 ( 0xb758c000 ) libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 ( 0xb756d000 ) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 ( 0xb73b6000 ) /lib/ld-linux.so.2 ( 0xb774d000 )

如上所示,编译后的模块 opensc-pkcs11.so 依赖于一个名为 "libopensc.so.6" 的库,存储在 /root/OpenSC/src/libopensc/.libs/libopensc.so.6 中。到目前为止,只有 opensc-pkcs11.so 被下载到目标系统,并且库找不到 libopensc.so.6,从而导致错误。

工具 "patchelf" 可用于调整加载 libopensc.so.6 的位置,要将搜索路径从 /root/OpenSC/src/libopensc/.libs/ 更改为 / tmp /,可以使用以下命令:

patchelf --set-rpath /tmp opensc-pkcs11.so

上面的命令会将 "rpath" 更改为 /tmp,要检查修改是否成功,可以再次调用 ldd 命令。

root@debian:~/OpenSC/src/pkcs11/.libs# ldd opensc-pkcs11.so linux-gate.so.1 ( 0xb774b000 ) libopensc.so.6 => /tmp/libopensc.so.6 ( 0xb75a4000 ) libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 ( 0xb758c000 ) libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 ( 0xb756d000 ) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 ( 0xb73b6000 ) /lib/ld-linux.so.2 ( 0xb774d000 )

修改共享对象后,就要准备生成所有有效载荷了。要生成 shell,需要执行以下操作 :

1. 将修改后的 libopensc.so.6 下载到 / tmp /;

2. 将 opensc-pkcs11.so 的修改版本下载到任意位置;

3. 添加 opensc-pkcs11.so,将其作为 Firefox 中的安全设备;

指定共享对象的路径后,Firefox 将加载 PKCS11 模块并执行以下代码。

上面的屏幕截图显示,xterm 已经成功生成。

总结

当需要执行代码并且将 Firefox 作为单个 Kiosk 应用程序运行时,可以使用以上所描述的技术。

虽然使用这个方法之前,需要提前创建一个执行自定义代码的共享对象,但它是跨平台的,而且一旦库被下载到目标系统,调用它就非常容易。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值