复现LitCTF 2023的RE部分题

发布时间 2023-11-28 20:30:43作者: kelec0ka

[LitCTF 2023]世界上最棒的程序员

签到题

pe查壳,无壳32位,拖入IDA中

image

打开start函数

image

[LitCTF 2023]ez_XOR

pe查壳,无壳32位,拖入IDA中

image

一道xor题,打开XOR函数

image

编写脚本

#include<stdio.h>
#include<string.h>
int main() 
{
	int i;
	const char* s = "E`}J]OrQF[V8zV:hzpV}fVF[t";
	for (i = 0; i < strlen(s); i++)
	{
		printf("%c", s[i] ^ 9);
	}
}

得到flag

image

[LitCTF 2023]enbase64

pe查壳,无壳32位,拖入IDA中

image

看看base64函数

image

看到basechange函数

image

看看basecheck

image

初步判定为换表题

先用脚本生成新表

#include <string.h>
#include <stdio.h>
int main() {
	int v3[65];
	char Source[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	char Destination[65];
	v3[0] = 16;
	v3[1] = 34;
	v3[2] = 56;
	v3[3] = 7;
	v3[4] = 46;
	v3[5] = 2;
	v3[6] = 10;
	v3[7] = 44;
	v3[8] = 20;
	v3[9] = 41;
	v3[10] = 59;
	v3[11] = 31;
	v3[12] = 51;
	v3[13] = 60;
	v3[14] = 61;
	v3[15] = 26;
	v3[16] = 5;
	v3[17] = 40;
	v3[18] = 21;
	v3[19] = 38;
	v3[20] = 4;
	v3[21] = 54;
	v3[22] = 52;
	v3[23] = 47;
	v3[24] = 3;
	v3[25] = 11;
	v3[26] = 58;
	v3[27] = 48;
	v3[28] = 32;
	v3[29] = 15;
	v3[30] = 49;
	v3[31] = 14;
	v3[32] = 37;
	v3[34] = 55;
	v3[35] = 53;
	v3[36] = 24;
	v3[37] = 35;
	v3[38] = 18;
	v3[39] = 25;
	v3[40] = 33;
	v3[41] = 43;
	v3[42] = 50;
	v3[43] = 39;
	v3[44] = 12;
	v3[45] = 19;
	v3[46] = 13;
	v3[47] = 42;
	v3[48] = 9;
	v3[49] = 17;
	v3[50] = 28;
	v3[51] = 30;
	v3[52] = 23;
	v3[53] = 36;
	v3[54] = 1;
	v3[55] = 22;
	v3[56] = 57;
	v3[57] = 63;
	v3[58] = 8;
	v3[59] = 27;
	v3[60] = 6;
	v3[61] = 62;
	v3[62] = 45;
	v3[63] = 29;
	strcpy(Destination, Source);
	for (int i = 0; i <= 47; ++i) {
		for (int j = 0; j <= 63; ++j)
			Source[j] = Destination[v3[j]];
		strcpy(Destination, Source);
	}
	printf("%s", Destination);
}

很奇怪,在VS上跑不出来,即便加了#define _CRT_SECURE_NO_WARNINGS也不行,有木有大神解释一下,最终在菜鸟上跑出来了

image

再把这个表和之前看到的

image

放到赛博厨子里去

image

拿到flag

[LitCTF 2023]snake

新人第一次拿到python逆向,看了看网上的反编译方法,链接:py反编译

发现在线反编译不行,遂接着看

用uncompyle6反编译也不可行,没办法了,看了看wp,发现需要进行python文件magic的修复

下面是关于pyc文件magic的修复:

放入hex里面发现e3前面全是0,正常的pyc文件前面应该有Magic number和时间戳

Python3.3以下的版本中,只有Magic Number和四位时间戳
Python3.3到Python3.7(不包含3.7)版本中,只有Magic Number和八位时间戳 + 大小信息
Python3.7及以上版本的编译后二进制文件中,头部除了四字节Magic Number,还有四个字节的空位和八个字节的时间戳 + 大小信息,后者对文件反编译没有影响,全部填充0即可

这里是参考博客参考

但是不知道此题的py版本,于是一个个的试,发现为python3.7,文件头改为42 0d 0d 0a

接着配置反编译pycdc,参考pycdc

然后开始反编译,结果寄了...

image

看看问题出在哪,搜了一晚上没发现跟我有一样错误的人,到回来看发现《2023]》?好吧...把文件名改成1.pyc

反编译成功

'''璐悆铔?''
import random
import sys
import time
import 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('璐悆铔?

为什么它反编译不全啊?!缺了一大块,好烦!

还是用在线的吧

# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.7

'''贪吃蛇'''
import random
import sys
import time
import 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 None:
        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
                snake = init_snake()
                food = create_food(snake)
                food_style = get_food_style()
                pos = (1, 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[1]:
                        pos = (0, -1)
                        b = False
                        continue
                        if not (event.key in (K_s, K_DOWN) or b) and pos[1]:
                            pos = (0, 1)
                            b = False
                            continue
                            if not (event.key in (K_a, K_LEFT) or b) and pos[0]:
                                pos = (-1, 0)
                                b = False
                                continue
                                if not event.key in (K_d, K_RIGHT) and b and pos[0]:
                                    pos = (1, 0)
                                    b = False
                                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 not game_over:
            curTime = time.time()
            if not curTime - last_move_time > speed and 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()
                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, 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, 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] ^ 136
                flag[i + 1] = 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 and start:
            print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2, (SCREEN_HEIGHT - fheight) // 2, 'GAME OVER', RED)
        pygame.display.update()

if __name__ == '__main__':
    main()

好长一截,直接看关键部分吧

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] ^ 136
                flag[i + 1] = flag[i] ^ 119

编写脚本时只需要把后面部分改为以下内容即可

for i in range(0, len(flag), 2):
    temp = flag[i]
    flag[i] = flag[i + 1] ^ 136
    flag[i + 1] = temp ^ 119
    print(chr(flag[i]),end='')
    print(chr(flag[i+1]),end='')

image

如果不加end=''就会变成这样

image

完工!