进入靶场
都点击看看
发现点击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 jwtjwt_str = "eyJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiIxYTQxZTY3OC1kOGYyLTQxMDItYWRkOS1iMDM0M2ZmNzQ3M2UiLCJqa2wiOjQ5fQ.6QOmMhmKuPRJIDOlJzZ2AGXr8zXN6mjUh8TNk7nDOMM"
try:# 解码JWTdecoded = jwt.decode(jwt_str, options={"verify_signature": False})# 修改jk值decoded["jk"] = 1000000000000000000000000000# 重新编码JWTnew_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 "/" doredirect '/shop', 302
end# 处理/filebak路径的GET请求,将当前文件的内容作为文本返回
get "/filebak" docontent_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算法和环境变量中的密钥对负载进行编码,生成JWTauth = 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" doerb :shop
end# 处理/work路径的GET请求,处理用户工作相关的逻辑
get "/work" do# 调用islogin方法检查用户是否已登录islogin# 从Cookie中获取JWT并解码auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }# 获取解码后的负载auth = auth[0]# 检查请求参数中是否包含SECRETunless params[:SECRET].nil?# 检查请求参数中的SECRET是否与环境变量中的SECRET匹配if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}")# 如果匹配,打印FLAGputs ENV["FLAG"]endend# 检查请求参数中的do是否符合特定格式if params[:do] == "#{params[:name][0,7]} is working" then# 如果符合格式,将用户的jkl值增加一个0到9之间的随机数auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)# 重新对更新后的负载进行编码,生成新的JWTauth = JWT.encode auth,ENV["SECRET"] , 'HS256'# 将新的JWT存储在Cookie中cookies[:auth] = auth# 弹出一个提示框,告知用户工作成功ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").resultend
end# 处理/shop路径的POST请求,处理用户购买FLAG的逻辑
post "/shop" do# 调用islogin方法检查用户是否已登录islogin# 从Cookie中获取JWT并解码auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }# 检查用户的jkl值是否足够购买FLAGif auth[0]["jkl"] < FLAGPRICE then# 如果不足,返回一个包含错误信息的JSON响应json({title: "error",message: "no enough jkl"})else# 如果足够,将FLAG信息添加到负载中auth << {flag: ENV["FLAG"]}# 重新对更新后的负载进行编码,生成新的JWTauth = 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/