-
[pwnable.kr] Level 5 - passcodeWargame/pwnable.kr 2023. 4. 1. 01:49반응형
Level 5 - passcode를 풀어보자.
문제를 보면 아들이 C 코드로 작성한 문제가 있는 파일을 컴파일한 것 같다.
엄마는 말렸지만, 말을 안 듣는 것 같다..

<passcode의 문제 화면> Kali에서 ssh로 해당 문제에 접속을 해보도록 하자.
존재하는 파일들을 보면, flag와 passcode 파일 그리고 passcode의 소스 코드가 있다.

<passcode 문제 접속> 작성된 소스 코드를 먼저 보도록 하자.
login, welcome, main의 세 함수로 이루어진 파일이다.
login에서는 두 개의 passcode를 입력받고, 그 값을 비교해 문제 해결 여부를 보여준다.
welcome에서는 name을 입력받고, 입력받은 name의 Welcome 문구를 보여준다.
마지막으로 main은 welcome 함수와 login 함수를 실행하는 것 외에 특별한 동작은 하지 않는 것 같다.
그런데, login 함수에서 passcode1과 passcode2의 scanf 함수를 잘 보면 & 문자가 없다.
이 문자가 없다는 것은, passcode1과 passcode2의 주소에 입력 값을 넣는다는 것이 아니다.
즉, 현재 passcode1과 passcode2의 주소에 저장되어 있는 값이 가리키는 곳에 입력 값을 넣는다는 것이다.
이것을 이용해 그 값들이 가리키는 주소를 변경하여 공격을 진행하면 된다.
여기에서 이용되는 공격 방법이 PLT와 GOT를 이용한 공격이 되겠다.

<passcode 문제의 소스 파일> passcode 파일이 작동하는 방식을 보도록 하자.
파일을 실행한 후 name에 test를 입력하니, Welcome test!가 출력되었다.
그 후 test를 passcode1에 입력하니, passcode2에서는 checking...이 나타나면서 Login에 실패한다.
이것은 passcode1 뒤의 fflush에 의한 것인데, 리눅스에서 이 함수가 이상하게 작동한다고 한다.
그래서 어떤 값을 넣어도 '\n'이 입력되고 passcode2에 아무런 값을 입력할 수가 없는 것이다.
문제를 해결하기 위해서는 이 fflush 함수를 이용해야 한다.

<passcode 파일의 동작> 우선 파일에 적용된 보호 정책을 살펴보기 위해 checksec을 실행하였다.
NX와 Canary가 적용되어 있는 것을 볼 수 있다.

<passcode 파일의 보호 기법> 이제 필요한 함수의 PLT와 GOT를 알아보기 위해, gdb를 이용해 분석을 해보자.
첫 번째로 main 함수를 보았는데, 특별하게 눈에 띄는 것은 없다.
아무래도 다른 함수를 호출하는 것 외에 다른 동작을 안하기 때문인 듯하다.

<main 함수 분석> 다음으로 welcome 함수를 분석해보자.
<welcome+48>을 보면 scanf 함수가있는 것을 볼 수 있다.
그 위의 값 [ebp-0x70]이 scanf의 인자로 들어가는 name이 될 것이다.
100 바이트를 입력받는데, 더미 값이 있는 것을 생각하고 넘어가도록 하자.

<welcome 함수 분석> 마지막으로 login 함수를 분석해보자.
<login+34>를 보면, scanf가 있다.
이번에는 [ebp-0x10]의 위치에 passcode1이 있다는 것을 알 수 있다.
또한, <login+47>를 통해 fflush@plt가 있는 것이 보인다.
우선은 여기까지 분석을 하고, 다음으로 넘어가자.

<login 함수 분석> 값을 입력했을 때, name과 passcode1이 어떤 식으로 되어 있는지 확인해보도록 하자.
표준입력 방식이므로 <<< 를 이용해 파이썬 코드를 넣을 수 있다.
<welcome+53>, <login+34>에 브레이크 포인트를 건 후, 'a'를 100개 입력하고 실행한다.
먼저 name은 ebp-0x70에 위치해 있는데 넉넉하게 ebp-0x80을 범위로 잡았다.
name의 시작 위치가 0xffffc368인 것을 볼 수 있다.
다음으로 passcode1의 위치를 확인해보기 위해 continue를 하고, ebp-0x10의 위치를 보았다.
passcode1은 0xffffc3c8에 위치한 것을 볼 수 있다.
그런데, passcode1의 위치는 name의 범위인 0xffffc368 ~ 0xffffc3cb에 속해있다.
이건 같은 ebp에서 시작해 범위가 정해지면서, 메모리가 겹치는 문제가 발생한 것이다.
이 정보도 페이로드를 작성할 때, 이용하도록 하자.

<name, passcode1 위치 확인> 이제 페이로드를 어떻게 작성할지 생각해보자.
먼저, 이번 공격은 앞에서 언급한 PLT와 GOT를 이용하여 수행할 것이다.
프로그램이 작동하면 main 함수가 시작되면서 그 안의 함수들의 PLT, GOT가 등록된다.
fflush를 이용해 공격을 하기로 했으므로, fflush의 GOT를 알아보도록 하자.
<login+47>을 보면 fflush의 PLT가 0x8048430인 것이 보인다.
이 곳을 들어가보면, fflush의 PLT가 0x804a004로 점프를 하는데, 여기가 fflush의 GOT가 된다.
알아낸 GOT에 <login+127>에 있는 0x080485e3: system("/bin/cat flag")를 넣어 주면 공격이 될 것이다.
결국 공격은 name에 값을 입력하여 진행을 할 것이고, passcode1이 실행되도록 할것이다.

<fflush의 GOT> 이것을 세세하게 풀어보자면, 먼저 name에 96 바이트만큼 값을 넣는다.
이 값은 name:[ebp-0x70]과 passcode1:[ebp-0x10]의 차이인 값이다.
그 다음 4 바이트에 fflush의 GOT를 넣고, system을 실행하도록 하면 된다.
즉, name에 96 바이트의 쓰레기 값 + 4 바이트의 fflush GOT를 넣는다.
그리고 passcode1이 입력받을 때 & 기호가 없어, 해당 주소의 값이 가리키는 값이 변하게 된다.
거기에 system("/bin/cat flag")의 주소를 넣어주는 것이다.
이렇게 페이로드를 작성하면 fflush가 실행될 때, 변경한 GOT로 인해 system("/bin/cat flag")이 실행된다.
여기서 system("/bin/cat flag")의 주소를 10진수로 바꾼건 passcode1이 10진수로 입력을 받기 때문이다.
이렇게 페이로드를 입력하고 system("/bin/cat flag")의 주소를 입력해주면 flag가 출력된다.

<passcode의 flag 확인> 반응형'Wargame > pwnable.kr' 카테고리의 다른 글
[pwnable.kr] Level 7 - input (0) 2023.04.09 [pwnable.kr] Level 6 - random (0) 2023.04.09 [pwnable.kr] Level 4 - flag (0) 2023.02.05 [pwnable.kr] Level 3 - bof (0) 2023.01.07 [pwnable.kr] Level 2 - col (0) 2023.01.06