目录
题目附件链接:https://pan.baidu.com/s/1CcS8BPGx8fKnsJgRvEi0bA?pwd=t2yj
提取码:t2yj
一.Dump得到pyc文件
使用命令:python pyinstxtractor.py snake.exe
二.pyc反编译得到py源码
在线反编译工具python反编译 - 在线工具 (tool.lu)
这里%e8%b4%aa...是url编码,可以用url编码在线解密修复
三.分析程序逻辑
代码:
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.8
''' 贪吃蛇小游戏 '''
import random
import sys
import time
import pygame
from pygame.locals import *
from collections import deque
FLAG_IS_ME = "import hashlib \nimport string \nsalt_1 = 'xxxxxxxxxxx' \nsalt_2 = 'xxxxxxxxxxx' \nsalt_3 = 'xxxxxxxxxxx' \nsalt = salt_1 + salt_2 + salt_3 \ndata = 'HZNUCTF{xxxxx}' #5位 ascii+digits+_ \nsalt_data = salt + data \ndata_sha = hashlib.sha256(salt_data.encode('utf-8')).hexdigest() \nprint(data_sha) #c08521f3c380906d05ee8afbc7fa2943afb3788d9cec94c1b86771ee35ca4738"
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 480
SIZE = 20
def print_text(screen, font, x, y, text, fcolor=((255, 255, 255),)):
imgText = font.render(text, True, fcolor)
screen.blit(imgText, (x, y))
def main():
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('贪吃蛇')
light = (100, 100, 100)
dark = (200, 200, 200)
font1 = pygame.font.SysFont('SimHei', 24)
font2 = pygame.font.Font(None, 72)
red = (200, 30, 30)
(fwidth, fheight) = font2.size('GAME OVER')
line_width = 1
black = (0, 0, 0)
bgcolor = (40, 40, 60)
pos_x = 1
pos_y = 0
b = True
scope_x = (0, SCREEN_WIDTH // SIZE - 1)
scope_y = (2, SCREEN_HEIGHT // SIZE - 1)
snake = deque()
food_x = 0
food_y = 0
def _init_snake():
snake.clear()
snake.append((2, scope_y[0]))
snake.append((1, scope_y[0]))
snake.append((0, scope_y[0]))
def _create_food():
food_x = random.randint(scope_x[0], scope_x[1])
food_y = random.randint(scope_y[0], scope_y[1])
if (food_x, food_y) in snake:
food_x = random.randint(scope_x[0], scope_x[1])
food_y = random.randint(scope_y[0], scope_y[1])
continue
_init_snake()
_create_food()
game_over = True
start = False
score = 0
orispeed = 0.5
speed = orispeed
last_move_time = None
pause = False
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
continue
if event.type == KEYDOWN or event.key == K_RETURN or game_over:
start = True
game_over = False
b = True
_init_snake()
_create_food()
pos_x = 1
pos_y = 0
score = 0
last_move_time = time.time()
continue
if not event.key == K_SPACE or game_over:
pause = not pause
continue
if not (event.key in (K_w, K_UP) or b) and pos_y:
pos_x = 0
pos_y = -1
b = False
continue
if not (event.key in (K_s, K_DOWN) or b) and pos_y:
pos_x = 0
pos_y = 1
b = False
continue
if not (event.key in (K_a, K_LEFT) or b) and pos_x:
pos_x = -1
pos_y = 0
b = False
continue
if not event.key in (K_d, K_RIGHT) and b and pos_x:
pos_x = 1
pos_y = 0
b = False
continue
screen.fill(bgcolor)
for x in range(SIZE, SCREEN_WIDTH, SIZE):
pygame.draw.line(screen, black, (x, scope_y[0] * SIZE), (x, SCREEN_HEIGHT),
line_width)
for y in range(scope_y[0] * SIZE, SCREEN_HEIGHT, SIZE):
pygame.draw.line(screen, black, (0, y), (SCREEN_WIDTH, y), line_width)
if game_over or start:
print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2,
(SCREEN_HEIGHT - fheight) // 2, 'GAME OVER', red)
else:
curTime = time.time()
if score == 10:
print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2 - 100,
(SCREEN_HEIGHT - fheight) // 2, 'salt_1 : mxx307shuai', red)
elif score == 20:
print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2 - 100,
(SCREEN_HEIGHT - fheight) // 2, 'salt_2 : mxx407shuai', red)
elif score == 30:
print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2 - 100,
(SCREEN_HEIGHT - fheight) // 2,
" salt_3 : ''.join([chr(ord(c)+i) for i, c in enumerate('xxxxxxxxxxxx')]) answer: mhigexn|irlt ",
red)
if not curTime - last_move_time > speed and pause:
b = True
last_move_time = curTime
next_s = (snake[0][0] + pos_x, snake[0][1] + pos_y)
if next_s[0] == food_x and next_s[1] == food_y:
_create_food()
snake.appendleft(next_s)
score += 10
speed = orispeed - 0.03 * (score // 100)
elif next_s[0] <= next_s[0] or next_s[0] <= scope_x[1]:
pass
else:
scope_x[0]
elif next_s[1] <= next_s[1] or next_s[1] <= scope_y[1]:
pass
else:
scope_y[0]
elif next_s not in snake:
snake.appendleft(next_s)
snake.pop()
else:
game_over = True
if not game_over:
pygame.draw.rect(screen, light, (food_x * SIZE, food_y * SIZE, SIZE, SIZE), 0)
for s in snake:
pygame.draw.rect(screen, dark, (
s[0] * SIZE + line_width, s[1] * SIZE + line_width, SIZE - line_width * 2, SIZE - line_width * 2), 0)
print_text(screen, font1, 30, 7, f'''速度: {score // 100}''')
print_text(screen, font1, 450, 7, f'''得分: {score}''')
pygame.display.update()
continue
if __name__ == '__main__':
main()
可以看到有一条提示:
FLAG_IS_ME = "import hashlib \nimport string \nsalt_1 = 'xxxxxxxxxxx' \nsalt_2 = 'xxxxxxxxxxx' \nsalt_3 = 'xxxxxxxxxxx' \nsalt = salt_1 + salt_2 + salt_3 \ndata = 'HZNUCTF{xxxxx}' #5位 ascii+digits+_ \nsalt_data = salt + data \ndata_sha = hashlib.sha256(salt_data.encode('utf-8')).hexdigest() \nprint(data_sha) #c08521f3c380906d05ee8afbc7fa2943afb3788d9cec94c1b86771ee35ca4738"z
意思是:
salt=salt1+salt2+salt3 //盐的组成
data='HZNUCTF{xxxxx}' //5位 ascii+digits+_,限定了字符范围
salt_data=salt+data //用于sha256计算的字符串是salt+data的形式
data_sha=sha256(salt_data)="c08521f3c380906d05ee8afbc7fa2943afb3788d9cec94c1b867
这里推荐一篇介绍sha256+salt的文章:Sha256Hash+salt 密码加密使用
可以在代码下方找到salt
salt_1:mxx307shuai
salt_2:mxx407shuai
salt_3:''.join([chr(ord(c)+i) for i, c in enumerate('xxxxxxxxxxxx')]) answer: mhigexn|irlt
salt3是加密过的,这条语句的作用是将字符串中的每个字符加上他在字符串中的位置,求salt3的脚本:
s=''.join([chr(ord(c)-i) for i, c in enumerate('mhigexn|irlt')])
print(s)
#mggdashuaibi
所以salt:mxx307shuaimxx407shuaimggdashuaibi
salt_data:mxx307shuaimxx407shuaimggdashuaibiHZNUCTF{xxxxx}
四.hashcat爆破
hashcat的使用这里推荐几篇文章:
这里使用Kali Linux自带的hashcat,使用命令:
hashcat -a 3 -m 1400 c08521f3c380906d05ee8afbc7fa2943afb3788d9cec94c1b86771ee35ca4738 mxx307shuaimxx407shuaimggdashuaibiHZNUCTF{?a?a?a?a?a}
其中"-a 3"指定掩码攻击模式,"-m 1400" 指定加密算法为sha256,然后跟上sha256的目标值,最后跟上掩码字符串,花括号内"?a"表示字母或数字或特殊字符
爆破结果:mxx307shuaimxx407shuaimggdashuaibiHZNUCTF{1s_R4}
得到flag:HZNUCTF{1s_R4}