Skip to content

0x07. Inject Shared Libraries into Executables

liyansong2018 edited this page Apr 10, 2025 · 2 revisions

While a program is executing, utilizing system calls like ptrace enables you to attach to and debug the target process. Injecting code or dynamic link library (DLL/SO) files into a running process dynamically is typically straightforward. However, injecting DLL/SO into an inactive program(static ELF file) poses challenges. In a prior chapter, we covered static injection of parasitic code. In this section, we will delve into the injection of shared libraries into ELF files.

Case study

For binary crackme.bin, the flag will be printed only when the user enters the correct username and password

jerry@jerry-virtual-machine:~/elfspirit/examples/07_inject_so$ ./crackme.bin tom 123
Wrong password!

The username and password detection logic is implemented in check.so. The source code is as follows

int check_username(char* input) {
    if (strcmp(input, "tom"))
        return 0;
    else
        return 1;
}

int check_password(char* input) {
    if (strcmp(input, "654321"))
        return 0;
    else
        return 1;
}

We must now adjust the logic and update the check function. In practical scenarios, check.so typically contains intricate code, making direct replacement challenging. Leveraging static injection allows us to seamlessly substitute a small portion of the codebase.

  • Use the elfspirit editing module, statically inject a fake so
  • Use the elfspirit editing module, modify the external symbol called by ELF and call the so we just injected

Inject statically

The code of the parasitic code/shellcode/malicious so is as follows. This is mainly to re-implement the detection logic

int my_check_username(char* input) {
    return 1;
}

int my_check_password(char* input) {
    return 1;
}

Inject the target so file(my.so) into the target file. Before injecting, find a suitable location in the .dynamic section to load so

jerry@jerry-virtual-machine:~/elfspirit/examples/07_inject_so$ elfspirit parse -L crackme.bin
[+] Dynamic link information
[+] Dynamic section at offset 0x2d70 contains 33 entries
    [Nr] Tag          Type              Name/Value                    
    [ 0] 00000001   DT_NEEDED         Shared library: [check.so]    
    [ 1] 00000001   DT_NEEDED         Shared library: [libc.so.6]   
    [ 2] 0000001d   DT_RUNPATH        0xeb [./]                     
    [ 3] 0000000c   DT_INIT           0x1000                        
    [ 4] 0000000d   DT_FINI           0x1388                        
    [ 5] 00000019   DT_INIT_ARRAY     0x3d60                        
    [ 6] 0000001b   DT_INIT_ARRAYSZ   0x8                           
    [ 7] 0000001a   DT_FINI_ARRAY     0x3d68                        
    [ 8] 0000001c   DT_FINI_ARRAYSZ   0x8                           
    ...                 
    [25] 6fffffff   DT_VERNEEDNUM     0x1                           
    [26] 6ffffff0   DT_VERSYM         0x616                         
    [27] 6ffffff9   DT_RELACOUNT      0x3                           
    [28] 00000000   DT_NULL           0x0                           
    [29] 00000000   DT_NULL           0x0                           
    [30] 00000000   DT_NULL           0x0                           
    [31] 00000000   DT_NULL           0x0                           
    [32] 00000000   DT_NULL           0x0 

inject so

jerry@jerry-virtual-machine:~/elfspirit/examples/07_inject_so$ elfspirit edit -L -i28 -j0 -m1 crackme.bin
0->1
jerry@jerry-virtual-machine:~/elfspirit/examples/07_inject_so$ elfspirit edit -L -i28 -j2 -smy.so crackme.bin
->my.so
0x0->0xee
[*] dynamic strtab addr: 0x528, size: 0xee
[*] program header table is not at the end of the file
[*] move program header table
[*] move the phdr: 244
[*] get the phdr load index: [13]
[*] add a phdr
[*] add segment successfully: [14]
[*] set phdr
528->8f78
ee->f4
[*] set shdr
528->3f78
528->8f78
ee->f4

Check if the injection was successful

jerry@jerry-virtual-machine:~/elfspirit/examples/07_inject_so$ ldd crackme.bin
	linux-vdso.so.1 (0x00007ffee550d000)
	check.so => ./check.so (0x000076cb3f4b6000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000076cb3f200000)
	my.so => ./my.so (0x000076cb3f4a1000)
	/lib64/ld-linux-x86-64.so.2 (0x000076cb3f4c7000)

Replace symbol

After injecting so, we need to consider how to run our own so code. Here, we directly use symbol replacement to hijack the check functions.

Find the coordinates of check_password and check_username

jerry@jerry-virtual-machine:~/elfspirit/examples/07_inject_so$ elfspirit parse -D crackme.bin
 [+] .dynsym table
     [Nr]    Value Size Type     Bind     Vis       Ndx Name                
     [ 0] 00000000    0 NOTYPE   LOCAL    DEFAULT     0                     
     [ 1] 00000000    0 FUNC     GLOBAL   DEFAULT     0 decrypt             
     [ 2] 00000000    0 FUNC     GLOBAL   DEFAULT     0 __libc_st[...]      
     [ 3] 00000000    0 NOTYPE   WEAK     DEFAULT     0 _ITM_dere[...]      
     [ 4] 00000000    0 FUNC     GLOBAL   DEFAULT     0 puts                
     [ 5] 00000000    0 FUNC     GLOBAL   DEFAULT     0 __stack_c[...]      
     [ 6] 00000000    0 FUNC     GLOBAL   DEFAULT     0 printf              
     [ 7] 00000000    0 FUNC     GLOBAL   DEFAULT     0 getchar             
     [ 8] 00000000    0 NOTYPE   WEAK     DEFAULT     0 __gmon_start__      
     [ 9] 00000000    0 FUNC     GLOBAL   DEFAULT     0 check_password      
     [10] 00000000    0 FUNC     GLOBAL   DEFAULT     0 exit                
     [11] 00000000    0 FUNC     GLOBAL   DEFAULT     0 check_username      
     [12] 00000000    0 NOTYPE   WEAK     DEFAULT     0 _ITM_regi[...]      
     [13] 00000000    0 FUNC     WEAK     DEFAULT     0 __cxa_finalize

Directly replace the function

jerry@jerry-virtual-machine:~/elfspirit/examples/07_inject_so$ elfspirit edit -D -i9 -j6 -smy_check_password crackme.bin
check_password->my_check_password
jerry@jerry-virtual-machine:~/elfspirit/examples/07_inject_so$ elfspirit edit -D -i11 -j6 -smy_check_username crackme.bin
check_username->my_check_username

Result

The target program has successfully loaded our so.

截屏2025-01-14 19 26 41

At this time, if we run the target program, we will find that no matter what account name and password we enter, the flag will be printed.

jerry@jerry-virtual-machine:~/elfspirit/examples/07_inject_so$ ./crackme.bin 1 1
flag{You_Got_first_lucky_CHARM_of_2025}

Clone this wiki locally