Sections

The ELF Virus Writing HOWTO: sparc-debian2.2-linux
Prev |  | Next

# 6. Sections

| All trails have more uphill sections than they have downhill sections.
| Shedenhelm's Law

The standard describes section headers as optional for programs, but you can't build dynamically linked executables without them. Still worse, strip(1) performs a destructive operation on the section headers that will break infected executables if we don't maintain the section headers as well. Let's have another look at The language of evil.

## 6.1. objdump -h

Command: pre/sparc-debian2.2-linux/sections/objdump.sh

    #!/bin/bash
    cd tmp/sparc-debian2.2-linux/evil_magic
    /bin/ls -Ll att
    /usr/bin/objdump -h att

Output: out/sparc-debian2.2-linux/sections/objdump

    -rwxr-xr-x    1 alba     alba          444 Feb 15 23:55 att

    att:     file format elf32-sparc

    Sections:
    Idx Name          Size      VMA               LMA               File off  Algn
      0 .text         00000024  0000000000010074  0000000000010074  00000074  2**0
                      CONTENTS, ALLOC, LOAD, READONLY, CODE
      1 .data         00000000  0000000000020098  0000000000020098  00000098  2**0
                      CONTENTS, ALLOC, LOAD, DATA
      2 .sbss         00000000  0000000000020098  0000000000020098  00000098  2**0
                      CONTENTS
      3 .bss          00000000  0000000000020098  0000000000020098  00000098  2**0
                      ALLOC

`objdump`'s output for sections is outright disgusting. A real problem is the broken numbering due to ignored entries in the section table. The item on index 0 is actually of type `SHT_NULL`. Its index (`SHN_UNDEF` = 0) serves to mark an unused value of `sh_link`. Less troublesome is the ignored string table, a section of type `STRTAB`. And it does not help at all that the section type itself is not included in the output.

## 6.2. readelf

Command: pre/sparc-debian2.2-linux/sections/readelf.sh

    #!/bin/bash
    cd tmp/sparc-debian2.2-linux/evil_magic
    /bin/ls -Ll att
    /usr/bin/readelf -S att

Output: out/sparc-debian2.2-linux/sections/readelf

    -rwxr-xr-x    1 alba     alba          444 Feb 15 23:55 att
    There are 6 section headers, starting at offset 0xcc:

    Section Headers:
      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 0]                   NULL            00000000 000000 000000 00       0   0 0
      [ 1] .text             PROGBITS        00010074 000074 000024 00  AX   0   0 1
      [ 2] .data             PROGBITS        00020098 000098 000000 00  WA   0   0 1
      [ 3] .sbss             PROGBITS        00020098 000098 000000 00   W   0   0 1
      [ 4] .bss              NOBITS          00020098 000098 000000 00  WA   0   0 1
      [ 5] .shstrtab         STRTAB          00000000 000098 000032 00       0   0 1
    Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings)
                  I (info), L (link order), O (extra OS processing required)
                  o (os specific), p (processor specific) x (unknown)

The line starting with "There are 6 section headers" shows the value of `e_shnum` and `e_shoff`. Since Offset of e_entry we know that `sizeof(Elf32_Shdr)` is 40.

> First byte beyond the section header table:

> `e_shoff + e_shnum * sizeof_Shdr =`

> `0xcc + 0x6 * 0x28 =`

> `204 + 6 * 40 = 0x1bc = 444`

`ls` reported a file size of 444 bytes.

## 6.3. Observations

The start of section `.text`, `0x10074`, equals the entry point (compare with objdump -fp). This is nowhere specified in the standard. But further down it is demonstrated on `/bin/bash`. See Scan entry point for empirical prove.

The relation between file size and ELF header is more complicated. In most executables the section header table itself is the last region of the file. But there is a second kind where the section described by the last item of the section header table is the last region of the file. With `gcc` the type of this last section is always `SHT_STRTAB`. Some of Sun's native sparc executables have a section called `.comment` (type `SHT_PROGBITS`) there instead. See Scan file size for empirical prove.

## 6.4. Sections of /bin/bash

Let's zoom in on our target. [1].

Command: pre/sparc-debian2.2-linux/sections/sh/readelf.sh

    #!/bin/bash
    shell=$( /bin/sed 1q \
    	out/sparc-debian2.2-linux/scanner/segment_padding/infect )
    /bin/ls -Ll ${shell}
    /usr/bin/readelf -S ${shell}

Output: out/sparc-debian2.2-linux/sections/sh/readelf

    -rwxr-xr-x    1 root     root       512932 Jul 17  2002 /bin/bash
    There are 25 section headers, starting at offset 0x7cfbc:

    Section Headers:
      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 0]                   NULL            00000000 000000 000000 00       0   0 0
      [ 1] .interp           PROGBITS        000100f4 0000f4 000013 00   A   0   0 1
      [ 2] .note.ABI-tag     NOTE            00010108 000108 000020 00   A   0   0 4
      [ 3] .hash             HASH            00010128 000128 002738 04   A   4   0 4
      [ 4] .dynsym           DYNSYM          00012860 002860 005c50 10   A   5   1 4
      [ 5] .dynstr           STRTAB          000184b0 0084b0 005d95 00   A   0   0 1
      [ 6] .gnu.version      VERSYM          0001e246 00e246 000b8a 02   A   4   0 2
      [ 7] .gnu.version_r    VERNEED         0001edd0 00edd0 000060 00   A   5   2 4
      [ 8] .rela.bss         RELA            0001ee30 00ee30 000078 0c   A   4  15 4
      [ 9] .rela.plt         RELA            0001eea8 00eea8 0006cc 0c   A   4  12 4
      [10] .init             PROGBITS        0001f574 00f574 000024 00  AX   0   0 4
      [11] .text             PROGBITS        0001f598 00f598 055bbc 00  AX   0   0 4
      [12] .fini             PROGBITS        00075154 065154 000014 00  AX   0   0 4
      [13] .rodata           PROGBITS        00075168 065168 0105fb 00   A   0   0 8
      [14] .data             PROGBITS        00095768 075768 004ff0 00  WA   0   0 8
      [15] .eh_frame         PROGBITS        0009a758 07a758 000004 00  WA   0   0 8
      [16] .ctors            PROGBITS        0009a75c 07a75c 000008 00  WA   0   0 4
      [17] .dtors            PROGBITS        0009a764 07a764 000008 00  WA   0   0 4
      [18] .plt              PROGBITS        0009a76c 07a76c 000700 0c WAX   0   0 4
      [19] .got              PROGBITS        0009ae6c 07ae6c 000018 04  WA   0   0 4
      [20] .dynamic          DYNAMIC         0009ae84 07ae84 0000b0 08  WA   5   0 4
      [21] .bss              NOBITS          0009af38 07af38 0038a0 00  WA   0   0 8
      [22] .comment          PROGBITS        00000000 07af38 001637 00       0   0 1
      [23] .note             NOTE            0009e7d8 07c56f 000974 00       0   0 1
      [24] .shstrtab         STRTAB          00000000 07cee3 0000d6 00       0   0 1
    Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings)
                  I (info), L (link order), O (extra OS processing required)
                  o (os specific), p (processor specific) x (unknown)

> First byte beyond the section header table:

> `e_shoff + e_shnum * sizeof_Shdr =`

> `0x7cfbc + 0x25 * 0x28 =`

> `511932 + 37 * 40 = 0x7d584 = 513412`

`ls` reported a file size of 512932 bytes.

LSB [1] has a good overview of section names. [2] Anyway, a detailed look on section `.text` shows that its start address (0x1f598) equals the entry point (compare with Segments of /bin/bash).

### Notes

[1] | http://www.linuxbase.org/
[2] | http://www.linuxbase.org/spec/gLSB/gLSB/specialsections.html

Prev | Home | Next
Segments |  | Scanners