CyKor week9

soon_haari·2022년 7월 2일
0

Cykor Seminar (1 - 1)

목록 보기
6/6
post-thumbnail

chall6

main

int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[256]; // [rsp+20h] [rbp-118h] BYREF

memset(v4, 0, sizeof(v4));
sub_1400011B0("Input : ", argv, envp);
sub_140001210("%256s", v4);
if ( (unsigned int)sub_140001000(v4) )
    puts("Correct");
else
    puts("Wrong");
return 0;
}

sub_140001000

__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]

for ( i = 0; (unsigned __int64)i < 0x12; ++i )
{
    if ( byte_140003020[*(unsigned __int8 *)(a1 + i)] != byte_140003000[i] )
    return 0i64;
}
return 1i64;
}

byte_140003020(a1[i]) == byte_140003000[i] 를 항상 만족시켜야 함을 알 수 있다.

.data:0000000140003000 ; unsigned __int8 byte_140003000[32]
.data:0000000140003000 byte_140003000  db 0, 4Dh, 51h, 50h, 0EFh, 0FBh, 0C3h, 0CFh, 92h, 45h
.data:0000000140003000                                         ; DATA XREF: sub_140001000+40↑o
.data:0000000140003000                 db 4Dh, 0CFh, 0F5h, 4, 40h, 50h, 43h, 63h, 0Eh dup(0)

다음과 같은 코드를 사용해서 플래그를 얻을 수 있었다.

#include <stdio.h>

int main()
{
    int byte_140003000[] = { 0x00, 0x4D, 0x51, 0x50, 0xEF, 0xFB, 0xC3, 0xCF, 0x92, 0x45, 0x4D, 0xCF, 0xF5, 0x04, 0x40, 0x50, 0x43, 0x63};
    int byte_140003020[] = {
        0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67,
        0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA,
        0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72,
        0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34,
        0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23,
        0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27,
        0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52,
        0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00,
        0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A,
        0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33,
        0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3,
        0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21,
        0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97,
        0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
        0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE,
        0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A,
        0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4,
        0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C,
        0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25,
        0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B,
        0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
        0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8,
        0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9,
        0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6,
        0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16,
    };

    for(int i=0;i<sizeof(byte_140003000)/4;i++)
        for(int j=0;j< sizeof(byte_140003020)/sizeof(int);j++)
            if(byte_140003000[i]==byte_140003020[j])
                printf("%c", j);
    return 0;
}

flag

Replac3_the_w0rld




chall7

main

int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[256]; // [rsp+20h] [rbp-118h] BYREF

memset(v4, 0, sizeof(v4));
sub_140001120("Input : ", argv, envp);
sub_1400011B0("%256s", v4);
if ( (unsigned int)sub_140001000(v4) )
    puts("Correct");
else
    puts("Wrong");
return 0;
}

sub_140001000

__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]

for ( i = 0; (unsigned __int64)i < 0x1F; ++i )
{
    if ( (i ^ (unsigned __int8)__ROL1__(*(_BYTE *)(a1 + i), i & 7)) != byte_140003000[i] )
    return 0i64;
}
return 1i64;
}

ROL1 함수의 역할에 대해 알아볼 필요가 있다. 비트를 왼쪽으로 순환시키는 함수, 8비트에서 작동하는 함수이다.

i ^ __ROL1__(a1[i], i&7) == byte_140003000[i]

를 만족시켜야 한다.

#include <stdio.h>

int ROR(int x, int n) {
    int shift = x >> n;
    int src = x << (8-n);
    src &= 255;
    return shift | src;
}

int main()
{
    int byte_140003000[] = {0x52, 0xDF, 0xB3, 0x60, 0xF1, 0x8B, 0x1C, 0xB5, 0x57, 0xD1,
        0x9F, 0x38, 0x4B, 0x29, 0xD9, 0x26, 0x7F, 0xC9, 0xA3, 0xE9,
        0x53, 0x18, 0x4F, 0xB8, 0x6A, 0xCB, 0x87, 0x58, 0x5B, 0x39,
        0x1E
    };
    
    for(int i=0;i<sizeof(byte_140003000)/4;i++){
        int x = i^byte_140003000[i];
        //이제 오른쪽으로 돌리기
        printf("%c", ROR(x, i&7));
    }
    return 0;
}

flag

Roll_the_left!_Roll_the_right!




chall9

main

int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[256]; // [rsp+20h] [rbp-118h] BYREF

memset(v4, 0, sizeof(v4));
sub_1400012E0("Input : ", argv, envp);
sub_140001340("%256s", v4);
if ( (unsigned int)sub_140001000(v4) )
    puts("Correct");
else
    puts("Wrong");
return 0;
}

sub_140001000

_BOOL8 __fastcall sub_140001000(const char *a1)
{
int i; // [rsp+20h] [rbp-18h]
int v3; // [rsp+24h] [rbp-14h]

v3 = strlen(a1);
if ( (v3 + 1) % 8 )
    return 0i64;
for ( i = 0; i < v3 + 1; i += 8 )
    sub_1400010A0(&a1[i]);
return memcmp(a1, &unk_140004000, 0x19ui64) == 0;
}

먼저 a1의 길이를 8로 나눈 나머지가 7이어야 한다.

그리고 조작을 한 후 25의 길이만큼 스트링이 동일해야 한다.

sub_1400010A0(a1), sub_1400010A0(a1+8), sub_1400010A0(a1+16)을 실행시킬 것으로 예상된다.

sub_1400010A0

__int64 __fastcall sub_1400010A0(unsigned __int8 *a1)
{
__int64 result; // rax
unsigned __int8 v2; // [rsp+0h] [rbp-48h]
int j; // [rsp+4h] [rbp-44h]
int i; // [rsp+8h] [rbp-40h]
char v5[16]; // [rsp+10h] [rbp-38h] BYREF

strcpy(v5, "I_am_KEY");
result = *a1;
v2 = *a1;
for ( i = 0; i < 16; ++i )
{
    for ( j = 0; j < 8; ++j )
    {
    v2 = __ROR1__(a1[((_BYTE)j + 1) & 7] + byte_140004020[(unsigned __int8)v5[j] ^ v2], 5);
    a1[((_BYTE)j + 1) & 7] = v2;
    }
    result = (unsigned int)(i + 1);
}
return result;
}

리버스 코드

#include <stdio.h>

unsigned char ROL(unsigned char x, int n) {
    unsigned char shift = x << n;
    shift &= 255;
    unsigned char src = x >> 8-n;
    return shift | src;
}

unsigned char ROR(unsigned char x, int n) {
    unsigned char shift = x >> n;
    unsigned char src = x << (8-n);
    src &= 255;
    return shift | src;
}
int main()
{
    unsigned char byte_140004020[] = {
        0x63 ,0x7C ,0x77 ,0x7B ,0xF2 ,0x6B ,0x6F ,0xC5 ,0x30 ,0x01 ,0x67 ,0x2B ,0xFE ,0xD7 ,0xAB ,0x76
        ,0xCA ,0x82 ,0xC9 ,0x7D ,0xFA ,0x59 ,0x47 ,0xF0 ,0xAD ,0xD4 ,0xA2 ,0xAF ,0x9C ,0xA4 ,0x72 ,0xC0
        ,0xB7 ,0xFD ,0x93 ,0x26 ,0x36 ,0x3F ,0xF7 ,0xCC ,0x34 ,0xA5 ,0xE5 ,0xF1 ,0x71 ,0xD8 ,0x31 ,0x15
        ,0x04 ,0xC7 ,0x23 ,0xC3 ,0x18 ,0x96 ,0x05 ,0x9A  ,0x07 ,0x12 ,0x80 ,0xE2 ,0xEB ,0x27 ,0xB2 ,0x75
        ,0x09 ,0x83 ,0x2C ,0x1A ,0x1B ,0x6E ,0x5A ,0xA0  ,0x52 ,0x3B ,0xD6 ,0xB3 ,0x29 ,0xE3 ,0x2F ,0x84
        ,0x53 ,0xD1 ,0x00 ,0xED ,0x20 ,0xFC ,0xB1 ,0x5B  ,0x6A ,0xCB ,0xBE ,0x39 ,0x4A ,0x4C ,0x58 ,0xCF
        ,0xD0 ,0xEF ,0xAA ,0xFB ,0x43 ,0x4D ,0x33 ,0x85  ,0x45 ,0xF9 ,0x02 ,0x7F ,0x50 ,0x3C ,0x9F ,0xA8
        ,0x51 ,0xA3 ,0x40 ,0x8F ,0x92 ,0x9D ,0x38 ,0xF5  ,0xBC ,0xB6 ,0xDA ,0x21 ,0x10 ,0xFF ,0xF3 ,0xD2
        ,0xCD ,0x0C ,0x13 ,0xEC ,0x5F ,0x97 ,0x44 ,0x17  ,0xC4 ,0xA7 ,0x7E ,0x3D ,0x64 ,0x5D ,0x19 ,0x73
        ,0x60 ,0x81 ,0x4F ,0xDC ,0x22 ,0x2A ,0x90 ,0x88  ,0x46 ,0xEE ,0xB8 ,0x14 ,0xDE ,0x5E ,0x0B ,0xDB
        ,0xE0 ,0x32 ,0x3A ,0x0A ,0x49 ,0x06 ,0x24 ,0x5C  ,0xC2 ,0xD3 ,0xAC ,0x62 ,0x91 ,0x95 ,0xE4 ,0x79
        ,0xE7 ,0xC8 ,0x37 ,0x6D ,0x8D ,0xD5 ,0x4E ,0xA9  ,0x6C ,0x56 ,0xF4 ,0xEA ,0x65 ,0x7A ,0xAE ,0x08
        ,0xBA ,0x78 ,0x25 ,0x2E ,0x1C ,0xA6 ,0xB4 ,0xC6  ,0xE8 ,0xDD ,0x74 ,0x1F ,0x4B ,0xBD ,0x8B ,0x8A
        ,0x70 ,0x3E ,0xB5 ,0x66 ,0x48 ,0x03 ,0xF6 ,0x0E  ,0x61 ,0x35 ,0x57 ,0xB9 ,0x86 ,0xC1 ,0x1D ,0x9E
        ,0xE1 ,0xF8 ,0x98 ,0x11 ,0x69 ,0xD9 ,0x8E ,0x94  ,0x9B ,0x1E ,0x87 ,0xE9 ,0xCE ,0x55 ,0x28 ,0xDF
        ,0x8C ,0xA1 ,0x89 ,0x0D ,0xBF ,0xE6 ,0x42 ,0x68  ,0x41 ,0x99 ,0x2D ,0x0F ,0xB0 ,0x54 ,0xBB ,0x16
    };
    
    unsigned char unk_140004000[] = {
        0x7E ,0x7D ,0x9A ,0x8B ,0x25 ,0x2D ,0xD5 ,0x3D  ,0x03 ,0x2B ,0x38 ,0x98 ,0x27 ,0x9F ,0x4F ,0xBC
        ,0x2A ,0x79 ,0x00 ,0x7D ,0xC4 ,0x2A ,0x4F ,0x58  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
    };
    
    unsigned char v5[16] = "I_am_KEY";
    
    unsigned char ans[30];
    for(int i=0;i<24;i++)ans[i]=unk_140004000[i];
    
    for(int i=0;i<24;i+=8){
        
        for(int k=0;k<16;k++){
            for(int j=8;j>=1;j--){
                ans[i+(j%8)]=ROL(ans[i+(j%8)], 5)-byte_140004020[(ans[i+j-1]^v5[j-1])];
            }
        }
    }
    for(int i=0;i<24;i++)printf("%c", ans[i]);
    return 0;
}

flag

Reverse__your__brain_;)




easyarray

main

int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[96]; // [rsp+20h] [rbp-60h] BYREF
int v5; // [rsp+80h] [rbp+0h]
int i; // [rsp+8Ch] [rbp+Ch]

_main(argc, argv, envp);
memset(v4, 0, sizeof(v4));
v5 = 0;
printf("input:");
scanf("%s", v4);
if ( (unsigned int)mystrlen(v4) != 27 )
{
    puts("wrong input length");
    getch();
    exit(0);
}
for ( i = 0; i <= 11; ++i )
    v4[i] = enc1((unsigned __int8)v4[i]);
for ( i = 12; i <= 26; ++i )
    v4[i] = enc2((unsigned __int8)v4[i]);
for ( i = 0; i <= 26; ++i )
{
    if ( (unsigned __int8)v4[i] != table[i] )
    {
    puts("wrong flag");
    getch();
    exit(0);
    }
}
puts("correct! input is your flag");
getch();
return 0;
}

enc1

__int64 __fastcall enc1(unsigned __int8 a1)
{
return sbox[sbox[sbox[a1]]];
}

enc2

__int64 __fastcall enc2(unsigned int a1)
{
__int64 result; // rax
int i; // [rsp+Ch] [rbp-4h]

result = a1;
for ( i = 0; i <= 255; ++i )
{
    result = (unsigned __int8)a1;
    if ( rsbox[i] == (unsigned __int8)a1 )
    return (unsigned int)i;
}
return result;
}

플래그 구하는 코드

#include <stdio.h>

int main()
{
    
    //table, sbox, rsbox는 너무 길기에 생략
    for(int i=0;i<12;i++){
        for(int j=0;j<256;j++)
            if(sbox[sbox[sbox[j]]]==table[i])printf("%c", j);
    }
    for(int i=12;i<27;i++){
        printf("%c", rsbox[table[i]]);
    }
    return 0;
}

flag

CYKOR{WOW_v3ry_34sy_arr4y!}




ransome

main

int __cdecl main(int argc, const char **argv, const char **envp)
{
FILE *Stream; // [rsp+28h] [rbp-38h]
char v5; // [rsp+34h] [rbp-2Ch]
char v6; // [rsp+38h] [rbp-28h]
void *Buffer; // [rsp+40h] [rbp-20h]
unsigned int Size; // [rsp+4Ch] [rbp-14h]
FILE *Size_4; // [rsp+50h] [rbp-10h]
signed int i; // [rsp+5Ch] [rbp-4h]

_main(argc, argv, envp);
if ( argc > 1 )
{
    Size_4 = fopen(argv[1], "rb");
    if ( Size_4 )
    {
    fseek(Size_4, 0, 2);
    Size = ftell(Size_4);
    Buffer = malloc(Size);
    fseek(Size_4, 0, 0);
    fread(Buffer, 1ui64, Size, Size_4);
    srand(0x1234u);
    for ( i = 0; Size > i; ++i )
    {
        v6 = rand();
        v5 = rand();
        *((_BYTE *)Buffer + i) = (*((_BYTE *)Buffer + i) + v6 - v5) ^ rand();
        *((_BYTE *)Buffer + i) = *((_BYTE *)Buffer + i);
    }
    Stream = fopen("out.enc", "wb");
    if ( Stream )
    {
        fwrite(Buffer, Size, 1ui64, Stream);
        fclose(Stream);
        fclose(Size_4);
        return 0;
    }
    else
    {
        puts("file error");
        getch();
        return 1;
    }
    }
    else
    {
    puts("file error");
    return 1;
    }
}
else
{
    puts("How to use : ./binary <input file>");
    getch();
    return 0;
}
}

작성한 c 코드, 이 코드가 작동하지 않아서 파이썬을 사용하였다.
이 코드가 왜 작동하지 않는지는 이해하기 어려웠다.

#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
    FILE* file = fopen("out.enc", "rb");
    fseek(file, 0, 2);
    long size = ftell(file);
    fseek(file, 0, 0);
    char buf[20000];
    fread(buf, sizeof(char), size, file);
    srand(0x1234u);
    
    for(int i=0;i<size;i++){
        char v6 = rand();
        char v5 = rand();
        buf[i]=((buf[i]) ^ (char)rand()) - v6 + v5;
        printf("%c", buf[i]);
    }
    FILE* stream = fopen("out.png", "wb");
    fwrite(buf, size, sizeof(char), stream);
    return 0;
}

python

from ctypes import *
libc = CDLL("msvcrt")
libc.srand(0x1234)

enc = open("out.enc","rb").read()
key = ""
for i in range(len(enc)):
v6 = libc.rand()
v5 = libc.rand()
key += chr(((enc[i] ^ libc.rand()) - v6 + v5) & 0xff)

data=list(map(ord,key))
open("out.png","wb").write(bytes(data))

flag는 이미지 파일로 확인할 수 있었다.

CYKOR{Gr34t_r4ns0m3w4r3}
profile
Wonder why

0개의 댓글