前言:有一段时间没有更新博客了,正好遇到新生培训,和前几天整理的 IOT 一起上传博客。
总结一点 SQL 和抓包 的知识,也当作是复习了,已经大概半年没有碰这些东西了。
Pikachu 环境搭建
之前一直懒得搭建 pikachu,给新生培训也不想再重新拉了,直接起一个 docker 得了:
1 | docker pull area39/pikachu |

然后打开 docker 直接就能使用了:


为了讲课,还要拉取一下源码:这样子就大功告成了

题目讲解:
采取先写,之后去了解内部逻辑的方式:
先讲述一个万能密码:

1 |
|
写了两段 PHP 语句,先看第一段:
1 |
|
get 传参给到 id
数字型注入就是注入点的数据类型是数字型,没有用单引号或者双引号引起来,而是直接拼接到了后面,$id这个SQL语句的子句中,这样的注入就是典型的数字型注入。
判断数字型注入的方法如下:
- 输入单引号,不正常返回。
如果用户提交index.php?id=1',那么后面的 SQL 语句就变为 SELECT * FROM users WHERE id=1' LIMIT 0,1,SQL语句本身存在语法错误,会有不正常的结果返回。
- 输入
and 1=1,正常返回。
如果用户提交 index.php?id=1 and 1=1,那么后面的 SQL 语句就变为SELECT * FROM users WHERE id=1 and 1=1 LIMIT 0,1,会有正常的结果返回。
- 输入
and 1=2,不正常返回。
如果用户提交 index.php?id=1 and 1=2,那么后面的 SQL 语句就变为 SELECT * FROM users WHERE id=1 and 1=2 LIMIT 0,1,会有不正常的结果返回。
数字型注入的注入点主要通过上面3个语句来判断,如果输入的返回结果与上面相符,说明测试语句中的恶意SQL语句被带入数据库中并且成功执行,那么就可能存在数字型注入。具体有没有数字型注入,是否可以通过数字型注入获取有效信息,还需要大量的测试来验证。
字符型同理**' and '1'='1**
那么说到这里,基本上注入大概就知道是个什么东西了,我们接下来来看数据库:
MySQL 注入:
MySQL 使用最常用的 SQL 管理语言进行数据库管理
information_schema 数据库:
win+r 启动一下命令行:登录 sql 数据库:
1 | mysql -u root -p |

从 MySQL5 开始,MySQL 自带 information_schema 数据库。information_schema 数据库存储 SCHEMATA 表、TABLES 表和 COLUMNS 表,我们主要是要理解这三个表的用途:< 一些 SQL 语句自己去了解了解 >
先切换到 information_schema:
1 | USE information_schema; |

SCHEMATA:
SCHEMATA 表提供了当前 MySQL 实例中所有数据库的信息,show databases 命令的结果就取自其表:

查询 SCHEMATA 表存储所有的数据库名:可以看到和上面的图片内容是一致的:

TABLES:
TABLES 表提供了关于数据库中的表的信息,包括某个表属于哪个 schema
由于SELECT * FROM information_schema.TABLES 没有 WHERE 条件,这会导致 MySQL 去扫描所有数据库、所有表的元数据。在 MySQL 5.7 上,information_schema 的性能并不好,遇到数据库数量多或表数量庞大的情况,容易耗尽内存或超过资源限制,从而被服务器强制杀掉连接,因此我们去单个查找:
查找 mysql 库里的表:
1 | SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'mysql'; |

COLUMNS:
查 mysql 库里所有表的列名,用 information_schema.COLUMNS,条件里同时限定库名即可。
1 | SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'mysql'; |

简而言之:
1 | SCHEMATA 所有数据库的信息 |
有了初步的了解,我们就可以去打 pikachu 的靶场,上面的知识不要求立刻吸收,知道有主要的那三个表即可。
基本的查询语法:
1 | SELECT 列 |
从 mysql.user 表中找 user 和 host 列:
1 | SELECT user, host FROM mysql.user; |

加限制,只查找 root:
1 | SELECT user, host FROM mysql.user WHERE user = 'root'; |

排序 user 这一列按照升序排列:

降序加上 DESC:
1 | SELECT user, host FROM mysql.user ORDER BY user DESC; |

限制行数
1 | SELECT user, host FROM mysql.user ORDER BY user DESC LIMIT 1,2; |
1 | LIMIT 2 -- 从第 0 行开始,取 2 行(等价于 LIMIT 0,2) |

Union 联合查询:全部输出,
1 | SELECT user, host FROM mysql.user |

Pikachu:
sqli-数字型注入

随意查找一个 2,然后去抓包:


然后放到 repeater,发送看看渲染:

这里直接 and 1=1 发包看一看:发现没有报错

试一下 and 1=2 发包看一看,结果报错了,这里和我们上面讲述的数字型注入是一样的,证明是数字型注入

接下来我们可以使用 order by 来判断可以显示的列:

我们看到查询字段数为 2 的时候显示正常,为 3 就报错了,证明数据只有 2 列
接着我们利用 union 查询两列的内容

还可以去查数据库和数据库版本:
id=-2 union select database(),version()

到这里我感觉就差不多了,没必要继续往下查下去了,其实还有很多内容,但是感觉一下讲这么多没办法吸收
暂且到这里吧,有余力的可以看:https://blog.csdn.net/qq_65165505/article/details/131568188
说些什么吧!