春秋杯CTF2022 WP

春秋杯CTF2022 WP,第1张

已经过了交wp的时间了,这里就不再详细写了,写个大概吧

WEB Mercy-code

无参数RCE,参考bytectf boring code

https://blog.csdn.net/a3320315/article/details/102989485/

简单的说就是想办法构造 ‘.’ 然后拿到文件名,show_source就能拿到flag,这里我用的是数学函数

picture convert

flask的题,实际上是个命令注入,源码如下

import json
from flask import Flask
import hashlib
from flask import request,session
from flask import render_template
import os
import uuid

app = Flask(__name__)

app.config['SECRET_KEY'] = os.urandom(16)
Black_list = [b"metadata", b"$", b"qx", b'tmp', b'&#']



def check_data(data):
    for black_key in Black_list:
        if black_key in data:
            return True
    return False



def file_md5(s):
    return hashlib.md5(s.encode()).hexdigest()



@app.route('/', methods=['GET', 'POST'])
def index():
    return render_template("index.html")



@app.route('/upload', methods=['GET', 'POST'])
def upload():
    type = request.form.get("type", "jpg")
    print(type)
    file_info = request.files['file']
    file_data = file_info.read()
    if check_data(file_data):
        return "No hacker"
    f = open("./static/images/tmpimg", 'wb')
    f.write(file_data)
    f.close()
    new_filename = str(uuid.uuid4()) + '.' + type
    session["filename"] = new_filename
    print(session)
    return "文件上传成功,其他模块还在开发中~~~"



@app.route('/info', methods=['GET'])
def info():
    json_data = {"info": os.popen("su - exif -c '/app/exiftool-12.23/exiftool /app/static/images/tmpimg'").read()}
    return json.dumps(json_data)



@app.route('/convert', methods=['GET'])
def convert():
    os.system(f"su - conv -c 'cd /app/static/images/ && convert tmpimg {session['filename']}'")
    print(session["filename"])
    json_data = {"path": session['filename']}
    return json.dumps(json_data)



if __name__ == '__main__':
    app.run(debug=True)

可以看到原本可以就行exiftool的rce,但是被过滤了。
仔细观察可以发现

type = request.form.get("type", "jpg")

这里,type是我们可以控制的,最后作为 session[“filename”] 在convert路由中会拼接到os.system中执行,所以就造成了代码注入
首先我们需要upload一个文件,拿到恶意文件名的session值,然后拿着这个session值访问convert路由,即可造成命令注入

这里当时没有截图,数据包大概是这个样子的

拿到包含恶意文件名的session


访问convert触发


MISC 签到

去公众号拿到图片,按照图片上d琴就有flag

tiger

套娃题目,简单说下吧

1.png-key,rot47 :28a217fe

2.python lsb.py extract key.png-stego.png 1.txt 28a217fe

得到压缩包密码

71zr9H6jnXRHn64WBxMbCzz16saCZWiw

3.明文攻击,得到解压密码为

Nh6i@=

4.解压出来是个二维码,用python扫一下,得到一串0宽

import pyzbar.pyzbar as pyzbar
from PIL import Image

img = Image.open('flag.png')
# decode image
barcodes = pyzbar.decode(img)
# extract results
for barcode in barcodes:
    # render barcode and data to image
    f = open('1.txt', 'wb')
    f.write(barcode.data)
    f.close()
    print(barcode.data)


解码用这个

https://yuanfux.github.io/zero-width-web/

解出来

Ƀwl wvn n xhkm SBWav krttqbu gfq gja jhheu up yljycxjpu, vvtx R jzeh pydv usd zp lalhmk, ic brtkac ya whep{866q3755-t358-5119-txnr-juw666e8099m}, uroa okv!

5.维吉尼亚

https://www.guballa.de/vigenere-solver

Ƀou are a good CTFer because you can solve my challenge, next I will give you my secret, my secret is flag{866d3755-c358-5119-abeb-bda666a8099d}, have fun!

Capture Radiate Chart

有点小猜谜,仔细看题目发现首字母是crc,加上题目给的png分了那么多idat,肯定有问题,观察可以发现每个idat的crc合起来可以得到一个rar压缩包

from PIL import Image
def subStrIndex(substr,str):
    result = []
    index = 0
    while str.find(substr,index,len(str)) != -1:
        temIndex = str.find(substr,index,len(str))
        result.append(temIndex)
        index = temIndex + 1
    return result
f = open('alien.png', 'rb').read()
IDAT_index = subStrIndex(b'IDAT',f)
IDAT_len = []
for i in IDAT_index:
    IDAT_len.append(int.from_bytes(f[i-4:i],'big'))
CRC = []
for i in IDAT_index:
    # print(f[i-8:i-4].hex())
    CRC.append(f[i-5:i-4].hex())
CRC.append(f[f.index(b'IEND')-8:f.index(b'IEND')-4].hex())
CRC = CRC[1:]
# print(CRC)
print(bytes.fromhex(''.join(CRC)))
f = open('1.rar', 'wb')
f.write(bytes.fromhex(''.join(CRC)))
f.close()

压缩包解压出来是个pdf,但是无内容,仔细观察发现里面塞了张png的IDAT块,但是去了头尾,自己加回去就行,宽高pdf里也都有

补全头尾得到flag

PINTU

基础的拼图题,坐标在bmp的前面的冗余位里面,读取出来写个脚本拼就行

from PIL import Image
import os
import matplotlib.pyplot as plt
img = Image.new('RGB', (32*120, 18*120))
for i in range(14400):
    f = open(f'img/{i}.bmp', 'rb').read()
    x ,y = f[6],f[8]
    print(x, y)
    tmpimg = Image.open(f'img/{i}.bmp')
    img.paste(tmpimg, (x*32, y*18))
img.save('all.bmp')
plt.imshow(img)
plt.show()
被带走的机密文件

磁盘取证,如果有取证大师的话非常好做,可以直接发现有残留的打印机缓存文件,没有就麻烦一点,这里可以用ftk挂载后去做

ftk挂载后,进入这个目录Windows\System32\spool\PRINTERS\00004.SPL

这个是打印机的缓存文件,可以用下面这个软件打开

http://www.prnwatch.com/ok-printer-viewer/

打开后拿到flag

RecoverMe

首先给了一个文本文档,说给了vera加密的磁盘文件,同时也给了密码表,可以去爆破,这里我用的是passware,只能说passware真的好用,yyds!

拿到密码后用veracrypt挂载,发现两张没啥用的图片,所以用winhex试了下,发现流量包

导出后发现是icmp流量,每个包的长度都不一样,用tshark导出后转hex,发现是个压缩包

tshark.exe -r .\secret.pcapng -T fields -e data.len -Y icmp.resp_to > out.txt
f = open('out.txt').readlines()
for i in f:
    if i.strip() == '':
        print('00', end='')
    else:
        print(hex(int(i.strip()))[2:].zfill(2),end='')
s = bytes.fromhex('504b0304140001000000c99e7c54f14d019732000000260000000a0000007365637265742e747874ca074c3412d95fd1106721520cf2ce8a67b8f1412b394b2b82706bb2596cbed90bf669edb520eaf3e2f0b682616d0184c4a8504b01023f00140001000000c99e7c54f14d019732000000260000000a00240000000000000020000000000000007365637265742e7478740a0020000000000001001800ed4faa8d9a42d8012210ebaa9a42d80118ff50729a42d801504b050600000000010001005c0000005a00000015006970b5c4b1e4bbafcac7b9cad2e2b5c4c2f0a3bf00')
f1 = open('1.zip','wb')
f1.write(s)
f1.close()

拿到压缩包后发现有密码,但是注释给了提示,说看ip,返现ip在有38和39,拿出来转01就是密码

tshark.exe -r .\secret.pcapng -T fields -e ip.src -Y icmp.resp_to > out1.txt
f = open('out1.txt').readlines()
for i in f:
    if '38' in i.strip():
        print('0', end='')
    else:
        print('1', end='')
s = '011100000110000101110011011100110111011101101111011100100110010001101000001100110111001000110011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'
tmp = ''
for i in s:
    tmp += i
    if len(tmp) == 8:
        print(chr(int(tmp, 2)), end='')
        tmp = ''

解压后得到flag

CRYPTO Train

题目多半是出错了,通过第一步sha256校验后直接随便输入两个一样的字符串就能得到flag

源码

from Crypto.Util.number import*
from hashlib import sha256
import socketserver
import signal
import string
import random
from secret import flag
banner = br'''
 .oooooo..o                             oooo  oooo  ooooooooooooo                     o8o            
d8P'    `Y8                             `888  `888  8'   888   `8                     `"'            
Y88bo.      ooo. .oo.  .oo.    .oooo.    888   888       888      oooo d8b  .oooo.   oooo  ooo. .oo.   
 `"Y8888o.  `888P"Y88bP"Y88b  `P  )88b   888   888       888      `888""8P `P  )88b  `888  `888P"Y88b  
     `"Y88b  888   888   888   .oP"888   888   888       888       888      .oP"888   888   888   888  
oo     .d8P  888   888   888  d8(  888   888   888       888       888     d8(  888   888   888   888  
8""88888P'  o888o o888o o888o `Y888""8o o888o o888o     o888o     d888b    `Y888""8o o888o o888o o888o 
'''
n0 = 30798082519452208630254982405300548841337042015746308462162479889627080155514391987610153873334549377764946092629701
g = 64146569863628228208271069055817252751116365290967978172021890038925428672043
def TrainHash(msg):
    n = n0
    msg = map(ord,msg)
    for i in msg :
        n = g * (n+i)
        n = n & (1<<383)
    return n - 0xf5e33dabb114514
table = string.ascii_letters+string.digits
MENU = br'''

class Task(socketserver.BaseRequestHandler):
    def _recvall(self):
        BUFF_SIZE = 2048
        data = b''
        while True:
            part = self.request.recv(BUFF_SIZE)
            data += part
            if len(part) < BUFF_SIZE:
                break
        return data.strip()
    def send(self, msg, newline=True):
        try:
            if newline:
                msg += b'\n'
            self.request.sendall(msg)
        except:
            pass
    def recv(self, prompt=b'SERVER : '):
        self.send(prompt, newline=False)
        return self._recvall()
    def proof_of_work(self):
        proof = (''.join([random.choice(table)for _ in range(20)])).encode()
        sha = sha256(proof).hexdigest().encode()
        self.send(b"[+] sha256(XXXX+" + proof[4:] + b") == " + sha )
        XXXX = self.recv(prompt = b'[+] Plz Tell Me XXXX :')
        if len(XXXX) != 4 or sha256(XXXX + proof[4:]).hexdigest().encode() != sha:
            return False
        return sha.decode()
    def handle(self):
        signal.alarm(30)
        FirstBlockHash = self.proof_of_work()
        if not FirstBlockHash:
            self.request.close()
        self.send(banner)
        self.send(b"\nPlease give me 2 strings that are same when are hashed  =.=  ")
        string1 = self.recv().decode()
        string2 = self.recv().decode()
        if TrainHash(string1) == TrainHash(string2):
            self.send(b'\nJust do it!~ You can do more!')
            if string2.encode()[-50:] == string1.encode()[-50:]:
                self.send(flag)
        self.send(b"\nConnection has been closed  =.=  ")
        self.request.close()
class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass
class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
    pass
if __name__ == "__main__":
    HOST, PORT = '0.0.0.0', 10012
    print("HOST:POST " + HOST+":" + str(PORT))
    server = ForkedServer((HOST, PORT), Task)
    server.allow_reuse_address = True
    server.serve_forever()

sha256爆破

# 爆破sha256
import hashlib
def sha256(msg):
    m = hashlib.sha256()
    m.update(msg.encode('utf-8'))
    return m.hexdigest()
from string import ascii_letters,digits
d = ascii_letters + digits
for i in d:
    for j in d:
        for k in d:
            for l in d:
                res = i+j+k+l
                if sha256(res+'FcPzD2zaMLX8gwqF')=='639a9844067973c82a5b11cc432d9c18caf2316146a03b59b4787130fcaa41ed':
                    print(res)
                    break

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/874985.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存