Closed ChocolateOverflow closed 3 years ago
Thank you for your first issue report :D
Hi @ChocolateOverflow First of all, thank you for the issue report!
I don't think there's a problem with your testing itself. I think I need to test this with a juice shop and check what it response. Dalfox tests based on reflection parameters. and I think can know the exact cause by looking at the action of juice shop 😁
The payload <img src=# onerror=javascript:alert(1)>
definitely gets reflected and pops an alert.
Hello again @ChocolateOverflow I checked now, juishop is SPA(Single Page Application) service, which is slightly different from normal web pages. The XSS you mentioned is a typical DOM XSS issue that is difficult to detect in Dalfox, which does not use a headless browser 😭
$ http http://localhost:8088/\#/search\?q\=asd%22%3E%3CifraMe%2Fsrc%3D%22jaAvScriPT:alert\(45\)%22%3E
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>OWASP Juice Shop</title>
<meta name="description" content="Probably the most modern and sophisticated insecure web application">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link id="favicon" rel="icon" type="image/x-icon" href="assets/public/favicon_js.ico">
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script>
window.addEventListener("load", function(){
window.cookieconsent.initialise({
"palette": {
"popup": { "background": "#546e7a", "text": "#ffffff" },
"button": { "background": "#558b2f", "text": "#ffffff" }
},
"theme": "classic",
"position": "bottom-right",
"content": { "message": "This website uses fruit cookies to ensure you get the juiciest tracking experience.", "dismiss": "Me want it!", "link": "But me wait!", "href": "https://www.youtube.com/watch?v=9PnbKL3wuH4" }
})});
</script>
<link rel="stylesheet" href="styles.css"></head>
<body class="mat-app-background bluegrey-lightgreen-theme">
<app-root></app-root>
<script src="runtime-es2015.js" type="module"></script><script src="runtime-es5.js" nomodule defer></script><script src="polyfills-es5.js" nomodule defer></script><script src="polyfills-es2015.js" type="module"></script><script src="vendor-es2015.js" type="module"></script><script src="vendor-es5.js" nomodule defer></script><script src="main-es2015.js" type="module"></script><script src="main-es5.js" nomodule defer></script></body>
</html>
To address these challenges, I considered using headless browsers, but did not apply because they use incredibly inefficient resources.
@ChocolateOverflow First, I'll think about ways to solve it technically. it is certainly very weak for DOM-like XSS because there is a not using a headless browser.
If there's anything you don't understand, please reply 🤩
Use headless browser only for DOM XSS
package main
import (
"context"
"log"
"fmt"
"time"
"github.com/chromedp/chromedp"
"github.com/chromedp/cdproto/page"
)
func main() {
// create chrome instance
ctx, cancel := chromedp.NewContext(
context.Background(),
chromedp.WithLogf(log.Printf),
)
defer cancel()
// create a timeout
ctx, cancel = context.WithTimeout(ctx, 15*time.Second)
defer cancel()
// navigate to a page, wait for an element, click
var example string
chromedp.ListenTarget(ctx, func(ev interface{}) {
if ev, ok := ev.(*page.EventJavascriptDialogOpening); ok {
fmt.Println("closing alert:", ev.Message)
go func() {
if err := chromedp.Run(ctx,
page.HandleJavaScriptDialog(true),
); err != nil {
log.Fatal(err)
}
}()
}
})
err := chromedp.Run(ctx,
chromedp.Navigate(`https://xss-game.appspot.com/level1/frame?query=a%3CSvg%2Fonload%3Dalert%281%29+class%3Ddalfox%3E
`),
// wait for footer element is visible (ie, page is loaded)
chromedp.WaitVisible(`body > footer`),
)
if err != nil {
log.Fatal(err)
}
}
$ go build
$ ./gitasdfasdf
closing alert: Congratulations, you executed an alert:
1
@hahwul Can you recommend a box dalfox
would work on well? I've tried several applications so far and haven't got a single PoC.
@ChocolateOverflow
Please wait a little longer. I'll adding(working...) a function so that we can test hash-type queries(/page/#/search\?q\=asd
), not ordinary queries.
@ChocolateOverflow First, I applied it so that DOM-XSS can handle URL Fragment. I'll add same logic to other function the tonight. Perhaps further development is needed. Please refer to it!
$ ./dalfox url https://juice-shop.herokuapp.com/\#/search\?q\=aaa --headless
......
[*] 🦊 Start scan [SID:Single] / URL: https://juice-shop.herokuapp.com/#/search?q=aaa
[I] Found 0 testing point in DOM base parameter mining
[I] Content-Type is text/html; charset=UTF-8is 🔍
[I] X-Frame-Options is SAMEORIGIN
[I] Access-Control-Allow-Origin is *
[V] Triggered XSS Payload (found dialog in headless)aram and waiting dom xss
[POC][V][GET] https://juice-shop.herokuapp.com/#/search?q=%3Csvg/OnLoad=%22%60$%7Bprompt%601%60%7D%60%22%3E
@ChocolateOverflow And I'll share a little bit of the road map I think. If there is no problem with the performance as much as possible, I would like to use headless for DOM XSS and inJS(in javascript area xss) XSS cases. Of course, most logic is based on the current DOM Parser, so there will be no rapid slowdown. I'll try my best and try to use it as a default value if possible. Thanks to you, I can see the clue of the most difficult problem from the beginning. Thank you.
func getDOMXSSPayload() []string {
payload := []string{
"<svg/OnLoad=\"`${prompt`DALFOX_ALERT_VALUE`}`\">",
"<img/src/onerror=.1|alert`DALFOX_ALERT_VALUE`>",
"alert(DALFOX_ALERT_VALUE)",
"prompt(DALFOX_ALERT_VALUE)",
"confirm(DALFOX_ALERT_VALUE)",
}
return payload
}
$ cat 1.sh 11:28:09 오후
pueue add "./dalfox url http://testphp.vulnweb.com/listproducts.php\?cat\=123 --headless"
pueue add "./dalfox url http://testphp.vulnweb.com/listproducts.php\?cat\=123\&a\=1 --headless"
pueue add "./dalfox url http://testphp.vulnweb.com/listproducts.php\?cat\=123\&a\=1\&b\=1 --headless"
pueue add "./dalfox url http://testphp.vulnweb.com/listproducts.php\?cat\=123\&a\=1\&b\=1\&c\=1 --headless"
pueue add "./dalfox url http://testphp.vulnweb.com/listproducts.php\?cat\=123\&a\=1\&b\=1\&c\=1\&d\=1 --headless"
pueue add "./dalfox url http://testphp.vulnweb.com/listproducts.php\?cat\=123\&a\=1\&b\=1\&c\=1\&d\=1\&e\=1 --headless"
$ ./1.sh
Add approximately one minute for one parameter
do not test dom xss
/ why? The check for reflection, use built-in dom parser is much faster and more accurate than the headless browser.test to dom xss
always
, verify using headless browserBy default, use the headless browser (because of inJS) and adjust the number of payloads in DOM XSS. Instead, I'll add flags for deep check to dom xss.
--skip-headless
--deep-domxss
--headless
(only dev version flag)
Should we add a --level
flag similar to sqlmap
? The lowest level would just run the basic reflection checks, whereas a higher level would add scans & checks for higher accuracy at some cost like the headless browser. Of course, fine-grained control of the scans would also be great.
@ChocolateOverflow Well, I don't think need a level flags. I think the sqlmap's level and risk options is for safe the backend system more than the speed itself 🤔
it would be better to run the headless browser at Dalfox to a minimum. Anyway, dalfox's DOM Parser(common detection logic) is fast and accurate, with the exception of a few cases (DOM XSS, In javascript XSS). So reinforced those parts with the partial use of the headless browser.
Tested until the last commit, the speed is now much faster than the initial application of the headless browser, and it is not much different from the existing dalfox 🏁
Anyway, I going to use headless for this 2.4
version by default, but only for the parts that are really needed 😊
diff: 1.26s
diff: 2.44s
Even if we target about 20 parameters, there is only a difference of 2 seconds per scan. It's not much different from the previous one, so I think it's okay to include it as default.
Question
When I tried dalfox on real site, I only ever got up to
[I] Reflected PATH
messages but never got a[PoC]
result or an output file, so I'm testing it on OWASP Juice Shop. The test is as follows:I've confirmed that the
q
parameter in the URL is vulnerable to XSS but dalfox is getting nothing. Am I doing something wrong?Environment
localhost:3000