티스토리 뷰

이번 문제는 fgets 로 입력을 받고 입력받은 것을 strcpy 로 옮겨주는 문제입니다.

버퍼는 256 바이트만큼 입력받는데 fgets 로 1024 바이트만큼 입력받은 값을 옮기기 때문에 취약합니다.

먼저, 힌트를 보시면 fake ebp 나 got overwrite 를 사용하라고 나와있습니다.

만... 사실 두 가지 방법 외에도 do_system 을 이용한 공격이 가능한데... 이것은 따로 찾아보시기 바랍니다.

아무튼... 저는 원래 쉽고 간단한 do_system 으로 풀었습니다만, 여러분들을 위해 !

mprotect 라는 함수를 이용한 방법을 소개해드리겠습니다.(워 게임에서 mprotect를 사용한 것은 이 문제가 최초군요.)

일단 환경은 ASLR, Ascii-Armor, NX-Bit 입니다. 하지만 stdin(임시버퍼)는 랜덤이 아니므로,

stdin 에 fake ebp 를 구성하여 mprotect 를 호출 후에 쉘코드를 실행하겠습니다.

저희에게 필요한 주소는 위의 두 주소 뿐만아니라 leave의 주소인 0x08048561 입니다.

그럼 먼저 공격을 어떻게 수행해야하는지 생각해보겠습니다.

| buf(264) | ebp(4) | ret(4) | -> 와 같이 스택이 구성되어있고, ebp 값을 복구됩니다.

따라서, fake ebp 를 사용하려면 ebp 가 가리키는 값을 한 번 더 덮어줘야 합니다.

먼저 제가 공격한 코드를 보여드리고 설명하겠습니다.

크.... 어마어마하게 복잡하게 보이죠 ?? 정리해서 하나씩 뜯어가며 분석해보겠습니다.(디버깅만은...)

간단하게 코드를 나타내면,

A*268 + leave + C*88 + 0xf6ffe16c + leave + mprotect@plt + 쉘코드주소 + 인자1 + 인자2 + 인자3 + 쉘코드

입니다. 이렇게보니까 정말 간단하죠 ?(-_-?)

걱정마세요. 저도 위와 같이 코드 구성하는데 정말 애먹고 오래걸렸습니다...(do_system 짱짱맨...)

일단 리턴 부분에 바로 0xf6ffe16c 를 넣지 않은 이유는 직접 리턴하는 것이 아닌 리턴 값에 들어가는 것은,

바로 '실행' 하려고 하기 때문입니다.

esp 의 값을 eip 에 넣어서 리턴을 하는 것과 리턴 값에 주소를 넣는 것의 차이를 잘 아셔야 합니다.

이것만 설명해드리면 위의 코드를 이해할 수 있을 것 같으니(사실 설명하기 매우 귀찮기도...) 말씀드리겠습니다.


리턴이 수행되는 과정을 다시 한 번 생각해보시기 바랍니다.

ebp: 0x34, esp: 0x23 이라고 가정해보겠습니다.

leave 가 수행되면, mov esp, ebp; pop ebp 에 따라서 esp 의 값은 0x38 이 됩니다.

이때 만약 0x38에 0xf6ffe16c 를 넣어놨다면, 0xf6ffe16c 에 있는 값을 '실행' 하려고 합니다.

하지만 애석하게도 저 부분은 실행 권한이 존재하지 않기 때문에 실패하고 맙니다.

그렇다면 실제로 원하는 방향으로 이끌기 위해서는,

esp 의 값 자체를 0xf6ffe16c 으로 바꿔줘야 합니다.

이를 위해 리턴 값에 leave 의 주소를 넣어주게 되면, ebp 에 있던 0xf6ffe16c + 4 의 값으로 점프하게 됩니다.

이 때는 '실행' 이 아닌 0xf6ffe170 의 주소에 있는 '값' 을 수행하려고 합니다.

그렇게 되면 자동적으로 mprotect 함수가 수행되고 실행 권한까지 모두 얻게 된 후에,

다음 리턴주소에는 직접 쉘코드의 주소를 넣어서 쉘코드를 '실행' 하게 됩니다.

이해되셨나요 ??? 만약 되셨다면 ! 위의 코드의 구조를 디버깅하면서 풀어보세요 ~~

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함