The simplest observations can lead to finding huge vulnerabilities.
Here's how @Shlibness & I gained access to data of 25,233 employees:
Here's how @Shlibness & I gained access to data of 25,233 employees:
@Shlibness 1/ @Shlibness messaged me.
He had something for me to look at:
https://digitalcontrol.███/workday/workday_profiles_lookup
I'd never seen this endpoint.
But looked juicy!
Workday allows employees to check-in & out of work, get paid, etc.
I requested it &
He had something for me to look at:
https://digitalcontrol.███/workday/workday_profiles_lookup
I'd never seen this endpoint.
But looked juicy!
Workday allows employees to check-in & out of work, get paid, etc.
I requested it &
@Shlibness 2/ Employee data!
"count": 1,
"next": null,
"previous": null,
"results": [{
"user": "employee@████.com",
"user_id": "386",
"worker_id": "121600",
"prid": "████",
"work_email": "employee@████.com",
"display_name": "████"
}]
However,
"count": 1,
"next": null,
"previous": null,
"results": [{
"user": "employee@████.com",
"user_id": "386",
"worker_id": "121600",
"prid": "████",
"work_email": "employee@████.com",
"display_name": "████"
}]
However,
3/ The application returned the data of ONLY one employee.
So, we thought we were missing a parameter.
I tried using JSON keys from the response as parameters:
- ?user=employee@████.com
- ?user_id=
- ?worker_id=
No luck.
So I threw it into Burp Suite's Param-Miner.
And
So, we thought we were missing a parameter.
I tried using JSON keys from the response as parameters:
- ?user=employee@████.com
- ?user_id=
- ?worker_id=
No luck.
So I threw it into Burp Suite's Param-Miner.
And
4/ Nothing!
Well, maybe the endpoint accepts POST instead?
OPTIONS /workday/workday_profiles_lookup
Host: digitalcontrol.███.com
> HTTP/1.1 204 No Content
> Allow: OPTIONS, GET, HEAD
Nope.
Well, I changed the request to POST anyways and reran Param-Miner.
This time,
Well, maybe the endpoint accepts POST instead?
OPTIONS /workday/workday_profiles_lookup
Host: digitalcontrol.███.com
> HTTP/1.1 204 No Content
> Allow: OPTIONS, GET, HEAD
Nope.
Well, I changed the request to POST anyways and reran Param-Miner.
This time,
5/ It found nothing.
I sat back, thinking it was a lost cause.
Then, I looked closer at the SSL Certificate on this host.
The Subject Alternative Name field.
This field allows more hostnames/IPs to be protected by the cert.
This certificate had another domain listed in it!
I sat back, thinking it was a lost cause.
Then, I looked closer at the SSL Certificate on this host.
The Subject Alternative Name field.
This field allows more hostnames/IPs to be protected by the cert.
This certificate had another domain listed in it!
6/ But the domain belonged to a 3rd party:
> prod.CompanyName.catalogue.VendorName\.com
Weird!
I noticed that it specified "prod" in the subdomain.
Indicating this was a production instance.
Maybe there's a staging version somewhere!
So I went to Shodan:
> prod.CompanyName.catalogue.VendorName\.com
Weird!
I noticed that it specified "prod" in the subdomain.
Indicating this was a production instance.
Maybe there's a staging version somewhere!
So I went to Shodan:
7/ I searched for the subdomain:
> ssl.cert.subject\.cn:*.catalogue.vendor[.]com
And there was a result!
https://staging1\.COMPANY.catalogue.VENDOR\.com
So I visited the following URL:
> ssl.cert.subject\.cn:*.catalogue.vendor[.]com
And there was a result!
https://staging1\.COMPANY.catalogue.VENDOR\.com
So I visited the following URL:
8/
https://staging1\.COMPANY.catalogue.VENDOR\.com/workday/workday_profiles_lookup
This time, the "count" in the response was not 1.
It was 25233!
Tons of employee information.
But each page only had about the data of 100 employees
But, "next" had a value too!
https://staging1\.COMPANY.catalogue.VENDOR\.com/workday/workday_profiles_lookup
This time, the "count" in the response was not 1.
It was 25233!
Tons of employee information.
But each page only had about the data of 100 employees
But, "next" had a value too!
9/ We could specify a page through the ?page= parameter and just keep scrolling!
/workday/workday_profiles_lookup?page=2
This could have been easily automated to steal the data of all 25233 employees!
But since it was staging, surely it was fake information, right?
So,
/workday/workday_profiles_lookup?page=2
This could have been easily automated to steal the data of all 25233 employees!
But since it was staging, surely it was fake information, right?
So,
10/ I grabbed a name, went to LinkedIn, and searched.
A profile came up.
Clicked.
They worked at this company.
I did it several more times.
This information was REAL!
We reported it to the company.
They fixed & paid us within two days! Awesome.
A profile came up.
Clicked.
They worked at this company.
I did it several more times.
This information was REAL!
We reported it to the company.
They fixed & paid us within two days! Awesome.
Lessons:
- Collaborate! I had never seen this endpoint even though I hacked on this program.
- Be curious.
- Be observant.
- Think.
- Collaborate! I had never seen this endpoint even though I hacked on this program.
- Be curious.
- Be observant.
- Think.
I spent 56 minutes & 56 seconds writing this out.
So, if you enjoyed:
• I have a newsletter! Sign up if you want: newsletter.threat.dev
• follow
@hacker_
(or don't!)
• buy me a coffee (or multiple): buymeacoff.ee
So, if you enjoyed:
• I have a newsletter! Sign up if you want: newsletter.threat.dev
• follow
@hacker_
(or don't!)
• buy me a coffee (or multiple): buymeacoff.ee
Loading suggestions...