SWPUCTF-2016

SWPUCTF-2016

十月 26, 2016

前几天无意中看到一个小比赛,虽然没怎么听说过,还是组队去试试看。虽然出了一些乌龙,感觉还是挺有意思的。

SWPUCTF–Writeup

MISC部分

0x01 MISC150

MICS150

是一个数据包的流量分析,导出HTTP请求之后发现里面有个压缩包Flag.zip,点进去发现里面一堆数组?看得出每一组都代表了一个像素点,所以首先想到了把他还原成一张图片。

那么问题来了:不知道图片的分辨率怎么还原。

写个简单的脚本拆分98457

1
2
3
4
for i in range(0,98457):s
for j in range(0,98457):
if i*j == 98457:
print i,"*",j

得到了三组数据,分别是3x32819,37x2661,111x887。感觉第三组数据应该是正常的分辨率,然后写脚本生成图片。

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
import Image
import re

x = 887
y = 111
ii = 0
m = 0
list = []

for line in open('ce.txt','r'):
if line.strip():
list.append(line);
ii = ii + 1

for jj in range(0,ii):
ss = re.findall(r'([0-9]+)',list[jj])
print jj,list[jj],int(ss[0]),int(ss[1]),int(ss[2])
jjj = -1
c = Image.new("RGB",(x,y))
for i in range(0,x):
for j in range(0,y):
jjj = jjj + 1
ss = re.findall(r'([0-9]+)',list[jjj])
print ss[0],ss[1],ss[2]
c.putpixel(([i,j]),(int(ss[0]),int(ss[1]),int(ss[2])))
c.show()
c.save("misc150.png")

得到了flag。

0x02 MISC100–2

MICS100–2

图片隐写的题目。这个题之前被出题方放过原图(幸好没删除),用Hexcmp比较,发现在图片最后多出了一串字符。

得到的字符串是一串Base32,解过之后继续用Base64解密。得到了具有格式的字符串,首先想到了凯撒加密。

但是凯撒加密全解过之后发现有flxx{xxxxx}和xxag{xxxxx}两种开起来比较像flag。这两种情况分别出现在偏移+10和偏移-10。

然后想到分段凯撒,每两个字母进行一次解密,但是得到了错误的flag。

最后发现,这段字符串是按照ascii码的奇偶来进行凯撒加密的。(出题人的脑洞真是大的可以。)

然后附上脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
s = "vbkqukCkSvrduztucCVQXVuvzuckrvtZDUBTGYSkvcktv"
flag = ""
for char in s:
if (ord(char) >= 65 and ord(char) <= 90):
if (ord(char)-65) % 2 == 1:
temp = (ord(char) - 65 + 10) % 26
char = chr(temp + 65)
flag = flag + char
else:
temp = (ord(char) - 65 - 10) % 26
char = chr(temp + 65)
flag = flag + char
else:
if (ord(char)-97) % 2 == 1:
temp = (ord(char) -97 + 10) % 26
char = chr(temp + 97)
flag = flag + char
else:
temp = (ord(char) -97 - 10) % 26
char = chr(temp + 97)
flag = flag + char

print flag

需要自己加上格式,得到flag。

flag{kaSaI_fbnkjdksSFGHFkfjksabfdJNKLDWOIafsadf}

0x03 MISC100

MICS100

打开之后发现是一堆奇奇怪怪的东西,JS混淆。利用FuckJS解密,得到新的加密代码。

发现这是一段Brainfuzz加密,解密后得到flag。

Re部分

0x01 Re50

Re50

讲道理,Re50是最后一个做出来的Re题目。用ResourseHacker打开题目,发现flag。

0x02 Re100

Re100

用OD找到出弹窗的部分,即找到了判断输入的部分。映射到ida中,F5看下代码,然后复现。

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <cstdio>
#include <Windows.h>
int x[10] = { 1, 9, 4, 9, 1, 0, 0, 1 };
int sub_70361E(int a)
{
int v5 = 1;
for (int i = 0; i < a; i++)
v5 *= 10;
return v5;
}
int fun1()
{
int v13, v11, v10, v6, v5, v4, v2;
int v1 = 28;
int v15;
v15 = x[7] + 10 * x[6] + 100 * x[5] + 1000 * x[4] + 10000 * x[3] + 100000 * x[2] + 1000000 * x[1] + 10000000 * x[0];
int v3 = 0xBC614E ^ v15;
v15 ^= 0xBC614E;

for (int i = 8; i > 0; --i)
{
v11 = 8 - i;
v10 = i - 1;
if (8 == i)
{
v4 = sub_70361E(v10);
v2 = v11;
x[v11] = v15 / v4;
}
else
{
v5 = sub_70361E(v10);
v13 = v15 / v5;
for (int j = 0; j < v11; ++j)
{
v6 = sub_70361E(v11 - j);
v13 %= v6;
}
v2 = v13;
x[8 - i] = v13;
}
v3 = i - 1;
}
return 0;
}

int fun2()
{
int v14, v15, v12 = 0x2E, v13 = 0x1F;
int v11 = 2654;
v15 = x[5] + 10 * x[4];
int v1 = 28;
int v16 = x[7] + 10 * x[6];
int v2 = v14;
if (v14 != v11 || (v2 = v15, v15 != v12) || (v2 = v16, v16 != v13))
MessageBox(0, L"error", L"error", MB_OK);
else
MessageBox(0, L"OK", L"OK", MB_OK);
return 0;
}
int main()
{
for (int i = 0; i < 8; i++)
printf("%d :%x\n", i, x[i]);
fun1();
printf("\nafter\n");
for (int i = 0; i < 8; i++)
printf("%d :%x\n", i, x[i]);
fun2();
return 0;
}

然后得到了通关密码是19491001。(出题人好爱国啊)

得到flag。

0x03 Re150

Re150

apk逆向,表示并不懂apk,但听说题目挺简单的就试了一下。

用jeb打开题目,然后可以得到题目的源代码(表示并看不懂JAVA,但是大致意思还是知道的)。试着复现了一下源码,然后修改一下源码,得到了一个爆破脚本。

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
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;

string Encode1(string &flag)
{

for (int i = 0; i < 16; i++)
{
flag[i] ^= 29;
}
for (int i = 1; i <8; i++)
{
flag[i] = flag[15 - i];
flag[15 - i] = flag[i];
}
return flag;
}
string encode2(string encode, string flag)
{
for (int i = 0; i < 16; i++)
{
if (i % 2 == 0)
{
encode[i] = flag[i];
}
}
return encode;
}

int main()
{
string input = "0000000000000000";
unsigned char v2[] = {73, 48, 109, 97, 115, 46, 95, 116, 105, 111, 51, 89, 124, 73, 45, 73};
cin >> input;



string xx = input;
Encode1(input);
xx = encode2(input, xx);

for (int i = 0; i < 16; i++)
printf("%d\n", xx[i]);


return 0;
}

然后拿着得到的东西去找客服,得到了flag。

Flag{I’m_s0_Tir3D|T-T}

0x04 Re200

Re200

其实当时并没有看懂Re200的反汇编,无意中按到了一个”F”,突然出现了一个弹窗。

然后,就想到了爆破,然后,就没有然后了。。。

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

#include <cstdio>
char flag[30] = { 0 };
int main()
{
HWND mainh = FindWindow(nullptr,L"CM200");
if (mainh == nullptr)
printf("error");
HWND XX = FindWindowEx(mainh, nullptr, L"Edit", nullptr);
if(XX == nullptr)
printf("error2");
flag[0] = 'F';
flag[1] = 'l';
flag[2] = 'a';
flag[3] = 'g';
flag[4] = '{';
flag[5] = 'y';
flag[6] = '3';
flag[7] = 's';
flag[8] = '_';
flag[9] = 'I';
flag[10] = 's';
flag[11] = '_';
flag[12] = 't';
flag[13] = 'H';
flag[14] = '3';
flag[15] = '_';
flag[16] = 'L';
flag[17] = 'a';
flag[18] = 'S';
flag[19] = 't';
flag[20] = '}';
for (char i = 0x20; i < 0x7e; i++)
{
flag[20] = i;
SendMessageA(XX, WM_SETTEXT, NULL, (LPARAM)flag);
HWND box = FindWindow(nullptr, L"wow");
Sleep(10);
if (box != nullptr)
{

exit(0);
}
}
return 0;
}

得到了flag。

Flag{y3s_Is_tH3_LaSt}

后记

比赛不大,但蛮有意思的。感觉还是多打比赛才能有更快的提高,反正近期比较闲,可以找点小比赛练练,hhhh。