HackCTF Reversing 여섯 번째 문제는 static이다.
분석이 좀 오래 걸렸다. 구조가 다소 복잡해 살펴보는 데 아마 오래걸린 것 같다.
파일 구조를 보면 64bit ELF 파일인데, strip이 걸려 있다.
역시나 파일을 실행하면 "Nope."이라는 문구가 출력되며 프로그램이 종료가 된다.
먼저 IDA로 파일을 까서 정적 분석을 해 보려고 했다.
중간중간 쓰이는 함수들만 나오고 main에 대해서는 나타나 있지 않다. 일단 gdb를 통해 동적 분석을 진행해 보겠다.
libc_start_main 부분에 bp를 걸고 프로그램을 실행시키면 아래와 같이 main 함수에 대한 주소를 알 수 있다.
main 부분이다. [ rbp-0x18 ]에 0x0을 저장하고 있는데, 이는 0x1과 같지 않아 0x555555554a58으로 점프한다.
RDI에는 아래에서 확인할 수 있듯이 "team_name"이 저장된다.
이후 getenv 함수를 호출해 "team_name"의 환경 변수가 있는지 확인하고 있다.
이후 환경 변수의 값을 [ rip + 0x137 ]에 있는 bi0s와 비교한다. (귀찮아서 일단 IDA 옆에 켜 두고 다시 시작했다.)
이때 조건을 불만족해서 jne 부분으로 점프하면, 위의 부분으로 점프하고 처음에 프로그램을 실행시켰을 때와 같이 "Nope." 문장을 출력하며 프로그램을 종료한다.
main 함수의 인자수인 [ rbp-0x24 ] 값이 2라면 0x555555554aa8로 점프하게 된다.
점프한 후 0x55555555487c 함수를 호출한다.
이 함수의 리턴 값이 1이면 0x555555554830 함수를 호출하며 종료한다.
0x55555555487c 함수에는 문자열을 암호화하는 과정이 있다. 이를 통해 입력해야 하는 문자열을 추측할 수 있다.
[ rbp - 68h ]에는 위에 있던 "bi0s" 문자열이 있다.
[ rbp - 70h ]에는 우리가 입력한 문자열이 있다.
[ rbp - 40h ]에는 "1617181926381617919194" 문자열이 저장된다.
또한, 마지막의 비교하는 분기문에 의해 우리가 입력한 문자열의 길이는 16h, 즉, 22 임을 알 수 있다.
이 부분을 통해 문자열을 역순으로 가져와 비교함을 알 수 있다.
이 부분을 정리해 보자. 홀수면 loc_97D로 점프하지 않아 아래 코드들이 실행이 될 것이다. 이로 인해 홀수번째 글자들은 4를 더하고, 0xC와 xor 연산을 한다. 반대로, 짝수면 loc_97D로 점프하고, 그 부분의 코드가 실행이 될 것이다. 따라서 짝수번째 글자들은 4를 빼고, 0xC와 xor 연산을 한다.
이렇게 암호화된 루틴을 통해 아래와 같이 코드를 짜 주면 우리가 입력해야 하는 값, 즉, 플래그를 얻을 수 있다.
처음 key 값을 봤을 때는 혹시 저게 플래그였나 싶었는데 맞았다.
(+뒤늦게 깨달은 사실: 기드라 툴 쓰면 메인이 보인다. 그래도 동적 분석 해 봐야 됐던 건 마찬가지였다. 구조가 복잡해서 조금은 오래 걸렸던 문제였다.)
[HackCTF-Reversing#7] BabyMIPS - 400 points (0) | 2021.03.10 |
---|---|
[HackCTF-Reversing#5] keygen - 200 points (0) | 2021.01.06 |
[HackCTF-Reversing#4] Strncmp - 150 points (0) | 2021.01.05 |
[HackCTF-Reversing#3] Handray - 100 points (0) | 2021.01.03 |
[HackCTF-Reversing#2] Reversing Me - 100 points (0) | 2021.01.02 |
댓글 영역