# getdentsby kevin115 solves
Oh shit! Data have been stolen from my computer... I looked for malicious activity but found nothing suspicious. Could ya give me a hand and find the malware and how it's hiding?
[Memory image](https://storage.googleapis.com/insomnihack/media/memory_a97a5b9a792b61131eb6193e09c69616df875bb43539359af0e421b1b0798ba7.zip)
## AnalysisYou are presented with a `memory.vmem` and a `Ubuntu_4.15.0-72-generic_profile.zip` file.A .vmem file is a memory dump of VMWare Workstation. I heard the tool of choice is [volatility](https://www.volatilityfoundation.org/) and the "profile" archive was a good hint that we're supposed to use it too.
I've never used volatility before, so this might get a little bit verbose if you're familiar.
### Poking with `binwalk`A team member first got a really small ELF executable file out of the memory dump, which did some syscalls to connect to a local IP `192.168.180.131:1337`, read 126 bytes of shellcode from the socket and execute it? They used `binwalk` to find all ELF files, filter out all shared objects, so there were only a few executables left, and carved them out closely using `dd`.
So we're after some network payload hopefully still in memory somewhere?
### ReconInstall volatility first. It's thankfully packaged in most linux distributions.```bash$ sudo apt install volatility```
Then I had to figure out how to use that profile, since volatility only came with windows profiles in my case. `--plugins=.` in the folder with the profile.zip did the trick.```bash$ volatility --plugins=. --infoVolatility Foundation Volatility Framework 2.6
Profiles--------LinuxUbuntu_4_15_0-72-generic_profilex64 - A Profile for Linux Ubuntu_4.15.0-72-generic_profile x64VistaSP0x64                              - A Profile for Windows Vista SP0 x64VistaSP0x86                              - A Profile for Windows Vista SP0 x86...```
Following a [nice tutorial](https://medium.com/@zemelusa/first-steps-to-volatile-memory-analysis-dcbd4d2d56a1), I tried to get some output, just to realize that most of the used commands are Windows-only and you need to use the `linux_` prefixed plugins.
```bash$ volatility --plugins=. -f memory.vmem --profile=LinuxUbuntu_4_15_0-72-generic_profilex64 pslistVolatility Foundation Volatility Framework 2.6ERROR   : volatility.debug    : This command does not support the profile LinuxUbuntu_4_15_0-72-generic_profilex64$ volatility --plugins=. -f memory.vmem --profile=LinuxUbuntu_4_15_0-72-generic_profilex64 linux_pslistVolatility Foundation Volatility Framework 2.6Offset             Name                 Pid             PPid            Uid             Gid    DTB                Start Time------------------ -------------------- --------------- --------------- --------------- ------ ------------------ ----------...0xffff8a9db6dc0000 bash                 1733            1724            1000            1000   0x0000000014662000 2020-01-16 14:00:57 UTC+00000xffff8a9dcf5ec5c0 sudo                 1750            1733            0               0      0x000000005388a000 2020-01-16 14:01:22 UTC+00000xffff8a9dcf5edd00 meterpreter          1751            1750            0               0      0x0000000014540000 2020-01-16 14:01:22 UTC+0000...0xffff8a9dc3c40000 sh                   2964            1751            0               0      0x0000000076aec000 2020-01-16 14:02:57 UTC+0000```
I've stripped down the output of the process list to the processes that looked most interesting and possibly contain user input.
I tried a few random `linux_*` plugins to see if there is anything suspicious. volatility has a pretty good `--help` system for every command, so it was easy to use. `linux_lsmod` to list all loaded kernel modules didn't show anything unusual. `linux_ifconfig` showed that the IP we found earlier is actually the local IP of the machine:
```bash$ volatility --plugins=. -f memory.vmem --profile=LinuxUbuntu_4_15_0-72-generic_profilex64 linux_ifconfigVolatility Foundation Volatility Framework 2.6Interface        IP Address           MAC Address        Promiscous Mode---------------- -------------------- ------------------ ---------------lo               127.0.0.1            00:00:00:00:00:00  False          ens33            192.168.180.132      92:3d:f2:bb:2d:48  False          lo               127.0.0.1            00:00:00:00:00:00  False```
The bash history looked interesting too:```bash$ volatility --plugins=. -f memory.vmem --profile=LinuxUbuntu_4_15_0-72-generic_profilex64 linux_bashVolatility Foundation Volatility Framework 2.6Pid      Name                 Command Time                   Command-------- -------------------- ------------------------------ -------    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo apt upgrade    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo apt upgrade    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo apt update    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo apt update    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo reboot    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo reboot    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo apt upgrade    1733 bash                 2020-01-16 14:00:36 UTC+0000   rub    1733 bash                 2020-01-16 14:00:36 UTC+0000   uname -a    1733 bash                 2020-01-16 14:00:36 UTC+0000   AWAVH??    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo apt update    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo apt autoclean     1733 bash                 2020-01-16 14:00:36 UTC+0000   uname -a    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo apt upgrade    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo reboot    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo apt upgrade    1733 bash                 2020-01-16 14:00:36 UTC+0000   sudo reboot    1733 bash                 2020-01-16 14:00:41 UTC+0000   chmod +x meterpreter    1733 bash                 2020-01-16 14:00:42 UTC+0000   sudo ./meterpreter```
So all that happened was starting [meterpreter](https://www.metasploit.com/) as root. I tried to get a history of that other `sh` process using the same `linux_bash` plugin, but it looks like it really only supports `bash` processes. Go figure.
Lets dump the memory of those processes and see if there's anything:```bash$ volatility --plugins=. -f memory.vmem --profile=LinuxUbuntu_4_15_0-72-generic_profilex64 linux_procdump -D ./procdumps -p 1733,1751,2964$ strings procdumps/sh.2964.0x55f26b1a8000...insmod /home/julien/Downloads/rkit.ko hide=rJ/1g5PA5amy176A64akjuq/jryOug== hide_pid=1751...```
Now that's interesting. `rkit.ko` sounds like some rootkit kernel module. The `meterpreter` process has pid 1751, checking that binary from the dump turns out to be the same one we found using `binwalk` in the beginning. So the rootkit probably replaced the meterpreter binary in memory with that code?
Lets see if we can dump the rootkit.```bash$ volatility --plugins=. -f memory.vmem --profile=LinuxUbuntu_4_15_0-72-generic_profilex64 linux_enumerate_files     Inode Address Inode Number              Path------------------ ------------------------- ----...0xffff8a9dc38422e8                   2363716 /home/home/home/julien/Downloads               0x0 ------------------------- /home/home/home/julien/Downloads/.hidden0xffff8a9dd42755e8                   2359303 /home/home/home/julien/Downloads/rkit.ko0xffff8a9d948151a8                   2367790 /home/home/home/julien/Downloads/meterpreter...0xffff8a9db536da40                       890 /sys/module0xffff8a9df5ac0be0                     45233 /sys/module/rkit0xffff8a9df5ac5ca0                     45235 /sys/module/rkit/uevent...
$ volatility --plugins=. -f memory.vmem --profile=LinuxUbuntu_4_15_0-72-generic_profilex64 linux_find_file --inode=0xffff8a9dd42755e8 --outfile=./files/rkit.ko```
### Analysing the rootkitOpening the kernel module in the reverse engineering framework of choice reveals only a few functions.The basic outline of the functionality is as follows:
 - base64 decode the `hide` parameter and save a pointer to it in the global `ep` variable. - get some data from the network interface `ens33` and setup a key like `sk[i] = pk[i] ^ networkthing[i]`, while `pk` is a hardcoded string in the binary. - replace the `getdents` syscall handler with a custom function. That's probably where the challenge got its name from :) - the custom handler decrypts the global `ep` variable using `sk`, does something with the syscall arguments I guess, then encrypts `ep` again like `ep[i] ^= sk[i % len(sk)]`.
The key `sk` is only created once when the module is loaded and stays the same over the time of the program. We know the value of the `hide` parameter from the dump of the `sh` process above: `rJ/1g5PA5amy176A64akjuq/jryOug==`. So if we could dump the copy of the kernel module in memory we should be able to get that key `sk`!
The `linux_lsmod` plugin couldn't find the rootkit kernel module, lets try another one.
```bash$ volatility --plugins=. -f memory.vmem --profile=LinuxUbuntu_4_15_0-72-generic_profilex64 linux_check_modulesVolatility Foundation Volatility Framework 2.6    Module Address       Core Address       Init Address Module Name             ------------------ ------------------ ------------------ ------------------------0xffffffffc0943080 0xffffffffc0941000                0x0 rkit```
There you are. Dump it.```bash$ volatility --plugins=. -f memory.vmem --profile=LinuxUbuntu_4_15_0-72-generic_profilex64 linux_moddump --base=0xffffffffc0943080 --dump-dir=./moddump```
The command took half an hour on my laptop, but eventually spit out a `rkit.0xffffffffc0943080.lkm` file. This was the same kernel module, just with actual values (and absolute addresses) in the `.bss` section. From there we could extract the secret key `sk` and get the flag using xor, like the binary did.
```pythonimport base64param = base64.b64decode('rJ/1g5PA5amy176A64akjuq/jryOug==')key = bytes.fromhex('E5 D1 A6 F8 C1 F0 D5 DD  F9 E6 CA C6 DB F4 F6 E1 DA D4 E7 D9 FD C7 A5 FC  C8 C4 E4 DE E3 A2 F7 C5 FE A3 FF D0 C3 E0 AB C2  A7 D8 D7 E2 DF EB DC AA A1 A0 D3 CB A4 F1 FA C0  FB F5 D6 F3 EA E8 00 00')print(bytes(param[i] ^ key[i%len(key)] for i in range(len(param))))# b'INS{R00tK1tF0rRo0kies}'```