Dreamhack/Dreamhack Wargame (Challenge)

[25] IT 비전공자 [dreamhack] simple-operation문제 풀기

imaginefuture-1 2024. 10. 4. 13:38

25번째 문제다 가보자구!

 

 

 

 

풀이를 안보고 gpt랑 같이 풀었는데

ghidra라가 필요해서 당누받아 분석하고

 

 

Ghidra는 미국 국가안보국(NSA)에서 개발한 오픈소스 리버스 엔지니어링 도구입니다. 바이너리 파일을 분석하고 디컴파일하는 데 매우 유용하며, 특히 ELF, PE 등 다양한 파일 포맷을 지원하여 리눅스, 윈도우, macOS 환경에서 실행되는 프로그램을 분석할 수 있습니다.

햐 디컴파일!
코드도 야무지게 설명해주는 우리 gpt..

 

이 후 이 값을 어떻게 알아야 되나 싶은건 더이상 머리가 막혀서 풀이를 찾아봤다

 

https://velog.io/@janequeen/%EB%93%9C%EB%A6%BC%ED%95%B5-simple-operation-%EA%B8%B0%EB%93%9C%EB%9D%BC%EB%A1%9C-%EC%B2%98%EC%9D%8C-%EB%B6%84%EC%84%9D%ED%95%B4%EB%B3%B4%EA%B8%B0

 

[드림핵] simple-operation 기드라로 프로그램 처음 분석해보기

초보자에게 꼭 나오는 XOR 연산 특징을 이용한 문제를 풀어봅시다.

velog.io

https://hannahsecurity.tistory.com/entry/%EB%93%9C%EB%A6%BC%ED%95%B5Dreamhack-simple-operation

 

[드림핵(Dreamhack)] simple-operation

아래처럼 Random number를 주고 input을 받은 다음 result를 출력하는 프로그램이다 아이다로 역 연산 해보면 input이 0x7d1c4b0a^ran이어야한다. input은 real time으로 계산해서 넘기면 된다. result가 a0b4c1d7이

hannahsecurity.tistory.com

https://eunginius.tistory.com/entry/Dreamhack-Beginner-simple-operation

 

[Dreamhack] Beginner: simple-operation

simple-operation Description 우리의 친구 아모가 미션을 주었습니다. "내가 원하는 결과가 나오도록 값을 입력해 줘!" 주어진 바이너리를 분석하고 알맞은 값을 입력하면 플래그가 출력됩니다. 플래그

eunginius.tistory.com

에 왜 입력이 안되지
이 코드를 짜신 블로그님꺼 사용할려는데 막혔다..아니 왜 안돼...
또 입력 오류..

하...엔터를 눌러도 다음 화면으로 안넘어가고 그냥 줄바꿈이 되버린다...

하 왜 왜 input 값을 구해왔는데 입력을 할 수 없니...

 

 


 

 

2024-10-22 다시 문제 풀러 왔다..

 

IDA로 디컴파일했다..이거 너무 편한데..습관들이면 안된다.. 어셈블리어랑 친해져야한다ㅏㅣㅏㅏ아ㅏㅏ

 

int __fastcall main(int argc, const char **argv, const char **envp)
{
  char s1[9]; // [rsp+6h] [rbp-3Ah] BYREF
  char s[9]; // [rsp+Fh] [rbp-31h] BYREF
  int v6; // [rsp+18h] [rbp-28h] BYREF
  int v7; // [rsp+1Ch] [rbp-24h] BYREF
  char *s2; // [rsp+20h] [rbp-20h]
  int fd; // [rsp+2Ch] [rbp-14h]
  void *buf; // [rsp+30h] [rbp-10h]
  int v11; // [rsp+38h] [rbp-8h]
  int i; // [rsp+3Ch] [rbp-4h]

  v7 = 0;
  v6 = 0;
  v11 = 0;
  initialize(argc, argv, envp);
  buf = malloc(0x45uLL);
  fd = open("./flag", 0);
  read(fd, buf, 0x45uLL);
  close(fd);
  get_rand_num(&v6);
  printf("Random number: %#x\n", v6);
  printf("Input? ");
  __isoc99_scanf("%d", &v7);
  v11 = v6 ^ v7;
  snprintf(s, 9uLL, "%08x", v6 ^ v7);
  for ( i = 0; i <= 7; ++i )
    s1[i] = s[7 - i];
  printf("Result: %s\n", s1);
  s2 = "a0b4c1d7";
  if ( !strcmp(s1, "a0b4c1d7") )
  {
    puts("Congrats!");
    puts((const char *)buf);
  }
  else
  {
    puts("Try again");
  }
  return 0;
}

 

 


코드의 흐름을 먼저 보자.
17-20: flag 파일을 열어서 파일 디스크립터를 fd 변수에 담는다. 45바이트만큼 읽어서 buf 변수에 받고 다시 닫는다.
21: 난수를 v6에 저장한다.
24: v7에는 사용자 입력값을 받는다.
25: v6 ^ v7 은 XOR 연산을 의미한다.
26: snprintf 함수는 출력 결과를 문자열 버퍼에 저장하는 함수이다. 버퍼의 크기를 지정하여 버퍼 오버플로우를 방지하는데 여기서는 9uLL로 지정했다. 9는 버퍼의 크기이고, uLL은 unsigned long long 타입임을 나타낸다. 추가로 %08x는 16진수로 출력하고 최소 8자리를 출력하며 부족한 자릿수는 0으로 채운다는 걸 의미한다.
27-28: 그 결과가 담긴 s 문자열을 s1에 거꾸로 담는다.
31: 그 결과가 a0b4c1d7과 일치하는지 판별한다.
 
즉, 랜덤값과 입력값을 XOR 연산한 결과가 a0b4c1d7과 일치하게 만들면 된다.

출처 ㅣ https://eunginius.tistory.com/entry/Dreamhack-Beginner-simple-operation
그리고 for문을 통해 s1 배열은 s 배열을 뒤집어서 저장하고 있다. 그런데 이 s1을 a0b4c1d7과 비교해서
분기함으로(같으면 Congrats!, 다르면 Try again) s는(buffer_for_random xor input) = 7dc14b0a가 되어야 한다.  

출처ㅣ https://hyunhe2e.tistory.com/m/132

 

해서 변경하는데 계속 입력이 안된다...

열심히 계산기 돌렸지만 안된다..

91ea9fff xor 7d1c4b0a -> 10진수 변경한걸 입력해도 그냥 줄바꿈 된다

열심히 계산해서 입력했지만 그냥 줄바꿈이 되버린다..후..

 

 

 

https://eunginius.tistory.com/entry/Dreamhack-Beginner-simple-operation

 

 


결국pwn 모듈을 사용했다.

from pwn import *

# 지정 호스트의 지정 포트로 원격 접속
r = remote("host3.dreamhack.games", <포트번호>)

# 서버에서 rand 값 받기
r.recvuntil(b"number: ")
rand = r.recvn(10)

print("rand : ", rand)

# 16진수로 변환한 후 XOR 연산
x = int(rand, 16) ^ 0x7d1c4b0a
# 문자열로 변환 후 바이트 형식으로 인코딩
x = str(x).encode()

# Input?이란 문자열이 나올 때 값을 전송
r.sendlineafter(b"Input? ", x)

# 프로그램 제어(입출력 등)를 사용자에게 넘김
r.interactive()

코드 출처ㅣ  https://eunginius.tistory.com/entry/Dreamhack-Beginner-simple-operation