15. strace/ltrace로 리버싱 10분 컷 단서 찾기
시스템 호출 추적은 프로그램의 의도를 알려주는 도구가 아니라, 관찰 가능한 경계를 보여주는 도구다. 승인된 CTF 바이너리나 자기 소유의 Linux 실행 파일에서 먼저 외부 세계와의 접점을 기록하면, 정적 분석이 조사할 범위를 줄일 수 있다. “10분 컷”은 목표가 아니라, 추측을 빨리 버리는 습관에 가깝다.
strace로 운영체제 경계를 본다
strace는 libc 함수가 아니라 시스템 호출을 추적한다. 파일·프로세스·네트워크 접근을 확인할 때 출력 파일을 분리하고, 자식 프로세스와 문자열을 함께 기록한다.
strace -f -s 128 -o strace.log ./crackme
strace -f -e trace=file,process,network ./crackme
배포판과 권한에 따라 네트워크 호출이 보이지 않거나 ptrace 제한으로 실패할 수 있다. openat가 보인다고 파일 내용이 모두 출력되는 것은 아니며, 실제 read와 반환값을 함께 해석해야 한다. 비밀 파일을 읽게 만드는 식의 실험은 하지 말고, 테스트 디렉터리와 샘플 파일로 동작을 재현한다.
ltrace로 동적 라이브러리 경계를 좁힌다
ltrace는 동적 라이브러리 호출을 보여주므로 strcmp, memcmp, strlen, strstr 같은 검증 단서를 찾는 데 유용하다.
ltrace -f -s 128 -o ltrace.log ./crackme
ltrace -f -e 'strcmp+strncmp+memcmp+strlen' ./crackme
이 도구는 정적 링크, 인라인 함수, 직접 시스템 호출, 심볼 제거에 약하다. 출력에 strcmp("입력", "정답")처럼 보이는 값이 있어도 그 호출이 실제 판정 경로인지 반환값과 직후 분기를 확인해야 한다. 반대로 호출이 없다고 검증이 암호학적으로 강하다는 뜻도 아니다.
추적을 분석으로 연결하기
입력 전후 로그를 비교하고, 한 글자만 바꾼 실행에서 어떤 호출과 파일 접근이 달라지는지 기록한다. 이후 디버거·디컴파일러에서 해당 호출자의 주소와 분기를 연결한다. 성능과 노이즈를 고려해 처음부터 모든 호출을 수집하지 말고, 질문에 맞는 이벤트만 필터링한다. 정상 종료와 실패 종료의 exit code, 시그널, 자식 프로세스도 함께 저장하면 오류 메시지에 의존하지 않게 된다.
추적 파일에는 입력과 경로가 그대로 남을 수 있으므로 공유 전에 마스킹한다. 좋은 결과는 긴 로그가 아니라 “입력 검증은 memcmp 호출 뒤 반환값에서 결정되고, 외부 파일은 읽지 않는다”처럼 재현 가능한 주장이다. 동적 추적은 정적 분석을 대체하지 않지만, 다음에 읽을 함수와 반례를 선택하게 해준다.