Table of contents
2. Decompile pyc to get py source code
Question attachment link: https://pan.baidu.com/s/1CcS8BPGx8fKnsJgRvEi0bA?pwd=t2yj
Extraction code: t2yj
1. Dump to get the pyc file
Use command: python pyinstxtractor.py snake.exe
2. Decompile pyc to get py source code
Online decompilation tool python decompilation - online tool (tool.lu)
Here%e8%b4%aa... is URL encoding, which can be decrypted and repaired online using URL encoding.
3. Analyze program logic
Code:
#!/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()
You can see a prompt:
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
Meaning:
salt=salt1+salt2+salt3 //The composition of salt
data='HZNUCTF{xxxxx}' //5 digits ascii+digits+_, limits the character range
salt_data=salt+data //The string used for sha256 calculation is in the form of salt+data
data_sha=sha256(salt_data)="c08521f3c380906d05ee8afbc7fa2943afb3788d9cec94c1b867
Here is an article introducing sha256+salt: Sha256Hash+salt password encryption use
The salt can be found below the code
salt_1:mxx307shuai
salt_2:mxx407shuai
salt_3:''.join([chr(ord(c)+i) for i, c in enumerate('xxxxxxxxxxxx')]) answer: mhigexn|irlt
salt3 is encrypted. The function of this statement is to add each character in the string to its position in the string. Find the script of salt3:
s=''.join([chr(ord(c)-i) for i, c in enumerate('mhigexn|irlt')])
print(s)
#mggdashuaibi
So salt:mxx307shuaimxx407shuaimggdashuaibi
salt_data:mxx307shuaimxx407shuaimggdashuaibiHZNUCTF{xxxxx}
4. Hashcat blasting
Here are a few articles recommended for the use of hashcat:
1. All-purpose password cracking tool: Hashcat password cracking strategy
2. Detailed usage tutorial of hashcat
3. Detailed explanation of Hashcat command
Here we use the hashcat that comes with Kali Linux and use the command:
hashcat -a 3 -m 1400 c08521f3c380906d05ee8afbc7fa2943afb3788d9cec94c1b86771ee35ca4738 mxx307shuaimxx407shuaimggdashuaibiHZNUCTF{?a?a?a?a?a}
Among them, "-a 3" specifies the mask attack mode, "-m 1400" specifies the encryption algorithm as sha256, followed by the target value of sha256, and finally followed by the mask string. "?a" in curly brackets represents letters or numbers. or special characters
Explosion result:mxx307shuaimxx407shuaimggdashuaibiHZNUCTF{1s_R4}
Get flag: HZNUCTF{1s_R4}