目录
一.Dump得到pyc文件
二.pyc反编译得到py源码
三.分析程序逻辑
四.hashcat爆破
题目附件链接: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 dequeFLAG_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 = 20def 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 = 1black = (0, 0, 0)bgcolor = (40, 40, 60)pos_x = 1pos_y = 0b = Truescope_x = (0, SCREEN_WIDTH // SIZE - 1)scope_y = (2, SCREEN_HEIGHT // SIZE - 1)snake = deque()food_x = 0food_y = 0def _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 = Truestart = Falsescore = 0orispeed = 0.5speed = orispeedlast_move_time = Nonepause = Falsefor event in pygame.event.get():if event.type == QUIT:sys.exit()continueif event.type == KEYDOWN or event.key == K_RETURN or game_over:start = Truegame_over = Falseb = True_init_snake()_create_food()pos_x = 1pos_y = 0score = 0last_move_time = time.time()continueif not event.key == K_SPACE or game_over:pause = not pausecontinueif not (event.key in (K_w, K_UP) or b) and pos_y:pos_x = 0pos_y = -1b = Falsecontinueif not (event.key in (K_s, K_DOWN) or b) and pos_y:pos_x = 0pos_y = 1b = Falsecontinueif not (event.key in (K_a, K_LEFT) or b) and pos_x:pos_x = -1pos_y = 0b = Falsecontinueif not event.key in (K_d, K_RIGHT) and b and pos_x:pos_x = 1pos_y = 0b = Falsecontinuescreen.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 = Truelast_move_time = curTimenext_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 += 10speed = orispeed - 0.03 * (score // 100)elif next_s[0] <= next_s[0] or next_s[0] <= scope_x[1]:passelse:scope_x[0]elif next_s[1] <= next_s[1] or next_s[1] <= scope_y[1]:passelse:scope_y[0]elif next_s not in snake:snake.appendleft(next_s)snake.pop()else:game_over = Trueif 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()continueif __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的使用这里推荐几篇文章:
1.密码破解全能工具:Hashcat密码破解攻略
2.hashcat详细使用教程
3.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}












