Skip to content

Commit 676655a

Browse files
authored
Merge pull request #215 from edoardottt/devel
Automatic Prototype Pollution Exploitation #200
2 parents 68977fa + 66ed0fd commit 676655a

File tree

17 files changed

+905
-148
lines changed

17 files changed

+905
-148
lines changed

.golangci.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ linters:
1111
- err113
1212
- errcheck
1313
- exhaustive
14-
- gochecknoinits
1514
- goconst
1615
- gocritic
1716
- godot
@@ -49,4 +48,9 @@ linters-settings:
4948
# Default: []
5049
ignored-numbers:
5150
- '2'
52-
- '0644'
51+
- '0644'
52+
53+
issues:
54+
exclude-rules:
55+
- path: pkg/exploit/exploit.go
56+
text: "append result not assigned to the same slice"

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ INPUT:
6161

6262
CONFIGURATION:
6363
-c, -concurrency int Concurrency level (default 50)
64-
-t, -timeout int Connection timeout in seconds (default 10)
64+
-t, -timeout int Connection timeout in seconds (default 20)
6565
-px, -proxy string Set a proxy server (URL)
6666
-rl, -rate-limit int Set a rate limit (per second)
6767
-ua, -user-agent string Set a custom User Agent (random by default)
@@ -72,6 +72,7 @@ SCAN:
7272
-p, -payload string Custom payload
7373
-js, -javascript string Run custom Javascript on target
7474
-jsf, -javascript-file string File containing custom Javascript to run on target
75+
-e, -exploit Automatic Exploitation
7576

7677
OUTPUT:
7778
-o, -output string File to write output results
@@ -103,6 +104,12 @@ pphack -l targets.txt
103104
cat targets.txt | pphack
104105
```
105106

107+
Automatic exploitation
108+
109+
```console
110+
pphack -e -u https://edoardottt.github.io/pp-test/
111+
```
112+
106113
[Read the Wiki](https://github.com/edoardottt/pphack/wiki) to understand how to use pphack.
107114

108115
Changelog 📌
@@ -117,7 +124,7 @@ Just open an [issue](https://github.com/edoardottt/pphack/issues) / [pull reques
117124

118125
Before opening a pull request, download [golangci-lint](https://golangci-lint.run/usage/install/) and run
119126

120-
```bash
127+
```console
121128
golangci-lint run
122129
```
123130

go.mod

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ go 1.23
55
require (
66
github.com/chromedp/chromedp v0.12.1
77
github.com/edoardottt/golazy v0.1.4
8-
github.com/projectdiscovery/goflags v0.1.70
9-
github.com/projectdiscovery/gologger v1.1.43
10-
github.com/projectdiscovery/utils v0.4.9
8+
github.com/projectdiscovery/goflags v0.1.71
9+
github.com/projectdiscovery/gologger v1.1.44
10+
github.com/projectdiscovery/utils v0.4.10
11+
github.com/stretchr/testify v1.10.0
1112
go.uber.org/ratelimit v0.3.1
1213
)
1314

@@ -16,9 +17,10 @@ require (
1617
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
1718
github.com/aymerick/douceur v0.2.0 // indirect
1819
github.com/benbjohnson/clock v1.3.5 // indirect
19-
github.com/chromedp/cdproto v0.0.0-20250120090109-d38428e4d9c8
20+
github.com/chromedp/cdproto v0.0.0-20250208210249-fa305b1d5b8a
2021
github.com/chromedp/sysutil v1.1.0 // indirect
2122
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 // indirect
23+
github.com/davecgh/go-spew v1.1.1 // indirect
2224
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
2325
github.com/gobwas/httphead v0.1.0 // indirect
2426
github.com/gobwas/pool v0.2.1 // indirect
@@ -41,18 +43,19 @@ require (
4143
github.com/nwaples/rardecode v1.1.3 // indirect
4244
github.com/pierrec/lz4/v4 v4.1.22 // indirect
4345
github.com/pkg/errors v0.9.1 // indirect
46+
github.com/pmezard/go-difflib v1.0.0 // indirect
4447
github.com/projectdiscovery/blackrock v0.0.1 // indirect
4548
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
4649
github.com/tidwall/gjson v1.18.0 // indirect
4750
github.com/tidwall/match v1.1.1 // indirect
4851
github.com/tidwall/pretty v1.2.1 // indirect
4952
github.com/ulikunitz/xz v0.5.12 // indirect
5053
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
51-
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
52-
golang.org/x/mod v0.22.0 // indirect
54+
golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3 // indirect
55+
golang.org/x/mod v0.23.0 // indirect
5356
golang.org/x/net v0.34.0 // indirect
54-
golang.org/x/sync v0.10.0 // indirect
55-
golang.org/x/sys v0.29.0 // indirect
57+
golang.org/x/sync v0.11.0 // indirect
58+
golang.org/x/sys v0.30.0 // indirect
5659
golang.org/x/tools v0.29.0 // indirect
5760
gopkg.in/djherbis/times.v1 v1.3.0 // indirect
5861
gopkg.in/yaml.v3 v3.0.1 // indirect

go.sum

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP
77
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
88
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
99
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
10-
github.com/chromedp/cdproto v0.0.0-20250120090109-d38428e4d9c8 h1:Q2byC+xLgH/Z7hExJ8G/jVqsvCfGhMmNgM1ysZARA3o=
11-
github.com/chromedp/cdproto v0.0.0-20250120090109-d38428e4d9c8/go.mod h1:RTGuBeCeabAJGi3OZf71a6cGa7oYBfBP75VJZFLv6SU=
10+
github.com/chromedp/cdproto v0.0.0-20250208210249-fa305b1d5b8a h1:AfyrGZiCnK66SBxtNhrTWzGEoheSOV3K1wrnPLqaTT8=
11+
github.com/chromedp/cdproto v0.0.0-20250208210249-fa305b1d5b8a/go.mod h1:RTGuBeCeabAJGi3OZf71a6cGa7oYBfBP75VJZFLv6SU=
1212
github.com/chromedp/chromedp v0.12.1 h1:kBMblXk7xH5/6j3K9uk8d7/c+fzXWiUsCsPte0VMwOA=
1313
github.com/chromedp/chromedp v0.12.1/go.mod h1:F6+wdq9LKFDMoyxhq46ZLz4VLXrsrCAR3sFqJz4Nqc0=
1414
github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM=
@@ -85,18 +85,18 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
8585
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
8686
github.com/projectdiscovery/blackrock v0.0.1 h1:lHQqhaaEFjgf5WkuItbpeCZv2DUIE45k0VbGJyft6LQ=
8787
github.com/projectdiscovery/blackrock v0.0.1/go.mod h1:ANUtjDfaVrqB453bzToU+YB4cUbvBRpLvEwoWIwlTss=
88-
github.com/projectdiscovery/goflags v0.1.70 h1:MaBZBBHntxhY4bAb+WrLEk0nLV62O2gT7mf0XeJIqYw=
89-
github.com/projectdiscovery/goflags v0.1.70/go.mod h1:7iGZbDfySFEKYQ0QTNHaEKnJ4Gh+K4sOXovsfUxGGeA=
90-
github.com/projectdiscovery/gologger v1.1.43 h1:26DOeBUK2xus/UpM8jzHfNqEU5tWams3VGBtjJtI02I=
91-
github.com/projectdiscovery/gologger v1.1.43/go.mod h1:993FxohnjVo34dSgE3bw+L4TOCDNQfQ5zNbK0YhYrEw=
92-
github.com/projectdiscovery/utils v0.4.9 h1:GzYKy5iiCWEZZPGxrtgTOnRTZYiIAiCditGufp0nhGU=
93-
github.com/projectdiscovery/utils v0.4.9/go.mod h1:/68d0OHGgYF4aW4X7kS1qlFlYOnZxgtFDN85iH732JI=
88+
github.com/projectdiscovery/goflags v0.1.71 h1:CmgHQUEo2VCUOypIsSvIa4YlpzIQSIg2bmfyQXYoe48=
89+
github.com/projectdiscovery/goflags v0.1.71/go.mod h1:ikxJf0Jy7tQe13LpvTp0tanRAnqqYIlQlJaikSHnhY8=
90+
github.com/projectdiscovery/gologger v1.1.44 h1:tprWkKzKt37pz4HG2tvhzrOCQNIn8A3CEki6BRzXE5o=
91+
github.com/projectdiscovery/gologger v1.1.44/go.mod h1:ZQS0eJq7BwKM0xxFqwZFUkAH1bkIqe90EOFBP4LENH4=
92+
github.com/projectdiscovery/utils v0.4.10 h1:rwTHowpQgEWZqpuKCzNP/loUNVcM0z3zyfjd8rvJRiM=
93+
github.com/projectdiscovery/utils v0.4.10/go.mod h1:rjMHKcVQ0EbF6Zo69bjkDSqQHoXqaW/DxA8V9SU4/Zw=
9494
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
9595
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
9696
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
9797
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
98-
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
99-
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
98+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
99+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
100100
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
101101
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
102102
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
@@ -116,17 +116,17 @@ go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
116116
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
117117
go.uber.org/ratelimit v0.3.1 h1:K4qVE+byfv/B3tC+4nYWP7v/6SimcO7HzHekoMNBma0=
118118
go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJhRk=
119-
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA=
120-
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
121-
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
122-
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
119+
golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3 h1:qNgPs5exUA+G0C96DrPwNrvLSj7GT/9D+3WMWUcUg34=
120+
golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
121+
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
122+
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
123123
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
124124
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
125-
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
126-
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
125+
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
126+
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
127127
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
128-
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
129-
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
128+
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
129+
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
130130
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
131131
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
132132
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

pkg/exploit/exploit.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
pphack - The Most Advanced Client-Side Prototype Pollution Scanner
3+
4+
This repository is under MIT License https://github.com/edoardottt/pphack/blob/main/LICENSE
5+
*/
6+
7+
package exploit
8+
9+
import (
10+
"context"
11+
_ "embed"
12+
"encoding/json"
13+
"errors"
14+
"log"
15+
"strings"
16+
"sync"
17+
"time"
18+
19+
"github.com/chromedp/cdproto/page"
20+
"github.com/chromedp/chromedp"
21+
"github.com/projectdiscovery/gologger"
22+
)
23+
24+
var (
25+
//go:embed exploits.json
26+
exploitsJSON string
27+
28+
//go:embed fingerprint.js
29+
Fingerprint string
30+
31+
exploits map[string]Product
32+
ErrProductNotFound = errors.New("product not found")
33+
)
34+
35+
type Product struct {
36+
Reference string `json:"reference"`
37+
Exploits []struct {
38+
Payload string `json:"payload"`
39+
Verifiable string `json:"verifiable"`
40+
} `json:"exploits"`
41+
}
42+
43+
func init() {
44+
if err := json.Unmarshal([]byte(exploitsJSON), &exploits); err != nil {
45+
log.Fatal("error while unmarshaling exploits.json")
46+
}
47+
}
48+
49+
// CheckExploit tries to find a working Proof of Concept for an actual exploit (XSS).
50+
func CheckExploit(pctx context.Context, chromedpTasks chromedp.Tasks, fingerprint []string,
51+
targetURL string, verbose bool, timeout int) ([]string, error) {
52+
var (
53+
result []string
54+
wg sync.WaitGroup
55+
)
56+
57+
target := strings.Split(targetURL, "?")
58+
59+
for _, product := range fingerprint {
60+
wg.Add(1)
61+
62+
info, err := GetProductInfo(product)
63+
if err != nil && verbose {
64+
gologger.Error().Msg(err.Error())
65+
}
66+
67+
go func() {
68+
for _, exploit := range info.Exploits {
69+
ctx, cancel := context.WithTimeout(pctx, time.Second*time.Duration(timeout))
70+
ctx, _ = chromedp.NewContext(ctx)
71+
72+
chromedp.ListenTarget(ctx, func(ev interface{}) {
73+
if ev, ok := ev.(*page.EventJavascriptDialogOpening); ok {
74+
result = append(result, ev.URL)
75+
76+
cancel()
77+
}
78+
})
79+
80+
chromedpTasksa := append(chromedpTasks, chromedp.Navigate(target[0]+exploit.Payload))
81+
82+
err = chromedp.Run(ctx, chromedpTasksa)
83+
84+
if err != nil && verbose {
85+
gologger.Error().Msg(err.Error())
86+
}
87+
88+
cancel()
89+
}
90+
91+
wg.Done()
92+
}()
93+
}
94+
95+
wg.Wait()
96+
97+
return result, nil
98+
}

0 commit comments

Comments
 (0)