浙江省省赛2023决赛复现

还是太菜了,队友抬到二等奖,本来队友目标是一等的,呜呜,又拖后腿了,看到好多不会的,还得加油

Re

ida_pro

有壳,但是不能直接脱壳,看了一下发现是被modified

又发现EP节被改了,那就改回来,把O改成U,然后再去脱壳

看伪c,flag由4部分组成

第一部分shift+f12

第二部分看函数名

第三部分是Xref,一开始断网没想起来,后来才想到是交叉引用

比赛的时候看汇编看着看着就出了,其实是找第一个字串

交叉引用过去

数字转ascii

连起来,注意一二两部分看似有两根下划线,实际上只有一根,两根也不符合常理

Ez8or-1

有反调试

可以jnz改jmp强制跳转,也可以运行完cmp之后修改ZF的值,最终绕过反调试

这题因为比较的长度是输入的长度,并不是固定的60,所以可以采用爆破的形式,且是elf,用pwn的方式爆破更快

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
from pwn import *
context.update(os = 'linux',arch = 'amd64')
context.log_level = 'debug'
filename = './Ez8or'


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()

s1='DASCTF{'
ch="1234567890qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM!@#$^+=%&*()_-}~/."
for i in range(53):
for j in range(len(ch)):
payload=s1+ch[j]
io = process(filename)
ru("[?] Plz input the flag:")
sl(payload)
ru('\n')
s2=r()
if b'incorrect' in s2:
io.close()
continue
else:
s1+=ch[j]
print(s1)
io.close()
break
#inter()

鸡哥直接逆向的,主要是我比赛写的脚本一直出不了,用python还是有点小trick

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
a=[0xA8, 0xAC, 0x36, 0x6A, 0xC4, 0x0A, 0x9A, 0xDC, 0x12, 0x48,
0xF2, 0x60, 0xCB, 0xCC, 0x3A, 0x5E, 0xF2, 0x63, 0x9C, 0x94,
0xF5, 0x48, 0xCD, 0x17, 0x82, 0xCD, 0xF7, 0x71, 0x9F, 0x36,
0xB4, 0x88, 0xAF, 0x5F, 0xDD, 0x64, 0x85, 0x96, 0xF7, 0x5E,
0xC4, 0x09, 0xAD, 0xDD, 0xAB, 0x16, 0x99, 0x60, 0x9B, 0xDE,
0xF5, 0x53, 0xC3, 0x21, 0xFC, 0x80, 0xF8, 0x10, 0xC7, 0x26]
print(len(a))
b23=0x2b
b22=0x8e
b21=0x7d
b24=0x31
b25=0x9c
b20=0x4f
for i in range(0,60,6):
v8=i-57+256#c负数可以强制类型转换,但是py直接-57得到的是-0x39,需要加256
for j in range(i,i+6,1):
v8=v8>>(j%3)

a[j]^=v8

a[i]^=b23
b23+=1

a[i+1]^=b22
b22+=1

a[i+2]^=b21
b21+=1

a[i+3]^=b24
b24+=1

a[i+4]^=b25
b25+=1

a[i+5]^=b20
b20+=1
flag=''
for i in range(60):
flag+=chr(a[i])
print(flag)

后面研究了一下写c反而不容易出错

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
#include<stdio.h>
int main(){
unsigned __int8 v8;
char a[]={0xA8, 0xAC, 0x36, 0x6A, 0xC4, 0x0A, 0x9A, 0xDC, 0x12, 0x48,
0xF2, 0x60, 0xCB, 0xCC, 0x3A, 0x5E, 0xF2, 0x63, 0x9C, 0x94,
0xF5, 0x48, 0xCD, 0x17, 0x82, 0xCD, 0xF7, 0x71, 0x9F, 0x36,
0xB4, 0x88, 0xAF, 0x5F, 0xDD, 0x64, 0x85, 0x96, 0xF7, 0x5E,
0xC4, 0x09, 0xAD, 0xDD, 0xAB, 0x16, 0x99, 0x60, 0x9B, 0xDE,
0xF5, 0x53, 0xC3, 0x21, 0xFC, 0x80, 0xF8, 0x10, 0xC7, 0x26};
int b23=0x2b;
int b22=0x8e;
int b21=0x7d;
int b24=0x31;
int b25=0x9c;
int b20=0x4f;
for(int i=0;i<60;i+=6){
v8=i-57;
for(int j=i;j<i+6;++j){
v8=(int)v8>>(j%3);
a[j]^=v8;
}
a[i]^=b23++;
a[i+1]^=b22++;
a[i+2]^=b21++;
a[i+3]^=b24++;
a[i+4]^=b25++;
a[i+5]^=b20++;
}
for(int i=0;i<60;i++){
printf("%c",a[i]);
}
return 0;
}

apk_re-1

tea魔改

解完发现不对,找了一下发现还有初始化操作(感谢yuro✌提醒)

前面一部分相当于特征码搜索,找到i+31的地方改为75

大概率是在tea算法中有修改

原来的0b改为4b,从add变成sub,那大概率就对了

这题恶心的点在于输入的高位赋给v9,v9=v7,v7最后是密文的低位

还有解密的时候在写第几行千万要看仔细,我的经验是写哪行选中哪行

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
#include <stdio.h>
#include <stdint.h>

int main() {
uint32_t v[2] = {1, 2};
uint32_t v0 = v[0], v1 = v[1]; /* set up */
uint32_t delta = 0x69C36EC5;
uint32_t sum=0;
uint32_t v5[10] = {0xf9540b5c,0x4bcb6502,0x68542963,0x47431049,0xefd6a62c,0xd200c2c2,0x7e9a1b88,0x3d98999c,0xe9fbde0d,0xf17cca00};

unsigned int k[4] = {850486483,132849155,881013232,1124630387}, l = 0, r = 0;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
for (int m = 0; m < 10; m += 2) {//flag不全的话有可能是10
sum = 28*delta;
uint32_t v9=v5[m];
uint32_t v6=v5[m+1];
for (int i = 0; i <=27; i++) {
sum -= delta; /* basic cycle start */
v9 -= ((v6 << 5) + 0x348331F0) ^ (v6 + sum+delta) ^ ((v6 >> 4) - 0x43087F73);
v6 -= ((v9 << 3) + 0x32B164D3) ^ (v9 + sum+delta) ^ ((v9 >> 6) + 0x7EB1E03);
v5[m]=v6;
v5[m+1]=v9;
} /* end cycle */
}

for (int i = 0; i < 10; i++) {
for (int m = 0; m <= 3; m++) {
printf("%c", (v5[i] >> (8 * m)) & 0xff);
}
}

return 0;
}
//DASCTF{1w0,W@NDr01DRe4v3rsE|S150-EA=1sy}

Crypto

RSA-1

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
from Crypto.Util.number import *
#from flag import flag
import random
from libnum import n2s

#assert size(m)<360

while True:
p = getPrime(512)
q = getPrime(512)
r = getPrime(512)
s = getPrime(512)
t = getPrime(512)
real_p = p * q * r * s * t
real_q = p + q + r + s + t
if isPrime(real_q) == True:
n = real_p * real_q
break

e=65537
#c=pow(m,e,n)

print('real_p=',real_p)
print('real_q=',real_q)

#print('c=',c)


real_p= 55062197317446999463174096263876498316593115551165463378239159905809676640454208209918217385995561457672251651152473557992138742135601815169185076218362135899344751677854110957095631491941800392408438811446405332089775007801060526398896827361974179433880944797942088556569121442758603066960469154848058525555919633585074687002653178371734389317920858433073228324119903275748010661381766238387457768079481851583182446632335485869275973875534654769410510717692168386489418039967948185844825093846853624216235947670855966394462382073931422900372413115651622846475697848013017412006570314438593706146398436291246626158990758006393615755523796444561949003170112244508437710660501492796759763772367048031312446027160494843576151592257914618405347047042441934740949960412334441
real_q= 45155472176560032394858410670734933043941707240560969397865820853107208563396632699891831616425752109128199454680206954866754585433276759685964959793491769
c= 29523353286662420447288429739820034783180593797609319451802397100630230980492429018460170953928563500202582346942199142197785013588760361998950680313834852877108490792872966526015601050884302042018430083206594510237759312983601611859463798190030017950871533501858080631812335748118077560727632343411246129300608114305005550505334558174100631528820258311294104339625598892394650057151595693208992748213949675232397315855876112627150056755058037371576593415880216272977089381300018893299243081150404742921857440064511032025713772327330252031889227225225823090259315491541462395033093742723528280894218885823268632726414223235862198062147879817814619506196476372010238569022037192794906574876350397747710442236263832960264742898816690984736558117232240584876068441918457179310704845718452829124188403042383896118962087518608022867798693371250897927956711708162621772577123078819978462483151316840145260542738057960771219011604

real_p并不是质数,要求phi还得知道p,q,r,s,t。然后看到assert size(m)<360,m挺小,就可以把原本的模数n换成模数real_q,这样phi=real_q-1

1
2
3
4
5
6
7
8
9
10
11
12
from Crypto.Util.number import inverse, long_to_bytes

real_p= 55062197317446999463174096263876498316593115551165463378239159905809676640454208209918217385995561457672251651152473557992138742135601815169185076218362135899344751677854110957095631491941800392408438811446405332089775007801060526398896827361974179433880944797942088556569121442758603066960469154848058525555919633585074687002653178371734389317920858433073228324119903275748010661381766238387457768079481851583182446632335485869275973875534654769410510717692168386489418039967948185844825093846853624216235947670855966394462382073931422900372413115651622846475697848013017412006570314438593706146398436291246626158990758006393615755523796444561949003170112244508437710660501492796759763772367048031312446027160494843576151592257914618405347047042441934740949960412334441
real_q= 45155472176560032394858410670734933043941707240560969397865820853107208563396632699891831616425752109128199454680206954866754585433276759685964959793491769
c= 29523353286662420447288429739820034783180593797609319451802397100630230980492429018460170953928563500202582346942199142197785013588760361998950680313834852877108490792872966526015601050884302042018430083206594510237759312983601611859463798190030017950871533501858080631812335748118077560727632343411246129300608114305005550505334558174100631528820258311294104339625598892394650057151595693208992748213949675232397315855876112627150056755058037371576593415880216272977089381300018893299243081150404742921857440064511032025713772327330252031889227225225823090259315491541462395033093742723528280894218885823268632726414223235862198062147879817814619506196476372010238569022037192794906574876350397747710442236263832960264742898816690984736558117232240584876068441918457179310704845718452829124188403042383896118962087518608022867798693371250897927956711708162621772577123078819978462483151316840145260542738057960771219011604

e = 65537
phi = real_q-1
d = inverse(e, phi)
m = pow(c, d, real_q)

print(long_to_bytes(m))

浙江省省赛2023决赛复现
https://j1ya-22.github.io/2024/08/10/浙江省省赛2023决赛复现/
作者
j1ya
发布于
2024年8月10日
许可协议