우선 nightmare의 소스를 확인해 보도록 하겠습니다.

ret의 부분은 반드시 strcpy의 주소로 덮어 주어야 하고요.

스택의 ret다음 4byteAAAA로 초기화 해주는 코드가 보이네요.

 

처음에 이 문제를 어떻게 풀어야 하나 많이 고민을 많이 했습니다.

힌트에 PLT라고 적혀 있어서 strcpy를 통해 plt를 수정해서 system을 실행시켜야 하나 고민했었죠.

 

하지만 생각보다 strcpy를 이용한 문제풀이는 간단하였습니다.

 

기본 아이디어는 다음과 같습니다.

메모리에 system’s address + \x11\x11\x11\x11 + “/bin/sh”’s adress로 구성 되어 있는 데이터를 집어 넣는다.

strcpy함수를 통하여 데이터의 내용을 strcpy’s address가 들어있는 ret의 다음 4byte위치에 덮는다.

 

스택을 보며 설명해 드리도록 하겠습니다.

 

Buff’s address

RET’s address+4

AAAA

RET : strcpy’s address

NOP * 32

“/bin/sh”’s address

\x11\x11\x11\x11

System’s address

main함수가 끝나기 전에는 스택의 구성이 위와 같이 됩니다.

 

그리고 main함수가 끝난 후 RETstrcpy’s address로 인하여 strcpy가 실행되게 됩니다.

RET+4에는 RET’s address+4, RET+8에는 Buff’s address를 전달해 주었으니 strcpy(&RET+4, &Buff)가 실행되게 됩니다.

Buff의 내용이 RET+4에 덮어 씌워지게 되는 것이죠.

 

그럼 strcpy가 끝난 후 스택의 모습은 다음과 같이 될것입니다.

“/bin/sh”’s address

\x11\x11\x11\x11

System’s address

RET : strcpy’s address

NOP * 32

“/bin/sh”’s address

\x11\x11\x11\x11

System’s address

RET strcpy함수가 끝났으므로 그 위의 system함수를 실행하고 인자는 /bin/sh가 될것이고, 결과적으로 쉘이 뜰것입니다.

 

이를 위한 페이로드는 다음과 같습니다.

system’s address + 0x11111111 + “/bin/sh”’s address + NOP*32 + strcpy’s address + AAAA + (RET’s address + 4) + Buff’s address

 

그럼 우선 필요한 값들을 얻도록 하겠습니다.

strcpy의 주소는 0x08048410입니다.

system의 주소는 0x40058ae0입니다.


“/bin/sh”의 주소는 0x400fbff9입니다.

 

그리고 RET’s address + 4의 값은 ebp+8로 계산하고, Buff’s addressebp-40으로 구하면 됩니다.

 

현재까지 구한 값을 페이로드에 반영하고 디버깅 하여 ebp를 확인하여 나머지 값들도 얻도록 하겠습니다.

획득한 ebp의 값은 0xbffffab8입니다.

따라서 strcpy에서 dest이 될 주소는 0xbffffac0, src가 될 주소는 0xbffffa90이 될듯 하네요.

 

페이로드에 이를 반영하여 테스트 해보도록 하겠습니다.

역시 세그펄트가 발생했네요. 한번에 될거란 기대도 없었습니다.

 

core dump를 이용해 디버깅 하여 buff의 주소를 알아보도록 하겠습니다.

dest의 주소는 srcbuff의 주소에 0x30만 더해주면 되니깐요.

buff의 시작 주소는 0xbffffaa0이네요. 그럼 dest의 주소는 0xbffffad0입니다.

 

페이로드를 수정하여 테스트 하도록 하겠습니다.

복사본에서 쉘이 획득 되었습니다.

 

메모리의 주소값이 바뀌기 전에 어서 원본파일에 공격하도록 하겠습니다.

성공적으로 nightmare의 쉘이 획득 되었습니다.

nightmare의 패스워드는 beg for me입니다.

+ Recent posts