In our previous Hacker's Corner article, we covered some simple anti-debugging. Here, we will see some better techniques. . Self-Modifying Code Last time we tried to attach to own process, and used that as detection/prevention mechanism for debugging by someone else. Here, we will improve it by making it much harder to run code under debugger. This technique relies on using incorrect code, and patching it dynamically to make it correct. The patching part is done by same ptrace mechanism. Here, we have to ensure that our incorrect code should not kill the code. Instead we should be able to intercept the error, and then patch the code on the fly before re-attempting the execution. There are many ways to achieve this: 1. Raising a signal like SIGCONT 2. Forcibly triggering CPU fault (like illegal instruction fault) 3. Segmentation Fault 4. and many more... For sake of example, we will use an illegal syscall (that does not even exist) for our incorrect code. To ensure that we get a signal right before said code is called, we will raise SIGCONT, and capture that. The scheme goes something like this: Parent Process 1. Fork 2. Run protected function in child process 3. Wait for child process to change its status 4. Continue the process until it hits a syscall. 5. Check if syscall number matches to illegal syscall number used. 6. Change the syscall to correct one. 7. Let the process run. Go back to step 3. Child Process 1. Attach to self 2. Raise SIGCONT 3. Run the code which is using illegal syscall The syscall we are going to use is syscall number 10000, which is slightly modified version of **write** syscall: Original Syscall - Syscall number: 1 - RAX: 1 - RDI: File descriptor - RSI: Pointer to buffer - RDX: Number of bytes Our Syscall - Syscall number: 10000 - RAX: 10000 - RDI: Pointer to buffer - RSI: File descriptor - RDX: Number of bytes This means, patching the code is as simple as: 1. Put 1 in RAX 2. Swap RDI and RSI The complete code for this will looksomething like this: #include #include #include #include #include #include #include #define SYS_CUSTOM_write 10000 void print_custom(char *str) { syscall(SYS_CUSTOM_write, str, 1, strlen(str)); } void tracee() { ptrace(PTRACE_TRACEME, 0, 0, 0); raise(SIGCONT); std::cout
Thanks to Anand Jahagirdar for this feature! As the variety of attacks and threats grow, you need to be prepared. In this HOWTO, get a feeling for the Fork Bombing Attack, what it is, how it works, where it comes from, how to deal with it and more. . Fork Bombing: Eckie S. Fork bombing means invoking fork system call infinite times by one or more processes. It is also defined as Spawning nearly infinite processes by one or more user processes. E.g. Simple C Loop *: - while (1) fork (); It spawns infinite processes which in turn lead to fork bombing. Fork bombing attack is usually done by a non root user. For example, a non root user, as an attacker, sends infinite requests to the server for denial of service. Another example of fork bombing attack is a simple loop *: - main () {fork() main () ;} In this case main function calls itself recursively. This loop can make the system crawl. (* warning: - execute both the loop at your own risk). It . Fork bombing targets system resources by rapidly generating processes, causing severe performance issues and potentially crashing systems, disrupting user access. Fork Bombing, Denial of Service, Process Management. . Anthony Pell
Get the latest Linux and open source security news straight to your inbox.