본문 바로가기

[Wargame Write-up]/Lord of Buffer Overflow

[LoB RedHat 6.2] LEVEL 7: darkelf -> orge

LEVEL 7: check argv[0]



이번엔 argv[0]가 77자리이도록 길이제한을 두었다.


argv[2]의 제한은 아직도 없기 때문에, 이것으로 공략해보자.




이상하게 그냥 bash2로 쉘을 실행해서는 \xff가 \x00로 되는 버그가 사라지지 않아서, chsh 명령어로 쉘을 변경했다.


아래처럼 쉘을 바꾼 뒤




다시 로그인하면 아래처럼 쉘이 바뀌어 있다.




gdb 실행 시에는 절대주소로 들어가기 때문에, argv[0]을 77자리로 구성할 때, /home/darkelf/를 포함하여 고려해야 한다.


경로에서 현재 경로를 뜻하는 .이나 상위 경로를 뜻하는 ..이 없는 "/"의 경우엔 무시되기 때문에, 활용하기엔 안성맞춤이다.


argv[0]은 끝났고, 각 argv들의 주소를 파악하기 위해 argv[2]까지 넣어줬다.


이번엔 약간 방법을 달리하여, 함수 프롤로그 부분에 breakpoint를 걸어 분석하려고 한다.


0x8048503에 걸어주고




esp를 뜯어보면 다음과 같이 나온다. 3번째에 나오는 3이 argc, 다음에 나오는 값은 argv 값이 저장된 곳의 주소를 담고 있는 값이다.




0xbffffa74에 들어있는 값을 보면, 0xbffffb6c인데 여기가 argv의 주소가 된다.


다음으로 특정 주소로부터 문자열로 변환하여 5개 보여주는 x/5s로 그 주소를 보면


argv[0], argv[1], argv[2] 순으로 저장되어 있는 것을 볼 수 있다. 그 뒤는 환경변수임을 알 수 있다.




이제 payload를 작성해보자. 위에서 argv[2]의 주소가 0xbffffbeb임을 알아두고,


argv[0]에는 gdb 인자로 줬던 것을 써도 되지만, 좀더 짧게 하기 위해 "./" + "/" 71개(77-len("./")-len("orgf")) + "orgf"로 구성했다.


argv[1]에는 제약 사항에 맞춰 A 44개, argv[2] 주소값 4바이트, 총 48바이트로 구성했고,


argv[2]에는 NOP sled 구성을 위해 NOP 500개, 마지막으로 쉘코드를 주었다.


하지만 에러가...




다시 확인해보니 argv[2] 주소가 0xbffffa0f로 달라져 있다(!)




주소를 다시 설정해서 공격하니 성공했다.




원본에 하면 다음 레벨로 가는 password를 얻을 수 있다.




며칠동안 실패하면서 상당히 짜증났었는데, 방법을 달리하여 결국 풀어내서 다행이다.