Skip to content

Commit

Permalink
(Closed #175) Adjust XSS injection phase for targets that reflected a…
Browse files Browse the repository at this point in the history
…ll injections
  • Loading branch information
hahwul committed Feb 15, 2021
1 parent 2dc2161 commit a4bbf19
Showing 1 changed file with 42 additions and 34 deletions.
76 changes: 42 additions & 34 deletions pkg/scanning/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func Scan(target string, options model.Options, sid string) {
Timeout: time.Duration(t) * time.Second,
Transport: transport,
}

if !options.FollowRedirect {
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
Expand Down Expand Up @@ -141,15 +141,15 @@ func Scan(target string, options model.Options, sid string) {
defer bavWaitGroup.Done()
SSTIAnalysis(target, options)
}()
go func(){
go func() {
defer bavWaitGroup.Done()
OpeRedirectorAnalysis(target, options)
}()
bavWaitGroup.Wait()
printing.DalLog("SYSTEM", "BAV analysis done ✓", options)
}()
}

s := spinner.New(spinner.CharSets[4], 100*time.Millisecond, spinner.WithWriter(os.Stderr)) // Build our new spinner
s.Prefix = " "
s.Suffix = " Waiting routines.."
Expand Down Expand Up @@ -200,7 +200,7 @@ func Scan(target string, options model.Options, sid string) {

// set path base xss

if (isAllowType(policy["Content-Type"]) && !options.OnlyCustomPayload){
if isAllowType(policy["Content-Type"]) && !options.OnlyCustomPayload {

arr := optimization.SetPayloadValue(getCommonPayload(), options)
for _, avv := range arr {
Expand All @@ -216,7 +216,7 @@ func Scan(target string, options model.Options, sid string) {
PathFinal = tmpTarget.Scheme + "://" + tmpTarget.Hostname() + "/" + tmpTarget.Path
}

tq, tm := optimization.MakeRequestQuery(PathFinal + ";" + avv, "", "", "inPATH", "toAppend", "NaN", options)
tq, tm := optimization.MakeRequestQuery(PathFinal+";"+avv, "", "", "inPATH", "toAppend", "NaN", options)
tm["payload"] = ";" + avv
query[tq] = tm
}
Expand Down Expand Up @@ -306,7 +306,7 @@ func Scan(target string, options model.Options, sid string) {
}

// loop parameter list
for k,_ := range params {
for k, _ := range params {
// loop payload list
for _, bpayload := range bpayloads {
// Add plain XSS Query
Expand Down Expand Up @@ -340,10 +340,10 @@ func Scan(target string, options model.Options, sid string) {
tq, tm := optimization.MakeRequestQuery(target, k, customPayload, "toHTML", "toAppend", "NaN", options)
query[tq] = tm
// Add URL encoded XSS Query
etq, etm := optimization.MakeRequestQuery(target, k, customPayload, "inHTML", "toAppend", "urlEncode",options)
etq, etm := optimization.MakeRequestQuery(target, k, customPayload, "inHTML", "toAppend", "urlEncode", options)
query[etq] = etm
// Add HTML Encoded XSS Query
htq, htm := optimization.MakeRequestQuery(target, k, customPayload, "inHTML", "toAppend", "htmlEncode",options)
htq, htm := optimization.MakeRequestQuery(target, k, customPayload, "inHTML", "toAppend", "htmlEncode", options)
query[htq] = htm
}
}
Expand Down Expand Up @@ -382,7 +382,7 @@ func Scan(target string, options model.Options, sid string) {
rl.Block(k.Host)
resbody, _, vds, vrs, err := SendReq(k, v["payload"], options)
abs := optimization.Abstraction(resbody, v["payload"])
if containsFromArray(abs,v["payload"]) {
if containsFromArray(abs, v["payload"]) {
vrs = true
} else {
vrs = false
Expand Down Expand Up @@ -639,25 +639,33 @@ func ParameterAnalysis(target string, options model.Options) map[string][]string
} else {
p, _ = url.ParseQuery(options.Data)
}

if options.Mining {
// Param mining with Gf-Patterins
if options.MiningWordlist == "" {
for _, gfParam := range GetGfXSS() {
if gfParam != "" {
if p.Get(gfParam) == "" {
p.Set(gfParam, "")
tempURL, _ := optimization.MakeRequestQuery(target, "pleasedonthaveanamelikethis_plz_plz", "pleasedonthaveanamelikethis_plz_plz", "PA", "toAppend", "NaN", options)
rl.Block(tempURL.Host)
_, _, _, vrs, _ := SendReq(tempURL, "pleasedonthaveanamelikethis_plz_plz", options)
if vrs {
p.Set("pleasedonthaveanamelikethis_plz_plz", "")
} else {
// Param mining with Gf-Patterins
if options.MiningWordlist == "" {
for _, gfParam := range GetGfXSS() {
if gfParam != "" {
if p.Get(gfParam) == "" {
p.Set(gfParam, "")
}
}
}
}
} else {
ff, err := readLinesOrLiteral(options.MiningWordlist)
if err != nil {
printing.DalLog("SYSTEM", "Mining wordlist load fail..", options)
} else {
for _, wdParam := range ff {
if wdParam != "" {
if p.Get(wdParam) == "" {
p.Set(wdParam, "")
ff, err := readLinesOrLiteral(options.MiningWordlist)
if err != nil {
printing.DalLog("SYSTEM", "Mining wordlist load fail..", options)
} else {
for _, wdParam := range ff {
if wdParam != "" {
if p.Get(wdParam) == "" {
p.Set(wdParam, "")
}
}
}
}
Expand All @@ -675,7 +683,7 @@ func ParameterAnalysis(target string, options model.Options) map[string][]string
Timeout: time.Duration(t) * time.Second,
Transport: transport,
}

if !options.FollowRedirect {
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
//return errors.New("Follow redirect") // or maybe the error from the request
Expand Down Expand Up @@ -820,18 +828,18 @@ func SendReq(req *http.Request, payload string, options model.Options) (string,
Timeout: time.Duration(options.Timeout) * time.Second,
Transport: netTransport,
}
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
if(strings.Contains(req.URL.Host, "google")){
printing.DalLog("GREP", "Found Open Redirector. Payload: " + via[0].URL.String(), options)

client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
if strings.Contains(req.URL.Host, "google") {
printing.DalLog("GREP", "Found Open Redirector. Payload: "+via[0].URL.String(), options)
if options.FoundAction != "" {
foundAction(options, via[0].Host, via[0].URL.String(), "BAV: OpenRedirect")
}
}

return nil
}

resp, err := client.Do(req)
if err != nil {
//fmt.Printf("HTTP call failed: %v --> %v", req.URL.String(), err)
Expand Down Expand Up @@ -873,7 +881,7 @@ func SendReq(req *http.Request, payload string, options model.Options) (string,
}

if options.FoundAction != "" {
foundAction(options, req.URL.Host, rst.PoC, "BAV: " + rst.Type)
foundAction(options, req.URL.Host, rst.PoC, "BAV: "+rst.Type)
}

for _, vv := range v {
Expand Down Expand Up @@ -901,7 +909,7 @@ func SendReq(req *http.Request, payload string, options model.Options) (string,
}

if options.FoundAction != "" {
foundAction(options, req.URL.Host, rst.PoC, "BAV: " + rst.Type)
foundAction(options, req.URL.Host, rst.PoC, "BAV: "+rst.Type)
}

for _, vv := range v {
Expand Down Expand Up @@ -935,9 +943,9 @@ func SendReq(req *http.Request, payload string, options model.Options) (string,
for _, vv := range v {
printing.DalLog("CODE", vv, options)
}

if options.FoundAction != "" {
foundAction(options, req.URL.Host, rst.PoC, "BAV: " + rst.Type)
foundAction(options, req.URL.Host, rst.PoC, "BAV: "+rst.Type)
}

if options.Format == "json" {
Expand Down

3 comments on commit a4bbf19

@rotemreiss
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @hahwul , maybe I misunderstand something from just reviewing the code, but worth asking anyway.
In the new way, if this imaginary param is reflected, then you are completely skipping the mining. Is that correct? If so, you will miss cases where mining can find another param which is reflected somewhere else in the DOM.
I hope that I missed something here..

@hahwul
Copy link
Owner Author

@hahwul hahwul commented on a4bbf19 Feb 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello again @rotemreiss
Yes, you're right. Virtual parameters have been reflected, but mining is required. However, there are so many unnecessary scans right now, so I applied them to filter out with the code.

The process of filtering meaningful and meaningless reflections with random parameters reflected will be included in the code section below, and logic will need to be considered more think. (Param / reflected corresponds to N*N, so I don't know if it's easy to implement.)

@rotemreiss
Copy link
Contributor

@rotemreiss rotemreiss commented on a4bbf19 Feb 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello again @rotemreiss
Yes, you're right. Virtual parameters have been reflected, but mining is required. However, there are so many unnecessary scans right now, so I applied them to filter out with the code.

The process of filtering meaningful and meaningless reflections with random parameters reflected will be included in the code section below, and logic will need to be considered more think. (Param / reflected corresponds to N*N, so I don't know if it's easy to implement.)

So maybe we need to allow an aggressive flag for such cases to continue mining anyway, or/and throw a message that the mining was skipped due to a global reflection.
BTW in case of such a message, we can also provide the line number, and allow the user to set something like skip-reflection-line=X, and then for a narrow scope, the user will be able to initiate another scan with skipping reflections on a specific line . WDYT?

Please sign in to comment.