Web 开发的安全之旅(攻击篇)| 青训营笔记

183 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的的第5天

👋本文分享要点:攻击篇(XSS/CSRF/SQL 注入/SSRF/DoS/中间人攻击)

Web 安全比我们想象的常见的多
安全问题“很常见”,会危害

  • 用户·(用户的隐私)
  • 公司 (公司的利益)
  • 程序员(祭天)

攻击篇

跨站脚本攻击 Cross-Site Scripting(XSS)

在我们开发维护的页面中,攻击者通过注入恶意脚本到网站,用户访问页面时脚本执行进而攻击,这种就是XSS
后果就是用户隐私泄露或用户的机器被当成挖矿的机器

// 恶意脚本代码
<script>alert("xss");</script>

🤔XSS主要利用了什么呢?

Snipaste_2022-07-30_17-08-02.png

  • 作为开发者盲目信任用户的提交的内容
  • 作为前端工程师,直接将用户提交的字符串转化为DOM

XSS的一些特点

  • 通常难以从UI上感知(暗地执行脚本)
  • 窃取用户信息(cookie/token)
  • 绘制UI(例如弹窗),诱骗用户点击/填写表单

XSS demo

public async submit(ctx){
const{content,id}=ctx.request.body;
//没有对 content 过滤
await db.save({
  content,
  id
});
  
public async render(ctx){
  const{content}=await db.query({
  id:ctx.query.id
});
//没有对 content 过滤
ctx.body='<div>${content}</div>';
}

第一个接口(submit)读数据和第二个接口(render)写数据都没有对用户提交的内容进行过滤

😈那我们来攻击一下吧😈

//提交时候
fetch("/submit",{
  body:JsoN.stringify({
  id:"1",
  content:`<script>alert("xss");</script>`
  });
});
//服务器渲染的时候
ctx.body=`
  <div>
    <script>alert("xss");</script>
  </div>`;

服务器渲染这段内容的时候就会导致html中插入了一个script标签,攻击者便这样完成了一次XSS攻击

😁XSS按照性质可以分为几大类:存储型 Stored XSS、反射型 Reflected XSS、DOM型 Dom-based XSS、Mutation-based XSS

存储型 Stored XSS

Stored XSS的特点

  • 恶意脚本被存在数据库中
  • 访问页面→读数据=被攻击
  • 危害最大,对全部用户可见

假如有一个视频网站存在着XSS的漏洞,有人上传了一个视频,之中插入了一个XSS恶意脚本,用户看这个视频的时候,所有观看这个页面的用户都会被攻击到,被攻击到的用户隐私有可能被泄露,电商网站就可能会搜到用户视频网站的账户
Snipaste_2022-07-30_17-35-38.png

反射型 Reflected XSS

  • 不涉及数据库
  • 从URL上攻击

Snipaste_2022-07-30_17-45-21.png

//服务器端的代码
public async render(ctx){
  const { param }=ctx. query; 
  ctx. status=200; 
  ctx. body='<div>${ param}</div>';
}

DOM型 Dom-based XSS

  • 不需要服务器的参与
  • 恶意攻击的发起 + 执行,都是在浏览器完成的

Snipaste_2022-07-30_17-47-50.png

//在浏览器中
const content=new URL(location.href).searchParams.get"param");
const div=document.createElement"div");
//恶意脚本注入
div.innerHTML=content;
document.body.append(div);

🤔这样看起来 Reflected XSS 和 Dom-based XSS很类似啊,但还是有区别,在完成注入脚本的地方,反射型Reflected是在服务器进行注入,而基于Dom型的XSS是在浏览器端完成攻击

Mutation-based XSS

  • 利用了浏览器渲染DOM的特性(独特优化)
  • 不同浏览器,会有区别(按浏览器进行攻击)

Snipaste_2022-07-30_18-21-32.png
img标签的src属性出错,导致执行onerror里的内容,这里可以注册恶意脚本,进行攻击,攻击者非常懂浏览器是如何渲染的,也是很难防御的一种攻击

跨站伪造请求 Cross-site request forgery(CSRF)

CSRF的特点

  • 在用户不知情的前提下
  • 利用用户的权限(cookie)
  • 构造指定HTTP请求,窃取或修改用户敏感信息

😈我们来看一个具体的demo

Snipaste_2022-07-30_18-27-00.png


这就是一个非常典型的跨站伪造请求


而跨站伪造请求非常常见的就是GET请求方式,也非常容易构建

<a href="https://bank.com/transfer?to=hacker&amount=100">点我抽奖</a>
<!--确实中奖了-—>
<img style="display:none;"src="https://bank.com/transfer?to=hackersamount=100">



一点击a标签或图片一被加载就完成一次CSRF攻击

😈当然也不局限于GET请求攻击

843364e4-81e9-4104-9133-b761d0c5dfa7.png
这次攻击则是构造了一个表单,提交一个POST请求完成攻击

Injection注入

最常见的注入攻击呢,就是SQL 注入

SQL 注入

🤔什么是SQL 注入 SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。【选自百度百科】
Snipaste_2022-07-30_18-36-54.png

😈Injection注入 示例1:SQL 注入

//现在服务器有一个接口:renderForm
public async renderForm(ctx){
  const {username, form_id}=ctx. query; 
  const result=await sql. query(`
    SELECT a,b,c FROM table
    WHERE username=${username}
    AND form_id=${form_id}
`); 
  ctx. body=renderForm(result);
}
  1. 读取请求字段 2. 直接以字符串的形式拼接SQL 语句

而攻击者则可以这样做:

fetch("/api",{ 
  method:"POST", 
  headers:{
    "Content-Type":"applicaiton/json"
  }, 
  body: JSON. stringify({
  username:"any; DROP TABLE table;",
  })
})
//而username这段语句在服务器端会是这样的
SELECT XXX FROM XXX;	DROP TABLE table;

🙌恭喜你,完成了被动删库跑路的成就

Injection 不止于SQL

  • CLI
  • OS command
  • Server-Side Request Forgery(SSRF),服务端伪造请求
    • 严格而言,SSRF不是injection,但是原理类似

😈示例2:cli

一个视频转换的例子:假如我调用了一个convert-cli进行视频格式转换,接收用户传递的一些option参数(这里没有进行任何过滤)
Snipaste_2022-07-30_18-51-39.png


攻击者则可以这样做:


Snipaste_2022-07-30_18-57-34.png
服务器执行这样的命令后,会把若干文件进行删除

😈除了删除之外,读取+修改也是对服务器危害较大的一种行为

😈示例3:OS command

假如攻击者能修改我们的nginx的配置,那么他可以把网站的请求代理转发到另一个网站
Snipaste_2022-07-30_19-00-20.png

😈示例4:Server-Side Request Forgery(SSRF)


  1. 请求【用户自定义】的callback URL
  2. web server 通常有内网访问权限



Snipaste_2022-07-30_19-05-58.png

Denial of Service(DoS)

通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而雪崩效应。

👋在讲DoS之前先插播一条:正则表达式——贪婪模式



重复匹配时[ ?]vs[ no?] :满足“ 一个 ” 即可vs尽量多


Snipaste_2022-07-30_19-11-41.png

ReDoS 基于正则表达式的Dos

贪婪:n 次不⾏?n - 1 次再试试?——回溯
暴力回溯,会导致系统的响应时间边长,接口的吞吐量下降
Snipaste_2022-07-30_19-13-49.png

Distributed DoS DDoS 分布式DoS

短时间内,来⾃⼤量僵⼫设备的请求流量,服务器不能及时完成 全部请求,导致请求堆积,进⽽雪崩效应,⽆法响应新请求
😈**「不搞复杂的,量⼤就完事⼉了」**

DDoS 攻击的特点

  1. 直接访问IP
  2. 任意API
  3. 消耗大量带宽(耗尽)

😈看个例子:最常见的洪水攻击

Snipaste_2022-07-30_19-17-58.png

中间人攻击

基于传输层(在浏览器和服务器中间)的一种攻击

中间人攻击的前提

  1. 明文传输
  2. 信息篡改不可知
  3. 对方身份未验证

Snipaste_2022-07-30_19-20-11.png

总结

通过作为攻击者,我们了解了XSS/CSRF/SQL 注入/SSRF/DoS/中间人攻击 这些攻击方式,当然我们最好不要去攻击其他人的网站哦

Snipaste_2022-07-30_16-50-27.png