촉촉한초코칩

WolvCTF 2024 본문

CTF

WolvCTF 2024

햄친구베이컨 2024. 3. 17. 17:51
Web: The Gauntlet

 

 

사이트 들어가보았다. 

 

hidden 하고 값이 있어서 flag로 제출했는데 실패함

디코 보니까 Burp Suite 사용해라 어쩌구 저쩌구 있는 것 같은데 모르겠다 

hidden은 바로 있는데 flag는 아님.. 

 

https://medium.com/@realm3ter/wolvctf-web-the-gauntlet-write-up-b6526513cec8 참고하기

간단한게아니였음...ㅋㅋ

 

Rev: babyre

 

문제 파일을 다운 받았는데 파일 확장명이 나오지 않아서 IDA로 열었다.

 

둘러보다가 flag 형식의 문자열 발견..

 

Crypto: yORs Truly <3

 

문제 : key 찾기
힌트 : XOR 함수를 키로 다시 적용하기만 하면 문자열을 복호화할 수 있다.

import base64

plaintext = "A string of text can be encrypted by applying the bitwise XOR operator to every character using a given key"
key = "" # I have lost the key!

def byte_xor(ba1, ba2):
    return bytes([_a ^ _b for _a, _b in zip(ba1, ba2)])

ciphertext_b64 = base64.b64encode(byte_xor(key.encode(), plaintext.encode()))

ciphertext_decoded = base64.b64decode("NkMHEgkxXjV/BlN/ElUKMVZQEzFtGzpsVTgGDw==")

print(ciphertext_decoded)

byte_xor() 함수는 두 개의 바이트 배열을 받아서 각 바이트의 xor 연산을 수행하여 새로운 바이트 배열을 반환한다.

encode() 는 문자열을 특정 인코딩 방식으로 인코딩하는데 사용된다. ex) UTF, ASCII 등 
보통 인코딩 방식을 지정하여 사용한다. ex) 문자열.encode('utf-8')
그러면 문자열이 UTF-8 형식으로 인코딩되어 바이트 객체로 반환된다. 

ciphertext_b64를 보면 key와 plaintext를 xor 연산을 해서 암호화한다. 
그 값을  base 64로 인코딩한다. 

ciphertext_decoded는 괄호 안에 있는 문자열을 base64로 디코딩한다.
> 아마도 이게 암호화문..??

xor연산은 키가 없으면 정상적으로 동작하지 않는다. 
그래서 ciphertext_b64를 출력하면 빈 문자열이 나온다. 

해결 방법 > 키 재생성, 암호화된 텍스트 해독 

키 찾는 방법
1. 암호문과 평문 길이가 동일하므로, 암호문의 각 문자와 평문의 각 문자 간의 xor 연산 수행
2. 암호문과 평문의 xor 연산 결과를 통해 원래의 키 추출 

import base64

plaintext = "A string of text can be encrypted by applying the bitwise XOR operator to every character using a given key"
ciphertext_decoded = base64.b64decode("NkMHEgkxXjV/BlN/ElUKMVZQEzFtGzpsVTgGDw==")

def byte_xor(ba1, ba2):
    return bytes([_a ^ _b for _a, _b in zip(ba1, ba2)])

def find_key(plaintext, ciphertext):
    key = []
    for byte_pt, byte_ct in zip(plaintext, ciphertext):
        key.append(byte_pt ^ byte_ct)
    return bytes(key)

key = find_key(plaintext.encode(), ciphertext_decoded)
print("Found key:", key.decode())

find_key 함수를 만들어서 plaintext와 ciphertext의 한 글자씩 xor 연산을 하고 key 배열에 넣는다. 

 

* 인코딩 : 텍스트 > 바이트로 변환 
* 디코딩 : 바이트 > 텍스트로 변환 

 

 

 

 

 

파이썬으로 코드 짜는 거 연습하기........................

 

Pwn: babypwn

 

#include <stdio.h>
#include <string.h>
#include <unistd.h>

struct __attribute__((__packed__)) data {
  char buff[32];
  int check;
};

void ignore(void)
{
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stdin, NULL, _IONBF, 0);
}

void get_flag(void)
{
  char flag[1024] = { 0 };
  FILE *fp = fopen("flag.txt", "r");
  fgets(flag, 1023, fp);
  printf(flag);
}

int main(void) 
{
  struct data name;
  ignore(); /* ignore this function */

  printf("What's your name?\n");
  fgets(name.buff, 64, stdin);
  sleep(2);
  printf("%s nice to meet you!\n", name.buff);
  sleep(2);
  printf("Binary exploitation is the best!\n");
  sleep(2);
  printf("Memory unsafe languages rely on coders to not make mistakes.\n");
  sleep(2);
  printf("But I don't worry, I write perfect code :)\n");
  sleep(2);

  if (name.check == 0x41414141) {
    get_flag();
  }

  return 0;
}

name이 0x41414141과 같다면 flag를 보여주는 것으로 이해했다.

1. 코드를 조금 수정해보았는데, name.check는 항상 4096이 나왔다.
그래서 name.check를 그냥 0x41414141로 미리 넣어주었다.

int main(void) {
  struct data name;
  //ignore(); /* ignore this function */

  printf("What's your name?\n");
  fgets(name.buff, 64, stdin);
  printf("%s nice to meet you!\n", name.buff);
  printf("Binary exploitation is the best!\n");
  printf("Memory unsafe languages rely on coders to not make mistakes.\n");
  printf("But I don't worry, I write perfect code :)\n");

  name.check = 0x41414141;
  if (name.check == 0x41414141) {
    printf("check!\n");
    get_flag();
  } else {
    printf("no check..%d\n", name.check);
  }

  return 0;
}

 

2. flag.txt 파일 열기.. 

시스템 스터디에서 배운 걸 활용해려고 했는데 파이썬으로 한 거라서 remote 함수를 c언어에서는 어떻게 해야 하는지 모르겠음

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

struct __attribute__((__packed__)) data {
  char buff[32];
  int check;
};

void ignore(void)
{
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stdin, NULL, _IONBF, 0);
}

void get_flag(void) {
  char flag[1024] = { 0 };
  char *argv[] = {"/flag.txt","1337",NULL};
  char *envp[] = {"babypwn.wolvctf.io",NULL};
  execve("/flag.txt",argv,envp);
  
  FILE *fp = fopen("flag.txt", "r");
  fgets(flag, 1023, fp);
  printf("flag : %s\n", flag);
}

int main(int argc, char *argv[]) {
  struct data name;
  //ignore(); /* ignore this function */

  printf("What's your name?\n");
  fgets(name.buff, 64, stdin);
  printf("%s nice to meet you!\n", name.buff);
  printf("Binary exploitation is the best!\n");
  printf("Memory unsafe languages rely on coders to not make mistakes.\n");
  printf("But I don't worry, I write perfect code :)\n");

  name.check = 0x41414141;
  if (name.check == 0x41414141) {
    printf("check!\n");
    get_flag();
  } 

  return 0;
}

 

 

참고해서 다시 풀어보기 https://juntheworld.tistory.com/23

 

 

'CTF' 카테고리의 다른 글

VolgaCTF 2024  (0) 2024.03.31
JerseyCTF 2024  (0) 2024.03.24
Digital Overdose Ctf 2022  (0) 2022.11.20
WPI CTF 2022  (0) 2022.09.25
DownUnderCTF 2022  (0) 2022.09.25