TAMUctf

前几天的一个美国的比赛
因为是第一次写国外比赛的题,和国内区别还是有的,题目也不怎么难。。。但有点奇怪吧。。。

RE

RE方向目前写出来7题,有一道汇编的没做。。。

Cheesy

直接放入ida
cheesy1
可以看到很多像base64的字符串
一个个解一下
gigem{3a5y_R3v3r51N6!}

Snakes over cheese

反编译直接

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
#!/usr/bin/env python
# encoding: utf-8
# 如果觉得不错,可以推荐给你的朋友!http://tool.lu/pyc
from datetime import datetime
Fqaa = [
102,
108,
97,
103,
123,
100,
101,
99,
111,
109,
112,
105,
108,
101,
125]
XidT = [
83,
117,
112,
101,
114,
83,
101,
99,
114,
101,
116,
75,
101,
121]

def main():
print 'Clock.exe'
input = raw_input('>: ').strip()
kUIl = ''
for i in XidT:
kUIl += chr(i)

if input == kUIl:
alYe = ''
for i in Fqaa:
alYe += chr(i)

print alYe
else:
print datetime.now()

if __name__ == '__main__':
main()

看到可疑的字符串
吧对应ASCII整出
flag{decompile}
SuperSecretKey

042

用文本编辑器打开后。。。
因为以前一直看的是intel汇编
这种汇编第一次见
往下翻可以看到一堆mov操作
吧ASCII打出

1
2
3
4
5
6
flag = 'gigem{'
a = [65,53,53,51,77,98,49,89]
for i in range(len(a)):
flag += chr(a[i])
flag += '}'
print flag

gigem{A553Mb1Y}

KeyGenMe

程序主要是根据输入进行加密后再字符串匹配
key
一开始想用z3去解的,但是因为key可以是很多种
就直接爆破了

1
2
3
4
5
6
7
8
a = 'H[OIonU2_<__nK<KsK'
for i in range(len(a)-1):
key = ''
for temp in range(32,128):
if ord(a[i+1]) == ((temp + 12) * ord(a[i]) + 17) % 70 + 48:
key += chr(temp)
print key
#G4Z2S09577095926

直接输入后得flag

1
2
3
4
5
6
pisanbao@pisanbao-virtual-machine:~/ctf$ nc rev.tamuctf.com 7223

Please Enter a product key to continue:
G4Z2S09577095926
gigem{k3y63n_m3?_k3y63n_y0u!}

NoCCBytes

这题的话
刚刚又做了一遍,一开始有点懵逼
后来发现还是不怎么难啊
程序大概是对输入进行了一堆神奇的操作,再对里面一串字符串进行解密操作后与之相匹配
那么简单了啊
直接调试在这个解密的地方下断点
毕竟每次异或操作的数是v2,v2不会变
nocc
发现v2值为0x11
那么直接解密

1
2
3
4
5
6
a = 'Fpee~Bphb'
flag = ''
for i in range(len(a)):
flag += chr(ord(a[i])^0x11)
print flag
# WattoSays

答案出现

1
2
3
4
5
6
pisanbao@pisanbao-virtual-machine:~$ nc rev.tamuctf.com 8188

Welcome. Please Enter a password to continue:
WattoSays
gigem{Y0urBreakpo1nt5Won7Work0nMeOnlyMon3y}

还有俩到题目虽然说是写出来了,但是方法不是那么的正常。。。
如果有些出来的希望能私信一下
我想知道咋写鸭~~~

Cr4ckZ33C0d3

虽然说题目要求用z3去写
但是呢。。。。。。。。。。。。。
没写出来
不知道为什么
z3写出来的答案总是有问题//不知道是不是因为
没办法了,只能慢慢分析然后用c去写
而且这题呢。。。输入29个字符,只对其中部分有限制
或者说?这题也有多解???像keygenme一样???
//导致z3解不出???(猜测)
程序只对17个字符进行判断
其中7个字符可以定下
让我们来解其余10个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
已知条件
a[0] = 77
a[5] = 45
a[11] = 45
a[17] = 45
a[20] = 66
a[21] = 66
a[23] = 45

限制条件
(unsigned int)(a1[1] - 48) <= 9
&& (unsigned int)(a1[4] - 48) <= 9
&& (unsigned int)(a1[6] - 48) <= 9
&& (unsigned int)(a1[9] - 48) <= 9
&& (unsigned int)(a1[15] - 48) <= 9
&& (unsigned int)(a1[18] - 48) <= 9
&& (unsigned int)(a1[22] - 48) <= 9
&& (unsigned int)(a1[27] - 48) <= 9
&& (unsigned int)(a1[28] - 48) <= 9
这边不一一列举,只把重要的写一下。

来看一下check3
a1[4] - 48 == 2 * (a1[1] - 48) + 1 && a1[4] - 48 > 7 && a1[9] == a1[4] - (a1[1] - 48) + 2
首先上面限制条件a[4] - 48 <= 9,这边又有a[4] - 48 > 7
所以a[4]只能取56,57
再看a1[4] - 48 == 2 * (a1[1] - 48) + 1
所以a[4] - 48 为奇数
a[4] = 57
所以a[1] = 52,a[9] = 55
ok,现在还剩下7个未知
再看看check4,5,6,7,8

1
2
3
4
5
6
(a1[1] + a1[4] * a1[6]) % 41 == 5;
(a1 + 27) + *(char *)(a1 + 28)) % 13 == 8;
(a1 + 27) + *(char *)(a1 + 22)) % 22 == 18;
(a1 + 18) + *(char *)(a1 + 22)) % 11 == 5;
(a1[22] + a1[28] + a1[18]) % 26 == 4;
别忘了这边涉及的所有未知数都有a[x]-48<=9的限制

c语言爆破,套个5层循环。。。//其实可以爆,毕竟范围限制在那

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main()
{
char a27,a28,a22,a18,a6;
for(a27=32;a27<58;a27++)//32开始为可打印字符
{
for(a22=32;a22<58;a22++)
{
for(a28=32;a28<58;a28++)
{
for(a18=32;a18<58;a18++)
{
for(a6=32;a6<58;a6++)
{
if((52+57*a6)%41==5 && (a27+a28)%13==8 && (a27+a22)%22==18 && (a18+a22)%11 == 5 && (a22+a28+a18)%26==4)
printf("a6=%d,a18=%d,a22=%d,a27=%d,a28=%d\n",a6,a18,a22,a27,a28);
}
}
}
}
}
return 0;
}

头文件啥的不加了
跑出来结果

1
2
3
4
5
6
a6=56,a18=41,a22=52,a27=32,a28=41
a6=56,a18=32,a22=50,a27=34,a28=52
a6=56,a18=54,a22=39,a27=45,a28=41
a6=56,a18=45,a22=37,a27=47,a28=52
a6=56,a18=36,a22=35,a27=49,a28=37
a6=56,a18=54,a22=50,a27=56,a28=56

果断选择最后一个
下面看check9
这就可以用z3了

1
2
3
4
5
6
7
from z3 import *
s = Solver()
a15 = BitVec('a15',8)
s.add((((((a15-56)>>31)>>30)+a15-56)&3)-(((a15-56)>>31)>>30)==1)
if s.check()==sat:
print s.model()#[a15 = 57]

a15 = 57
check0A是帮你验证的,因为前面有多解嘛
选择最像的,验证我就不验证了啊
看check0C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
char a9;
for(a9=32;a9<58;a9++)
{
if((56+57*a9)%10==1)
printf("a9=%d\n",a9);
}
//a9=35
//a9=45
//a9=55
return 0;
}


a9 = 55
那就ok了啊

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
int main()
{
char a[29]={0};
a[0] = 77;
a[1] = 52;
a[4] = 57;
a[5] = 45;
a[6] = 56;
a[9] = 55;
a[11] = 45;
a[15] = 57;
a[17] = 45;
a[18] = 54;
a[20] = 66;
a[21] = 66;
a[22] = 50;
a[23] = 45;
a[27] = 56;
a[28] = 56;
int i;
for(i=0;i<29;i++)
{
if(a[i])
printf("%c",a[i]);
else
printf("0");
}
return 0;
}

跑一下
M4009-80070-00090-60BB2-00088
看样子就是答案了

1
2
3
4
5
6
pisanbao@pisanbao-virtual-machine:~$ nc rev.tamuctf.com 8189

Please Enter a product key to continue:
M4009-80070-00090-60BB2-00088
gigem{z3_b3st_thr33}

Obfuscaxor

黑盒测试猜出来的答案
放进ida发现这部分有点奇怪,看汇编
o
转成代码发现strcmp
o
接下去就是猜了。。。
猜测加密方法
我们输入一串a进去
看输出
o
4个一循环
那就可以猜测异或了

1
2
3
4
5
6
7
8
a = [0xAE, 0x9E, 0xFF, 0x9C, 0xAB, 0xC7, 0xD3, 0x81, 0xE7, 0xEE,
0xFB, 0x8A, 0x9D, 0xEF, 0x8D, 0xAE]
b = [0xBF, 0xCC, 0xDF, 0x8E]
key = ''
for i in range(len(a)):
key += chr(a[i]^b[i%4]^ord('a'))
print key
# p3Asujmn9CEeCB3A

得到key

1
2
3
4
5
6
pisanbao@pisanbao-virtual-machine:~$ nc rev.tamuctf.com 7224

Please Enter a product key to continue:
p3Asujmn9CEeCB3A
gigem{x0r_64d5by}

pwn的话
有机会再总结下吧。。。

文章目录
  1. 1. RE
    1. 1.1. Cheesy
    2. 1.2. Snakes over cheese
    3. 1.3. 042
    4. 1.4. KeyGenMe
    5. 1.5. NoCCBytes
    6. 1.6. Cr4ckZ33C0d3
    7. 1.7. Obfuscaxor
|