Search

[HackCTF] strncmp

Tags
reversing
Category
HackCTF
Create Time
2022/01/07 12:50

1. 문제

1) mitigation 확인
PIE가 안걸려있다
2) 문제 확인
입력을 받고 어떤 문자열이 나온다. 자세한건 아이다를 통해 확인해보자
3) 코드흐름 파악
main(){ ... puts("Enter your input:"); __isoc99_scanf("%s", &v4); if ( !strcmp_(&v4, &v5) ) puts("Good game"); else puts("Always dig deeper"); return 0; }
C
복사
int __fastcall strcmp_(const char *a1, const char *a2) { int v3; // [rsp+14h] [rbp-1Ch] signed int i; // [rsp+18h] [rbp-18h] int j; // [rsp+1Ch] [rbp-14h] v3 = 0; for ( i = 0; i <= 21; ++i ) v3 = (v3 + 1) ^ 0x17; for ( j = 0; j < strlen(a1); ++j ) a1[j] ^= key; return strncmp(a1, a2, 0x1CuLL); }
C
복사
메인에서 입력한 값을 strcmp_에 넣고, v5와 비교하는것으로 보인다. strcmp_는 커스텀함수이다. v5에 들어가는 값을 gdb로 보면 다음과 같다
v5 = OfdlDSA|3tXb32~X3tX@sX`4tXtz
C
복사
strcmp_ 함수를 보면, 입력한 값이 a1, a2는 위의 문자열이 들어가있다. 결국 xor 연산을 통해 strncmp의 반환값을 0으로 만들면 될것같다.

2. 접근방법

초기에 v3 xor 연산은 사용되지 않으므로 필요없다. 문제는 a1[j] ^ key 인데, key 값이 0이다 ???
pwndbg> x/20gx 0x0000000000601064 0x601064 <key>: 0x0000000000000000 0x0000000000000000 0x601074: 0x0000000000000000 0x0000000000000000 0x601084: 0x0000000000000000 0x0000000000000000 0x601094: 0x0000000000000000 0x0000000000000000 0x6010a4: 0x0000000000000000 0x0000000000000000 0x6010b4: 0x0000000000000000 0x0000000000000000
C
복사
그럼 결국 입력값 ^ 0 을 해봤자 자기자신이므로 입력값에 OfdlDSA|3tXb32~X3tX@sX`4tXtz 이거를 그대로 넣으면 된다.
라는 바보같은 생각은 하지말자. 분명 플래그는 HackCTF{} 형식인데 ....
바이너리를 잘 보면 check라는 함수가 보인다
int __fastcall check(int a1, const char **a2) { int v3; // [rsp+1Ch] [rbp-4h] v3 = atoi(a2[1]); if ( v3 * (v3 - 14) == -49 ) key = v3; else key = 0; return main(a1, a2, a2); }
C
복사
조건문을 잘보면 v3이 키 값으로 들어갈수가 있다. 처음엔 bof로 check 함수를 호출시킬라고 했으나 카나리도 걸려있고, 생각해보면 이건 리버싱문제이니까 저 함수를 호출할 필요가 없네??
그냥 v3값을 일단 알아내면 간단한 2차방정식으로 v3=7인걸 알수있고, 키값을 7로 하여 다시 연산해보자.
우리가 입력한 값을 input 이라고 했을때, 다음의 수식으로 정리할수 있다.
input ^ key = a2(아까 v5값)
즉 a2 ^ key 의 결과를 input으로 주면 될것이다

3. 풀이

key=7 flag="" fuck="OfdlDSA|3tXb32~X3tX@sX`4tXtz" for i in fuck: flag=flag+chr(ord(i)^key) print(flag)
C
복사

4. 몰랐던 개념