-
-
[原创] KCTF 2023 第八题 wp - 98k
-
发表于: 2023-9-17 15:44 8815
-
代码量非常少,不过编译器优化得到逻辑很乱。整理下逻辑:
所以问题大致是这样的,给定了 10 个初始比特值,还给了 10 组(实际上是 11 组)比特值,每次从这 10 组中有限制的选择一组出来,异或到初始比特值中,要求最后使 10 个比特值都变成 0 。
将初始比特值和可选择异或的比特值计算出来得到:
也就是每次可以改变 1 比特。限制条件为每隔一轮需要将最低比特改掉;除最低比特外,能修改某个比特位的条件就是它后续的比特位最高位为 1 ,后面的全是 0 (上面代码中 check 的检查)
根据这些限制条件就可以手动构造,再转成输入:
正常来说输入转换得到的数字应该不能为 9 ,但是程序中并没有对 9 做错误的返回,所以可以在输入的任意 4 个连续的偶数位置插 9 (奇数位补0),得到的结果不变,就能构造出多解。上面代码中给出了在末尾补 9 时得到的几组多解。
int
check(
char
* input,
int
length) {
char
_flag[10][4];
char
key[5][4];
for
(
int
i = 0; i < length; i++) {
int
j = trans(input, i);
// 0~9
if
(i & 1)
assert
(j == 0);
else
assert
(j != 0);
if
(!check(key, j)) j = 9;
for
(
int
a = 0; a < 5; a++) {
for
(
int
b = 0; b < 4; b++) {
key[a][b] ^= _flag[j][b];
}
}
if
(j == 9) {
_flag[9][1] = ~_flag[9][1] & 0x7f;
}
}
int
a = 0;
int
b = 0;
for
(
int
i = 0; i < 5; i++) {
a ^= key[i][0] ^ key[i][2];
b ^= key[i][1] ^ key[i][3];
}
return
(a & 0x1f) == 0 && (b & 0x1f) == 0;
}
int
check(
char
* input,
int
length) {
char
_flag[10][4];
char
key[5][4];
for
(
int
i = 0; i < length; i++) {
int
j = trans(input, i);
// 0~9
if
(i & 1)
assert
(j == 0);
else
assert
(j != 0);
if
(!check(key, j)) j = 9;
for
(
int
a = 0; a < 5; a++) {
for
(
int
b = 0; b < 4; b++) {
key[a][b] ^= _flag[j][b];
}
}
if
(j == 9) {
_flag[9][1] = ~_flag[9][1] & 0x7f;
}
}
int
a = 0;
int
b = 0;
for
(
int
i = 0; i < 5; i++) {
a ^= key[i][0] ^ key[i][2];
b ^= key[i][1] ^ key[i][3];
}
return
(a & 0x1f) == 0 && (b & 0x1f) == 0;
}
01000
10101
00000
00001
00000
00010
00000
00100
00000
01000
00000
10000
00001
00000
00010
00000
00100
00000
01000
00000
10000
00000
01000
10101
00000
00001
00000
00010
00000
00100
00000
01000
00000
10000
00001
00000
00010
00000
00100
00000
01000
00000
10000
00000
#!/usr/bin/env python3
def
check(
input
):
_flag
=
list
(b
'flag{BzcZDnfNIqmQCtkTGlwLyDYeiHIjxSXwkRKzpFPv}\x00\x00'
)
key
=
list
(b
'Can you crack me?^olo^\x00\x00'
)
v7
=
_flag[
42
]
for
i
in
range
(
len
(
input
)):
c
=
input
[i]
v9
=
(c
+
(
0xFFFEC610
>> (i
%
31
)))
%
10
assert
(i &
1
)
=
=
int
(v9 <
1
)
v26
=
0
for
j
in
range
(
4
):
v26 |
=
(key[
16
+
j] ^ key[
12
+
j] ^ key[
8
+
j] ^ key[
4
+
j] ^ key[j]) << (
8
*
j)
# print(hex(v26))
# print(((v26 >> 16) ^ v26) & 0x1f, ((v26 >> 24) ^ (v26 >> 8)) & 0x1f)
while
v9 >
=
1
:
if
v9 >
=
6
:
if
(v26 ^ (v26 >>
16
)) &
0x1f
!
=
0
:
v9
=
9
break
else
:
v12
=
(v26 >>
24
) &
0xff
v13
=
13
-
v9
v14
=
(v26 >>
8
) &
0xff
else
:
v12
=
(v26 >>
16
) &
0xff
v13
=
8
-
v9
v14
=
v26 &
0xff
# print(bin(v12)[2:].rjust(8, '0'), bin(v14)[2:].rjust(8, '0'), v13)
if
(((v14 << v13)
+
0x80
) &
0xff
) !
=
((v12 << v13) &
0xff
):
v9
=
9
break
if
v9:
print
(v9, end
=
' '
)
for
i
in
range
(
5
):
for
j
in
range
(
4
):
key[
4
*
i
+
j] ^
=
_flag[
4
*
v9
+
5
+
j]
if
v9 >
8
:
v7
=
~v7 &
0x7f
_flag[
42
]
=
v7
# 42 - 5 = 37, (9, 1)
print
()
v26
=
0
for
j
in
range
(
4
):
v26 |
=
(key[
16
+
j] ^ key[
12
+
j] ^ key[
8
+
j] ^ key[
4
+
j] ^ key[j]) << (
8
*
j)
print
(
hex
(v26),
bin
(((v26 >>
16
) ^ v26) &
0x1f
)[
2
: ].rjust(
5
,
'0'
),
bin
(((v26 >>
24
) ^ (v26 >>
8
)) &
0x1f
)[
2
: ].rjust(
5
,
'0'
))
if
((v26 >>
16
) ^ v26) &
0x1f
!
=
0
or
((v26 >>
24
) ^ (v26 >>
8
)) &
0x1f
!
=
0
:
return
False
else
:
return
True
'''
flag = [0x3f] * 62
for i in range(len(flag)):
if i & 1:
flag[i] = (10 - (0xFFFEC610 >> (i % 31))) % 10
else:
flag[i] = (9 - (0xFFFEC610 >> (i % 31))) % 10
while flag[i] < 0x30:
flag[i] += 10
print(bytes(flag))
# 38968638916054237581658165816584705954700796332849074907490749
print(check(bytes(flag)))
'''
key
=
b
'Can you crack me?^ol'
s
=
[
0
]
*
2
for
i
in
range
(
2
):
for
j
in
range
(
0
,
len
(key),
4
):
s[i] ^
=
(key[j
+
i] ^ key[j
+
i
+
2
]) &
0x1f
_flag
=
b
'BzcZDnfNIqmQCtkTGlwLyDYeiHIjxSXwkRKzpFPvp9Pv'
# _flag = b'BzcZDnfNIqmQCtkTGlwLyDYeiHIjxSXwkRKzp9Pv'
t
=
[]
for
i
in
range
(
11
):
t.append([])
for
j
in
range
(
2
):
t[
-
1
].append((_flag[
4
*
i
+
j] ^ _flag[
4
*
i
+
j
+
2
]) &
0x1f
)
print
(
' '
.join(
bin
(i)[
2
:].rjust(
5
,
'0'
)
for
i
in
s[::
-
1
]))
print
()
for
_t
in
t:
print
(
' '
.join(
bin
(i)[
2
:].rjust(
5
,
'0'
)
for
i
in
_t[::
-
1
]))
flag
=
[]
values
=
[
# 01000 10101
1
,
# 01000 10110
2
,
# 01000 10011
1
,
# 01000 10000
5
,
# 01001 10001
1
,
# 01001 10010
2
,
# 01001 10111
1
,
# 01001 10100
3
,
# 01001 11101
1
,
# 01001 11110
2
,
# 01001 11011
1
,
# 01001 11000
4
,
# 01001 01001
1
,
# 01001 01010
2
,
# 01001 01111
1
,
# 01001 01100
3
,
# 01001 00101
1
,
# 01001 00110
2
,
# 01001 00011
1
,
# 01001 00000
6
,
# 01011 00001
1
,
# 01011 00010
2
,
# 01011 00111
1
,
# 01011 00100
3
,
# 01011 01101
1
,
# 01011 01110
2
,
# 01011 01011
1
,
# 01011 01000
4
,
# 01011 11001
1
,
# 01011 11010
2
,
# 01011 11111
1
,
# 01011 11100
3
,
# 01011 10101
1
,
# 01011 10110
2
,
# 01011 10011
1
,
# 01011 10000
5
,
# 01010 10001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
7
,
# 01110 00001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
5
,
# 01111 10001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
6
,
# 01101 00001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
5
,
# 01100 10001
1
,
# 01100 10010
2
,
# 01100 10111
1
,
# 01100 10100
3
,
# 01100 11101
1
,
# 01100 11110
2
,
# 01100 11011
1
,
# 01100 11000
4
,
# 01100 01001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
# 01100 00000
8
,
# 00100 00001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
5
,
# 00101 10001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
6
,
# 00111 00001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
5
,
# 00110 10001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
7
,
# 00010 00001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
5
,
# 00011 10001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
6
,
# 00001 00001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
5
,
# 00000 10001
1
,
2
,
1
,
3
,
1
,
2
,
1
,
4
,
1
,
2
,
1
,
3
,
1
,
2
,
1
,
]
values
+
=
[
9
,
9
,
9
,
9
]
*
0
for
i
in
range
(
2
*
len
(values)):
if
i &
1
:
flag.append((
0
-
(
0xFFFEC610
>> (i
%
31
)))
%
10
)
else
:
flag.append((values[i
/
/
2
]
-
(
0xFFFEC610
>> (i
%
31
)))
%
10
)
while
flag[
-
1
] <
0x30
:
flag[
-
1
]
+
=
10
print
(bytes(flag))
print
(check(bytes(flag)))
# 582606981190746395118531851185249089744027265368693769576937697816165851808443150195011501950410798490871663488927792799277958360668112074539521851185318514909974002766535869476937695769681626582180144305010501950115040079949037162348792789277927995826067811907483951185218511853490897410272653986937694769376988161658318084433501950105019504207984904716634829277927892779584606681100745395418511852185149009740027365358697769376947696816365821809443050125019501050400790490371673487927
# 58260698119074639511853185118524908974402726536869376957693769781616585180844315019501150195041079849087166348892779279927795836066811207453952185118531851490997400276653586947693769576968162658218014430501050195011504007994903716234879278927792799582606781190748395118521851185349089741027265398693769476937698816165831808443350195010501950420798490471663482927792789277958460668110074539541851185218514900974002736535869776937694769681636582180944305012501950105040079049037167348792749074907
# 5826069811907463951185318511852490897440272653686937695769376978161658518084431501950115019504107984908716634889277927992779583606681120745395218511853185149099740027665358694769376957696816265821801443050105019501150400799490371623487927892779279958260678119074839511852185118534908974102726539869376947693769881616583180844335019501050195042079849047166348292779278927795846066811007453954185118521851490097400273653586977693769476968163658218094430501250195010504007904903716734879274907490749389686
# 582606981190746395118531851185249089744027265368693769576937697816165851808443150195011501950410798490871663488927792799277958360668112074539521851185318514909974002766535869476937695769681626582180144305010501950115040079949037162348792789277927995826067811907483951185218511853490897410272653986937694769376988161658318084433501950105019504207984904716634829277927892779584606681100745395418511852185149009740027365358697769376947696816365821809443050125019501050400790490371673487927490749074938968638916054
# 58260698119074639511853185118524908974402726536869376957693769781616585180844315019501150195041079849087166348892779279927795836066811207453952185118531851490997400276653586947693769576968162658218014430501050195011504007994903716234879278927792799582606781190748395118521851185349089741027265398693769476937698816165831808443350195010501950420798490471663482927792789277958460668110074539541851185218514900974002736535869776937694769681636582180944305012501950105040079049037167348792749074907493896863891605423758165
# 5826069811907463951185318511852490897440272653686937695769376978161658518084431501950115019504107984908716634889277927992779583606681120745395218511853185149099740027665358694769376957696816265821801443050105019501150400799490371623487927892779279958260678119074839511852185118534908974102726539869376947693769881616583180844335019501050195042079849047166348292779278927795846066811007453954185118521851490097400273653586977693769476968163658218094430501250195010504007904903716734879274907490749389686389160542375816581658165
#!/usr/bin/env python3
def
check(
input
):
_flag
=
list
(b
'flag{BzcZDnfNIqmQCtkTGlwLyDYeiHIjxSXwkRKzpFPv}\x00\x00'
)
key
=
list
(b
'Can you crack me?^olo^\x00\x00'
)
v7
=
_flag[
42
]
for
i
in
range
(
len
(
input
)):
c
=
input
[i]
v9
=
(c
+
(
0xFFFEC610
>> (i
%
31
)))
%
10
assert
(i &
1
)
=
=
int
(v9 <
1
)
v26
=
0
for
j
in
range
(
4
):
v26 |
=
(key[
16
+
j] ^ key[
12
+
j] ^ key[
8
+
j] ^ key[
4
+
j] ^ key[j]) << (
8
*
j)
# print(hex(v26))
# print(((v26 >> 16) ^ v26) & 0x1f, ((v26 >> 24) ^ (v26 >> 8)) & 0x1f)
while
v9 >
=
1
:
if
v9 >
=
6
:
if
(v26 ^ (v26 >>
16
)) &
0x1f
!
=
0
:
v9
=
9
break
else
:
v12
=
(v26 >>
24
) &
0xff
v13
=
13
-
v9
v14
=
(v26 >>
8
) &
0xff
else
:
v12
=
(v26 >>
16
) &
0xff
v13
=
8
-
v9
v14
=
v26 &
0xff
# print(bin(v12)[2:].rjust(8, '0'), bin(v14)[2:].rjust(8, '0'), v13)
if
(((v14 << v13)
+
0x80
) &
0xff
) !
=
((v12 << v13) &
0xff
):
v9
=
9
break
if
v9:
print
(v9, end
=
' '
)
for
i
in
range
(
5
):
for
j
in
range
(
4
):
key[
4
*
i
+
j] ^
=
_flag[
4
*
v9
+
5
+
j]
if
v9 >
8
:
v7
=
~v7 &
0x7f
_flag[
42
]
=
v7
# 42 - 5 = 37, (9, 1)
print
()
v26
=
0
for
j
in
range
(
4
):
v26 |
=
(key[
16
+
j] ^ key[
12
+
j] ^ key[
8
+
j] ^ key[
4
+
j] ^ key[j]) << (
8
*
j)
print
(
hex
(v26),
bin
(((v26 >>
16
) ^ v26) &
0x1f
)[
2
: ].rjust(
5
,
'0'
),
bin
(((v26 >>
24
) ^ (v26 >>
8
)) &
0x1f
)[
2
: ].rjust(
5
,
'0'
))
if
((v26 >>
16
) ^ v26) &
0x1f
!
=
0
or
((v26 >>
24
) ^ (v26 >>
8
)) &
0x1f
!
=
0
:
return
False
else
:
return
True
'''
flag = [0x3f] * 62
for i in range(len(flag)):
if i & 1:
flag[i] = (10 - (0xFFFEC610 >> (i % 31))) % 10
else:
flag[i] = (9 - (0xFFFEC610 >> (i % 31))) % 10
while flag[i] < 0x30:
flag[i] += 10
print(bytes(flag))
# 38968638916054237581658165816584705954700796332849074907490749
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
看原图
赞赏
雪币:
留言: