Web

1. 签到题

题目描述:
签到题就在这里~

Image.png

填入队伍token,发现无法点击下面的按钮。F12查看源码,去掉disabled="disabled"然后再点击按钮,即可得到flag。

2. 信息安全 2077

题目描述:
2077 年很快到来了。此时正值祖国 128 周年华诞,中国科学技术大学也因其王牌专业信息安全,走出国门,成为了世界一流大学。作为向信息安全专业输送人才的重要渠道,第 64 届信息安全大赛也正在如火如荼地开展着。
千里之行,始于足下。作为一名渴望进入信息安全专业的学生,你的第一个任务是拿到第 64 届信息安全大赛的签到题的 flag。我们已经为你找到了签到题的入口,你只需要把 flag.txt 的内容读出来就可以了。
注:为了照顾到使用黑曜石浏览器的用户,第 64 届信息安全大赛的签到题决定沿袭之前 63 届信息安全大赛的惯例,仍然基于 HTTP 1.x。当然了,使用其他浏览器也是可以顺利完成任务的。

观察题目,发现是一个倒计时

Image2.png

倒计时结束的时候就能拿到flag。
抓取数据包,看到有一个特殊的header头

Image3.png

这个header头代表当前时间,将其改到很多年之后,就可以得到flag了。

3. 网页读取器

题目描述:
今年,刚刚学会网络编程的小 T 花了一点时间,写了一个非常简单的网站:输入一个 URL,返回对应的内容。
不过小 T 想对用户访问的站点进行一些限制,所以他决定自己来解析 URL,阻止不满足要求的请求。这样也顺便解决了 SSRF(Server-Side Request Forgery, 服务器端请求伪造)的问题。
想象很美好,但小 T 真的彻底解决了问题吗?

本题的灵感来源于 A New Era of SSRF - Exploiting URL Parser in Trending Programming Languages!。而这道题主要的点就是 URL 的 parser 和 requester 的不一致性导致的意料之外的 SSRF 问题。

关于 URI(统一资源标志符)

URL(统一资源定位符)是 URI 最常见的一种形式,而 URL 就是我们常说的「网址」。

根据 RFC3986 (Uniform Resource Identifier (URI): Generic Syntax) 第 3 节的描述,URI 的语法大概长成下面这个样子:

scheme:[//authority]path[?query][#fragment]

其中用 [] 围住的是可选的。然后我们来看一下各部分:

  • 协议 (scheme):访问资源使用的协议,比如说 http, https 之类的。
  • 来源 (authority):来源中包含了主机名,和可选的用户信息和端口号,比如 www.ustc.edu.cn, admin:admin@www.example.com:2333(使用用户名为 admin,密码为 admin,访问 www.example.com 的 2333 端口获取资源)。
  • 路径 (path):比如说 /cgi-bin, /a/b/c/d/e/f/g 等,有等级 (hierarchical) 关系。
  • 查询 (query):没有等级 (non-hierarchical) 关系的数据。一般来说,查询中的参数会被网站的后端获取到,然后进行对应的处理,比如 ?q=keyword?a=1&b=2
  • 片段 (fragment):指向一个更低级别的资源,例如 #Examples,浏览器访问时会滚动到 idExamples 的标签。如果写过单页面应用 (SPA) 的同学可能会知道,一些框架处理路由时使用 hash 模式,这里的 hash 就是片段开头的 #

我们围观一下小 T 自己造的 parser 轮子:

def check_hostname(url):
    for i in whitelist_scheme:
        if url.startswith(i):
            url = url[len(i):]  # strip scheme
            url = url[url.find("@") + 1:]  # strip userinfo
            if not url.find("/") == -1:
                url = url[:url.find("/")]  # strip parts after authority
            if not url.find(":") == -1:
                url = url[:url.find(":")]  # strip port
            if url not in whitelist_hostname:
                return (False, "hostname {} not in whitelist".format(url))
            return (True, "ok")
    return (False, "scheme not in whitelist, only {} allowed".format(whitelist_scheme))

看起来似乎没有什么问题:把协议丢掉,来源后面的东西丢掉,用户信息和端口号也丢掉,剩下来的不就是主机名吗?对大部分的 URL,这没有太大的问题。

但如果我们构造一个奇怪的 URL 会怎么样?如果我们能想办法让 check_hostname 解释出主机名为 example.com 的同时,让 requests.get() 实际访问我们想要的地址,那就成功了。

预期解就使用到了 fragment(当然用 ? 也是可以的)。现有的 requester 都会直接忽略掉 # 后面的东西,毕竟这对请求网站内容是没有意义的。但这里的代码没有对 # 进行任何处理,而且会粗暴地忽略掉 @ 前面的所有内容。

也就是说,可以构造出类似于下面的东西:

http://web1/flag#@example.com

输入进去,就拿到 flag 啦。

4. 达拉崩吧大冒险

题目描述:
某一天,C 同学做了一个神奇的梦。在梦中,他来到了蒙达鲁克硫斯伯古比奇巴勒城……

观察到 WebSocket 的 JavaScript 代码中,向服务器通信的代码如下:

    $("#send").click(
        function () {
            let v = $("#input option:selected").val();
            addMsg("我", opts[parseInt(v)]);
            ws.send(v)
        }
    );

直接将选择框的选项编号直接发送,可能会存在注入的可能。

在“料理大市场”买鸡的时候,当 v = -1900000000000000000 时候,则会发生大整数溢出,并使得自己的攻击力溢出,而后挑战恶龙即可。

最简单的做法是使用 Chrome 调试的功能,就可以完成拿到 flag 。首先在途中位置打断点。将 v 的值改为 -1900000000000000000。即可获得 flag。

5. 被泄漏的姜戈

题目描述:
「听说有离职的同学,把你们的代码和数据库泄漏了出去?好像还在什么 hub 还是 lab 来着建了一个叫 openlug……」
「没关系,反正 admin 用户的密码长度有 1024 位,我自己都忘了密码,就算老天爷来了,也看不到我们的 flag!」

  1. 社工,在github查到这个项目的源代码
  2. 本地搭建一个Django,添加一个可以让自己登录为admin的路由

app/views.py添加:

from django.contrib.auth.models import User
def backdoor(request):
    user = User.objects.get(username="admin")  # 使用 Django ORM 选择 admin 用户
    login(request, user) # 以 admin 的身份登录
    return redirect(reverse("profile")) # 跳转到 profile

app/urls.py里的urlpatterns里面添加URL:

path('backdoor', views.backdoor, name='backdoor')

然后开跑:

python manage.py runserver

访问我们加入的 backdoor,就可以看到 admin 的 cookie 了。把这个 cookie 复制,在 Console 里面 document.cookie=... 给 cookie 赋值,进入 /profile 就行了。

Last modification:January 2nd, 2020 at 09:46 pm
给肥宅一点零花钱买可乐叭 (゜-゜)つロ