워게임/CodeEngn

[CodeEngn] Pro RCE L01

name2965 2022. 7. 4. 23:32
728x90

 

 

 

이번 문제는 코드엔진 사이트를 알게됐었던 날과 여러 문제들을 풀면서 한번 풀어보고 싶었던 문제입니

 

 

문제를 exeinfope로 열어보면

 

 

 

 

역시 Pro 문제답게 첫문제부터 UPX 패킹이 되어있는것을 알수 있습니다.

 

제대로 분석하기 위해서 upx.exe로 언패킹 해줍니다.

 

 

 

 

 

그리고나서 다시 exeinfope로 확인해보면

 

 

 

 

제대로 언패킹이 된것을 확인할수 있습니다.

 

32비트 기반 실행파일이고 비주얼 c++로 작성되었네요.

 

 

이제 한번 프로그램을 실행시켜보겠습니다.

 

 

 

 

프로그램을 실행시키면 다음과 같이 문자열들이 나온뒤

인증키를 입력하라고 나옵니다.

 

여기서 아무값이나 입력하면

 

 

 

 

다음과 같이 인증 실패라는 문자열과 암호화된 플래그가 메세지박스로 출력됩니다.

이것들을 이용해서 키값 검사루틴을 찾아보겠습니다.

 

 

저는 IDA를 사용해서 분석해보겠습니다.

 

 

먼저 아까전에 출력되었던 문자열들이나 메세지박스로 출력되었던 문자열이 어디있는지 먼저 찾아보면

 

 

 

 

이렇게 많은 문자열들이 보입니다.

그런데 암호화 플래그가 하나가 아닌 2개가 있습니다.

 

그리고 암호화 플래그를 잘보면 뭔가 base64/32로 인코딩된값같은 형태를 띄고 있습니다.

그러므로 이 두개의 플래그를 base64로 디코딩 해보면

 

 

 

아까전에 제가 봤었던 플래그는 페이크 플래그인것같고

 

 

또다른 플래그를 확인해보면 다음과 같은 문자열이 나오는데

키값+알고리즘 약자 이름+리버서 라고 나와있습니다.

이것이 아마 인증할때 쓰는 플래그의 형식을 지정해준것같습니다.

그러므로 이 문제를 풀기위해서 찾아야할것들은

키값,프로그램에서 쓰인 알고리즘 약자, 그리고 저의 ID 일것입니다.

 

이제 한번 분석을 진행해보겠습니다.

먼저 암호화 플래그가 출력되는 함수를 보면

 

 

 

다음과 같이 분기가 나눠져 있습니다.

페이크 플래그는 잘못된 값을 입력했을때 출력될것이고

Virtual Bank Auth Success 와 같이 출력될 올바른 양식의 플래그가 출력 될때가 언젠지 알아내야합니다.

 

분기문의 조건을 보면 두 위치에 있는 값을 비교해서 같아야 하는 구조로 보입니다.

 

그렇다면 저기에 들어가야할 값이 무엇일지 생각해보면, ebp+?? 과 같은 방식으로 값들이 저장되어있으므로

스택에 푸쉬된 값들일 것인데, 이는 보통 함수 호출전에 인자를 스택에 푸쉬한다는것을 생각했을때

 

함수의 인자 2개일 것입니다.

 

그렇다면 이 함수의 인자값을 알아내기 위해서 이 함수를 호출한곳을 보겠습니다.

 

 

 

 

 

함수를 호출한 이곳을 살펴보면 이 함수가 main함수 라는것을 금방 알수있습니다.

 

그러므로 여기서부터 본격적인 분석을 하면 될것같습니다.

 

우선 함수를 호출한곳을 보면

 

 

 

 

다음과 같습니다.

위에서부터 보면, 아까전에 프로그램을 실행하면 출력되었던 문자열들이 

하나씩 푸쉬된다음 sub_411046이라는 함수를 호출하는데

뭔가 printf의 역할을 하는 함수같아보이지만 일단 한번 함수안쪽을 분석해보면

 

 

 

저의 예상대로 printf 함수 역할을 하는 사용자 정의 함수였습니다.

이제 그다음을 분석해봅시다.

 

 

 

4개의 문자열들이 전부다 출력되고나면, %d라는 포맷스트링이 푸쉬된뒤 sub_41109B 함수가 호출되는데

 

이것도 역시나 함수를 확인해보면

 

 

 

다음과 같이 scanf 함수 역할을 하는 사용자 정의 함수라는것을 알수 있습니다.

 

 

그다음 부분을 분석해보면 갑자기 sub_41114F 함수를 호출합니다

그리고난뒤 그 반환값을 ebp+var_30에 복사합니다.

 

그러면 이 함수는 어떤 함수인지 확인해보겠습니다.

 

 

 

뭔가 복잡한 연산이 이루어지고 있습니다.

이 함수는 동적분석을 해봐야 할것같습니다.

 

그런데 main함수의 첫부분을 보면

 

 

 

 

디버거를 탐지하는 함수가 호출되고 만약 탐지되면 디버거를 탐지했다는 문자열을 출력하면서 프로그램을 종료시킵니다.

그러므로 디버깅을 할땐 jnz 점프문을 jz로 패치해서 디버깅을 진행하겠습니다.

 

먼저 함수 앞에 중단점을 건뒤 실행하고

 

 

분기문을 패치해줍니다.

 

그리고나서 분석해야할 함수에 중단점을  걸어주고 다시 F9를 눌러준뒤

입력값으로 임의의 값을 입력해주면

 

 

함수에 진입하게 됩니다.

 

이제 하나하나 들어가는 값과 계산을 고려해서 분석을 해보겠습니다.

 

 

하나하나 분석해서 나온 연산 과정입니다.

 

이 연산에서 쓰인 알고리즘 같은게 있는거 같은데

도데체 어떤 알고리즘인지 잘 모르겠어서 시간을 엄청 잡아먹었습니다.

 

그리고나서 든 생각이 있었습니다.

처음에 나머지 연산을 하고난뒤 그 다음 연산은

2번째 피연산자와 결과값으로 다시 나머지 연산을 하는 구조인데

 

이 연산 구조가 어디선가 본듯하고 뭔가 예전에 해본것같다는 생각이 들었는데

 

마지막에 리턴하는 값의 연산을 보면

뒤에있는 2개의 4는 마지막 나머지 연산에서 쓰인 4를 가져다 쓰는것입니다.

 

그리고 4를 나머지 연산에 쓰인 모든 피연산자와 나머지 연산을 하면 전부다 0이 나온다는 사실을 통해서

이 알고리즘은 최대공약수를 구하는 알고리즘이구나 라는 생각이 들었습니다.

 

그래서 최대공약수와 연관된 알고리즘을 생각해보니

유클리드 호제법이라는 알고리즘이 떠올라서 검색을 해봤습니다.

 

 

최대공약수(GCD), 최소공배수(LCM) 구하기 유클리드 호제법 알고리즘 :: 코드자몽 (tistory.com)

 

최대공약수(GCD), 최소공배수(LCM) 구하기 유클리드 호제법 알고리즘 :: 코드자몽

최대공약수 GCD(Greatest Common Divisor) 최대공약수는 두 자연수의 공통된 약수 중 가장 큰 수를 의미한다. ex) 72 와 30의 최대공약수는 6이다. 최소공배수 LCM(Least Common Multiple) 최소공배수는 두 자연..

myjamong.tistory.com

 

이 블로그를 보면 나와있는 유클리드 호제법을 이용해서 최대공약수,최소공배수를 구하는 과정이

이 과정과 거의 같다는것을 봤을때

 

여기서 쓰인 알고리즘은 바로 최대공약수(GCD) 알고리즘과 최소공배수(LCM) 알고리즘 입니다.

 

이것을 약자로 하면 GCD,LCM 입니다.

 

이것을 기반으로 연산을 정리해보면

 

 

다음과 같이 과정을 서술할수 있습니다.

 

도데체 왜 LCM에 GCD를 한번더 더하는진 잘 모르겠습니다

아마 분석하기 헷갈리게 만들기위한 작업일것같습니다.

 

이제 어떤 알고리즘이 쓰이는지는 하나 알아냈으니 키값이 뭔지를 분석해봐야 합니다.

 

 

 

 

리턴값을 스택에 넣고 어떤 값을 eax에 복사하는데

이 값은 아까전에 제가 입력했던 임의의 데이터입니다.

 

그리고나서 eax를 푸쉬, 리턴값을 ecx에 복사한뒤 푸쉬 하고 sub_4111EA 함수를 호출합니다.

 

 

이 함수는 아까전에 처음에 분석했던 함수입니다.

그러므로 아까전의 분석을 기반으로 생각해보면

 

첫번째 인자는 사용자 입력이고

두번째 인자는 아까전에 연산에의한 리턴값입니다.

 

아까전의 분석을 토대로 생각해보면

키값의 검사루틴은 그저 이 정해져있는 리턴값과 사용자 입력이 같으면 성공이고 다르면 실패이기 때문에

리턴값이 바로 키값이라는 결론이 나옵니다.

 

리턴값은 334A4, 10진수로는 210084 입니다.

 

이 키값을 한번 입력해보면

 

 

 

다음과 같이 성공 문자열과 올바른 암호화 플래그가 출력되므로

 

키값은 바로 210084 입니다.

 

그리고 아까전에 복호화했던 플래그형식을 보면

 

키값+알고리즘 약자 이름+리버서

 

다음과 같습니다.

 

저는 처음에 리버서칸에 저의 ID를 적어야 하는줄 알고서 꽤나 삽질을 했는데

알고보니 그냥 영어로 reverser 라고 적으면 되는거였습니다.

 

그래서 나온 최종 정답은

210084GCDLCMreverser 입니다.

 

 

 

 

 

728x90

'워게임 > CodeEngn' 카테고리의 다른 글

[CodeEngn] Basic RCE L14  (0) 2022.07.06
[CodeEngn] Basic RCE L13  (0) 2022.07.06
[CodeEngn] Crypto Analysis L02  (0) 2022.07.04
[CodeEngn] Crypto Analysis L01  (0) 2022.07.03
[CodeEngn] Basic RCE L12  (0) 2022.07.03