Lissajous Pattern

https://tthtlc.github.io/lissajous_explore.html

And if you add a rotating circle pattern while travelling on the above Lissajous Figure, you get the following:

https://tthtlc.github.io/lissajous2_explore.html

Changing different values:

Next changes:

Proof of XXX in Blockchain technologies

The classic blog on the uselessness of Blockchain technology is this:

https://www.schneier.com/blog/archives/2022/06/on-the-dangers-of-cryptocurrencies-and-the-uselessness-of-blockchain.html

But given that there are 221k repo on github (https://github.com/search?q=blockchain&type=repositories) related to opensourced blockchain software, I think there must lots of demand arising from Blockchain technologies.

The following link is from ChatGPT, so verify it if it is true:

https://chatgpt.com/share/6712848f-9148-8013-8808-8273804db9d5

The following is the lecture notes from Cornell University:

https://www.cs.cornell.edu/courses/cs5412/2022fa/slides/Enrichment%20for%20blockchain%20material.pdf

Sinusoidal parametric equation

https://tthtlc.github.io/parametric_curve2_explore.html

x(t) = { return aaaa * Math.pow(Math.sin(-bbbb * t), 2) * Math.pow(2, Math.cos(Math.cos(4.28 * 2.3 * t))); }

y(t) = { return aaaa * Math.sin(Math.sin(-bbbb * t)) * Math.pow(Math.cos(4.28 * 2.3 * t), 2); }

where -cccc < t < +cccc

The result is this:

And this:

And this:

And this:

Non-blocking system calls in Linux

Not well known to many here are some non-blocking system calls:

  1. poll and select: Used for monitoring multiple file descriptors to see if I/O operations can be performed without blocking. They return immediately and indicate which file descriptors are ready.
  2. epoll (Linux-specific): Similar to poll and select, it monitors multiple file descriptors but is more efficient for a large number of descriptors. It can be configured in a non-blocking way.
  3. fcntl: Used to set a file descriptor to non-blocking mode by changing its properties with the O_NONBLOCK flag. After this, operations on the file descriptor, such as read or write, will be non-blocking.
  4. ioctl: Can configure various device files to operate in non-blocking mode, depending on the device’s support for non-blocking operations.
  5. read and write on non-blocking sockets or files: When a socket or file descriptor is set to non-blocking mode (using fcntl), read and write calls will not block. If the operation cannot be completed immediately, they return an error code (typically EAGAIN or EWOULDBLOCK).
  6. accept on non-blocking sockets: When listening on a non-blocking socket, accept will return immediately if no incoming connections are present, returning EAGAIN or EWOULDBLOCK.
  7. connect on non-blocking sockets: For non-blocking sockets, connect will return immediately with an error if the connection cannot be established instantly, and the operation will complete in the background.
  8. send and recv on non-blocking sockets: When called on non-blocking sockets, these will return immediately if the data cannot be sent or received, indicating the status with an error code like EAGAIN.
  9. Asynchronous I/O (AIO) system calls: Calls like aio_read, aio_write, etc., initiate I/O operations that return immediately, with the actual completion of the operations occurring asynchronously.

How to do process injection in Linux

Here I will discuss key concepts of "process injection".

Firstly, what motivates process injection.

First scenario, for the bad guys, assuming you have compromised a machine, so how to take control of any existing processes to do what you want? Eg, you want to erase or change the GUI display, or you want to change the variables of in a running application?

Or for the good guys, assuming you need to do performance analysis of any running process, how do you know what part of the process is suffering the highest performance bottleneck?

Process injection in Linux can be accomplished through a variety of methods in Linux.

1. ptrace-based Injection

ptrace is a system call in Linux primarily used for debugging, but it can be leveraged for process injection. ptrace can be used by a caller process (called "debugger process") to debug another callee process (called "debuggee process"). There are important considerations for using ptrace in a production or real world applications environment. This will be covered in another blog to explain in detail. The basic steps for injecting code into another process using ptrace are as follows:

Steps:

  1. Attach to the Target Process: Use ptrace(PTRACE_ATTACH) to attach to the target process, allowing the injector process to manipulate its memory and registers. It is important to remember that where the debuggee process has stopped execution is not within your control, as it is often random by nature. This will be elaborated in another blog.
    ptrace(PTRACE_ATTACH, pid, NULL, NULL);
    
    waitpid(pid, &status, 0); // Wait for the target to stop 
    
    
  2. Read Registers: Use ptrace(PTRACE_GETREGS) to get the CPU registers of the target process. This is important for saving the current state and redirecting execution to the injected code.
    struct user_regs_struct regs;
    
    ptrace(PTRACE_GETREGS, pid, NULL, &regs); 
    
    
  3. Allocate Memory in Target Process: To enable adding execution codes into memory, you’ll need to allocate memory for the payload. Unlike Windows, which have VirtualAllocEx() to allocate memory from a debugger into the debuggee memory space, Linux does not have this system call. It is therefore necessary – in the debuggee process context – to execute mmap() or mprotect() to allocate executable memory pages (malloc() cannot be used as the memory pages are not page-aligned). And since the memory pages need to be enabled for execution (normal memory allocation does not allow code execution of instructions in memory), you will need to use mprotect() to change the read/write/execute privilege of the memory. And as mprotect() work only with page-boundary allocated memory, please ensure that pages are allocated in pages. But now you will ask, since at step 1, the debuggee process is already in STOP mode, and process is not running, so how to enable it to execute these instructions as mentioned? This will be covered in another blog.
  4. Write Payload to Target Memory: Use ptrace(PTRACE_POKETEXT) or ptrace(PTRACE_POKEDATA) to write the payload (e.g., shellcode) into the allocated memory region of the debuggee process.
  5. for (size_t i = 0; i < payload_size; i += sizeof(long)) {
    
     long data = *((long *)(payload + i)); ptrace(PTRACE_POKETEXT, pid, remote_addr + i, data); } 
    
    
  6. Modify Instruction Pointer (RIP): Set the instruction pointer (RIP) to the address of the injected code, redirecting the execution to the new payload.
    regs.rip = remote_addr; // Set RIP to point to the injected code
    
    ptrace(PTRACE_SETREGS, pid, NULL, &regs); 
    
    
  7. Resume Execution: Finally, use ptrace(PTRACE_DETACH) to resume the target process, which now runs the injected code.
    ptrace(PTRACE_DETACH, pid, NULL, NULL);
    
    

2. Shared Library Injection (LD_PRELOAD)

In Linux, environment variables like LD_PRELOAD can be used to force a process to load a custom shared library (which contains malicious code) before any other libraries, effectively injecting code.

Steps:

  1. Create a Malicious Library: Write a shared object (.so file) that contains the payload or hooks into specific functions that you want to hijack in the target process.

    Example of overriding open():

    #include <stdio.h>
    
    #include <dlfcn.h> int open(const char *pathname, int flags) { printf("open() called for %s\n", pathname); int (*real_open)(const char *, int) = dlsym(RTLD_NEXT, "open"); return real_open(pathname, flags); } 
    
    
  2. Set the LD_PRELOAD Environment Variable: Use the LD_PRELOAD environment variable to load the shared library before the target process starts.
    LD_PRELOAD=/path/to/malicious.so ./target_process
    
    

This approach is easy to execute but is limited to injecting code into new processes rather than already running ones.

3. Process Hollowing (on Linux)

Why do you have "process hollowing" in the first place? One possible reason is to bypass Antivirus. When the process is first started, antivirus will intercept execution and ensure that the process is not a known malicious program. After it is allow to continue execution, process hollowing can proceed to change the content of the memory, perhaps replacing it with the malicious program. In Linux this can be achieved using ptrace and other system calls.

Steps:

  1. Fork a New Process: Start a new process and immediately stop it using ptrace or SIGSTOP.
  2. Replace Executable Code: Use system calls like execve() to overwrite the process’s memory with another binary or shellcode while maintaining the original process ID (PID). In this case, the caller of execve() will have the memory content replaced (understand how execve() vs fork() worked internally). So it is the debuggee that will have to call execve(). So like before, the debuggee process is already in STOP mode, you will need to design a way for it continue execution to call execve() to achieve this. (will be covered in another blog)
  3. Resume Execution: Resume the hollowed-out process with the newly injected code in its memory.

4. Using /proc/[pid]/mem

On Linux, the /proc file system provides access to memory and other resources of running processes. If you have sufficient permissions, you can directly modify the memory of a target process by writing to /proc/[pid]/mem.

Steps:

  1. Find the Target Process: Identify the target process by its PID.
  2. Open the Memory File: Open the memory file /proc/[pid]/mem for the target process with read and write permissions.
    int mem_fd = open("/proc/[pid]/mem", O_RDWR);
    
    
  3. Seek to the Injection Address: Use lseek to navigate to the appropriate address in the process memory where you want to inject the code.
    lseek(mem_fd, address, SEEK_SET);
    
    
  4. Write Payload: Write the payload directly to the memory at the specified address.
    write(mem_fd, payload, payload_size);
    
    
  5. Close the File: Close the /proc/[pid]/mem file to finalize the injection process.
    close(mem_fd);
    
    

5. Dynamic ELF Injection

Since Linux uses the ELF (Executable and Linkable Format), you can modify the running ELF binaries by manipulating the ELF header or adding sections. There are the relocation table, dynamic symbol table (.dynstr or .rel.dyn etc) and the global offset table (.got) and procedure linkage table (.plt) – all these are are involved in the dynamic linking process, or you can trigger it by programmatically calling dlopen() and then triggering the import/export symbol table resolution dynamically using dlsym(). For the purpose of self-education you can always write all these as a small shellcode and load it into the debuggee process for one-off execution. But in the real world application, a lot challenges exists. For example, the kernel control the pagetable allocation. More details on these will require further elaboration.

Steps:

  1. Parse the ELF File: Use tools like readelf or write custom code to parse the ELF headers and locate the injection point.
  2. Modify ELF Sections: Append new sections containing the malicious payload, ensuring the ELF format remains valid.
  3. Redirect Execution: Modify the ELF entry point or specific function pointers to redirect execution to the newly injected payload.

References:

https://docs.pwntools.com/en/stable/elf/elf.html

https://thenybble.de/posts/modifying-elf-dependency-versions/

https://github.com/NixOS/patchelf

https://linux-audit.com/elf-binaries-on-linux-understanding-and-analysis/

https://stackoverflow.com/questions/12645284/how-to-modify-an-elf-file-in-a-way-that-changes-data-length-of-parts-of-the-file

Global Shop SG - Global Commerce Store

Discover premium global products at GlobalShopSg.com, Singapore's trusted online store for quality automotive accessories, electronics, and home essentials with exceptional value.

Mathematically Generated Arts

Using mathematics to generate beautiful arts

mssv

Adrian Hon

Vickblöm

Research scattered with thoughts, ideas, and dreams

Penetration Testing Lab

Offensive Techniques & Methodologies

Astr0baby's not so random thoughts _____ rand() % 100;

@astr0baby on Twitter for fresh randomness

The Data Explorer

playing around with open data to learn some cool stuff about data analysis and the world

Conorsblog

Data | ML | NLP | Python | R

quyv

Just a thought

IFT6266 - H2017 Deep Learning

A Graduate Course Offered at Université de Montréal

Deep Learning IFT6266-H2017 UdeM

Philippe Paradis - My solutions to the image inpainting problem

Design a site like this with WordPress.com
Get started