Post

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의 주소를 얻는데lddnm 을 사용한다. 보통 함수의 주소를 구하기 위해 gdb로 실행한 다음 print 명령을 이용하지만 다음과 같은 방법으로도 가능하다.

  1. ldd로 shared library가 mapping되는 주소를 구한다.
  2. 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으로 바꿔 실행해 봤는데 안된다.

  1. libc.so.6이 mapping되는 주소를 변경한다
  2. libc.so.6 내부의 execve 위치를 변경한다. 2는 재컴파일 해야하니 실현성이 없고, 2는 header만 변경하면 되니까 가능할 것 같기는 한데 너무 귀찮아서 그냥 찾아보니 입력 자체를 문자열로 묶어 전달하면, 그러니까 perl 스크립트 자체를 ““로 묶어 전달하면 \x0a가 \x00으로 변경되지 않는다고 해서 argv[1] 입력 전체를 ““로 묶었다.

원래 *argv[]와 *envp[]자리를 “\x00”x8로 처리하려고 했는데, 다음 두가지 문제가 발생한다.

  1. \x00이 하나밖에 안들어간다.
  2. 하나 들어간 \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.