目录
这次的春季赛仍是被打爆了,re只做出了一题,发现自己还是太菜了,好在在后期复盘中又收获了许多新知识了,不亏。
sum
获取题目附件,64位,无壳。
用IDA对程序进行反编译,找到关键的main函数。
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rbp
int v4; // r14d
unsigned int v5; // r12d
__int64 i; // rbx
char v7; // al
int v8; // eax
const char *v9; // rax
v3 = &matrix;
v4 = 1;
v5 = 0;
puts("Welcome to Solver!");
do
{
for ( i = 0LL; i != 9; ++i )
{
if ( !v3[i] )
{
v7 = getchar();
if ( (v7 - 49) > 8u )
v4 = 0;
else
v3[i] = v7 - 48;
}
v8 = v3[i];
v5 += v8;
}
v3 += 9;
}
while ( v3 != &matrix + 81 );
if ( v4 && verify("Welcome to Solver!", argv) )
{
puts("You Win!");
__snprintf_chk(buf, 32LL, 1LL, 32LL, "%d", v5);
v9 = str2md5(buf, strlen(buf));
__printf_chk(1LL, "flag is: flag{%s}\n\n", v9);
exit(0);
}
puts("Again~");
return 0;
}
v7是来获取输入内容的,matrix中存放着一些值,长度为81,一开始以为是一个9*9的迷宫题,但发现matrix中存放的不只有0和1,还有一些其他值,不像是迷宫题。
用Chatgpt帮忙辅助分析了一下,才知道这是一个九宫格数独游戏。
因此,明白了matrix中存放的是九宫格中已知的值,写脚本dump出数独:
maze = [5, 3, 0, 0, 7, 0, 0, 0, 0, 6, 0, 0, 1, 9, 5, 0, 0, 0, 0, 9, 8, 0, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 0, 0, 3, 4, 0, 0, 8, 0, 3, 0, 0, 1, 7, 0, 0, 0, 2, 0, 0, 0, 6, 0, 6, 0, 0, 0, 0, 2, 8, 0, 0, 0, 0, 4, 1, 9, 0, 0, 5, 0, 0, 0, 0, 8, 0, 0, 7, 9]
for i in range(0,len(maze)):
if i % 9 == 0:
print('\n')
print(maze[i],end=" ")
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 0
8 0 0 0 6 0 0 0 3
4 0 0 8 0 3 0 0 1
7 0 0 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
数独中的0就是需要填的位置,找到一个在线解数独的网站在线数独求解器 (gwalker.cn)
这里想吐槽一下自己太粗心了,把绿色块当成是解出来的值,实际白色块才是解出来的。
468912723481342575971422657913948591537428763345261
接着将解出的值输入到程序中即可拿到flag。
FLAG:flag{bbcbff5c1f1ded46c25d28119a85c6c2}
Pytrans
获取题目文件,64位,无壳。
根据题目介绍猜测是用python编写的程序,所以可以直接用pyinstxtractor转成pyc文件,再用uncompyle6转成py文件。
# uncompyle6 version 3.9.0
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)]
# Embedded file name: run.py
import base64, zlib, ctypes
try:
mylib = ctypes.cdll.LoadLibrary('./mylib.so')
except:
print('file no exit!')
else:
a = []
try:
sstr = input("Please enter the 10 digits and ending with '\\n': ").split(' ')
if len(sstr) == 10:
for i in sstr:
a.append(int(i))
mylib.check.argtypes = (
ctypes.POINTER(ctypes.c_int), ctypes.c_int)
mylib.check.restype = ctypes.c_char_p
scrambled_code_string = mylib.check((ctypes.c_int * len(a))(*a), len(a))
try:
decoded_data = base64.b64decode(scrambled_code_string)
uncompressed_data = zlib.decompress(decoded_data)
exec(__import__('marshal').loads(uncompressed_data))
except:
print('Incorrect input caused decryption failure!')
except:
pass
# okay decompiling run.pyc
可以看见程序调用了一个mylib.so库,从pyinstxtractor导出的文件中找到mylib.so库。
放入IDA中进行分析,找到check函数。
void *__fastcall check(_DWORD *x)
{
void *v2; // [rsp+18h] [rbp-28h]
char v3[24]; // [rsp+20h] [rbp-20h] BYREF
unsigned __int64 v4; // [rsp+38h] [rbp-8h]
v4 = __readfsqword(0x28u);
sub_1239();
if ( -27 * x[7] + -11 * x[6] + 16 * x[5] + *x + 2 * x[1] - x[2] + 8 * x[3] - 14 * x[4] + 26 * x[8] + 17 * x[9] != 14462
|| -30 * x[8] + 13 * x[5] + x[3] + x[1] + 2 * *x - 15 * x[4] - 24 * x[6] + 16 * x[7] + 36 * x[9] != -2591
|| 16 * x[6] + -21 * x[5] + 7 * x[3] + 3 * x[1] - *x - x[2] + 12 * x[4] - 23 * x[7] + 25 * x[8] - 18 * x[9] != 2517
|| -6 * x[6] + 2 * x[2] - x[1] + 2 * x[5] + 9 * x[7] + 2 * x[8] - 5 * x[9] != 203
|| -5 * x[8] + 6 * x[7] + 3 * x[1] - x[3] - x[5] + x[6] + 5 * x[9] != 3547
|| -9 * x[8] + x[4] + x[2] + x[7] - 5 * x[9] != -7609
|| 2 * x[5] + -x[3] - x[4] + x[8] + 6 * x[9] != 4884
|| x[6] - x[7] + 2 * x[8] != 1618
|| x[4] - x[6] + 2 * x[9] != 1096
|| x[8] + x[4] + x[3] + x[2] + x[1] + *x - x[5] - x[6] - x[7] - x[9] != 711
|| 2 * (2 * x[4] + x[3]) + 5 * x[5] != 7151 )
{
return 0LL;
}
v3[0] = 0;
v3[1] = 0;
v3[2] = 0;
v3[3] = 0;
v3[4] = 0;
v3[5] = 0;
v3[6] = 0;
v3[7] = 0;
v3[8] = 0;
v3[9] = 0;
v3[10] = 0;
v3[11] = 0;
v3[12] = 0;
v3[13] = 0;
v3[14] = 0;
v3[15] = x[4] % 255;
v2 = malloc(0x4F0uLL);
sub_27E4(&unk_62C0, v2, v3);
return v2;
}
这里对输入值进行了比较,可以用z3进行求解来得出正确的输入值,脚本如下:
from z3 import *
def main():
x = [BitVec("x%d"%i,16)for i in range(10)]
s = Solver()
s.add( -27 * x[7] + -11 * x[6] + 16 * x[5] + x[0] + 2 * x[1] - x[2] + 8 * x[3] - 14 * x[4] + 26 * x[8] + 17 * x[9] == 14462)
s.add( -30 * x[8] + 13 * x[5] + x[3] + x[1] + 2 * x[0] - 15 * x[4] - 24 * x[6] + 16 * x[7] + 36 * x[9] == -2591)
s.add( 16 * x[6] + -21 * x[5] + 7 * x[3] + 3 * x[1] - x[0] - x[2] + 12 * x[4] - 23 * x[7] + 25 * x[8] - 18 * x[9] == 2517)
s.add( -6 * x[6] + 2 * x[2] - x[1] + 2 * x[5] + 9 * x[7] + 2 * x[8] - 5 *