Cuckoo Tips’n’Tricks
MalCon 0x7E1
hello!
I am Andriy Brukhovetskyy
● Senior Security Researcher at <censured>
● Member of -> meh boring stuff
● Cuckoo FANboy
● JE #nato #fresas #cyber #crypto#apt
<censured>
<censured>
1.
Agenda and Best practices
RTFM and do searches in Issues = <333
Initial tips ‘n’ tricks
Hooks
Signatures += Extractors
Goodies
Everything can be applied to Cuckoo V2 and Cuckoo-modified
What is Cuckoo?
● Official Page - Official repository
● Main dev - Jurriaan Bremer
● F**k yeah, it has the documentation
● Scalable? Official dist VS mine dist.py - can be ported to v2
○ Don’t use tags in distributed cuckoo - it will break it
+----+--------+----------------+---------+
| id | name | url | enabled |
+----+--------+----------------+---------+
| 1 | 55 | http://X:8090/ | 1 |
| 2 | 225 | http://X:8090/ | 1 |
| 3 | 232 | http://x:8090/ | 1 |
| 4 | master | http://X:8090/ | 1 |
| 5 | 67 | http://X:8090/ | 1 |
+----+--------+----------------+---------+
Supported platforms:
● Windows
● Linux
● Darwin
● Android (use cucko v1.2)
What is Cuckoo?
Supported hypervisors:
● KVM <333
● QEMU
● VirtualBox
● VmWare/ESX/VsPhere
● XEN
● Physical (FOG)
● “Openstack” platform
<censured>
“
Why reinvent the wheel!?
2
Why Cuckoo?
● Active project
● Coded in python
● Good setup -> KVM
● Easy to extend
● Kernel Driver aka Zer0m0n integration are coming
● Alternatives? Forks? Clones?
○ Demo 1 - Cuckoo v2 VS Cuckoo-Modified(Dead)
○ Cuckoo - CAPE (based on cuckoo-modified)
3
How easily retrieve our goodies aka configs
● In all signatures use common key as -> mlw_re_rocks
● Add to views.py or api.py (need to add /iocs)
if "mlw_re_rocks" in buf:
data["mlwr_re_rocks"] = buf["mlw_re_rocks"]
● Forget about that huge jsons with more than xxx MBs
Hooks in Cuckoo v2
● MSDN
● Hooks documentation
● Current Hooks
● Dependencies:
○ sudo apt-get install mingw-w64 python-pip nasm
○ sudo pip install sphinx docutils pyyaml
● To compile just type make
○ Replace files in
$CUCKOO_ROOT/data/monitor/latest with files from
monitor/bin/
HeapFree
========
Signature::
* Interesting: yes
* Library: kernel32
* Return value: BOOL
Parameters::
* HANDLE hHeap
* DWORD dwFlags
* LPVOID lpMem
Pre::
int buflen = 0;
LPVOID buffer;
buflen = HeapSize(hHeap,dwFlags,lpMem);
buffer = HeapAlloc(hHeap,dwFlags,buflen+2);
copy_bytes(buffer,lpMem,buflen);
Logging::
P Address lpMem
b buf buflen,buffer
i size buflen
s buf1 buffer
Post::
mem_free(buffer);
Hooks in Cuckoo-Modified
● How to compile?
● Visual Studio(Express >= 2015)
● Load solution file, modify the files
● Select Release and press build
■ ctrl+shift+b
● Place cuckoomod.dll in:
○ $CUCKOO_ROOT/analyzer/windows/dll
#### cuckoomon.c
HOOK(kernel32, HeapFree)
#### hooks.h
extern HOOKDEF(BOOL, WINAPI, HeapFree,
__in HANDLE hHeap,
__in DWORD dwFlags,
__in LPVOID lpMem
);
#### hook_file.c
HOOKDEF(BOOL, WINAPI, HeapFree,
__in HANDLE hHeap,
__in DWORD dwFlags,
__in LPVOID lpMem
) {
int buflen = 0;
LPVOID buffer;
buflen = HeapSize(hHeap, dwFlags, lpMem);
buffer = HeapAlloc(hHeap, dwFlags, buflen + 2);
memcpy(buffer, lpMem, buflen);
BOOL ret = Old_HeapFree(hHeap, dwFlags, lpMem);
LOQ_bool("process", "Pib", "Address", lpMem, "buflen", buflen, "buf",
buflen+2, buffer);
return ret;
}
Signatures -> abstracts.py
● Signatures VS modules
● Skeleton of basic signature:
○ filter_apinames
○ on_call
○ on_complate
● My extra checks:
○ Check if detected from behavior
(on_call)
○ Check Suricata
○ Check file name (scripted upload)
Demo 1 - Chanitor/Hancitor
Extractors
● Bridge between Signature <> Volatility/others
● Why?
● How?
● Dumped processes VS vm memory dump
Demo 2 - Andromeda/Gamarue
● Andromeda_vol.py + Josemi = <3
● Was:
signatures = {
'androm': """rule andromeda {
strings:
$fmt1 = "id:%lu|bid:%lu|os:%lu"
$fmt2 = "{"id":%lu,"bid":%lu,"os":%lu"
$s1 = "aReport"
$s2 = "aStart"
$s3 = "aUpdate"
$s4 = "User-Agent: Mozi1la/4.0"
condition: 1 of ($fmt*) and 1 of ($s*)
}
"""
}
● @DoomedRaven: @Seifreed make me
a yara
● @Seifreed: No!
● @DoomedRaven: sudo @Seifreed
make me a yara
● @Seifreed: Done :)
● @Seifreed we love you <3
Demo 2 - Andromeda/Gamarue
● Andromeda_vol.py + Josemi = <3
● Become:
signatures = {
'androm': """rule andromeda {
strings:
$fmt1 = "id:%lu|bid:%lu|os:%lu"
$fmt2 = "{"id":%lu,"bid":%lu,"os":%lu"
$fmt3 = "id:%lu|bid:%lu|bv:%lu|sv:%lu|pa:%lu|la:%lu|ar:%lu"
$fmt4 = "id:%lu|bid:%lu|bv:%lu|os:%lu|la:%lu|rg:%lu"
$fmt5 = "id:%lu|bid:%lu|os:%lu|la:%lu|rg:%lu"
$fmt6 = "{"id":%lu,"bid":%lu,"os":%lu,"la":%lu,"rg":%lu}"
$fmt7 = "{"id":%lu,"bid":%lu,"os":%lu,"la":%lu,"rg":%lu,"bb":%lu}"
condition: 1 of ($fmt*)
}
"""
}
/*
Update this function when a new version is seen -->
id:%lu|bid:%lu|bv:%lu|sv:%lu|pa:%lu|la:%lu|ar:%lu (<=2.06)
id:%lu|bid:%lu|bv:%lu|os:%lu|la:%lu|rg:%lu (2.07/2.08)
id:%lu|bid:%lu|os:%lu|la:%lu|rg:%lu (2.09)
{"id":%lu,"bid":%lu,"os":%lu,"la":%lu,"rg":%lu} (2.10?)
{"id":%lu,"tid":%lu,"err":%lu,"w32":%lu} (version 2.10)
{"id":%lu,"bid":%lu,"os":%lu,"la":%lu,"rg":%lu,"bb":%lu} (2.10.2)
more at http://eternal-todo.com/blog/andromeda-gamarue-loves-json
*/
Demo 2 - Andromeda/Gamarue
● Andromeda_vol.py + Josemi = <3
● Igual:
Demo 3 - Locky
● Step by step manual <- must read
Now time for real goodies ;)
Now time for real goodies ;)
Now time for real goodies ;)
Now time for real goodies ;)
Now time for real goodies ;)
Now time for real goodies ;)
Now time for real goodies ;)
Now time for real goodies ;)
Now time for real goodies ;)
Now time for real goodies ;)
Now time for real goodies.
Hey, fox, just hello ;P
WebGui visualization of configs
● In Cuckoo-Modified
○ Vim $CUCKOO_ROOT/web/templates/analysis/report.html
● Cuckoo v2 - See customizations slide
{% if analysis.mlw_re_rocks.locky %}
<li><a href="#locky" data-toggle="tab">Locky</a></li>
{% endif %}
<li><a href="#statistics" data-toggle="tab">Statistics</a></li>
<li><a href="#admin" data-toggle="tab">Admin</a></li>
{% if analysis.mlw_re_rocks.locky %}
<div class="tab-pane fade" id="locky">
{% include "analysis/locky/index.html" %}
{% endif %}
<div class="tab-pane fade" id="statistics">
{% include "analysis/statistics/index.html" %}
</div>
<div class="tab-pane fade" id="admin">
{% include "analysis/admin/index.html" %}
</div>
</div>
{% endblock %}
Goodies - Exit nodes
● - From our friend @charly837
Goodies - Packages
Goodies - EK Troller 2000
● Cuckoo v2 supports Mitmproxy, so here is time to play
● Inject EK expected header(s) on the fly to request(s) which comes from Cuckoo.
def request(context, flow):
res = sqliter(flow.request.url, 'select')
if res:
headers = json.loads(res)
exit_node = headers.get('exit_node', False)
if exit_node:
<removed>
for header, value in headers.items():
if header and value:
flow.request.headers[bytes(header)] = bytes(value)
Goodies - SMTP Sinkhole
● Don’t be a spammer, intercept and process it!
wget https://raw.githubusercontent.com/cuckoosandbox/cuckoo/legacy/utils/smtp_sinkhole.py -O smtp_sinkhole.py
mkdir dumps
python smtp_sinkhole.py 0.0.0.0 1025 --dir dumps
# smtp
sudo iptables -t nat -A PREROUTING -i IFACE -p tcp -m tcp --dport 25 -j REDIRECT --to-ports 1025
sudo iptables -t nat -A PREROUTING -i IFACE -p tcp -m tcp --sport 25 -j REDIRECT --to-ports 1025
# tls + ssl
sudo iptables -t nat -A PREROUTING -i IFACE -p tcp -m tcp --dport 465 -j REDIRECT --to-ports 1025
Goodies - Work in progress in cuckoo V2
Goodies - Work in progress in cuckoo V2
Goodies - Work in progress in cuckoo V2
Goodies - Work in progress in cuckoo V2
Extracted Powershell Artifacts
Customizations?
Why Not?
Party hard is coming!
Any many others...
¿Q&A?
My twitter:
@d00m3dr4v3n
Special Thanks to:
@shakethemalware

Malcon2017

  • 1.
  • 2.
    hello! I am AndriyBrukhovetskyy ● Senior Security Researcher at <censured> ● Member of -> meh boring stuff ● Cuckoo FANboy ● JE #nato #fresas #cyber #crypto#apt <censured> <censured>
  • 3.
    1. Agenda and Bestpractices RTFM and do searches in Issues = <333 Initial tips ‘n’ tricks Hooks Signatures += Extractors Goodies Everything can be applied to Cuckoo V2 and Cuckoo-modified
  • 4.
    What is Cuckoo? ●Official Page - Official repository ● Main dev - Jurriaan Bremer ● F**k yeah, it has the documentation ● Scalable? Official dist VS mine dist.py - can be ported to v2 ○ Don’t use tags in distributed cuckoo - it will break it +----+--------+----------------+---------+ | id | name | url | enabled | +----+--------+----------------+---------+ | 1 | 55 | http://X:8090/ | 1 | | 2 | 225 | http://X:8090/ | 1 | | 3 | 232 | http://x:8090/ | 1 | | 4 | master | http://X:8090/ | 1 | | 5 | 67 | http://X:8090/ | 1 | +----+--------+----------------+---------+
  • 5.
    Supported platforms: ● Windows ●Linux ● Darwin ● Android (use cucko v1.2) What is Cuckoo? Supported hypervisors: ● KVM <333 ● QEMU ● VirtualBox ● VmWare/ESX/VsPhere ● XEN ● Physical (FOG) ● “Openstack” platform
  • 6.
  • 7.
  • 8.
    2 Why Cuckoo? ● Activeproject ● Coded in python ● Good setup -> KVM ● Easy to extend ● Kernel Driver aka Zer0m0n integration are coming ● Alternatives? Forks? Clones? ○ Demo 1 - Cuckoo v2 VS Cuckoo-Modified(Dead) ○ Cuckoo - CAPE (based on cuckoo-modified)
  • 9.
    3 How easily retrieveour goodies aka configs ● In all signatures use common key as -> mlw_re_rocks ● Add to views.py or api.py (need to add /iocs) if "mlw_re_rocks" in buf: data["mlwr_re_rocks"] = buf["mlw_re_rocks"] ● Forget about that huge jsons with more than xxx MBs
  • 10.
    Hooks in Cuckoov2 ● MSDN ● Hooks documentation ● Current Hooks ● Dependencies: ○ sudo apt-get install mingw-w64 python-pip nasm ○ sudo pip install sphinx docutils pyyaml ● To compile just type make ○ Replace files in $CUCKOO_ROOT/data/monitor/latest with files from monitor/bin/ HeapFree ======== Signature:: * Interesting: yes * Library: kernel32 * Return value: BOOL Parameters:: * HANDLE hHeap * DWORD dwFlags * LPVOID lpMem Pre:: int buflen = 0; LPVOID buffer; buflen = HeapSize(hHeap,dwFlags,lpMem); buffer = HeapAlloc(hHeap,dwFlags,buflen+2); copy_bytes(buffer,lpMem,buflen); Logging:: P Address lpMem b buf buflen,buffer i size buflen s buf1 buffer Post:: mem_free(buffer);
  • 11.
    Hooks in Cuckoo-Modified ●How to compile? ● Visual Studio(Express >= 2015) ● Load solution file, modify the files ● Select Release and press build ■ ctrl+shift+b ● Place cuckoomod.dll in: ○ $CUCKOO_ROOT/analyzer/windows/dll #### cuckoomon.c HOOK(kernel32, HeapFree) #### hooks.h extern HOOKDEF(BOOL, WINAPI, HeapFree, __in HANDLE hHeap, __in DWORD dwFlags, __in LPVOID lpMem ); #### hook_file.c HOOKDEF(BOOL, WINAPI, HeapFree, __in HANDLE hHeap, __in DWORD dwFlags, __in LPVOID lpMem ) { int buflen = 0; LPVOID buffer; buflen = HeapSize(hHeap, dwFlags, lpMem); buffer = HeapAlloc(hHeap, dwFlags, buflen + 2); memcpy(buffer, lpMem, buflen); BOOL ret = Old_HeapFree(hHeap, dwFlags, lpMem); LOQ_bool("process", "Pib", "Address", lpMem, "buflen", buflen, "buf", buflen+2, buffer); return ret; }
  • 12.
    Signatures -> abstracts.py ●Signatures VS modules ● Skeleton of basic signature: ○ filter_apinames ○ on_call ○ on_complate ● My extra checks: ○ Check if detected from behavior (on_call) ○ Check Suricata ○ Check file name (scripted upload)
  • 13.
    Demo 1 -Chanitor/Hancitor
  • 14.
    Extractors ● Bridge betweenSignature <> Volatility/others ● Why? ● How? ● Dumped processes VS vm memory dump
  • 15.
    Demo 2 -Andromeda/Gamarue ● Andromeda_vol.py + Josemi = <3 ● Was: signatures = { 'androm': """rule andromeda { strings: $fmt1 = "id:%lu|bid:%lu|os:%lu" $fmt2 = "{"id":%lu,"bid":%lu,"os":%lu" $s1 = "aReport" $s2 = "aStart" $s3 = "aUpdate" $s4 = "User-Agent: Mozi1la/4.0" condition: 1 of ($fmt*) and 1 of ($s*) } """ } ● @DoomedRaven: @Seifreed make me a yara ● @Seifreed: No! ● @DoomedRaven: sudo @Seifreed make me a yara ● @Seifreed: Done :) ● @Seifreed we love you <3
  • 16.
    Demo 2 -Andromeda/Gamarue ● Andromeda_vol.py + Josemi = <3 ● Become: signatures = { 'androm': """rule andromeda { strings: $fmt1 = "id:%lu|bid:%lu|os:%lu" $fmt2 = "{"id":%lu,"bid":%lu,"os":%lu" $fmt3 = "id:%lu|bid:%lu|bv:%lu|sv:%lu|pa:%lu|la:%lu|ar:%lu" $fmt4 = "id:%lu|bid:%lu|bv:%lu|os:%lu|la:%lu|rg:%lu" $fmt5 = "id:%lu|bid:%lu|os:%lu|la:%lu|rg:%lu" $fmt6 = "{"id":%lu,"bid":%lu,"os":%lu,"la":%lu,"rg":%lu}" $fmt7 = "{"id":%lu,"bid":%lu,"os":%lu,"la":%lu,"rg":%lu,"bb":%lu}" condition: 1 of ($fmt*) } """ } /* Update this function when a new version is seen --> id:%lu|bid:%lu|bv:%lu|sv:%lu|pa:%lu|la:%lu|ar:%lu (<=2.06) id:%lu|bid:%lu|bv:%lu|os:%lu|la:%lu|rg:%lu (2.07/2.08) id:%lu|bid:%lu|os:%lu|la:%lu|rg:%lu (2.09) {"id":%lu,"bid":%lu,"os":%lu,"la":%lu,"rg":%lu} (2.10?) {"id":%lu,"tid":%lu,"err":%lu,"w32":%lu} (version 2.10) {"id":%lu,"bid":%lu,"os":%lu,"la":%lu,"rg":%lu,"bb":%lu} (2.10.2) more at http://eternal-todo.com/blog/andromeda-gamarue-loves-json */
  • 17.
    Demo 2 -Andromeda/Gamarue ● Andromeda_vol.py + Josemi = <3 ● Igual:
  • 18.
    Demo 3 -Locky ● Step by step manual <- must read
  • 19.
    Now time forreal goodies ;)
  • 20.
    Now time forreal goodies ;)
  • 21.
    Now time forreal goodies ;)
  • 22.
    Now time forreal goodies ;)
  • 23.
    Now time forreal goodies ;)
  • 24.
    Now time forreal goodies ;)
  • 25.
    Now time forreal goodies ;)
  • 26.
    Now time forreal goodies ;)
  • 27.
    Now time forreal goodies ;)
  • 28.
    Now time forreal goodies ;)
  • 29.
    Now time forreal goodies. Hey, fox, just hello ;P
  • 30.
    WebGui visualization ofconfigs ● In Cuckoo-Modified ○ Vim $CUCKOO_ROOT/web/templates/analysis/report.html ● Cuckoo v2 - See customizations slide {% if analysis.mlw_re_rocks.locky %} <li><a href="#locky" data-toggle="tab">Locky</a></li> {% endif %} <li><a href="#statistics" data-toggle="tab">Statistics</a></li> <li><a href="#admin" data-toggle="tab">Admin</a></li> {% if analysis.mlw_re_rocks.locky %} <div class="tab-pane fade" id="locky"> {% include "analysis/locky/index.html" %} {% endif %} <div class="tab-pane fade" id="statistics"> {% include "analysis/statistics/index.html" %} </div> <div class="tab-pane fade" id="admin"> {% include "analysis/admin/index.html" %} </div> </div> {% endblock %}
  • 31.
    Goodies - Exitnodes ● - From our friend @charly837
  • 32.
  • 33.
    Goodies - EKTroller 2000 ● Cuckoo v2 supports Mitmproxy, so here is time to play ● Inject EK expected header(s) on the fly to request(s) which comes from Cuckoo. def request(context, flow): res = sqliter(flow.request.url, 'select') if res: headers = json.loads(res) exit_node = headers.get('exit_node', False) if exit_node: <removed> for header, value in headers.items(): if header and value: flow.request.headers[bytes(header)] = bytes(value)
  • 34.
    Goodies - SMTPSinkhole ● Don’t be a spammer, intercept and process it! wget https://raw.githubusercontent.com/cuckoosandbox/cuckoo/legacy/utils/smtp_sinkhole.py -O smtp_sinkhole.py mkdir dumps python smtp_sinkhole.py 0.0.0.0 1025 --dir dumps # smtp sudo iptables -t nat -A PREROUTING -i IFACE -p tcp -m tcp --dport 25 -j REDIRECT --to-ports 1025 sudo iptables -t nat -A PREROUTING -i IFACE -p tcp -m tcp --sport 25 -j REDIRECT --to-ports 1025 # tls + ssl sudo iptables -t nat -A PREROUTING -i IFACE -p tcp -m tcp --dport 465 -j REDIRECT --to-ports 1025
  • 35.
    Goodies - Workin progress in cuckoo V2
  • 36.
    Goodies - Workin progress in cuckoo V2
  • 37.
    Goodies - Workin progress in cuckoo V2
  • 38.
    Goodies - Workin progress in cuckoo V2 Extracted Powershell Artifacts
  • 39.
  • 40.
  • 41.
    Any many others... ¿Q&A? Mytwitter: @d00m3dr4v3n Special Thanks to: @shakethemalware