进入靶场
都点击看看
发现点击work会增加¥
但肯定不能一直点下去
抓包看看
这看起来是一个 JWT(JSON Web Token)字符串。JWT 通常由三部分组成,通过点(.)分隔,分别是头部(Header)、载荷(Payload)和签名(Signature)。
- 头部解析:
- 经过 Base64 解码(注意,这里的 Base64 解码是 URL 安全的 Base64 变体),
eyJhbGciOiJIUzI1NiJ9
得到{"alg":"HS256"}
,表示使用的签名算法是 HMAC SHA256。- 载荷解析:
- 对
eyJ1aWQiOiIxYTQxZTY3OC1kOGYyLTQxMDItYWRkOS1iMDM0M2ZmNzQ3M2UiLCJqa2wiOjQ5fQ
进行 Base64 解码,得到{"uid":"1a41e678 - d8f2 - 4102 - add9 - b0343ff7473e","jk":49}
。这里的uid
可能是用户唯一标识符,jk
的含义则取决于应用程序的定义。- 签名部分:
6QOmMhmKuPRJIDOlJzZ2AGXr8zXN6mjUh8TNk7nDOMM
是签名部分,它是通过使用头部中指定的算法(HS256),结合一个密钥(只有服务器端知道)对头部和载荷进行签名计算得出的。其目的是验证消息在传输过程中没有被更改,并且,在使用私钥签名的情况下,还可以验证 JWT 的发送者的身份。
综上,我们可以尝试修改jk的值
import jwt
jwt_str = "eyJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiIxYTQxZTY3OC1kOGYyLTQxMDItYWRkOS1iMDM0M2ZmNzQ3M2UiLCJqa2wiOjQ5fQ.6QOmMhmKuPRJIDOlJzZ2AGXr8zXN6mjUh8TNk7nDOMM"
try:
# 解码JWT
decoded = jwt.decode(jwt_str, options={"verify_signature": False})
# 修改jk值
decoded["jk"] = 1000000000000000000000000000
# 重新编码JWT
new_jwt = jwt.encode(decoded, "secret_key", algorithm='HS256')
print(new_jwt)
except jwt.exceptions.InvalidTokenError as e:
print(f"解码错误: {e}")
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxYTQxZTY3OC1kOGYyLTQxMDItYWRkOS1iMDM0M2ZmNzQ3M2UiLCJqa2wiOjQ5LCJqayI6MTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMH0.uEaleEDczqr1mtKN1aoq4uLX6M5IxhtT20FN9tNNOc8
不对
可能只改这块不行
看看还有没有信息
# 引入Sinatra框架,用于构建Web应用
require 'sinatra'
# 引入Sinatra的cookies扩展,用于处理HTTP Cookie
require 'sinatra/cookies'
# 引入Sinatra的JSON扩展,用于方便地返回JSON响应
require 'sinatra/json'
# 引入JWT库,用于处理JSON Web Tokens
require 'jwt'
# 引入SecureRandom库,用于生成安全的随机数和UUID
require 'securerandom'
# 引入ERB库,用于处理嵌入式Ruby模板
require 'erb'
# 设置静态文件的存放目录,这里指定为当前文件所在目录下的static文件夹
set :public_folder, File.dirname(__FILE__) + '/static'
# 定义购买FLAG所需的jkl价格
FLAGPRICE = 1000000000000000000000000000
# 生成一个64字节的随机十六进制字符串作为JWT的密钥,并存储在环境变量中
ENV["SECRET"] = SecureRandom.hex(64)
# 配置应用的设置
configure do
# 启用日志记录
enable :logging
# 打开一个日志文件,用于记录HTTP请求信息
file = File.new(File.dirname(__FILE__) + '/../log/http.log',"a+")
# 确保日志文件的写入是同步的,即写入操作立即生效
file.sync = true
# 使用Rack的CommonLogger中间件将日志记录到指定的文件中
use Rack::CommonLogger, file
end
# 处理根路径的GET请求,重定向到/shop路径
get "/" do
redirect '/shop', 302
end
# 处理/filebak路径的GET请求,将当前文件的内容作为文本返回
get "/filebak" do
content_type :text
# 使用ERB渲染当前文件的内容
erb IO.binread __FILE__
end
# 处理/api/auth路径的GET请求,生成一个JWT并将其存储在Cookie中
get "/api/auth" do
# 定义JWT的负载,包含一个随机生成的UUID和初始jkl值
payload = { uid: SecureRandom.uuid , jkl: 20}
# 使用HS256算法和环境变量中的密钥对负载进行编码,生成JWT
auth = JWT.encode payload,ENV["SECRET"] , 'HS256'
# 将生成的JWT存储在Cookie中
cookies[:auth] = auth
end
# 处理/api/info路径的GET请求,从Cookie中获取JWT并返回用户信息
get "/api/info" do
# 调用islogin方法检查用户是否已登录
islogin
# 从Cookie中获取JWT,并使用环境变量中的密钥进行解码
auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
# 将用户信息(uid和jkl)以JSON格式返回
json({uid: auth[0]["uid"],jkl: auth[0]["jkl"]})
end
# 处理/shop路径的GET请求,渲染shop.erb模板
get "/shop" do
erb :shop
end
# 处理/work路径的GET请求,处理用户工作相关的逻辑
get "/work" do
# 调用islogin方法检查用户是否已登录
islogin
# 从Cookie中获取JWT并解码
auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
# 获取解码后的负载
auth = auth[0]
# 检查请求参数中是否包含SECRET
unless params[:SECRET].nil?
# 检查请求参数中的SECRET是否与环境变量中的SECRET匹配
if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}")
# 如果匹配,打印FLAG
puts ENV["FLAG"]
end
end
# 检查请求参数中的do是否符合特定格式
if params[:do] == "#{params[:name][0,7]} is working" then
# 如果符合格式,将用户的jkl值增加一个0到9之间的随机数
auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)
# 重新对更新后的负载进行编码,生成新的JWT
auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
# 将新的JWT存储在Cookie中
cookies[:auth] = auth
# 弹出一个提示框,告知用户工作成功
ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result
end
end
# 处理/shop路径的POST请求,处理用户购买FLAG的逻辑
post "/shop" do
# 调用islogin方法检查用户是否已登录
islogin
# 从Cookie中获取JWT并解码
auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
# 检查用户的jkl值是否足够购买FLAG
if auth[0]["jkl"] < FLAGPRICE then
# 如果不足,返回一个包含错误信息的JSON响应
json({title: "error",message: "no enough jkl"})
else
# 如果足够,将FLAG信息添加到负载中
auth << {flag: ENV["FLAG"]}
# 重新对更新后的负载进行编码,生成新的JWT
auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
# 将新的JWT存储在Cookie中
cookies[:auth] = auth
# 返回一个包含成功信息的JSON响应
json({title: "success",message: "jkl is good thing"})
end
end
# 定义一个辅助方法,用于检查用户是否已登录
def islogin
# 检查Cookie中是否包含auth字段
if cookies[:auth].nil? then
# 如果不包含,重定向到/shop路径
redirect to('/shop')
end
end
得到了密钥
用下下面的这个工具
https://jwt.io/