-
-
[原创][庆祝建党]2021GKCTF-WP(NAN)
-
发表于: 2021-6-29 16:07 13913
-
使用exeinforpe检查发现是用的Enigma Virtual Box打的包
下载工具EnigmaVBUnpacker将exe解包一下
得到QQQQT_unpacked.exe
拖入IDA分析
查找字符串得到比较数据和base58的码表:56fkoP8KhwCf3v7CEz和123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
写一个脚本解一下即可
得到apk,直接拖入jadx,得到关键逻辑
其实很简单,就是MainActivity里面调用的check函数检测我们输入的flag,而check函数是System.loadLibrary("native-lib");
使用工具apk-tools获取一下apk的资源,然后将lib文件夹里面的so拖入IDA进行分析
shift+f12查找字符串,发现会检测是否被调试
交叉引用一下发现检测调试的函数是sub_738378DF3C
然后关键的check函数是Java_com_example_myapplication_MainActivity_check
里面是将我们输入的字符串进行TEA加密, 里面有比较数据
使用IDA和adb调试一下,可以发现key,即那四个数字被改变
然后写个C脚本解一下即可
最后将这得到的flag{md5(input)}一下即可,flag{77bca47fe645ca1bd1ac93733171c9c4}
拖入IDA分析,main函数在先检测了input的格式,然后传入man_check函数检测,可以从maincheck函数中发现,GKCTF{之后的24个字节被传入了main_encrypto函数进行加密,再后面四字节是sha_256,再后面四字节是sha_512,再后面四字节是md5,main_encrypto函数内部是Des3,最后base64加密一下,后面那些hash函数直接查一下就可以得到,这个DES是关键,
最后将后面的hash拼接一下,得到flag为:GKCTF{87f645e9-b628-412f-9d7a-e402f20af940}
在scanf输入函数下断点之后,交叉引用输入的变量,发现下方有个函数引用了输入,
进去之后根据XXTEA的加密逻辑对拍一下,交叉引用一下,这里是生成delta的逻辑,调试到这里得到delta为0x33445566, 同时对拍也会得到key
然后下方跟着调试下去,可以在内存里得到比较数据
得到flag为:9b34a61df773acf0e4dec25ea5fb0e29
C# 逆向,DLL做核心验证,DLL 里面有反调试,简单 patch 即可
然后有一个极其恶心的 AES 魔改算法
行移位
外层的也很恶心
解密目标数据得到: Meaningless_!$!%*@^%#%_Code 字符串
C#层还有一个 code 计算
最后组合得到flag
flag{ginkgoCX@Meaningless!$!%*@^%#%_Code}
checkin
这有个栈溢出,可以覆盖rbp
Pass是个md5加密,在线解一下就行
然后就是略微麻烦的栈迁移加ROP了
登入后台,简单审计发现有一个任意文件读
先是注册,注册后有一个简单的任意文件下载
看到是纯Servlet写的,加大了我做这道题的信心(哈哈哈)
发现uploadServlet并没有验证是不是admin,可以直接上传
baseDao
这里直接xmldecode反序列化了
registerServlet
这里写的非常奇怪啊,反正注册的时候还会加载一次
上传../../db/db.xml
然后随便注册一个用户就可以弹了
套娃题,第一层跟巅峰极客tryRSA基本一致,第二层$modq1$稍微变换一下,消去p1之后和n2做一次gcd就好了,具体看代码实现
打开wireshark,跟踪http流,复制最长的那段base64的
打开ipython,用ctfbox解几次编码,最后将双写去掉就能拿到flag
# _*_ coding: utf-8 _*_
# editor: SYJ
# function: Reversed By SYJ
# describe:
def
b58encode(tmp:
str
)
-
>
str
:
tmp
=
list
(
map
(
ord
,tmp))
temp
=
tmp[
0
]
base58
=
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
for
i
in
range
(
len
(tmp)
-
1
):
temp
=
temp
*
256
+
tmp[i
+
1
]
tmp
=
[]
while
True
:
tmp.insert(
0
,temp
%
58
)
temp
=
temp
/
/
58
if
temp
=
=
0
:
break
temp
=
""
for
i
in
tmp:
temp
+
=
base58[i]
return
temp
def
b58decode(tmp:
str
)
-
>
str
:
import
binascii
base58
=
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
temp
=
[]
for
i
in
tmp:
temp.append(base58.index(i))
tmp
=
temp[
0
]
for
i
in
range
(
len
(temp)
-
1
):
tmp
=
tmp
*
58
+
temp[i
+
1
]
return
binascii.unhexlify(
hex
(tmp)[
2
:].encode(
"utf-8"
)).decode(
"UTF-8"
)
cmp
=
"56fkoP8KhwCf3v7CEz"
print
(
'flag{'
+
b58decode(
cmp
)
+
'}'
)
# 得到flag为:flag{12t4tww3r5e77}
# _*_ coding: utf-8 _*_
# editor: SYJ
# function: Reversed By SYJ
# describe:
def
b58encode(tmp:
str
)
-
>
str
:
tmp
=
list
(
map
(
ord
,tmp))
temp
=
tmp[
0
]
base58
=
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
for
i
in
range
(
len
(tmp)
-
1
):
temp
=
temp
*
256
+
tmp[i
+
1
]
tmp
=
[]
while
True
:
tmp.insert(
0
,temp
%
58
)
temp
=
temp
/
/
58
if
temp
=
=
0
:
break
temp
=
""
for
i
in
tmp:
temp
+
=
base58[i]
return
temp
def
b58decode(tmp:
str
)
-
>
str
:
import
binascii
base58
=
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
temp
=
[]
for
i
in
tmp:
temp.append(base58.index(i))
tmp
=
temp[
0
]
for
i
in
range
(
len
(temp)
-
1
):
tmp
=
tmp
*
58
+
temp[i
+
1
]
return
binascii.unhexlify(
hex
(tmp)[
2
:].encode(
"utf-8"
)).decode(
"UTF-8"
)
cmp
=
"56fkoP8KhwCf3v7CEz"
print
(
'flag{'
+
b58decode(
cmp
)
+
'}'
)
# 得到flag为:flag{12t4tww3r5e77}
#include <stdio.h>
#include <stdint.h>
void encrypt (uint32_t
*
v, uint32_t
*
k) {
uint32_t v0
=
v[
0
], v1
=
v[
1
],
sum
=
0
, i;
/
*
set
up
*
/
uint32_t delta
=
0x458BCD42
;
/
*
a key schedule constant
*
/
uint32_t k0
=
k[
0
], k1
=
k[
1
], k2
=
k[
2
], k3
=
k[
3
];
/
*
cache key
*
/
for
(i
=
0
; i <
32
; i
+
+
) {
/
*
basic cycle start
*
/
sum
+
=
delta;
v0
+
=
((v1<<
4
)
+
k0) ^ (v1
+
sum
) ^ ((v1>>
5
)
+
k1);
v1
+
=
((v0<<
4
)
+
k2) ^ (v0
+
sum
) ^ ((v0>>
5
)
+
k3);
}
/
*
end cycle
*
/
v[
0
]
=
v0; v[
1
]
=
v1;
}
void decrypt (uint32_t
*
v, uint32_t
*
k) {
uint32_t delta
=
0x458BCD42
;
/
*
a key schedule constant
*
/
uint32_t v0
=
v[
0
], v1
=
v[
1
],
sum
=
(delta
*
32
)&
0xffffffff
, i;
/
*
set
up
*
/
uint32_t k0
=
k[
0
], k1
=
k[
1
], k2
=
k[
2
], k3
=
k[
3
];
/
*
cache key
*
/
for
(i
=
0
; i<
32
; i
+
+
) {
/
*
basic cycle start
*
/
v1
-
=
((v0<<
4
)
+
k2) ^ (v0
+
sum
) ^ ((v0>>
5
)
+
k3);
v0
-
=
((v1<<
4
)
+
k0) ^ (v1
+
sum
) ^ ((v1>>
5
)
+
k1);
sum
-
=
delta;
}
/
*
end cycle
*
/
v[
0
]
=
v0; v[
1
]
=
v1;
}
int
main()
{
uint32_t array[]
=
{
0xF5A98FF3
,
0xA21873A3
};
/
/
{
0xF5A98FF3
,
0xA21873A3
};
uint32_t key[
4
]
=
{
9
,
7
,
8
,
6
};
/
/
encrypt(array, key);
decrypt(array, key);
/
/
printf(
"%x\n%x"
,array[
0
],array[
1
]);
printf(
"%c,%c,%c,%c,%c,%c,%c,%c"
,
*
((char
*
)&array[
0
]
+
0
),
*
((char
*
)&array[
0
]
+
1
),
*
((char
*
)&array[
0
]
+
2
),
*
((char
*
)&array[
0
]
+
3
),
*
((char
*
)&array[
1
]
+
0
),
*
((char
*
)&array[
1
]
+
1
),
*
((char
*
)&array[
1
]
+
2
),
*
((char
*
)&array[
1
]
+
3
));
return
0
;
/
/
GKcTFg0
}
#include <stdio.h>
#include <stdint.h>
void encrypt (uint32_t
*
v, uint32_t
*
k) {
uint32_t v0
=
v[
0
], v1
=
v[
1
],
sum
=
0
, i;
/
*
set
up
*
/
uint32_t delta
=
0x458BCD42
;
/
*
a key schedule constant
*
/
uint32_t k0
=
k[
0
], k1
=
k[
1
], k2
=
k[
2
], k3
=
k[
3
];
/
*
cache key
*
/
for
(i
=
0
; i <
32
; i
+
+
) {
/
*
basic cycle start
*
/
sum
+
=
delta;
v0
+
=
((v1<<
4
)
+
k0) ^ (v1
+
sum
) ^ ((v1>>
5
)
+
k1);
v1
+
=
((v0<<
4
)
+
k2) ^ (v0
+
sum
) ^ ((v0>>
5
)
+
k3);
}
/
*
end cycle
*
/
v[
0
]
=
v0; v[
1
]
=
v1;
}
void decrypt (uint32_t
*
v, uint32_t
*
k) {
uint32_t delta
=
0x458BCD42
;
/
*
a key schedule constant
*
/
uint32_t v0
=
v[
0
], v1
=
v[
1
],
sum
=
(delta
*
32
)&
0xffffffff
, i;
/
*
set
up
*
/
uint32_t k0
=
k[
0
], k1
=
k[
1
], k2
=
k[
2
], k3
=
k[
3
];
/
*
cache key
*
/
for
(i
=
0
; i<
32
; i
+
+
) {
/
*
basic cycle start
*
/
v1
-
=
((v0<<
4
)
+
k2) ^ (v0
+
sum
) ^ ((v0>>
5
)
+
k3);
v0
-
=
((v1<<
4
)
+
k0) ^ (v1
+
sum
) ^ ((v1>>
5
)
+
k1);
sum
-
=
delta;
}
/
*
end cycle
*
/
v[
0
]
=
v0; v[
1
]
=
v1;
}
int
main()
{
uint32_t array[]
=
{
0xF5A98FF3
,
0xA21873A3
};
/
/
{
0xF5A98FF3
,
0xA21873A3
};
uint32_t key[
4
]
=
{
9
,
7
,
8
,
6
};
/
/
encrypt(array, key);
decrypt(array, key);
/
/
printf(
"%x\n%x"
,array[
0
],array[
1
]);
printf(
"%c,%c,%c,%c,%c,%c,%c,%c"
,
*
((char
*
)&array[
0
]
+
0
),
*
((char
*
)&array[
0
]
+
1
),
*
((char
*
)&array[
0
]
+
2
),
*
((char
*
)&array[
0
]
+
3
),
*
((char
*
)&array[
1
]
+
0
),
*
((char
*
)&array[
1
]
+
1
),
*
((char
*
)&array[
1
]
+
2
),
*
((char
*
)&array[
1
]
+
3
));
return
0
;
/
/
GKcTFg0
}
from
Crypto.Cipher
import
DES3
ans
=
[
163
,
246
,
150
,
62
,
51
,
77
,
196
,
195
,
217
,
14
,
114
,
101
,
54
,
157
,
51
,
43
,
159
,
141
,
44
,
240
,
184
,
78
,
254
,
164
,
169
,
210
,
106
,
142
,
66
,
244
,
94
,
64
]
# 比较数据base64解码之后
c
=
bytes(ans)
key
=
b
'WelcomeToTheGKCTF2021XXX'
iv1
=
b
'1Ssecret'
iv2
=
b
'wumansgy'
# key = b'00000000'
# iv = b'00000000'
des
=
DES3.new(key,DES3.MODE_CBC,iv1)
m
=
des.decrypt(c)
print
(m)
from
Crypto.Cipher
import
DES3
ans
=
[
163
,
246
,
150
,
62
,
51
,
77
,
196
,
195
,
217
,
14
,
114
,
101
,
54
,
157
,
51
,
43
,
159
,
141
,
44
,
240
,
184
,
78
,
254
,
164
,
169
,
210
,
106
,
142
,
66
,
244
,
94
,
64
]
# 比较数据base64解码之后
c
=
bytes(ans)
key
=
b
'WelcomeToTheGKCTF2021XXX'
iv1
=
b
'1Ssecret'
iv2
=
b
'wumansgy'
# key = b'00000000'
# iv = b'00000000'
des
=
DES3.new(key,DES3.MODE_CBC,iv1)
m
=
des.decrypt(c)
print
(m)
#include <stdio.h>
#include <stdlib.h>
#define DELTA 0x33445566
int
main()
{
unsigned
int
v[
8
]
=
{
0x993CAB5C
,
0x3F40E129
,
0x777791DE
,
0x737DFEA6
,
0x0ECCF59E6
,
0x0C9604CE3
,
0x9682C0A5
,
0x556F2A1E
};
unsigned
int
key[
4
]
=
{
0x000036B0
,
0x00013816
,
0x00000010
,
0x0001E0F3
};
unsigned
int
sum
=
0
;
unsigned
int
y,z,p,rounds,e;
int
n
=
8
;
int
i
=
0
;
rounds
=
12
;
y
=
v[
0
];
sum
=
(rounds
*
DELTA)&
0xffffffff
;
do
/
/
0x9E3779B9
*
(
52
/
35
)
-
0x4AB325AA
,测试来要循环
7
次
{
e
=
sum
>>
2
&
3
;
for
(p
=
n
-
1
;p>
0
;p
-
-
)
/
/
34
次循环
{
z
=
v[p
-
1
];
v[p]
=
(v[p]
-
((((z>>
5
)^(y<<
2
))
+
((y>>
3
)^(z<<
4
))) ^ ((key[(p^e)&
3
]^z)
+
(y ^
sum
)))) &
0xffffffff
;
y
=
v[p];
}
z
=
v[n
-
1
];
v[
0
]
=
(v[
0
]
-
(((key[(p^e)&
3
]^z)
+
(y ^
sum
)) ^ (((y<<
2
)^(z>>
5
))
+
((z<<
4
)^(y>>
3
))))) &
0xffffffff
;
y
=
v[
0
];
sum
=
(
sum
-
DELTA)&
0xffffffff
;
}
while
(
-
-
rounds);
for
(i
=
0
;i<
8
;i
+
+
)
{
printf(
"%c%c%c%c"
,
*
((char
*
)&v[i]
+
0
),
*
((char
*
)&v[i]
+
1
),
*
((char
*
)&v[i]
+
2
),
*
((char
*
)&v[i]
+
3
));
}
return
0
;
}
#include <stdio.h>
#include <stdlib.h>
#define DELTA 0x33445566
int
main()
{
unsigned
int
v[
8
]
=
{
0x993CAB5C
,
0x3F40E129
,
0x777791DE
,
0x737DFEA6
,
0x0ECCF59E6
,
0x0C9604CE3
,
0x9682C0A5
,
0x556F2A1E
};
unsigned
int
key[
4
]
=
{
0x000036B0
,
0x00013816
,
0x00000010
,
0x0001E0F3
};
unsigned
int
sum
=
0
;
unsigned
int
y,z,p,rounds,e;
int
n
=
8
;
int
i
=
0
;
rounds
=
12
;
y
=
v[
0
];
sum
=
(rounds
*
DELTA)&
0xffffffff
;
do
/
/
0x9E3779B9
*
(
52
/
35
)
-
0x4AB325AA
,测试来要循环
7
次
{
e
=
sum
>>
2
&
3
;
for
(p
=
n
-
1
;p>
0
;p
-
-
)
/
/
34
次循环
{
z
=
v[p
-
1
];
v[p]
=
(v[p]
-
((((z>>
5
)^(y<<
2
))
+
((y>>
3
)^(z<<
4
))) ^ ((key[(p^e)&
3
]^z)
+
(y ^
sum
)))) &
0xffffffff
;
y
=
v[p];
}
z
=
v[n
-
1
];
v[
0
]
=
(v[
0
]
-
(((key[(p^e)&
3
]^z)
+
(y ^
sum
)) ^ (((y<<
2
)^(z>>
5
))
+
((z<<
4
)^(y>>
3
))))) &
0xffffffff
;
y
=
v[
0
];
sum
=
(
sum
-
DELTA)&
0xffffffff
;
}
while
(
-
-
rounds);
for
(i
=
0
;i<
8
;i
+
+
)
{
printf(
"%c%c%c%c"
,
*
((char
*
)&v[i]
+
0
),
*
((char
*
)&v[i]
+
1
),
*
((char
*
)&v[i]
+
2
),
*
((char
*
)&v[i]
+
3
));
}
return
0
;
}
void myshift(
int
pArray[
4
][
4
]){
int
tmpArr[
4
][
4
]
=
{
0
};
tmpArr[
0
][
0
]
=
pArray[
0
][
0
];
tmpArr[
0
][
1
]
=
pArray[
1
][
1
];
tmpArr[
0
][
2
]
=
pArray[
2
][
2
];
tmpArr[
0
][
3
]
=
pArray[
3
][
3
];
tmpArr[
1
][
0
]
=
pArray[
1
][
0
];
tmpArr[
1
][
1
]
=
pArray[
2
][
1
];
tmpArr[
1
][
2
]
=
pArray[
3
][
2
];
tmpArr[
1
][
3
]
=
pArray[
0
][
3
];
tmpArr[
2
][
0
]
=
pArray[
2
][
0
];
tmpArr[
2
][
1
]
=
pArray[
3
][
1
];
tmpArr[
2
][
2
]
=
pArray[
0
][
2
];
tmpArr[
2
][
3
]
=
pArray[
1
][
3
];
tmpArr[
3
][
0
]
=
pArray[
3
][
0
];
tmpArr[
3
][
1
]
=
pArray[
0
][
1
];
tmpArr[
3
][
2
]
=
pArray[
1
][
2
];
tmpArr[
3
][
3
]
=
pArray[
2
][
3
];
for
(
int
i
=
0
; i <
4
;
+
+
i) {
for
(
int
j
=
0
; j <
4
;
+
+
j) {
pArray[i][j]
=
tmpArr[i][j];
}
}
}
void myshift(
int
pArray[
4
][
4
]){
int
tmpArr[
4
][
4
]
=
{
0
};
tmpArr[
0
][
0
]
=
pArray[
0
][
0
];
tmpArr[
0
][
1
]
=
pArray[
1
][
1
];
tmpArr[
0
][
2
]
=
pArray[
2
][
2
];
tmpArr[
0
][
3
]
=
pArray[
3
][
3
];
tmpArr[
1
][
0
]
=
pArray[
1
][
0
];
tmpArr[
1
][
1
]
=
pArray[
2
][
1
];
tmpArr[
1
][
2
]
=
pArray[
3
][
2
];
tmpArr[
1
][
3
]
=
pArray[
0
][
3
];
tmpArr[
2
][
0
]
=
pArray[
2
][
0
];
tmpArr[
2
][
1
]
=
pArray[
3
][
1
];
tmpArr[
2
][
2
]
=
pArray[
0
][
2
];
tmpArr[
2
][
3
]
=
pArray[
1
][
3
];
tmpArr[
3
][
0
]
=
pArray[
3
][
0
];
tmpArr[
3
][
1
]
=
pArray[
0
][
1
];
tmpArr[
3
][
2
]
=
pArray[
1
][
2
];
tmpArr[
3
][
3
]
=
pArray[
2
][
3
];
for
(
int
i
=
0
; i <
4
;
+
+
i) {
for
(
int
j
=
0
; j <
4
;
+
+
j) {
pArray[i][j]
=
tmpArr[i][j];
}
}
}
void mydeaes(char
*
p, char
*
iv,
int
plen, char
*
key){
int
pArray0[
4
][
4
];
int
pArray1[
4
][
4
];
int
pIv[
4
][
4
];
int
k
=
0
;
char key_use[
16
];
convertToIntArray(iv, pIv);
for
(
int
k1
=
31
; k1 >
=
0
; k1
-
=
1
) {
memcpy(key_use, key,
16
);
getRoundIvAndKey(k1, iv, key_use, pIv);
/
/
f8
82
extendKey(key_use);
/
/
扩展密钥
convertToIntArray(&p[
16
], pArray1);
convertToIntArray(&p[
0
], pArray0);
addRoundKey(pArray1,
10
);
for
(
int
i
=
9
; i >
=
1
; i
-
-
) {
mydeshift(pArray1);
deSubBytes(pArray1);
addRoundKey(pArray1, i);
myTranspose(pArray1);
deMixColumns(pArray1);
/
/
列混合
myTranspose(pArray1);
}
mydeshift(pArray1);
/
/
行移位
deSubBytes(pArray1);
/
/
字节代换
addRoundKey(pArray1,
0
);
/
/
一开始的轮密钥加
for
(
int
i
=
0
; i <
4
;
+
+
i) {
for
(
int
j
=
0
; j <
4
;
+
+
j) {
pArray1[i][j] ^
=
pArray0[i][j];
}
}
addRoundKey(pArray0,
10
);
for
(
int
i
=
9
; i >
=
1
; i
-
-
) {
mydeshift(pArray0);
deSubBytes(pArray0);
addRoundKey(pArray0, i);
myTranspose(pArray0);
deMixColumns(pArray0);
/
/
列混合
myTranspose(pArray0);
}
mydeshift(pArray0);
/
/
行移位
deSubBytes(pArray0);
/
/
字节代换
addRoundKey(pArray0,
0
);
/
/
一开始的轮密钥加
for
(
int
i
=
0
; i <
4
;
+
+
i) {
for
(
int
j
=
0
; j <
4
;
+
+
j) {
pArray0[i][j] ^
=
pIv[i][j];
}
}
convertArrayToStr(pArray0, &p[
0
]);
convertArrayToStr(pArray1, &p[
16
]);
}
}
void mydeaes(char
*
p, char
*
iv,
int
plen, char
*
key){
int
pArray0[
4
][
4
];
int
pArray1[
4
][
4
];
int
pIv[
4
][
4
];
int
k
=
0
;
char key_use[
16
];
convertToIntArray(iv, pIv);
for
(
int
k1
=
31
; k1 >
=
0
; k1
-
=
1
) {
memcpy(key_use, key,
16
);
getRoundIvAndKey(k1, iv, key_use, pIv);
/
/
f8
82
extendKey(key_use);
/
/
扩展密钥
convertToIntArray(&p[
16
], pArray1);
convertToIntArray(&p[
0
], pArray0);
addRoundKey(pArray1,
10
);
for
(
int
i
=
9
; i >
=
1
; i
-
-
) {
mydeshift(pArray1);
deSubBytes(pArray1);
addRoundKey(pArray1, i);
myTranspose(pArray1);
deMixColumns(pArray1);
/
/
列混合
myTranspose(pArray1);
}
mydeshift(pArray1);
/
/
行移位
deSubBytes(pArray1);
/
/
字节代换
addRoundKey(pArray1,
0
);
/
/
一开始的轮密钥加
for
(
int
i
=
0
; i <
4
;
+
+
i) {
for
(
int
j
=
0
; j <
4
;
+
+
j) {
pArray1[i][j] ^
=
pArray0[i][j];
}
}