WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

gustavo-iniguez-goya/decloaker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

decloaker

a simple tool to reveal files, directories and connections hidden by malware.

decloacker3

•• UsageMalware analysis examplesDownloadsTODOResources ••

Usage

tl;dr: ./bin/decloaker --log-level detection scan system

There're five main areas:

cat, list, move, delete or copy files without the libc.

  • Useful for LD_PRELOAD based rootkits. Use these commands instead of system cp, rm, ls, mv, cat or stat to manipulate files.
  cp [<orig> [<dest>]] [flags]

  rm <paths> ... [flags]

  ls [<paths> ...] [flags]

  mv [<orig> [<dest>]] [flags]

  cat [<paths> ...] [flags]

  stat [<paths> ...] [flags]

List, copy or get info of directories and files by accessing directly the disk device (only ext4 filesystems).

  • These options help to manipulate files or directories hidden by some kernel rootkits (like Diamorphine).
  • NOTE: only available for ext4 filesystems for now. Can be added other filesystems like SquashFS.
  • NOTE: this feature does not work on tmpfs, so if /tmp is mounted on tmpfs, it won't find hidden files/directories. it'll work for LD_PRELOAD rootkits, and some kernel rootkits.
  disk ls --dev=STRING <paths> ... [flags]
    List directories and files by reading directly from the disk device

  disk cp --dev=STRING <orig> <dest> [flags]
    Copy directories and files directly from the disk device

  disk stat --dev=STRING <paths> ... [flags]
    Return information about a path

  disk cat --dev=STRING <path> [flags]
    Reads the content of a file and prints it to stdout

Scan the system to unhide files, directories, processes or kernel rootkits.

Use --with-builtin-paths to scan only hidden files or content predefined paths.

  scan hidden-files <paths> ... [flags]
    Look for hidden files, directories or processes (libc vs Go's std lib vs mmap).

  scan hidden-content <paths> ...
    Open a file and check if it has hidden content (libc vs Go's std lib vs mmap).

  scan hidden-lkms
    Look for hidden kernel modules.

  scan hidden-procs
    Look for hidden processes.

  scan hidden-sockets [<protos> ...] [flags]
    Look for hidden sockets.

  scan system
    scan the system looking for hidden procs, lkms, files or content.

List sockets:

  netstat [<protos> ...] [flags]
    List connections from kernel via netlink.

  conntrack list
    Dump conntrack connections table from kernel.

Dump processes, opened files or kernel modules directly from the kernel, without parsing /proc/*:

  dump files [flags]
    Dump opened files.

  dump kmods
    Dump loaded kernel modules.

  dump tasks [flags]
    Dump running tasks (processes).

Example of listing running processes:

root@:~# /home/ga/decloaker dump tasks
Pid        PPid       Inode    UID    GID    Host         Comm             Exe
1          1          1703544  0      0      debian12-k3s systemd          /usr/lib/systemd/systemd
3276       3276       261966   65535  65535  kubeapps-internal-dashboard-69689f47dc-hp5fn pause            /pause
3539       3539       265011   65532  65532  coredns-697968c856-wmlnd coredns          /coredns
3598       3598       268220   1001   2001   dashboard-metrics-scraper-5bd45c9dd6-b7qgf metrics-sidecar  /metrics-sidecar
3738       3738       280114   1001   1001   kubeapps-internal-dashboard-69689f47dc-hp5fn nginx            /opt/bitnami/nginx/sbin/nginx
3879       3879       156554   100000 100000 lxc-grafana-debian12 "containerd-shim" "/usr/bin/containerd-shim-runc-v2"
3887       3887       4432     100000 100000 832106eef6ad "sh"             "/usr/bin/dash"
3949       3949       10162    100472 100000 44555dd7bb6b "sh"             "/bin/busybox"
3950       3950       27724    100000 100000 cd77355cd571 "entrypoint.sh"  "/usr/bin/bash"
4187       4187       11816    100472 100000 44555dd7bb6b "grafana"        "/usr/share/grafana/bin/grafana"
2715       2715       134508   100000 100000 lxc-jenkins "master"         "/usr/lib/postfix/sbin/master"
2716       2716       134505   100101 100110 lxc-jenkins "pickup"         "/usr/lib/postfix/sbin/pickup"
2717       2717       134503   100101 100110 lxc-jenkins "qmgr"           "/usr/lib/postfix/sbin/qmgr"
2731       2731       131106   100000 100000 lxc-jenkins "miniserv.pl"    "/usr/bin/perl"

TODO

  • Read options from a configuration file.

  • Dump logs in json and structured text.

  • Display the differences when scanning with scan hidden-content.

  • Display what processes opened the existing sockets. - 1/2 done: does not work for connections opened in containers.

  • Scan eBPF modules.

Malware analysis examples

More analyses here: https://github.com/gustavo-iniguez-goya/decloaker/discussions/categories/malware-analysis

Father (LD_PRELOAD rootkit)

https://github.com/mav8557/Father

Revealing hidden content (this malware hides /etc/ld.so.preload):

root@localhost:~# echo /lib/selinux.so.3 > /etc/ld.so.preload
root@localhost:~# cat /etc/ld.so.preload
cat: /etc/ld.so.preload: No such file or directory
root@localhost:~#
root@localhost:~# /home/ga/decloaker scan hidden-content /etc/ld.so.preload
decloaker v0.0, pid: 763609

[i] Checking for hidden content /etc/ld.so.preload

=== CONTENT WARNING (read) /etc/ld.so.preload ===
cat content:
 
-----------------------------------------------------------------
Go read content:
 /lib/selinux.so.3

====================================
root@localhost:~#

Unmasking hidden files/directories (by default, anything with "lobster" in the name):

root@localhost:~# ls /home/ga/rootkits/ld_preload/Father/*lobster*
ls: cannot access '/home/ga/rootkits/ld_preload/Father/*lobster*': No such file or directory
root@localhost:~#

Using Go's standard lib (i.e.: using syscalls directly, without libc):

root@localhost:~# /home/ga/decloaker scan hidden-files --recursive /home/ga/rootkits/ld_preload/Father/
decloaker v0.0, pid: 764851

[i] Checking hidden files ["/home/ga/rootkits/ld_preload/Father/"]

drwxrwxr-x	4096	2025-09-25T10:07:57+01:00	/home/ga/rootkits/ld_preload/Father/.git/logs/refs/remotes
-rw-rw-r--	0	2025-09-25T16:07:16+01:00	/home/ga/rootkits/ld_preload/Father/lobster/file2.txt
[w] 	HIDDEN: /home/ga/rootkits/ld_preload/Father/lobster/file2.txt

(...)

HIDDEN dirs/files found:

	drwxrwxr-x	4096	2025-09-25T16:07:16+01:00	/home/ga/rootkits/ld_preload/Father/lobster
	-rw-rw-r--	0	2025-09-25T16:07:16+01:00	/home/ga/rootkits/ld_preload/Father/lobster/file0.txt
	-rw-rw-r--	0	2025-09-25T16:07:16+01:00	/home/ga/rootkits/ld_preload/Father/lobster/file1.txt
	-rw-rw-r--	0	2025-09-25T16:07:27+01:00	/home/ga/rootkits/ld_preload/Father/lobster_test1.txt
	-rw-rw-r--	0	2025-09-25T16:07:16+01:00	/home/ga/rootkits/ld_preload/Father/lobster/file2.txt
	-rw-rw-r--	0	2025-09-25T16:07:16+01:00	/home/ga/rootkits/ld_preload/Father/lobster/file3.txt

[i] use decloaker cp <orig> <dest> to backup the files, or decloaker rm <path> to delete them

root@localhost:~#
root@localhost:~# rm /etc/ld.so.preload
rm: cannot remove '/etc/ld.so.preload': No such file or directory
root@localhost:~# /home/ga/decloaker rm /etc/ld.so.preload
decloaker v0.0, pid: 765449

[i] Deleting files [/etc/ld.so.preload]
	/etc/ld.so.preload:	OK
root@locahost:~#

Diamorphine (kernel rootkit)

By default, it hides files or directories with "diamorphine_secret" in the name:

root@localhost:~# ls /home/ga/Diamorphine/
diamorphine.c	diamorphine.mod    diamorphine.o	   LICENSE.txt	  Module.symvers
diamorphine.h	diamorphine.mod.c  ***diamorphine_secret***	   Makefile	  README.md
diamorphine.ko	diamorphine.mod.o  ***diamorphine_secret.txt***  modules.order
root@localhost:~#

It can also hide processes, by sending them the signal -31. We'll hide these processes later:

root@localhost:~# sleep 99999 &
[1] 1203
root@localhost:~# sleep 99999 &
[1] 1204
root@localhost:~# pgrep sleep
1203
1204
root@localhost:~#

Load the rootkit, and verify that the files and directories with "diamorphine_secret" are gone:

root@localhost:~# insmod /home/ga/Diamorphine/diamorphine.ko 
root@localhost:~# ls /home/ga/Diamorphine/
diamorphine.c  diamorphine.ko	diamorphine.mod.c  diamorphine.o  Makefile	 Module.symvers
diamorphine.h  diamorphine.mod	diamorphine.mod.o  LICENSE.txt	  modules.order  README.md
root@localhost:~#

Try to list the files with decloaker disk ls tool:

root@localhost:~# /home/ga/decloaker --log-level detection disk ls -d /dev/sda1 /home/ga/Diamorphine/

HIDDEN dirs/files found:

	----------	0	2025-09-25T11:53:45+01:00	/home/ga/Diamorphine/diamorphine_secret.txt
	----------	4096	2025-09-25T11:53:51+01:00	/home/ga/Diamorphine/diamorphine_secret
	----------	0	2025-09-25T11:53:51+01:00	/home/ga/Diamorphine/diamorphine_secret/file_hidden.txt
root@localhost:~#

Now we'll hide the processes:

root@localhost:~# kill -31 1203
root@localhost:~# kill -31 1204
root@localhost:~# pgrep -a sleep
root@localhost:~# 
root@localhost:~# ls /proc/|grep 1204
root@localhost:~# ls /proc/|grep 1203
root@localhost:~#

Let's try to unhide these processes:

root@localhost:~# /home/ga/decloaker scan hidden-procs
[i] Checking hidden processes:

dr-xr-xr-x	0	2025-10-12T19:07:20+01:00	/proc/1
(...)
dr-xr-xr-x	0	2025-10-12T19:07:20+01:00	/proc/17

[i] 	files checked (151/150)
[i] 	no hidden dirs/files found

WARNING (ebpf): pid hidden?
	PID: 1203	PPid: 1203
	Inode: 946157	Uid: 0	Gid: 0
	Comm: "sleep"
	Path: ""

	PID confirmed via Stat: 1203, "sleep"

[i] Stat /proc/1203:
dr-xr-xr-x	0	2025-10-12T19:07:48+01:00	1203

	Size: 0 	Block size: 1024 	Blocks: 0
	Device: 21 	Rdev: 0 	Inode: 20865 	Links: 9
	UID: 0 GID: 0
	Access: 2025-10-12 19:07:48.916 +0100 BST
	Modify: 2025-10-12 19:07:48.916 +0100 BST
	Change: 2025-10-12 19:07:48.916 +0100 BST


WARNING (ebpf): pid hidden?
	PID: 1204	PPid: 1204
	Inode: 946157	Uid: 0	Gid: 0
	Comm: "sleep"
	Path: ""

	PID confirmed via Stat: 1204, "sleep"

[i] Stat /proc/1204:
dr-xr-xr-x	0	2025-10-12T19:07:49+01:00	1204

	Size: 0 	Block size: 1024 	Blocks: 0
	Device: 21 	Rdev: 0 	Inode: 20872 	Links: 9
	UID: 0 GID: 0
	Access: 2025-10-12 19:07:49.828 +0100 BST
	Modify: 2025-10-12 19:07:49.828 +0100 BST
	Change: 2025-10-12 19:07:49.828 +0100 BST


[w] hidden processes found.


root@localhost:~#

Some notes regarding this output:

  • Some kernel rootkits just hide the enumeration of /proc/* (ls /proc/).
  • If you list the path (ls /proc/1204/) you can list the files and read them.
  • You can also use cd to confirm that the path exists.
  • Some kernel rootkits prevent all of this, but sometimes stat still works, so that's why the message "PID confirmed via Stat" appears.

This rootkit also hides itself from the system:

root@localhost:~# grep diamorphine /proc/modules
root@localhost:~#

See if we can reveal it:

root@localhost:~# /home/ga/decloaker scan hidden-lkms
decloaker v0.0, pid: 763715

[i] Checking kernel integrity
WARNING: kernel tainted
	(E) unsigned module loaded on a kernel that supports module signatures
	(O) externally-built ('out-of-tree') module was loaded


[i] Checking loaded kernel modules
tainted: d diamorphine/, OE

	WARNING: "diamorphine" kmod HIDDEN from /proc/modules

root@localhost:~# 

You can also use decloaker disk --dev=/dev/sda1 cp /path/to/hidden_file.txt hidden_file_backup.txt (only for ext4 filesystems).

Resources

About

A simple tool to uncover files, directories, and connections hidden by malware.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published