SWPUCTF-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。

文章目录
  1. 1. SWPUCTF–Writeup
    1. 1.1. MISC部分
      1. 1.1.1. 0x01 MISC150
      2. 1.1.2. 0x02 MISC100–2
      3. 1.1.3. 0x03 MISC100
    2. 1.2. Re部分
      1. 1.2.1. 0x01 Re50
      2. 1.2.2. 0x02 Re100
      3. 1.2.3. 0x03 Re150
      4. 1.2.4. 0x04 Re200
  2. 2. 后记
,