<<< Previous |  |

# The entry point

| The longest part of the journey is said to be the passing of the gate.
| Marcus Terentius Varro

After emotions cooled down a bit we can examine the infected executable and compare it with the original.

Command.

    #!/bin/sh
    cd tmp/one_step_closer
    ls -l sh_infected
    readelf -l sh_infected

Output.

    -rwxrwxr-x    1 alba     alba       524060 Mar 14 19:19 sh_infected

    Elf file type is EXEC (Executable file)
    Entry point 0x80c1273
    There are 6 program headers, starting at offset 52

    Program Headers:
      Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
      PHDR           0x000034 0x08048034 0x08048034 0x000c0 0x000c0 R E 0x4
      INTERP         0x0000f4 0x080480f4 0x080480f4 0x00013 0x00013 R   0x1
          [Requesting program interpreter: /lib/ld-linux.so.2]
      LOAD           0x000000 0x08048000 0x08048000 0x7a273 0x7a273 R E 0x1000
      LOAD           0x07a280 0x080c2280 0x080c2280 0x057e0 0x09bd0 RW  0x1000
      DYNAMIC        0x07f980 0x080c7980 0x080c7980 0x000e0 0x000e0 RW  0x4
      NOTE           0x000108 0x08048108 0x08048108 0x00020 0x00020 R   0x4

     Section to Segment mapping:
      Segment Sections...
       00
       01     .interp
       02     .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.got .rel.bss .rel.plt .init .plt .text .fini .rodata
       03     .data .eh_frame .ctors .dtors .got .dynamic .bss
       04     .dynamic
       05     .note.ABI-tag

File size and code segment have grown as expected. Data segment and `DYNAMIC` segment moved accordingly:

> infected.file_size - sh.file_size = 524060 - 519964 = 4096 = 0x1000

> infected.`LOAD`[1].`Filesiz` - sh.`LOAD`[1].`Filesiz` = 0x7a273 - 0x79273 = 0x1000

> infected.`LOAD`[2].`Offset` - sh.`LOAD`[2].`Offset` = 0x7a280 - 0x79280 = 0x1000

> infected.`DYNAMIC`.`Offset` - sh.`DYNAMIC`.`Offset` = 0x7f980 - 0x7e980 = 0x1000

## First scan

Let's give the heuristic scanner a try.

Command.

    #!/bin/sh
    echo	'/bin/bash
    	tmp/one_step_closer/sh_infected' \
    | src/check_dist/check_dist.pl

Output.

    	tmp/one_step_closer/sh_infected virtaddr=0x80c2280 dist=0x00000d

    2 files; min_distance=0x00000d max_distance=0x00100d

As predicted. This is like playing chess against oneself, and losing. Can't do much about it, though. I'll fix something else in revenge.

## Second scan

The value of `Entry point` changed dramatically. In the original it is in the first part of the file:

> entry_point_ofs = 0x8059380 - 0x8048000 = 0x11380 = 70528 bytes.

The infected copy moved that to exactly 4096 bytes from the end of the code segment.

> entry_point_ofs = 0x80c1273 - 0x8048000 = 0x79273 = 496243 bytes.

> end_of_LOAD1 = 0x8048000 + 0x7a273 = 0x80c2273

> entry_point_distance_to_end = 0x80c2273 - 0x80c1273 = 0x1000 = 4096

This is another easy vulnerability to scanners. By restructuring our code we can make that number even smaller. But for a real cure we need stronger voodoo.

## Patch me if you can

If we chose to leave `entry_point` as it is, we have to patch something else. One approach is to disassemble the code, starting at `entry_point`, find the first `call` (or `jmp`) and abuse it. This requires way too much intelligence for a virus, though.

But then we are operating in a homogeneous environment, having one compiler and one C run-time library for all. The startup code should be the same for every executable.

Command.

    #!/bin/sh
    entry_point=$( readelf -l /bin/bash | sed -ne 's/^Entry point //p' )
    gdb /bin/bash -q <<EOT | sed -ne '/:$/,/hlt *$/p'
    	break *$entry_point
    	run
    	disassemble
    EOT

Output.

    (gdb) Dump of assembler code for function _start:
    0x8059380 <_start>:	xor    %ebp,%ebp
    0x8059382 <_start+2>:	pop    %esi
    0x8059383 <_start+3>:	mov    %esp,%ecx
    0x8059385 <_start+5>:	and    $0xfffffff0,%esp
    0x8059388 <_start+8>:	push   %eax
    0x8059389 <_start+9>:	push   %esp
    0x805938a <_start+10>:	push   %edx
    0x805938b <_start+11>:	push   $0x80ad030
    0x8059390 <_start+16>:	push   $0x8058a60
    0x8059395 <_start+21>:	push   %ecx
    0x8059396 <_start+22>:	push   %esi
    0x8059397 <_start+23>:	push   $0x8059480
    0x805939c <_start+28>:	call   0x8058fc8 <__libc_start_main>
    0x80593a1 <_start+33>:	hlt

<<< Previous | Home |
One step closer to the edge |  |