2

I'm trying to overwrite a .got entry using a string format exploit and I'm getting a SIGSEGV.

Here are some details on the binary:

ch24: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked,
interpreter /lib/ld-linux.so.2, for GNU/Linux
2.6.9, not stripped

RELRO           STACK CANARY      NX            PIE       RPATH      RUNPATH      FILE
Full RELRO      Canary found      NX enabled    No PIE    No RPATH   No RUNPATH   ch24

in gdb:

maintenance info sections
Exec file:
    `/media/sf_wargames/ch24', file type elf32-i386.
 [0]     0x8048154->0x8048167 at 0x00000154: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
 [1]     0x8048168->0x8048188 at 0x00000168: .note.ABI-tag ALLOC LOAD READONLY DATA HAS_CONTENTS
 [2]     0x8048188->0x80481c4 at 0x00000188: .hash ALLOC LOAD READONLY DATA HAS_CONTENTS
 [3]     0x80481c4->0x80481e4 at 0x000001c4: .gnu.hash ALLOC LOAD READONLY DATA HAS_CONTENTS
 [4]     0x80481e4->0x8048284 at 0x000001e4: .dynsym ALLOC LOAD READONLY DATA HAS_CONTENTS
 [5]     0x8048284->0x804830e at 0x00000284: .dynstr ALLOC LOAD READONLY DATA HAS_CONTENTS
 [6]     0x804830e->0x8048322 at 0x0000030e: .gnu.version ALLOC LOAD READONLY DATA HAS_CONTENTS
 [7]     0x8048324->0x8048364 at 0x00000324: .gnu.version_r ALLOC LOAD READONLY DATA HAS_CONTENTS
 [8]     0x8048364->0x804836c at 0x00000364: .rel.dyn ALLOC LOAD READONLY DATA HAS_CONTENTS
 [9]     0x804836c->0x80483ac at 0x0000036c: .rel.plt ALLOC LOAD READONLY DATA HAS_CONTENTS
 [10]     0x80483ac->0x80483c3 at 0x000003ac: .init ALLOC LOAD READONLY CODE HAS_CONTENTS
 [11]     0x80483c4->0x8048454 at 0x000003c4: .plt ALLOC LOAD READONLY CODE HAS_CONTENTS
 [12]     0x8048460->0x804876c at 0x00000460: .text ALLOC LOAD READONLY CODE HAS_CONTENTS
 [13]     0x804876c->0x8048788 at 0x0000076c: .fini ALLOC LOAD READONLY CODE HAS_CONTENTS
 [14]     0x8048788->0x80487a5 at 0x00000788: .rodata ALLOC LOAD READONLY DATA HAS_CONTENTS
 [15]     0x80487a8->0x80487ac at 0x000007a8: .eh_frame ALLOC LOAD READONLY DATA HAS_CONTENTS
 [16]     0x8049edc->0x8049ee4 at 0x00000edc: .ctors ALLOC LOAD DATA HAS_CONTENTS
 [17]     0x8049ee4->0x8049eec at 0x00000ee4: .dtors ALLOC LOAD DATA HAS_CONTENTS
 [18]     0x8049eec->0x8049ef0 at 0x00000eec: .jcr ALLOC LOAD DATA HAS_CONTENTS
 [19]     0x8049ef0->0x8049fd0 at 0x00000ef0: .dynamic ALLOC LOAD DATA HAS_CONTENTS
 [20]     0x8049fd0->0x804a000 at 0x00000fd0: .got ALLOC LOAD DATA HAS_CONTENTS
 [21]     0x804a000->0x804a008 at 0x00001000: .data ALLOC LOAD DATA HAS_CONTENTS
 [22]     0x804a008->0x804a010 at 0x00001008: .bss ALLOC
 [23]     0x0000->0x0033 at 0x00001008: .comment READONLY HAS_CONTENTS

This is where it fails:

EAX: 0x8049ffa --> 0xf7f0 
EBX: 0x1 
ECX: 0xf7fbd000 --> 0x1afdb0 
EDX: 0x7fb 
ESI: 0xffffbe00 --> 0xffffffff 
EDI: 0xf7fbdd60 --> 0xfbad2a84 
EBP: 0xffffc1b0 --> 0xffffcef0 --> 0x0 
ESP: 0xffffbc08 --> 0x0 
EIP: 0xf7e4e94a (mov    WORD PTR [eax],dx)
EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0xf7e4e93d:  movsx  eax,WORD PTR [ebx+eax*4]
   0xf7e4e941:  jmp    0xf7e4d2a2
   0xf7e4e946:  movzx  edx,WORD PTR [ebp+0x10]
=> 0xf7e4e94a:  mov    WORD PTR [eax],dx
   0xf7e4e94d:  jmp    0xf7e4cd55
   0xf7e4e952:  sub    esp,0x8
   0xf7e4e955:  mov    DWORD PTR [ebp-0x43c],ecx
   0xf7e4e95b:  push   0x20
[------------------------------------stack-------------------------------------]
0000| 0xffffbc08 --> 0x0 
0004| 0xffffbc0c --> 0x0 
0008| 0xffffbc10 --> 0x0 
0012| 0xffffbc14 --> 0x0 
0016| 0xffffbc18 --> 0x0 
0020| 0xffffbc1c --> 0x0 
0024| 0xffffbc20 --> 0xf7fe1eb9 (add    ebx,0x1b147)
0028| 0xffffbc24 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0xf7e4e94a in ?? () from /lib32/libc.so.6

EAX points to an address from the .got section - see [20]

I've written string format exploits before (for binaries with fewer security features enabled) and managed to override .got entries with no problem.

The maintenance info sections gdb command and objdump -h give info about the memory layout.

As long as an address range is not marked as READONLY, it should be writable, right? I'm a bit confused because I get the SIGSEGV even when I try to write something in the .dynamic section. Am I missing something?

Is there a protection mechanism that prevents me from doing this?

1 Answer 1

0

After doing some research I've learnt that RELRO will mark some sections(.init_array .fini_array .jcr .dynamic .got) as readonly. FULL RELRO will also mark the .got.plt section as readonly.

More info:

http://mudongliang.github.io/2016/07/11/relro-a-not-so-well-known-memory-corruption-mitigation-technique.html

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .