본문 바로가기

IT(개발, 보안)/pwnable

[Pwnable 풀이] 8. passcode

최근 여행을 다녀오고 오랜만에 다시 문제풀이를 시작했다.

이번 문제는 Login system의 코드를 분석해보고 취약점을 찾아서 flag를 찾아보는 문제이다.

 

문제의 passcode.c 파일이다. 

 

main 함수에서는 인삿말을 출력하고 welcome() 함수와 login() 함수의 호출 외에는 별다른 기능이 없다

 

welcome 함수는 100 크기를 가진 name 배열에 사용자의 이름을 입력받아 출력하는 기능을 한다.

 

login 함수에서는 정수형 passcode 2개를 입력받아 입력값을 검사하고 종료하는 기능을 한다.

 

해당 소스파일의 실행파일로 추정되는 passcode 실행파일을 실행해보았다.

실행파일을 실행해보면 passcode를 입력하는데에서 오류가 발생하며 종료되는데 다시 한번 위의 소스코드 파일을 살펴보자. 

 

login 함수의 scanf에 passcode인자에 &가 빠져 있음을 볼 수 있다. scanf의 인자로 주소 값을 주어야하는데 문자열 변수의 경우 그 문자열이 저장된 주소가 저장되어 &가 없어도 상관없지만 정수형 변수의 경우 &를 앞에 붙여서 주소 값으로의 변환이 꼭 필요하다.

 

하지만 이 오류를 해결하기 위해 소스코드를 바꾸고 다시 컴파일 할수는 없으므로 우리는 flag 값을 확인하기 위한 다른 취약점을 찾아보아야 한다.

 

welcome 함수를 어셈블리어로 변환해 구조를 살펴보았다. +38 열을 살펴보면 ebp-0x70에 사용자의 이름, name 변수가 저장됨을 확인할 수 있다. 총 100바이트 문자열 크기로 선언되었으므로 ebp -0x70 ~ -0xC 에 name 변수의 값이 저장된다.

 

login 함수를 disassemble 해서 구조를 살펴보자. +24 열에서 ebp -0x10에 passcode를 저장하는 scanf 구절을 찾을 수 있다. 그런데 welcome 함수와 login 함수는 동시에 실행되지 않기 때문에 같은 stack frame 을 공유하는데 welcome 함수에서 name 변수가 ebp -0x70 ~ -0xC에 저장되므로 passcode 1과 ebp -0x10에서 0xC 까지 4바이트가 공유됨을 알아낼 수 있다.

그렇다면 이 4바이트를 welcome 함수의 name 변수에 적절한 값을 집어 넣는 것으로 scanf를 통해 값이 저장되는 메모리 주소를 설정할 수 있음을 알 수 있다.

 

다음으로 scanf 이 후에 실행되는 fflush 함수를 살펴보자. 이에 관해 잘 정리해 둔 다음 블로그를 참조했다.

https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/

 

PLT와 GOT 자세히 알기 1

Dynamic Linking 과정을 추적해 PLT와 GOT를 이해해보자 :) 시스템 해킹을 공부하시는 분들이라면 PLT와 GOT에 대해 알고 있을 것입니다. 이제 막 시스템 해킹 공부를 시작한 분들도 한 번 쯤 들어보셨을

bpsecblog.wordpress.com

 

간단하게 요약하자면 실행 프로그램 내에서 사용되는 외부 라이브러리의 프로시져는 plt라는 테이블을 사용해 호출하고 got는 plt가 참조하는 테이블로 프로시저들의 주소가 저장되어 있다. fflush 함수는 본래 버퍼 내의 값을 비워내는 함수로 plt와 got 주소를 사용해 호출 되지만 이 주소를 조작할 수 있다면 우리는 원하는 함수를 fflush 대신 실행할 수 있게 된다.

 

+47번 라인의 fflush 함수의 plt주소를 따라가면 위와 같은 결과를 확인할 수 있다. 해당 정보가 PLT상의 정보인 것이고 0x804a004가 fflush 함수의 주소여서 해당 주소에 저장된 값을 변환하여 flag를 확인하는 system 명령어로 바꾸고자 한다.

 

다행히 실행하고자 하는 명령어는 login 함수의 if 문 안에 들어있어서 해당 명령어 주소 0x080485e3를 0x804a004에 저장하여 system 명령어를 실행할 수 있다.

 

입력해야하는 payload는 다음과 같다.

80485E3을 10진수로 변환한 134514147를 passcode1에 저장하여 fflush함수의 got 주소에 저장된 값을 바꾸어 flag값을 얻어 낼 수 있었다.

반응형

'IT(개발, 보안) > pwnable' 카테고리의 다른 글

[Pwnable 풀이] 10. input  (0) 2022.12.02
[Pwnable 풀이] 9. random  (2) 2022.11.29
[Pwnable 풀이] 7. bof  (0) 2022.11.20
[Pwnable 풀이] 6. flag  (0) 2022.11.19
[Pwnable 풀이] 5. cmd1  (0) 2022.11.15