Computer Security

#5 Pwnable.kr : passcode 문제풀이 본문

Wargame:Pwnable.kr

#5 Pwnable.kr : passcode 문제풀이

쿠리 Kuri 2022. 8. 5. 18:30
반응형

passcode


알아야 할 상식!

 

 PLT & GOT

 

PLT = Procedure Linkage Table

PLT로 말그대로 프로시져 ( 여러가지의 함수 & 외부 라이브러리 ) 들을 연결한 테이블이라고 이해하면 된다.

우리가 함수를 호출할때, 함수는 바로 호출되지않고 PLT를 통해 GOT를 참조하고, GOT에서 함수의 실제주소에 접근하여 함수가 실행된다.

GOT = Global Offset Table

프로시져의 실제 주소를 가지고있다. PLT가 참조하는 테이블이다.

그림으로 보자.

printf함수를 실행한다고 했을때, 일단 PLT로 간다. 

 

여기서 두가지의 경우로 나누어진다.

 

1. printf함수가 첫번째로 실행되었을 때

 

PLT > GOT > PLT > _dl_runtime_resolve > printf 호출                                                                                   

 

 

2. printf함수가 위와같은 과정을 거치고 두번째로 실행되었을 때

 

PLT > GOT > printf 호출                                                                                          

 

 

GOT에 이미 printf 함수의 주소가 적혀있기때문에 전보다 간결한 과정으로 함수를 호출한다.

 


페이로드

  •  사용에 있어서 전송되는 데이터를 뜻한다.
  • 페이로드는 전송의 근본적인 목적이 되는 데이터의 일부분으로 그 데이터와 함께 전송되는 헤더와 메타데이터와 같은 데이터는 제외한다.
  • 컴퓨터 보안에서 페이로드는 멀웨어의 일부를 뜻한다.
  • 웜, 바이러스, 트로이목마 같은 해로운 소프트웨어를 분석할 때 페이로드는 그 소프트웨어가 주는 피해를 뜻한다.
  • 예를 들어 페이로드에는 데이터 훼손, 스팸메일, 개인정보를 알아내기 위해 다수에게 보내는 이메일 등이 있다. 즉 페이로드는 전송 행위의 본래 의도를 뜻한다.

 

  • 페이로드라는 용어는 큰 데이터 덩어리 중에 '흥미 있는' 데이터를 구별하는 데 사용된다.
  • 이 용어는 운송업에서 비롯하였는데, 지급(pay)해야 하는 적화물(load)을 의미한다.
  • 예를 들어, 유조선 트럭이 20톤의 기름을 운반한다면 트럭의 총 무게는 차체, 운전자 등의 무게 때문에 그것보다 더 될 것이다.
  • 이 모든 무게를 운송하는데 비용이 들지만, 고객은 오직 기름의 무게만을 지급(pay)하게 된다. 그래서 'pay-load'란 말이 나온 것이다

 

 


1. vi passcode.c 를 해 코드를 살펴보자.

vi passcode.c

  • - 메인함수에서 printf로 인삿말을 한뒤, welcome 함수를 불러온다.
  • -welcome 함수를 보면 지역 변수로 100바이트 버퍼를 잡고 100바이트를 사용자한테 입력 받는다.
  • -그 다음 함수가 종료 후, 로그인을 호출한다.
  • -여기서 포인트는 함수가 호출되면 그 함수들이 스택을 할당 받아서 쓰게 되는데, 메인이 쓰던 스택 영역에서 welcome이 추가적으로 스택 영역을 이어서 쓰고,welcome함수가 리턴할때, 스택 영역이 반환이 되고, 다시 이후에 로그인이 웰컴이 반환한 스택영역을 잡아서 쓰게 된다.
  • -login 함수는  초기화 하지않은 두개의 변수를 두 변수의 주소를 이용해서 scanf의 target 위치로 이용하고 있다.

 

 

 

2.  위의 내용을 메모리 상에서 살펴보자.

disass main

  • 메인함수가 스택을 잡고 , 메인함수가 이미 잡은 스택에서 더 낮은 주소로 welcome , login이 한 번씩 더 스택을 이용한다.
  • 여기서 포인트는 welcome이 스택을 잡았다가 끝났을 때, 다시 스택을 반환 해서 원래 위치로 스택 포인터가 돌아오고, 다시 login이 welcome이 썼던 스택을 중첩해서 가져간다.

 

 

즉, 초기화 되지 않은 지역변수 값이 정해지는 가장 유력한 원인은 해당 지역변수를 가지는 함수 보다 이전에 호출 됐던 함수가 초기화 되지않은 값에 영향을 줄 확률이 높다.

 

 

 

3. disass welcome 으로 welcome을 들여다 보자.

disass welcome

  • welcome 함수는 스택을 sub $0x88 만큼 잡아서 쓰고 있다. 스택 포인터를 0x88만큼 sub 한다는게 공간을 확보한다는 뜻!
  • leave ret 명령어를 이용해서 다시 반환해주는 역할을 한다.
  • 결국엔 0x88 만큼 잡아서 자유롭게 사용하다가 다시 전부 반환을 한뒤, 바로 login함수가 호출된다.

 

 

 

 

4. disass login 으로 login 함수를 살펴보자.

disass login

  • login 함수는 0x28 만큼의 스택을 잡아서 사용하는데, 이전에 welcome에서 0x88만큼 잡았던 스택영역에 포함이 되는 것으로 볼 수 있다.
  • -0x10 이 첫번째 passcode1 의 메모리 위치가 되는데, 이 부분을 중첩 할 수가 있다.
  • welcome함수에서 100바이트를 -0x70위치에 받고 있는데, 여기서부터 100바이트를 받으면 (0x64)  -0xc까지 덮어씌어질 수 있다.
  • 여기서 ebp 같은경우는 같은 위치의 ebp 이므로 -0x70 과 -0x10 의 거리 차는 10진수로 바꾸면 96 거리 차이이다.
  • 결국, -70에서 96바이트를 전진하면, -0x10 의 위치까지 간다. 버퍼에서는 100바이트를 받으니, 4바이트가 남아있는 상황이라 그 4바이트가 -0x10(%ebp),%edx 위치랑 중첩이 된다. 

 

이 특성을 이용해 got 의 함수 포인터 값을 바꾸어 버리면 프로그램 흐름을 원하는대로 바꿀 수 있다!

 

 

 

 

5. scanf("%d",passcode1); 에서 system("bin/sh flag");의 시작주소를 넣어 fflush함수의 got 값을 변경한다.

x/10i 0x08049ff4

fflush의 got 주소 -> 0x804a004

system

system코드가 실행되는 시작주소 -> 0x080485e3

 

 

 

 

6. (python -c 'print "A"*96+"\x04\xa0\x04\x08"';cat) | ./passcode 를 이용해 끝내주자.

python

134514147이 나오는 이유는 scanf로 내가 원하는 걸 입력할 때 "정수"로 받기 때문에, 해당 system 주소 값을 정수로 변환해서 입력한 갑이 134514147이다!

 

 

 

 

7. Sorry mom.. I got confused about scanf usage :(    문구가 정답인지 확인 해보자!

passcode

성공!

반응형

'Wargame:Pwnable.kr' 카테고리의 다른 글

#6 Pwnable.kr : random 문제풀이  (0) 2022.08.06
#4 Pwnable.kr : flag 문제풀이  (0) 2022.08.04
#3 Pwnable.kr : bof 문제풀이  (0) 2022.08.02
#2 Pwnable.kr : collision 문제풀이  (0) 2022.08.01
#1 Pwnable.kr : fd 문제 풀이  (0) 2022.07.31
Comments