read_flag 함수를 이용하여 풀긴 했는데 궁금증이 있어서 질문드립니다.
드림핵 RTL 강의에 있는 방법대로 system 함수의 주소와 "/bin/sh"문자열 주소를 획득하여버퍼로 넣어주고, system 함수로 뛰는 것과 함수 내부에서 eax 레지스터에 /bin/sh 문자열 포인터까지 제대로 들어가는 것을 확인했는데, 강의에서의 example1.c 파일과 다르게 sh이 실행이 되질 않네요. 이유가 궁금합니다.
RET 주소에 system 함수의 plt 주소를 넣고,
RET +4 에 DUMMY 값 4byte 넣고
RET +8 에 /bin/sh 문자열이 들어간게 맞나요?
snwo님 댓글 답변입니다.
해당 문제 바이너리를 로컬에서 gdb로 연후
r <<< python -c 'print "A"*128 + "BBBB" + "\x30\x08\xe1\xf7" + "XXXX" + "\x52\xd3\xf5\xf7"'
실행시 쉘 실행안되고, eip XXXX로 끝납니다(seg fault). 그전에 system 함수로 ret된후(0xf7e10830) /bin/sh 문자열 포인터(0xf7f5d352)도 인자로 잘들어갑니다.
이상한 점은
r <<< python -c 'print "A"*128 + "BBBB" + "\x30\x08\xe1\xf7" + "XXXX" + "\x52\xd3\xf5\xf7\x0als -al"'
처럼 뒤에 "\x0als -al" 문자열을 추가해주면 ls -al은 실행되고 seg fault가 뜹니다.
사용중인 system함수의 주소를 보아하니 plt가 아닌 직접적인 system함수의 주소인것 같네요. gdb에서는 aslr(스택, 힙, 라이브러리 주소 랜덤화)보호기법이 기본적으로 꺼져있어서 된것이지만 해당 문제는 gdb에서 실행하는게 아니라 nc접속으로 푸는 문제입니다. 따라서 aslr보호기법이 적용되어 system함수를 직접 호출하는건 안되는 것입니다. 문제에서 read_flag함수를 준것도 이것때문입니다. aslr이 걸려있어도 code가 들어있는 text영역은 주소 랜덤화가 되지 않기때문에 read_flag함수는 직접 호출이 가능하지만 system함수는 라이브러리에 존재하므로 주소가 랜덤화 되어서 안되는 것입니다.