Kali Linux Căn Bản – Bài 9: Giới thiệu lỗ hổng SQL Injection

Xin chào,

Trong bài hôm nay, chúng ta sẽ tìm hiểu sơ lược về chức năng của cơ sở dữ liệu trong hệ thống web application. Chúng ta cũng sẽ có cơ hội tiếp xúc với SQL, một ngôn ngữ dòng lệnh được sử dụng để tương tác với cơ sở dữ liệu SQL. Cuối cùng, chúng ta sẽ học sơ qua về cách lỗi SQL Injection xảy ra.


1 – Cơ sở dữ liệu trong hệ thống web application

Trước khi đi vào sâu hơn, chúng ta hãy thử tìm hiểu sự khác nhau của một website và web application nhé.

1a – Website vs web application

Website là một trang mạng có chứa một nội dung cụ thể nào đó. Nội dung đó có thể được thể hiện dưới dạng văn bản, video, âm nhạc, hình ảnh, v.v. Khi một người dùng bình thường truy cập vào một website, tất cả những gì họ có thể làm chỉ là đọc nội dung được trình bày trên website đó mà thôi.

Web application là một website nhưng được tích hợp nhiều tính năng hơn cho phép người dùng cuối ngoài việc được phép đọc nội dung được trình bày trên website ra, người dùng còn có thể tương tác với các nội dung ấy nữa. Ví dụ như:

  • Người dùng có thể đánh giá (rating) chất lượng bài viết.
  • Người dùng có thể comment suy nghĩ của mình về bài viết.
  • Người dùng có thể sử dụng tính năng chat được tích hợp vào website để liên hệ trực tiếp với ban quan trị website.
  • Người dùng có thể đăng ký một tài khoản trên website.
  • Người dùng có thể mua hàng trên website.
  • v.v

Có thể nói, phần lớn các trang mạng hiện nay là web applications.

  • Chúng ta có những web application cung cấp vô số tính năng đa dạng như các trang mạng xã hội như Facebook và You Tube, v.v.
  • Chúng ta cũng có những web application lớn nhưng chỉ phục vụ cho một mục đích nhất định như:
    • Mua sắm: Amazon, Tiki, v.v
    • Xem phim trực tuyến: Netflix, VieON, v.v
  • Chúng ta cũng có những web application nhỏ chỉ cung cấp vài tính năng. Ví dụ như web application của một nhà hàng có tích hợp Google Map giúp thực khách xác định đường đến nhà hàng và một tính năng đặt bàn online.

1b – Cơ sở dữ liệu (database)

Cơ sở dữ liệu là một thành phần quan trọng của một web application. Bạn có thể liên tưởng cơ sở dữ liệu giống như một ngăn tủ chứa tài liệu, nơi tài liệu được phân loại theo chủ đề, theo tháng, theo năm và theo tên người phụ trách. Để khi bạn cần tìm một tài liệu nào đó, bạn sẽ có thể biết ngay tài liệu đó ở trong tập hồ sơ nào; việc còn lại của bạn chỉ đơn giản là lấy tập hồ sơ đó và tìm tài liệu mà bạn cần.

Với cơ sở dữ liệu trên các hệ thống web application, thay vì lần mò để tìm dữ liệu mình cần, bạn chỉ cần vài câu lệnh là có thể truy xuất được ngay dữ liệu cần thiết với độ chính xác tuyệt đối và thời gian tìm dữ liệu chỉ tính bằng giây.

Cơ sở dữ liệu được sử dụng để lưu giữ một cách có hệ thống các thông tin quan trọng như:

  • Thông tin cá nhân khách hàng (username, password hash, số điện thoại, địa chỉ nhà, v.v.)
  • Thông tin sản phẩm đang bày bán (mã hàng, loại sản phẩm, nhà sản xuất, giá bán, v.v.)
  • Nội dung của các trang trên web application
  • Các bình luận, đánh giá về sản phẩm đang được bày bán
  • v.v

Nếu không có cơ sở dữ liệu để quản lý trong khi dữ liệu có quá nhiều, thông tin và nội dung của web application có khả năng sẽ được lưu trữ rải rác khắp nơi trong server hoặc dữ liệu được lưu trữ không có tổ chức và trình tự, dẫn đến việc truy xuất dữ liệu sẽ lâu và tốn kém tài nguyên hệ thống hơn; việc này sẽ dẫn đến giảm trải nghiệm người dùng, do người dùng phải chờ đợi lâu hơn để đăng nhập tài khoản hay tìm kiếm thông tin trên web application. Việc sử dụng cơ sở dữ liệu cũng sẽ giúp bảo vệ dữ liệu tốt hơn thông qua các hình thức mã hóa dữ liệu và hạn chế việc dữ liệu bị truy cập một cách trái phép.

Hai kiểu cơ sở dữ liệu phổ biến nhất đang được sử dụng hiện nay là SQL và noSQL. Vì bài viết hôm nay chúng ta sẽ tập trung vào SQL Injection nên mình sẽ chỉ đề cập đến kiến trúc SQL thôi nhé.

1c – SQL

SQL viết tắt của Structure Query Language. SQL là tên của một dạng cơ sở dữ liệu, nhưng đồng thời cũng là tên của một ngôn ngữ dòng lệnh dùng để tương tác với các cơ sở dữ liệu được xây dựng dựa trên SQL như: MySQL, PostgreSQL, v.v. Câu lệnh SQL cho phép chúng ta có thể tương tác với cơ sở dữ liệu một cách nhanh chóng và hiệu quả nhằm thực hiện các công việc như:

  • Tạo hoặc xóa dữ liệu
  • Truy xuất dữ liệu
  • Kiểm tra dữ liệu
  • Lấy dữ liệu
  • v.v

Khi nhắc đến SQL, ta sẽ nhắc đến kiểu lưu trữ dữ liệu relational database. Có nghĩa là các dữ liệu sẽ được lưu trữ một cách có hệ thống trong các bảng dữ liệu (giống như Excel vậy).

Để cho các bạn dễ hiểu, chúng ta sẽ có một bảng dữ liệu tên world (hình H1c-1). Bảng này chứa một số thông tin cơ bản của các quốc gia trên thế giới như:

  • Tên quốc gia (name)
  • Lục địa (continent)
  • Diện tích (area)
  • Dân số (population)
  • GDP
  • Thủ đô (capital)
  • Đuôi tên miền (tld – top level domain)
  • Cờ

Với mỗi hàng là thông tin của một quốc gia khác nhau.

H1c-1

Để có thể truy xuất dữ liệu từ bảng này, ví dụ bạn muốn tìm thông tin của Việt Nam, bạn sẽ có 2 cách thực hiện:

  1. Rà dọc theo bảng để tìm dữ liệu của Việt Nam
  2. Dùng câu lệnh SQL

Cách 1 sẽ tốn thời gian hơn nếu bảng dữ liệu có vài nghìn dòng dữ liệu. Cách 2 sẽ nhanh và hiệu quả hơn.

Một câu lệnh truy xuất dữ liệu SQL cơ bản nhất sẽ có cú pháp như sau:

SELECT <tên-cột-cần-tìm> FROM <tên-bảng-dữ-liệu>

Trong đó:

  • SELECT: Có nghĩa là chọn cột có chứa nội dung cần tiềm
  • FROM: Từ bảng dữ liệu có tên là …

Như vậy, căn cứ vào hình H1c-1, nếu chúng ta muốn xuất ra toàn bộ dữ liệu của cột name, câu lệnh của chúng ta sẽ như sau:

SELECT name FROM world

Câu lệnh trên có nghĩa là: Xuất toàn bộ dữ liệu lưu trong cột “name” của bảng dữ liệu “world”.

Chúng ta cùng thực hành luôn cho nóng nhé. Các bạn truy cập vào trang sau.

Sau khi truy cập, chúng ta sẽ được giao diện như hình bên dưới.

H1c-2

Ô màu trắng sẽ là nơi nhập dòng lệnh và ô màu xanh lá sẽ là nơi xuất kết quả. Sau khi nhập câu lệnh xong, các bạn cần bấm nút Submit SQL màu xanh dương để câu lệnh được chạy. Chúng ta sẽ cùng thực tập một vài ví dụ sau:

Ví dụ 1: Xuất ra toàn bộ dữ liệu lưu ở cột “name” trong bảng dữ liệu “world”

B1: Các bạn xóa câu lệnh hiện tại ở ô màu trắng đi. (Cứ bôi đen và bấm nút xóa “<” trên bàn phím là xong)

B2: Gõ câu lệnh sau

SELECT name FROM world

B3: Click nút Submit SQL

Chúng ta sẽ được kết quả bên ô màu xanh lá cây như sau:

H1c-3

Các dữ liệu trong cột name sẽ được liệt kê ra cho chúng ta như trong hình H1c-3

Lưu ý: Nếu các bạn kéo bảng dữ liệu được xuất ra (Result) xuống dưới cùng, bạn sẽ thấy dòng chữ sau:

Results truncated. Only the first 50 rows have been shown.

Có nghĩa là nếu chúng ta sử dụng các câu lệnh SQL để truy xuất dữ liệu, chúng ta sẽ chỉ xem được tối đa 50 dòng đầu tiên của kết quả xuất ra trong một lần mà thôi.

Có nghĩa là admin hệ thống của SQL Zoo chỉ cho phép xem tối đa 50 dòng dữ liệu 1 lần truy xuất. Vì cơ sở dữ liệu thường chứa khá nhiều thông tin quan trọng, việc giới hạn số dòng dữ liệu xuất ra cùng lúc sẽ giúp tránh dữ liệu bị rò rỉ không cần thiết.

Ví dụ 2: Xuất tất cả dữ liệu trong tất cả các cột của bảng world

Để xuất tất cả dữ liệu trong tất cả các cột trong 1 bảng dữ liệu, chúng ta sẽ dùng câu lệnh sau:

SELECT * FROM world

Trong đó “*” dùng để chỉ tất cả các cột trong bảng dữ liệu.

Sau khi click Submit SQL, chúng ta sẽ được kết quả như sau.

H1c-4

Và cũng như ví dụ 1, sẽ chỉ có 50 dòng đầu tiên trong kết quả xuất ra được hiển thị.

Ví dụ 3: In ra dữ liệu của Việt Nam

Để xuất ra toàn bộ dữ liệu của Việt Nam được lưu trong bảng dữ liệu world, chúng ta sẽ cần đến một mệnh đề tên là WHERE. Mệnh đề WHERE hoạt động như một điều kiện dùng để lọc dữ liệu và chỉ những dữ liệu thỏa mãn WHERE mới được xuất ra và hiển thị.

Trong trường hợp chúng ta muốn in ra dữ liệu của Việt Nam, câu lệnh của chúng ta sẽ như sau:

SELECT * FROM world WHERE name = 'Vietnam'

Câu lệnh trên có nghĩa là: Xuất ra toàn bộ dữ liệu được lưu trong các cột của bảng dữ liệu world với điều kiện giá trị ở cột name phải là ‘Vietnam’.

Sau khi click Submit SQL, chúng ta sẽ được kết quả sau:

H1c-5

3 ví dụ trên chỉ là một phần rất nhỏ để giúp cho các bạn phần nào hiểu được cú pháp của một câu lệnh SQL. Vì SQL là một mảng kiến thức lớn nhưng lại rất quan trọng nếu như bạn thật sự nghiêm túc muốn theo nghiệp Penetration Testing, nên mình khuyến khích các bạn nên tự học thêm tại trang sau.

2 – Giới thiệu lỗ hổng bảo mật SQL Injection

2a – Khái niệm SQL Injection

Lỗ hổng bảo mật SQL Injection là lỗ hổng được phát hiện trên các cơ sở dữ liệu SQL. Lỗ hổng này cho phép các hackers lợi dụng những tính năng cho phép người dùng cung cấp thông tin để hệ thống xử lý nhằm mục đích chèn vào một đoạn ký tự nhất định nhằm làm thay đổi cách thức câu lệnh SQL hoạt động theo hướng có lợi cho hackers.

Lợi dụng lỗ hổng SQL Injection, hackers có thể vượt qua được các bước xác thực người dùng và truy cập vào bất kỳ account nào mà họ muốn. Nghiêm trọng hơn, hackers có thể truy cập vào toàn thể dữ liệu đang được lưu trong cơ sở dữ liệu của hệ thống nạn nhân sau đó thay đổi, thêm bớt, bán dữ liệu cho các bên tội phạm khác, sử dụng thông tin có được cho các hình thức tân công xa hơn, hoặc chỉ đơn giản xóa toàn bộ cơ sở dữ liệu để khiến hệ thống không còn hoạt động chính xác nữa.

Hiểu một cách đơn giản nhất: SQL Injection là lỗ hổng bảo mật cho phép hackers toàn quyền truy cập và thay đổi cơ sở dữ liệu của hệ thống nạn nhân thông qua việc thay đổi câu lệnh SQL đang được hệ thống sử dụng.

2b – SQL và form đăng nhập account user

Một trong những nơi phổ biến nhất trên một web application hay bị hacker tấn SQL Injection đó là form đăng nhập account user.

H2.1

Cơ chế cơ bản đằng sau các form đăng nhập này như sau:

uName = getRequestString("username");
uPass = getRequestString("userpassword");

sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

Giải thích: Chúng ta sẽ có 2 variables (biến) được dùng để chứa username và password (hoặc password hash) của người dùng tên là uName và uPass. UName dùng để chứa username, và uPass dùng để chứa password (hoặc password hash).

Một câu lệnh SQL sẽ được dùng để lấy thông tin được lưu trong hai variables là uName và uPasss sau đó tiến hành tra cứu trong cơ sở dữ liệu. Câu lệnh này có 2 điều kiện:

  1. Kiểm tra xem username được cung cấp bởi người dùng có tồn tại trong hệ thống hay không?
  2. Nếu có, kiểm tra xem password (hoặc password hash) được cung cấp có khớp với dữ liệu đã được lưu trong hệ thống hay không

Khi kiểm tra các điều kiện trên, với mỗi một điều kiện được thỏa mãn, hệ thống sẽ trả lại giá trị 1 nhằm cho biết điều kiện đã thỏa mãn hay dữ liệu nhận được từ user là chính xác. Và giá trị 0 nếu một trong hai hoặc cả 2 thông tin được cung cấp không chính xác. Khi cả 2 điều kiện được thỏa mãn, chúng ta sẽ có:

1 AND 1 

Với operator AND, chúng ta sẽ có bảng giá trị như sau:

1 AND 1 = 1
1 AND 0 = 0
0 AND 1 = 0
0 AND 0 = 0

(1 = TRUE và 0 = FALSE)

Như vậy, khi cả 2 điều kiện đều đã được thỏa mãn, câu lệnh SQL sẽ trả về kết quả như sau:

1 AND 1 = 1

Nhằm xác nhận cho hệ thống biết đã xác thực thông tin người dùng thành công, và người dùng có quyền truy cập vào tài khoản mà họ đã cung cấp.

Nếu câu lệnh SQL trả về giá trị 0, người dùng sẽ không được phép đăng nhập vào tài khoản.

Giả dụ chúng ta có username được cung cấp là Vincent và pass là 123456, chúng ta sẽ có câu lệnh SQL như sau:

SELECT * FROM Users WHERE Name ="Vincent" AND Pass ="123456"

2c – Cơ chế của lỗi SQL Injection

Một khi đã hiểu được cơ chế hoạt động đằng sau form đăng nhập người dùng, hackers chỉ cần làm cách nào đó để khi thực thi câu lệnh SQL kết quả được trả về là giá trị 1. Để làm được điều đó, các hackers sẽ điền vào các ô trong form một trong những chuỗi ký tự sau:

105" OR "1=1

HOẶC

" OR ""="

Lưu ý: Có rất nhiều chuỗi ký tự khác nhau có thể được dùng để khai thác lỗi SQL Injection, nhưng trong bài đầu tiên này, mình sẽ chỉ giới thiệu 2 chuỗi thôi.

Vậy cụ thể điều gì sẽ xảy ra khi hackers điền những ký tự này vào trong form đăng nhập?

Để hiểu được, chúng ta hãy nhìn qua bảng giá trị của operator OR như sau:

1 OR 1 = 1
1 OR 0 = 1
0 OR 1 = 1
0 OR 0 = 0

(1 = TRUE và 0 = FALSE)

Như vậy, với việc tận dụng operator OR, hacker có thể “phù phép” để cho giá trị trả về khi kiểm tra điều kiện luôn là 1.

Cụ thể với chuỗi ký tự 105″ OR “1=1”, khi được thêm vào câu lệnh SQL, chúng ta sẽ được như sau:

SELECT * FROM Users WHERE Name =”105″ OR “1=1” AND Pass =”105″ OR “1=1”

Phân tích câu lệnh trên các bạn sẽ thấy:

Với điều kiện Name: 105 chắc chắc không phải là một username hợp lệ vì gần như không ai đặt tên username là 105 cả, nên chắc chắc nó sẽ trả về FALSE hay giá trị 0. Tuy nhiên, khi xét đến mệnh đề “1=1” ở bên phải của OR, chúng ta lại được kết quả trả về là TRUE hay giá trị 1 vì ký tự “1” luôn trùng với ký tự “1”.

Lưu ý: Bên trong hai dấu ” ” là ký tự, không phải chữ số.

Xét theo bảng giá trị của operator OR, chúng ta có:

O OR 1 =1

Vậy, kết quả trả về cho điều kiện Name sẽ là giá trị 1.

Điều tương tự cũng xảy ra với điều kiện Pass.

Như vậy cuối cùng, sau khi chạy câu lệnh SQL để kiểm tra username và password, chúng ta sẽ có được kết quả trả về là 1. Vì:

1 AND 1 = 1

Như vậy, hackers đã thành công có được quyền truy cập vào một account nào đó. Vì 105″ OR “1=1 không phải là account thật, nên sẽ có 3 trường hợp xảy ra:

  1. Hệ thống sẽ tự tạo một account có username là 105″ OR “1=1 và cho phép hacker truy cập vào account đó
  2. Hệ thống sẽ cho phép hacker được truy cập vào account mặc định của hệ thống (thường là account của admin)
  3. Ở viễn cảnh tồi tệ nhất, hệ thống có thể trả về toàn bộ dữ liệu được lưu trong cột username. Hacker có thể dùng những dữ liệu này để đăng nhập vào account của những người dùng khác

Với chuỗi ” OR “”=”, khi được thêm vào câu lệnh SQL sẽ như sau:

SELECT * FROM Users WHERE Name =”” OR “”=”” AND Pass =”” OR “”=”

Với mệnh đề bên trái của OR là “”, mang ý nghĩa là không có dữ liệu nên nó sẽ trả về giá trị 0. Còn mệnh đề bên phải của OR là “”=”” sẽ luôn trả về giá trị 1, vì ký tự ” luôn luôn trùng với ký tự “. Như vậy chúng ta sẽ được giá trị 1 trả về sau khi kiểm tra xong điều kiện Name.

Điều tương tự cũng xảy ra với điều kiện Pass.

Như vậy, sau khi chạy câu lệnh SQL, hacker sẽ được kết quả trả về1 và sẽ truy cập được vào một account người dùng nào đó hoặc có thể truy cập vào cơ sở dữ liệu của mục tiêu.


Chúc các bạn học tốt,

Vincent Nguyễn

Source:

https://www.w3schools.com/sql/sql_injection.asp

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s