CTF_RE常见题

264 阅读6分钟

一些题目解出来不对,可能是有细微改动,函数少的可以挨个翻,或者ctrl+x交叉引用

一.base系列

1.换表

调换位置,动调,插入等等

2.自定义函数

base64是四个字符,三个字节一组

自定义Base64编码表

custom_base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

def custom_base64_encode(data): # 将字符串转换为对应的 ASCII 码序列 ascii_codes = [ord(c) for c in data]

# 将 ASCII 码序列转换为二进制表示
binary_string = ''.join(format(c, '08b') for c in ascii_codes)

# 补零操作,使得二进制字符串长度能被6整除
while len(binary_string) % 6 != 0:
    binary_string += '00'

# 按照每6位分组,并根据自定义编码表进行映射
base64_result = ''
for i in range(0, len(binary_string), 6):
    index = int(binary_string[i:i+6], 2)
    base64_result += custom_base64_table[index]

# 添加padding
padding_length = (4 - len(base64_result) % 4) % 4
base64_result += padding_length * '='

return base64_result

测试自定义Base64编码

input_data = "Hello, World!" encoded_data = custom_base64_encode(input_data) print(encoded_data)

或者123456789--》MTIzNDU2Nzg5

*注意:可能会有其他操作,如大小写转换,切片换位

import base64
table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
new=list(table)
for i in range(6,15):
    v1=new[i+10]
    new[i+10]=new[i]
    new[i]=v1
print(''.join(new))
enc='zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9'.swapcase()
my_table=''.join(new)
model=table
res=''
for i in range(len(enc)):
    res+=model[my_table.find(enc[i])]
print(base64.b64decode(res))
flag='FGFqMA4BLT8lES01UEEJRDIBZjE/FCIqKCYCDRRTMVV7Tw=='
a=base64.b64decode(flag).decode("utf-8")
print(a)
###################################
str='goldenticket'
str_bytes=str.encode('utf-8')
encoded_bytes=base64.b64encode(str_bytes)
enstr=encoded_bytes.decode('utf-8')
print(enstr)

二,数据类型间操作

大到小类型转换

image.png

10个int--》40个byte

hex_v7=[0x9FDFF04, 0xB0F301,0xadf00500,0x5170607, 0x17FD17EB,0x1EE01EA,0xFA05B1EA, 0xAC170108, 0xFDEA01EC,0x60705F0]
flag=''
for i in range(len(hex_v7)):
    flag+=chr(((((hex_v7[i]>>0)&0xff)+86)^0x32)%128)
    flag += chr(((((hex_v7[i] >> 8) & 0xff) + 86) ^ 0x32) % 128)
    flag += chr(((((hex_v7[i] >> 16) & 0xff) + 86) ^ 0x32) % 128)
    flag += chr(((((hex_v7[i] >> 24) & 0xff) + 86) ^ 0x32) % 128)
print(flag)
##   0xabcd>>8---->0x00ab

2.[LitCTF 2023]debase64

image.png

HIBYTE(),BYTE2(),BYTE1(),LOBYTE()是宏函数,取最高字节~最低字节

*注意数据小端序,三个字节一组,故0xff不要了

import base64
str_encoded = [0x46, 0xed, 0x18, 0x96, 0x56, 0x9E, 0xd2, 0x72, 0xb2, 0xb3, 0x80, 0x70]
bytes_encoded = bytes(str_encoded)
decoded_bytes = base64.b64encode(bytes_encoded).decode('utf-8')
print(decoded_bytes)

得到Ru0Yllae0nKys4Bw,不对 四个一组逆序一下

enc=b'Ru0Yllae0nKys4Bw'
enc_re=b''.join(enc[i:i+4][::-1] for i in range(0,len(enc),4))
print(enc_re)

最后有md5爆破 再根据题目描述,后面有三个等号,那么 len(flag)+3 = 19。flag长度为20

import hashlib
import string
en_flag = 'Y0uReallyKn0wB4s'
for i in string.printable:
    end = en_flag + i + '==='
    if hashlib.md5(end.encode()).hexdigest() == '5a3ebb487ad0046e52db00570339aace':
        print(end)
        exit()

3.hgame (int--byte)

image.png

v8=[0]*10
v8[0] = 0x9FDFF04
v8[1] = 0xB0F301
v8[2] = 0xADF00500
v8[3] = 0x5170607
v8[4] = 0x17FD17EB
v8[5] = 0x1EE01EA
v8[6] = 0xFA05B1EA
v8[7] = 0xAC170108
v8[8] = 0xFDEA01EC
v8[9] = 0x60705F0
byte_data=[]
enc=[]
for i in range(10):
    byte_data.append(v8[i].to_bytes(4,byteorder='little'))
for m in range(10):
    for n in range(4):
        enc.append(hex(byte_data[m][n]))
print(enc)
res=''
for j in range(len(enc)):
    res+=chr(((int(enc[j],16)+86)^0x32)&0xff)
print(res)

if ( s[i] != (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i]) )

sub_4007C0(); 06f1546d-f90b-46d7-acbf-9f4edf265b565740.png

Buf1 = 0i64;表示一个为0的64位的整数

三,查找

image.png

image.png

image.png 计算所在位置

image.png

image.png 字符串切片换位置

image.png

0x04. 运行获取 flag
#include <stdio.h>
int main(int argc, char* argv[]) {
const char* off_409004 = "Andromeda";
const char* off_409008 = "Messier";
const char* off_40900C = "Sombrero";
const char* off_409010 = "Triangulum";
char flag[20] = {0};
flag[0] = off_409004[8];
flag[1] = off_409010[7];
flag[2] = off_409008[4];
flag[3] = off_409004[6];
flag[4] = off_409004[1];
flag[5] = off_409008[2];
flag[6] = 95;
flag[7] = off_409004[8];
flag[8] = off_409004[3];
flag[9] = off_40900C[5];
flag[10] = 95;
flag[11] = off_409004[8];
flag[12] = off_409004[3];
flag[13] = off_409004[4];
flag[14] = off_409010[6];
flag[15] = off_409010[4];
flag[16] = off_409004[2];
flag[17] = 95;
flag[18] = off_409010[6];
flag[19] = off_409008[3];
flag[20] = 0;
printf("%s\n", flag);
return 0
}

四,进制转换

image.png

unsigned int hash = first * 31337 + (second % 17) * 11 + 7 - 1615810207;
cout << hash << endl;
cout <<hex<<hash<< endl;

五,语言源代码

#include <stdio.h>
#include <pthread.h>

#define FLAG_LEN 20

void * checking(void *arg) {
    char *result = malloc(sizeof(char));
    char *argument = (char *)arg;
    *result = (argument[0]+argument[1]) ^ argument[2];//=0,即两个数相等
    return result;
}

int highly_optimized_parallel_comparsion(char *user_string)
{
    int initialization_number;
    int i;
    char generated_string[FLAG_LEN + 1];
    generated_string[FLAG_LEN] = '\0';

    while ((initialization_number = random()) >= 64); 
    
    int first_letter;
    first_letter = (initialization_number % 26) + 97;//大写字母

    pthread_t thread[FLAG_LEN];
    char differences[FLAG_LEN] = {0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7};
    char *arguments[20];
    for (i = 0; i < FLAG_LEN; i++) {
        arguments[i] = (char *)malloc(3*sizeof(char));
        arguments[i][0] = first_letter;
        arguments[i][1] = differences[i];
        arguments[i][2] = user_string[i];

        pthread_create((pthread_t*)(thread+i), NULL, checking, arguments[i]);
    }

    void *result;
    int just_a_string[FLAG_LEN] = {115, 116, 114, 97, 110, 103, 101, 95, 115, 116, 114, 105, 110, 103, 95, 105, 116, 95, 105, 115};
    for (i = 0; i < FLAG_LEN; i++) {
        pthread_join(*(thread+i), &result);
        generated_string[i] = *(char *)result + just_a_string[i]; //result==0
        free(result);
        free(arguments[i]);
    }

    int is_ok = 1;
    for (i = 0; i < FLAG_LEN; i++) {
        if (generated_string[i] != just_a_string[i])
            return 0;
    }

    return 1;
}

int main()
{
    char *user_string = (char *)calloc(FLAG_LEN+1, sizeof(char));
    fgets(user_string, FLAG_LEN+1, stdin);
    int is_ok = highly_optimized_parallel_comparsion(user_string);
    if (is_ok)
        printf("You win!\n");
    else
        printf("Wrong!\n");
    return 0;
}

int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(start_routine)(void),void *arg);

创建新线程,成功返回0,否则numbererror

pthread_t *thread 线程标识符,pthread_attr_t *attr 设置线程属性(为null,则默认属性)

int pthread_join(pthread_t thread, void **value_ptr); thread:等待退出线程的线程号。 value_ptr:退出线程的返回值

给机器码或者汇编代码

一样先拖进ida中,可以看看各个窗口,转字符