(1)注入原理
通过利用一些查询语句的漏洞,将sql语句传递到服务器解析并执行。它是一种注入攻击,可以执行恶意的sql语句。它通过将任意sql代码插入数据库查询,使攻击者能够完全控制web应用程序后面的数据库服务器。攻击者可以使用sql注入漏洞绕过应用程序的安全措施,可以绕过网页或web 应用程序的身份验证和授权,并检索整个sql数据库的内容,还可以使用sql注入来添加,修改和删除数据库中的记录。
(2)分类
1)联合查询
使用$_REQUEST直接接收id参数,且没有进行过滤,且可以接收cookie get post这些传递方法。当传入1 时,页面正常返回用户信息。
mysqli_query() 函数执行某个针对数据库的查询。
mysqli_query(connection,query,resultmode);
connection | 必需。规定要使用的 MySQL 连接。 |
query | 必需,规定查询字符串。 |
resultmode | 可选。一个常量。可以是下列值中的任意一个:
|
mysqli_fetch_assoc() 函数从结果集中取得一行作为关联数组。
该函数返回的字段名是区分大小写的。
mysqli_fetch_assoc(result);
result | 必需。规定由 mysqli_query()、mysqli_store_result() 或 mysqli_use_result() 返回的结果集标识符。 |
is_object() 函数用于检测变量是否是一个对象。
PHP 版本要求: PHP 4, PHP 5, PHP 7
bool is_object ( mixed $var )
- $var:要检测的变量。
- 返回值。如果指定变量为对象,则返回 TRUE,否则返回 FALSE。
2)布尔盲注
接收id的值,直接带入查询,如果存在即返回语句
mysqli_num_rows() 函数返回结果集中行的数量。mysqli_num_rows(result);
result | 必需。规定由 mysqli_query()、mysqli_store_result() 或 mysqli_use_result() 返回的结果集标识符。 |
返回值: | 返回结果集中行的数量。 |
---|---|
PHP 版本: | 5+ |
is_null() 函数用于检测变量是否为 NULL。
bool is_null ( mixed $var ) $var:要检测的变量。
如果指定变量为 NULL,则返回 TRUE,否则返回 FALSE。
3)报错注入
如果语法错误,mysqli_error()、mysql_connect_error()会将语法错误信息显示到页面上
mysqli_error() 函数返回最近调用函数的最后一个错误描述。mysqli_error(connection);
connection | 必需。规定要使用的 MySQL 连接。 |
mysqli_connect_error() 函数返回上一次连接错误的错误描述。mysqli_connect_error();
返回值: | 返回一个描述错误的字符串。如果没有错误发生则返回 NULL。 |
---|---|
PHP 版本: | 5+ |
4)时间注入
获取id带入数据库进行查询,是否存在记录页面返回一样。
mysql_fetch_array() 函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有
返回根据从结果集取得的行生成的数组,如果没有更多行则返回 false。
mysql_fetch_array(data,array_type)
data | 可选。规定要使用的数据指针。该数据指针是 mysql_query() 函数产生的结果。 |
array_type | 可选。规定返回哪种结果。可能的值:
|
5)堆叠注入
程序获取get参数的id,使用mysqli的方式进行数据查询,在执行语句时候使用mysqli_multi_query函数处理sql语句,导致存在堆叠注入
mysqli_connect_errno() 函数返回上一次连接错误的错误代码。mysqli_connect_errno();
返回值: | 返回错误代码值,如果没有错误发生则返回 0。 |
---|---|
PHP 版本: | 5+ |
mysqli_select_db() 函数用于更改连接的默认数据库。mysqli_select_db(connection,dbname);
connection | 必需。规定要使用的 MySQL 连接。 |
dbname | 必需,规定要使用的默认数据库。 |
mysqli_multi_query() 函数执行一个或多个针对数据库的查询。多个查询用分号进行分隔。
mysqli_multi_query(connection,query);
connection | 必需。规定要使用的 MySQL 连接。 |
query | 必需。规定一个或多个查询,用分号进行分隔。 |
6)二次注入
mysql_escape_string函数会将特殊字符进行过滤,如'经过转义成了\',然后用insert into存入数据库中
在login.php查看源码,登录获取用mysql_escape_string对输入的参数进行转义,转义后在数据库中找到指定的账号和密码,再传入session
mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。
下列字符受影响:
- \x00
- \n
- \r
- \
- '
- "
- \x1a
如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。
mysql_real_escape_string(string,connection)
string | 必需。规定要转义的字符串。 |
connection | 可选。规定 MySQL 连接。如果未规定,则使用上一个连接。 |
看pass_change.php源码,$_SESSION['username']复制给$username无过滤带入UPDATE语句中造成注入。整个流程时注册用户,更改密码时触发注入。二次注入隐蔽,通常发送在更改,需要二次带入数据时提交的功能里。
mysql_affected_rows() 函数返回前一次 MySQL 操作所影响的记录行数。
mysql_affected_rows(link_identifier)
link_identifier | 必需。MySQL 的连接标识符。如果没有指定,默认使用最后被 mysql_connect() 打开的连接。如果没有找到该连接,函数会尝试调用 mysql_connect() 建立连接并使用它。如果发生意外,没有找到连接或无法建立连接,系统发出 E_WARNING 级别的警告信息。 |
7)宽字节注入
首先check_addlashes是将特殊字符进行过滤,将'变成\'mysql_query设置数据库的编码为gbk,将id参数传入到sql中带入查询。传入%df%27即可逃逸gbk,故存在宽字节注入。
在每个双引号(")前添加反斜杠:
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符是:
- 单引号(')
- 双引号(")
- 反斜杠(\)
- NULL
提示:该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。
默认地,PHP 对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。所以您不应对已转义过的字符串使用 addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。
addslashes(string)
string | 必需。规定要转义的字符串。 |
8)cookie注入
判断是否提交submit,如果存在,$cookie=$_COOKIE['uname'];获取值保存到$cookie中,再拼接到sql带入查询,造成注入。