h3xduck / TripleCross

A Linux eBPF rootkit with a backdoor, C2, library injection, execution hijacking, persistence and stealth capabilities.
GNU General Public License v3.0
1.79k stars 221 forks source link

Library injection path error: Segfault simple_timer and simple_open #44

Open h3xduck opened 2 years ago

h3xduck commented 2 years ago

Illegal instruction (core dumped) - when I run./simple_timer. and a segmentation fault (core dumped) - when I run ./simple_open?

I have not been able to carry out a PoC due to the above errors.

Originally posted by @Ifex370 in https://github.com/h3xduck/TripleCross/issues/40#issuecomment-1187048475

h3xduck commented 2 years ago

@Ifex370 can you give me more information about the error? Please provide me with the following information:

  1. Does the segmentation fault happen when the rootkit is active, or just during the normal execution of a program?
  2. I need info about your Linux version. Please execute uname -a and lsb_release -a and paste the output.
Ifex370 commented 2 years ago

@Ifex370 can you give me more information about the error? Please provide me with the following information:

  1. Does the segmentation fault happen when the rootkit is active, or just during the normal execution of a program?
  2. I need info about your Linux version. Please execute uname -a and lsb_release -a and paste the output.

@h3xduck

1. Does the segmentation fault happen when the rootkit is active, or just during the normal execution of a program? Yes, it happens when the rootkit is active, and by active I mean when I ran the deployer.sh script.

After modifying the deployer.sh script. This is the image of me running it image

Then, on a different terminal. image

2. I need info about your Linux version. Please execute uname -a and lsb_release -a and paste the output. My linux version is the same as the one specified in your project write up. Except the Kernel version where mine is slightly higher. (5.13.0-52)

image

h3xduck commented 2 years ago

Alright so it seems that the GOT hijacking technique succeeds, but the shellcode faults while running before calling the malicious library. This can be because of multiple reasons.

Different glibc version

Firstly, you are using Ubuntu 21.10 (I tested 21.04) which may include a different glibc version. This may lead eBPF into detecting the GOT section wrongly. Please check your glibc version (ldd --version) and I can tell you more information about this.

Different library path

Secondly, the shellcode is generated dynamically but, since it is a PoC, it is prepared to work under a specific environment. In particular, the shellcode calls the malicious library /home/osboxes/TFG/src/helpers/injection_lib.so, meaning that since yours is under /home/ubuntu/Desktop/TripleCross/src/helpers/injection_lib.so, you will need to modify the shellcode yourself (or store the malicious library under the same path as I did). Please check page 214 of the thesis document. In there, you will find the following:

Captura de pantalla (102)

That shellcode there loads the path of the library (/home/osboxes/TFG/src/helpers/injection_lib.so) to the heap so that it is called later. What you will have to do is modify the bytes that are getting loaded so that it corresponds to your library:

Captura de pantalla (104)

You would then load the bytes into the heap just as I did, with mov instructions, taking endianness into account. Taking the bytes I showed you in the screenshot before, the first instructions in your case should be the same as mine: mov dword [rax], 0x6d6f682f mov dword [rax+0x4], 0x736f2f65 And so on.

Then, you need to get the x86_64 assembly opcodes corresponding to these instructions, which I wrote as comments in the screenshot of the document I shared. In order to do this you can use your favorite method, I personally used nasmshell. Remember to set the 64 bits mode: mov dword [rax], 0x6d6f682f --> 0xC7002F686F6D

Once you have all the opcodes you must include them into the rootkit. You can find the shellcode at src/common/constants.h:

Captura de pantalla (106)

The highlighted part corresponds to the assembly code where we load the path of the library into the heap. That is the one you should be modifying in the end. If your shellcode for loading the library path is larger than the original, you have to modify the constant CODE_CAVE_SHELLCODE_ASSEMBLE_2_LEN accordingly.

Ifex370 commented 2 years ago

Alright so it seems that the GOT hijacking technique succeeds, but the shellcode faults while running before calling the malicious library. This can be because of multiple reasons.

Different glibc version

Firstly, you are using Ubuntu 21.10 (I tested 21.04) which may include a different glibc version. This may lead eBPF into detecting the GOT section wrongly. Please check your glibc version (ldd --version) and I can tell you more information about this.

Different library path

Secondly, the shellcode is generated dynamically but, since it is a PoC, it is prepared to work under a specific environment. In particular, the shellcode calls the malicious library _/home/osboxes/TFG/src/helpers/injectionlib.so, meaning that since yours is under _/home/ubuntu/Desktop/TripleCross/src/helpers/injectionlib.so, you will need to modify the shellcode yourself (or store the malicious library under the same path as I did). Please check page 214 of the thesis document. In there, you will find the following:

Captura de pantalla (102)

That shellcode there loads the path of the library (_/home/osboxes/TFG/src/helpers/injectionlib.so) to the heap so that it is called later. What you will have to do is modify the bytes that are getting loaded so that it corresponds to your library:

Captura de pantalla (104)

You would then load the bytes into the heap just as I did, with mov instructions, taking endianness into account. Taking the bytes I showed you in the screenshot before, the first instructions in your case should be the same as mine: mov dword [rax], 0x6d6f682f mov dword [rax+0x4], 0x736f2f65 And so on.

Then, you need to get the x86_64 assembly opcodes corresponding to these instructions, which I wrote as comments in the screenshot of the document I shared. In order to do this you can use your favorite method, I personally used nasmshell. Remember to set the 64 bits mode: mov dword [rax], 0x6d6f682f --> 0xC7002F686F6D

Once you have all the opcodes you must include them into the rootkit. You can find the shellcode at src/common/constants.h:

Captura de pantalla (106)

The highlighted part corresponds to the assembly code where we load the path of the library into the heap. That is the one you should be modifying in the end. If your shellcode for loading the library path is larger than the original, you have to modify the constant CODE_CAVE_SHELLCODE_ASSEMBLE_2_LEN accordingly.

Different glibc version

Please check your glibc version (ldd --version) and I can tell you more information about this. image

Different library path

I'm sorry Assembly might not be my first, second even fifth language so you will find me struggling a bit. From the endian topics from university, I knwo how you got this

mov dword [rax], 0x6d6f682f

I'm not particularly sure as to how you arrived at this second shell code

mov dword [rax+0x4], 0x736f2f65

and also generating the opcodes using nasm wasn't so good as well. image

Bottomline is I will retry with the exact ubuntu version. I just want to see the exploit in action so I can can study the way the system responds to it, and that is where the work begins for me.

h3xduck commented 2 years ago

Different glibc version

Please check your glibc version (ldd --version) and I can tell you more information about this. image

Alright thanks, we used 2.33, which is fairly close, and by your output it seems that it is recognizing the GOT section, so it does not seem to be the problem here anyway. Still, for anyone reading this, if you seek to make the rootkit work with other glibc versions, you may have to check that the instruction opcodes at the glibc function to hijack are the same as in 2.33, or otherwise update them. You can see page 86 of the document how the function at glibc looks like:

Captura de pantalla (108)

If yours looks different, you may have to update the opcodes at function check_syscall_opcodes at src/ebpf/include/bpf/injection.h, which are used by the eBPF program to detect the function at glibc.

Different library path

I'm not particularly sure as to how you arrived at this second shell code

mov dword [rax+0x4], 0x736f2f65

Oops, sorry about that, you are right, it should have been mov dword [rax+0x4], 0x62752f65. You got it then!

and also generating the opcodes using nasm wasn't so good as well. image

That's why I mentioned the 64 bits mode, you can see that after setting it, it works:

Captura de pantalla (110)

Bottomline is I will retry with the exact ubuntu version. I just want to see the exploit in action so I can can study the way the system responds to it, and that is where the work begins for me.

Alright it may be faster, in case you just want a quick PoC, to use a Linux version with the following setup I wrote in the README:

DISTRIBUTION KERNEL GCC CLANG GLIBC
VERSION Ubuntu 21.04 5.11.0 10.3.0 12.0.0 2.33

If you download Ubuntu 21.04 instead of Ubuntu 21.10 it should come with those versions. Then, create an user called "osboxes", storing the malicious library under a directory called /home/osboxes/TFG/src/helpers/lib_injection.so. Essentially, download the rootkit and check the directory name to "TFG" rather than "TripleCross".

I know this is not the best, we created this PoC to showcase a specific functionality under a strict set of conditions (specific glibc, a specific path, etc), so the library injection module does not currently work under all conditions or out-of-the-box (such as the backdoor).

I can update the module to make the library injection work under any arbitrary path, since that truly seems unnecessarily restrictive. I will leave this issue open and close it once it works under any library path.