티스토리가 불편한 점 중에 하나는 에디터 기능에서 클립보드의 이미지가 붙여넣기 되지 않는다는 것이다. 지금까지 LOB 원정대를 풀면서 정리한 내용들이 워드 파일형태로 되어있어서 여기에 저장하고 싶었는데, 그러면 워드에 있는 이미지들을 일일이 저장해야 했다.ㅠㅠ 그냥 안쓰기로 함..
일단 이번 코드는 이렇다.
인자를 두개 쓰는 방법으로 저번 문제와 저저번 문제를 풀었었는데, 이제는 불가능해졌다.
일단 메모리 구조를 자세히 보면, 스택 부분 위에 환경변수, 인자들이 저장됨을 알 수 있다.
인자는 1개이므로, argv[0]과 argv[1]가 저 부분에 저장이될텐데, argv[1]은 초기화되므로, argv[0]이 저장되는 부분을 이용하려고 한다.
일단 gdb를 할거니 복사를 해주고 디버깅를 한다.
어셈블리어를 인텔 버전으로 바꿔주고, main을 디스어셈블해보자.
우리는 argv[0]이 어디에 있는지 알아볼건데, argv[1]가 초기화되기 전 후를 살펴봐서 빈 곳을 알아보려고 한다.
그러려먼 함수 프롤로그 직후와 에필로그 직전에 브레이크 포인터를 걸어야 한다.
스택 프롤로그와 에필로그는 따로 설명하지 않을 것임..
따라서 main+3과 main+317(leave면 스택 에필로그 실행)에 브레이크 포인터를 건다.
그리고 버퍼의 크기를 살펴보면, 40바이트 이므로,.
SFP까지 44바이트를 아무거나 채워주고 임시 리턴어드레스를 \xbf\xbf\xbf\xbf로 잡고 인자로 전달해준다.
아까 유저영역 시작부분에서 argv가 저장되는 곳이 가까우니까 0xbfffffff직전 주소의 메모리를 살펴볼려고 한다. 0xbfffffff의 전 1000바이트부터 100바이트를 스트링 형태로 보여달라고 하자.
저기 내가 실행한 파일과 인자로 준 것들이 있다.
그리고 끝부분의 환경변수가 모여있는 곳도 보기위해 0xbfffffff근처 메모리도 비슷한 명령어로 살펴보면, 내가 실행한 파일 경로가 있다.
이번에는 스택 프롤로그 직전의 메모리를 살펴볼거다. n을 입력하면 다음 브레이크를 만날 때까지 실행된다.
argv[1]가 초기화 된 것을 볼 수 있다.
그리고 끝 부분 환경변수도 초기화 된 것을 볼 수 있다. 하지만 내가 실행한 파일의 경로는 초기화되지 않았다.
이 두 부분 중 하나에 쉘코드를 넣고 그 부분을 리턴 어드레스로 하면 공격이 가능할 것 같다.
하지만 argv[0]은 파일 경로이므로, 쉘코드를 이 부분에 넣을 때 \x2f는 포함되어서는 안된다.
\x2f는 '\'으로 디렉토리 구분 인자이다. 따라서 이부분에서는 \x2f를 디렉토리 경로로 인식한다.
\x2f가 없는 쉘코드를 이용하자.
그러면 argv[0]을 어떻게 조작하나? 파일 이름이 argv[0]이니까, 파일이름을 통해 조작할 수 있다.
앞에 문제에서 사용했던 심볼릭 링크를 이용할 것이다.
심볼릭 링크의 이름을 쉘코드로 해주고, 그걸 gdb해서 argv[0]의 위치를 리턴 어드레스로 해주면 된다.
위에서 살펴본 argv[0]가 저장되는 두번째 영역은 커널영역까지의 공간이 얼마 안남았으므로, 쉘 코드 길이가 긴 것을 이용하거나, 놉 슬라이딩 기법을 이용하여 길이가 길어지면 커널 영역을 침범하여 페이로드가 안 먹힐 수 있으므로, 앞의 부분을 이용하려고 한다.
cp한 파일이름을 NOP과 쉘코드로 바꿔준다. 나는 중간에 삭제해버려서 다시 cp함.
그리고 리턴 어드레스를 \xbf\xbf\xbf\xbf로 정해서 실행해서 코어 덤프를 뜬다.
아까처럼 메모리를 살펴보면, 이렇게 되고, 첫번째 부분을 사용하기로 했으니 대충 0xbfff960으로 잡는다. 앞의 두바이트는 ./라고 하므로 bffff95d부터 사용할 수 있지만, 어차피 NOP이므로 대충 잡는다.
뒷 부분도 있긴 함. 나중에 넣어보긴 할 것임.
이제 리턴 어드레스도 알아냈으니, 지우고 심볼링 링크를 생성한다.
근데 왜인지 실행이 안된다. 아마 쉘코드 부분이스트링으로 저장되는 과정에서 뭔가 다른 문자로 바뀐 것 같기도 하다. 그냥 *를 이용하기로 함.