CTF/포너블

[zer0ptsCTF] easy strcmp - 포너블 / ltrace

SecurityMan 2022. 3. 5. 09:00

chall 이라는 이름의 바이너리 파일이 하나 주어진다.

해당 파일은 리눅스에서 실행 가능한 elf 파일이다.

 

리눅스 환경으로 옮겨서 
chmod 777 등의 방법으로 실행권한을 부여한 뒤
./chall 이런식으로 실행시키면 된다.
실행시켜봤더니 ./chall <FLAG> 라고 사용법이 나온다.
a를 입력해 봤더니 Wrong! 이라고 나오는걸 보아
완전한 플래그를 맞게 입력해야 되는듯 하다.
 
해당 파일을 IDA로 열어보면 위와같은 부분을 발견할 수 있다.
strcmp 함수를 이용해서 "zer0pts{****CENSORED****}" 값과 입력값을 비교한 뒤
모든 글자가 맞으면 Correct! 틀리면 Wrong! 을 출력한다.
 
이 문제는 ltrace라는 도구를 이용하면 쉽게 풀 수 있다.
위키백과에는 ltrace가 이렇게 나와있다.
ltrace는 사용자 공간 애플리케이션의 공유 라이브러리에 대한 호출을 보여주는데 사용되는 리눅스의 디버깅
유틸리티이다. 이것은 동적 로딩 시스템을 후킹함으로써 가능해지며, 애플리케이션이 호출 시에 사용하는 
파라미터들과 라이브러리 호출이 리포트하는 반환 값을 보여주는 심(shim)들을 삽입한다. ltrace는 또한 리눅스 
시스템 호출을 트레이스할 수 있다. 이것이 동적 라이브러리 후킹 메커니즘을 사용하기 때문에, ltrace는 대상
바이너리에 직접적으로 정적 링크된 호출들을 트레이스할 수 없다.

읽어봤는데 무슨말인지 모르겠다면 정상이다.

이런건 직접 부딪혀보면서 배우면 된다.

 
ltrace의 사용법은 바이너리를 실행시킬때 위처럼 앞에 ltrace만 붙여주면 된다.
 
입력값을 a만 줬을때 strcmp에서 리턴하는 값이 -25이다.
이게 무슨 의미인지 생각해보자.
strcmp 함수가 사용자의 입력값과 비교하는 값은

"zer0pts{****CENSORED****}" 였다. ---> 맨 첫번째 글자가 소문자 z 이다.

위의 아스키코드표를 한번 보자.

참고로 아스키코드는 영문 키보드로 입력할 수 있는 모든 기호들이 할당되어 있는 기본 부호체계이다.

자세한 설명은 생략한다.

 

소문자 z의 10진수 값은 122이다.

그리고 소문자 a의 10진수 값은 97이다.

97-122는? -25가 된다.

ltrace가 리턴한 -25란 값은 strcmp 에서 비교한 첫번째 글자가 입력값보다 25칸 앞에 있다는 의미이다.
 
실제로 b, c, d, e 차례대로 넣어보면 리턴값이 -24, -23, -22, -21 이렇게 줄어드는걸 볼 수 있다.
그러다 z를 넣으면 갑자기 -101 이 나온다.
아스키코드표의 맨 처음에서 101번째 글자는 바로 소문자 e다.
플래그 포맷이 zer0pts 인걸 생각해보면 e가 다음에 올거라는걸 알 수 있다.
이런식으로 맨 앞글자부터 한글자씩 알아내면 된다.
 

 

중괄호({)를 입력한 후에는 리턴값이 값자기 이상하게 나오는데, 위처럼 괄호를 닫아버리면 {}
마지막 글자가 아스키코드표에서 } 로 부터 얼마나 떨어졌는지 숫자로 나온다.
하나씩 글자를 찾아서 채워넣으면
 

플래그가 완성되고, 완성된 플래그를 넣으면

Correct! 가 뜨면서 0을 리턴하게 된다.

 
반응형