LOB darkknight ~ bugbear → giant - ldd와 nm으로 함수 mapping 주소 찾기
darkknight - new attacker
argv[1][47] ==‘\xbf’ 이면 exit 한다. 즉 stack으로 return 못한다. RTL 사용하면 된다. /bin/my-pass 문자열 삽입은 환경변수를 사용했다.
bugbear - new divide
ret에 들어가는 주소가 execve의 주소여야만 한다. execve인지 검사하기 위해 execve의 주소를 얻는데ldd 와nm 을 사용한다. 보통 함수의 주소를 구하기 위해 gdb로 실행한 다음 print 명령을 이용하지만 다음과 같은 방법으로도 가능하다.
- ldd로 shared library가 mapping되는 주소를 구한다.
- nm [-D]으로 함수의 offset을 구한 다음 이를 mapping 주소와 더한다. shared library는 fPIC 옵션으로 컴파일 하기 때문에 nm으로 출력되는 주소가 절대 주소가 아니라 offset이다. execve(*filename, *argv[], *envp[]); 이지만 argv와 envp에 null을 넣어도 동작 하므로 filename만 잘 넣어주면 된다. execve로 ret하고 함수 프롤로그가 끝난 시점에 ebp-8부터 *filename, 0, 0이 차례로 있어야 하고, shellcode를 입력하는 파일 실행 시점의 그 위치(나중에 ebp-8이 되는 위치)는 ret위치 + 8byte다.
* execve 주소에 \x0a가 포함되어 있는데, 이게 argv에 들어갈 때 \x00으로 들어간다. 쉘 때문인가 싶어 다른 쉘로 바꿔도 보고 스크립트도 python으로 바꿔 실행해 봤는데 안된다.
- libc.so.6이 mapping되는 주소를 변경한다
- libc.so.6 내부의 execve 위치를 변경한다. 2는 재컴파일 해야하니 실현성이 없고, 2는 header만 변경하면 되니까 가능할 것 같기는 한데 너무 귀찮아서 그냥 찾아보니 입력 자체를 문자열로 묶어 전달하면, 그러니까 perl 스크립트 자체를 ““로 묶어 전달하면 \x0a가 \x00으로 변경되지 않는다고 해서 argv[1] 입력 전체를 ““로 묶었다.
원래 *argv[]와 *envp[]자리를 “\x00”x8로 처리하려고 했는데, 다음 두가지 문제가 발생한다.
- \x00이 하나밖에 안들어간다.
- 하나 들어간 \x00도 제대로 0으로 동작을 못한다. char ** 형이기 때문에, 0x00000000이 아니면 그냥 \x00이 포함된 4byte의 주소로 인식한다. 그래서 0을 넣어주려면 확실히 0x00000000을 넣어주어야 하는데, 이를 직접 입력하지 않고메모리에서 0x00000000이 위치하는 곳을 찾아서 그 주소를 적어 처리했다.
/bin/my-pass는 역시 제일 간단한 환경변수로 처리했다.
./giant “perl -e 'print "A"x44, "\x48\x9d\x0a\x40", "B"x4, "\x35\xff\xff\xbf", "\xfc\xff\xff\xbf"x2'
”
This post is licensed under CC BY 4.0 by the author.