LitCTF 2023--Reverse

发布时间 2023-10-08 16:59:05作者: TFOREVERY

世界上最棒的程序员(签到题,进去就送)

进IDA或者OD都可以:

拿到LitCTF{I_am_the_best_programmer_ever}

ez_xor(简单异或)

进IDA能看到大大的XOR

拿到异或的文档“E`}J]OrQF[V8zV:hzpV}fVF[t”,因为是简单的异或,用这个来运行一下,动调即可:

拿到LitCTF{XOR_1s_3asy_to_OR}

enbase64

进IDA:

上来就看到标码,但作为赛题又怎么可能那么简单,跟进base64:

发现basechange(改变)跟进:

简单来说就是定义了一大堆数字,用这些数据作为下标去改变标码(动调拿到改变的编码就好,不用手搓了(麻烦))

拿到改变后的标码:gJ1BRjQie/FIWhEslq7GxbnL26M4+HXUtcpmVTKaydOP38of5v90ZSwrkYzCAuND

有些人动调会遇到libgcc_s_dw2-1.dll缺失的问题,很好解决,随便在你的计算机上搜索一个libgcc_s_dw2-1.dll复制到这个文件的下边就行了,这里注意,是复制,不是剪切,剪切,你的另一个文件就会废掉。实在不行就手搓也是可以的

最后去找经过非标码base64加密后的字符串就好,跟进basecheck,拿到“GQTZlSqQXZ/ghxxwhju3hbuZ4wufWjujWrhYe7Rce7ju”,写个脚本返回去:

import base64
Str = "gJ1BRjQie/FIWhEslq7GxbnL26M4+HXUtcpmVTKaydOP38of5v90ZSwrkYzCAuND"  # 自定义base64码
model = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"  # 标准base64码
enc = "GQTZlSqQXZ/ghxxwhju3hbuZ4wufWjujWrhYe7Rce7ju"  # 目标
print(base64.b64decode(enc.translate(str.maketrans(Str, model))))

拿到LitCTF{B@5E64_l5_tooo0_E3sy!!!!!}

snake

下载后得到一个这个玩意,不用说反编译呗,那咱就做了呗

得到这个,发现事情不对了,出现这个一般说的是这个文件的magic头被改了,不是正常的magic头,进010看看

果然被改了,那么我们需要改回来,改成用这个版本python编译出来的magic头,哪个版本?它在下载出文件的时候有提示了,37,找个37版本的头:42 0D,在010中改了保存:

在IDA的Hex窗口改了也行,记得保存,都是可以的。

# uncompyle6 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)]
# Embedded file name: game.py
"""贪吃蛇"""
import random, sys, time, pygame
from pygame.locals import *
from collections import deque
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 480
SIZE = 20
LINE_WIDTH = 1
SCOPE_X = (
 0, SCREEN_WIDTH // SIZE - 1)
SCOPE_Y = (2, SCREEN_HEIGHT // SIZE - 1)
FOOD_STYLE_LIST = [
 (10, (255, 100, 100)), (20, (100, 255, 100)), (30, (100, 100, 255))]
LIGHT = (100, 100, 100)
DARK = (200, 200, 200)
BLACK = (0, 0, 0)
RED = (200, 30, 30)
BGCOLOR = (40, 40, 60)

def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
    imgText = font.render(text, True, fcolor)
    screen.blit(imgText, (x, y))


def init_snake():
    snake = deque()
    snake.append((2, SCOPE_Y[0]))
    snake.append((1, SCOPE_Y[0]))
    snake.append((0, SCOPE_Y[0]))
    return snake


def create_food(snake):
    food_x = random.randint(SCOPE_X[0], SCOPE_X[1])
    food_y = random.randint(SCOPE_Y[0], SCOPE_Y[1])
    while (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])

    return (
     food_x, food_y)


def get_food_style():
    return FOOD_STYLE_LIST[random.randint(0, 2)]


def main():
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption('贪吃蛇')
    font1 = pygame.font.SysFont('SimHei', 24)
    font2 = pygame.font.Font(None, 72)
    fwidth, fheight = font2.size('GAME OVER')
    b = True
    snake = init_snake()
    food = create_food(snake)
    food_style = get_food_style()
    pos = (1, 0)
    game_over = True
    start = False
    score = 0
    orispeed = 0.5
    speed = orispeed
    last_move_time = None
    pause = False
    while 1:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()

        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)

        curTime = game_over or time.time()
        if curTime - last_move_time > speed and not pause:
            b = True
            last_move_time = curTime
            next_s = (snake[0][0] + pos[0], snake[0][1] + pos[1])
            if next_s == food:
                snake.appendleft(next_s)
                score += food_style[0]
                speed = orispeed - 0.03 * (score // 100)
                food = create_food(snake)
                food_style = get_food_style()
            else:
                if SCOPE_X[0] <= next_s[0] <= SCOPE_X[1]:
                    if SCOPE_Y[0] <= next_s[1] <= SCOPE_Y[1]:
                        if next_s not in snake:
                            snake.appendleft(next_s)
                            snake.pop()
                        else:
                            game_over = True
                    if not game_over:
                        pygame.draw.rect(screen, food_style[1], (food[0] * SIZE, food[1] * 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}")
                    if score > 1000:
                        flag = [
                         30, 196, 
                         52, 252, 49, 220, 7, 243, 
                         3, 241, 24, 224, 40, 230, 
                         25, 251, 28, 233, 40, 237, 
                         4, 225, 4, 215, 40, 231, 
                         22, 237, 14, 251, 10, 169]
                        for i in range(0, len(flag), 2):
                            flag[i], flag[i + 1] = flag[i + 1] ^ 136, flag[i] ^ 119

                        print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2, (SCREEN_HEIGHT - fheight) // 2, bytes(flag).decode(), RED)
                        pygame.display.update()
                    if game_over:
                        if start:
                            print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2, (SCREEN_HEIGHT - fheight) // 2, 'GAME OVER', RED)
                pygame.display.update()


if __name__ == '__main__':
    main()
# okay decompiling game.cpython-37.pyc

拿到正常的代码,拿出flag那段代码小改:

flag = [30, 196, 52, 252, 49, 220, 7, 243, 3, 241, 24, 224, 40, 230, 25, 251, 28, 233, 40, 237, 4, 225, 4, 215, 40, 231, 22, 237, 14, 251, 10, 169]
flag1 = ''
for i in range(0, len(flag), 2):
    flag1 += chr(flag[i + 1] ^ 136)
    flag1 += chr(flag[i] ^ 119)
print(flag1)

拿到LitCTF{python_snake_is_so_easy!}

这边讲一下怎么在IDA中修改magic头:

光标移到开头:(保证是从头开始修改的,不然它会自动调整,这样就会改错)




把正确的头填到开始的两个就好了点击OK

能看到成功修改了。

接下来就是保存到原文件上了。



注意这里是开头修改的,所以从0开始,哪结束不重要,开始对了就行。点击OK。关了IDA,看看是否成功修改了:

成功。

For Aiur(这个有点恶心,我用uncompyle6出不来)

下载后得到

这三个程序,.exe文件扔进IDA哐哐找,啥也找不到(别问,问就是找了,没找到),怀疑有壳,看看:

被加包了,那么用pyinstxtractor解个包下载链接(找我拿也行):(https://github.com/pyinstaller/pyinstaller)

得到:进去:

emm,一堆东西,我们只找我们要的.pyc文件就可以,找到Probee.pyc文件,编它:

一般出现这种,八成是有问题了,看看反编译后的文件:

空的,那么换个工具:pycdc(window下的也行Linux下的也行)

将.pyc文件放入pycdc运行文件的目录下

Windows下输入pycdc.exe filename.pyc > filename.py(我是习惯看.py了所以转成py文件)

Linux下输入./pycdc calculator.pyc -o calculator.py(同样是转成py文件)

得到正常的反编译文件:跟进,发现导入了一个ch用来做check,在原来的包中找ch:


得到flag函数:

# uncompyle6 version 3.9.0
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)]
# Embedded file name: ch.py
enc = [
 98, 77, 94, 91, 92, 107, 125, 66, 87, 70, 113, 92, 83, 70, 85, 81, 
 19, 21, 109, 99, 87, 107, 127, 65, 65, 64, 109, 87, 93, 90, 65, 
 64, 64, 65, 81, 3, 109, 85, 86, 80, 91, 64, 91, 91, 92, 0, 94, 
 107, 66, 77, 94, 91, 92, 71]
lis = []

def check(num):
    flag = 'LitCTF{'
    if num % 2 == 0:
        if num % 4 == 0:
            if num % 6 == 0:
                if num % 8 == 0:
                    if num % 12 == 0:
                        if num % 13 == 11:
                            k = str(num)
                            for i in range(len(enc)):
                                flag += chr(ord(k[i % len(k)]) ^ enc[i])
                                lis.append(ord(k[i % len(k)]) ^ enc[i])
                            else:
                                flag += '}'
                                from cv2 import imread, imshow, namedWindow, WINDOW_NORMAL, FONT_HERSHEY_SIMPLEX, getTickCount, getTickFrequency, putText, LINE_AA, waitKey, getTextSize, resize, moveWindow, IMREAD_UNCHANGED, destroyAllWindows
                                from numpy import uint8, zeros
                                img = zeros((200, 20000, 3), uint8)
                                img.fill(255)
                                text = flag
                                font = FONT_HERSHEY_SIMPLEX
                                pos = (50, 120)
                                color = (0, 0, 0)
                                thickness = 2
                                putText(img, text, pos, font, 1, color, thickness, LINE_AA)
                                imshow('flag', img)
                                waitKey(0)
                                destroyAllWindows()
# okay decompiling D:\CTF\RE\pyinstxtractor-2023.02\Probe.exe_extracted\PYZ-00.pyz_extracted\ch.pyc

逆推即可