已经过了交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
签到
去公众号拿到图片,按照图片上弹琴就有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')
barcodes = pyzbar.decode(img)
for barcode in barcodes:
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:
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(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'''
<OPTION>
'''
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 <INPUT>: '):
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爆破
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
|