摘要:攻击实验攻击涉及用户受害者受信任的网站和恶意网站。攻击包括一系列步骤,如下受害者用户使用他她的用户名和密码登录到可信站点从而创建一个新的会话。浏览器将自动连接会话,因为它是恶意的要求针对可信站点。
CSRF攻击实验
CSRF攻击涉及用户受害者,受信任的网站和恶意网站。当受害者与受信任的站点拥有一个活跃的会话同时,如果访问恶意网站,恶意网站会注入一个HTTP请求到为受信任的站点,从而破话用户的信息。
CSRF 攻击总是涉及到三个角色:信赖的网站(Collabtive)、受害者的 session 或 cookie 以及一个恶意网站。受害者会同时访问恶意网站与受信任的站点会话的时候。攻击包括一系列步骤,如下:
受害者用户使用他/她的用户名和密码登录到可信站点,从而创建一个新的会话。
受信任站点存储受害者会话的 cookie 或 session 在受害者用户的 web 浏览器端。
受害者用户在不退出信任网站时就去访问恶意网站。
恶意网站的网页发送一个请求到受害者的受信任的站点用户的浏览器。
web 浏览器将自动连接会话 cookie,因为它是恶意的要求针对可信站点。
受信任的站点如果受到 CSRF 攻击,攻击者的一些恶意的请求会被攻击者发送给信任站点。
恶意网站可以建立HTTP GET或POST请求到受信任的站点。一些HTML标签,比如img iframe,框架,形式没有限制的URL,可以在他们的使用属性中。
环境搭建 服务器我使用的是koa框架作为后端框架搭建的服务器,顺便也算是学习一下koa框架,之前没有学过,由于是初学,搭建过程有点漫长
话不多说上代码:
// app.js const Koa = require("koa"); const app = new Koa(); const server = require("koa-static"); const router = require("koa-router")(); const PouchDB = require("pouchdb"); const db = new PouchDB("http://localhost:5984/csrf"); app.use(async (ctx, next) => { console.log(`Process ${ctx.request.method} ${ctx.request.url}...`); await next(); }); // add url-route: router.post("/login", async (ctx, next) => { let postData = await parsePostData( ctx ); try { let response = await db.get(`id_${postData.name}`); let exp = new Date(); ctx.cookies.set( "id", `id_${postData.name}`, { domain: "localhost", // 写cookie所在的域名 path: "/userInfo.html", // 写cookie所在的路径 maxAge: 24*60*60*1000, // cookie有效时长 expires: exp.setTime(exp.getTime() + 24*60*60*1000), // cookie失效时间 httpOnly: false, // 是否只用于http请求中获取 overwrite: false // 是否允许重写 } ) if(response.password === postData.password) ctx.redirect("userInfo.html") } catch (err) { ctx.body = "登录失败,点击这里返回
"; } }); router.post("/regist", async (ctx, next) => { let postData = await parsePostData( ctx ); postData._id = `id_${postData.name}`; try { let response = await db.put(postData); ctx.body = "注册成功,点击这里返回至登录界面
"; } catch (err) { ctx.body = "用户名已存在,点击这里返回
"; } }); router.post("/getUserInfo", async (ctx, next) => { let postData = await parsePostDataFromAjax( ctx ); let _id = {}; _id[postData.split(":")[0]] = postData.split(":")[1]; try { let doc = await db.get(_id.id); ctx.body = doc; } catch (err) { ctx.body = "发生错误"; } }); router.post("/change", async (ctx, next) => { let postData = await parsePostData( ctx ); console.log(postData); try { let doc = await db.get(postData.id); let response = await db.put({ _id: doc._id, _rev: doc._rev, name: postData.name, password: doc.password, sex: postData.sex, desc: postData.desc }); ctx.body = "修改成功,点击这里返回至登录界面
"; } catch (err) { console.log(err); } }); app.use(router.routes()); app.use(server(__dirname + "/")); app.listen(3001); /** * * 对于POST请求的处理,koa2没有封装获取参数的方法, * 需要通过解析上下文context中的原生node.js请求 * 对象req,将POST表单数据解析成query string(例 * 如:a=1&b=2&c=3),再将query string 解析成 * JSON格式(例如:{"a":"1", "b":"2", "c":"3"}) */ // 解析上下文里node原生请求的POST参数,这个是处理表单form传入参数 function parsePostData( ctx ) { return new Promise((resolve, reject) => { try { let postdata = ""; ctx.req.addListener("data", (data) => { postdata += data }) ctx.req.addListener("end",function(){ let parseData = parseQueryStr( postdata ) resolve( parseData ) }) } catch ( err ) { reject(err) } }) } // 解析上下文里node原生请求的POST参数,这个是处理Ajax传入参数 function parsePostDataFromAjax( ctx ) { return new Promise((resolve, reject) => { try { let postdata = ""; ctx.req.addListener("data", (data) => { postdata += data }) ctx.req.addListener("end",function(){ resolve( postdata ) }) } catch ( err ) { reject(err) } }) } // 将POST请求参数字符串解析成JSON function parseQueryStr( queryStr ) { let queryData = {} let queryStrList = queryStr.split("&"); for ( let [ index, queryStr ] of queryStrList.entries() ) { let itemList = queryStr.split("=") queryData[ itemList[0] ] = decodeURIComponent(itemList[1]) } return queryData }
就这一个文件,里面包含了很多东西
koa-static是koa的一个中间件,用于获取静态文件的
koa-router是koa的一个中间件,用于路由系统
pouchDB是我使用的couchDB的配套使用的框架
数据库我使用的是couchDB数据库,具体怎么使用看这里,用法很简单,他的界面是一个网页
前端页面前端页面总共有三个,分别是index.html,regist.html,userInfo.html,其作用分别是登录,注册,展示/修改用户信息,我这里没有使用css样式。。。有点丑
index.html注册 regist.html登录 登录
登录 userInfo.html注册 注册
这个页面我使用了ajax,所以引入了jQuery
用户信息 用户信息
姓名:性别:描述:修改信息
最后放上package.json
{ "name": "csrf", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "start": "node app.js" }, "author": "", "license": "ISC", "devDependencies": { "koa": "^2.2.0", "koa-router": "^7.2.1", "koa-static": "^3.0.0", "pouchdb": "^6.2.0" } }
命令行执行
npm install npm startCSRF攻击
终于到了关键,其实也就那么一刹那,很快我们的步骤如下:
首先我注册了一个账户,然后我登录这个账户查看信息,以及他的cookie参数,在图中我们发现cookie里面有一个重要信息是ID,这个就是当前用户的ID
接下来我通过浏览器开发者工具查看表单数据以及请求的url以方便我构造假请求
编写csrf_hack.html
攻击页面 这是一个攻击页面
``` 4. 然后在启动一个服务,将刚才编写的csrf_hack.html页面放进去,然后访问这个页面(这里我偷懒,直接把刚才的端口修改了一个,然后另开一个控制台启动服务,然后访问),接下来再次登录刚才的账号,发现刚才写在csrf_hack.html页面的信息更替上去了 注意事项 1. 如果要使用async,await这两个node版本需要在7以上
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/11258.html
摘要:浏览器对这种行为进行了限制。大多数情况下,该请求会失败,因为他要求的认证信息。在请求头中添加自定义例如在知乎中给文章点赞结合中对的的介绍,知乎的这种方式被称为。 概念 CSRF,Cross Site Request Forgery,跨站请求伪造。 为什么跨站的请求需要伪造? 因为浏览器实现了同源策略,这里可以将站和源视为同一个概念。 同源策略 The same-origin polic...
摘要:更新尝试了一下实现前后端分离,新的文章如下前后端分离之初试更新可另外用实现前后端分离,这篇文章可能局限性太大,只是个人的入门实践刚刚学习前端快一年,后台方面了解甚少,于是决定踩踩坑,学习一下。 2018.9.6更新:尝试了一下REST framework实现前后端分离,新的文章如下Django前后端分离之REST framework初试 2018.8.27更新:可另外用 restful...
阅读 1975·2021-11-24 09:38
阅读 3338·2021-11-22 12:07
阅读 1902·2021-09-22 16:03
阅读 1955·2021-09-02 15:41
阅读 2617·2021-07-24 23:28
阅读 2210·2019-08-29 13:17
阅读 1546·2019-08-29 12:25
阅读 2666·2019-08-29 11:10