level 10
인자 두 개 이상, 환경변수 초기화, 48번째 바이트 "\xbf", 48글자 초과 X, argv 배열 0으로 초기화, buffer 변수 초기화.
어우 많네요.
인자도 안되구 환경변수도 buffer 변수도 안되네요.
어떻게 해야할까요?
일단 gdb를 통해 디버깅해보겠습니다.
먼저 복사해야겠죠?
aaaa라는 파일로 복사했습니다.
먼저 core 파일에 dump 후에 gdb를 통해 디버깅합니다.
쓸만한 정보가 메모리에 남아있는지 확인하는 겁니다.
이때는 프로그램 실행으로 할당된 메모리 +- 1000바이트씩 확인합니다.
이 값으로 시작해 천천히 살펴보겠습니다.
음... dump되었던 당시 인자로 주었던 A와 BBB\xbf가 SFP와 RET주소에만 남고 buffer는 모두 0으로 초기화되었네요.
여기에선 쓸만한게 없을 것 같습니다.
어라 맨 아래로 가보니 '61'이라는 값이 보입니다. 이는 파일이름인 'a'의 아스키코드 값입니다.
한 번 확인해볼까요?
aaaa가 저장되어있네요..
즉, 파일 이름은 그대로 남아있다는 것입니다.
그러면 파일이름에 쉘코드를 저장하면 되지 않을까요?
심볼릭 링크를 이용해서 말이죠!
물론 파일이름에는 '/'가 들어가면 안되니 그에 맞는 쉘코드가 필요합니다.
직접 어셈블리어를 작성해보았습니다.
0x2f가 들어가면 안되기에 0x2e+0x1의 방법을 택했습니다.
코드가 살짝 길어졌네요.
objdump를 통해 기계어를 확인할 수 있었습니다.
기계어를 직접 작성한 파이썬 소스코드를 이용해 추출해보겠습니다.
추출되었습니다.
이제 이 코드를 실행시켜보겠습니다.
C언어를 작성한 뒤,
컴파일해 실행했더니 쉘이 떨어집니다.
기계어에 문제가 없다는 뜻이죠 ㅎㅎ
\x31\xc0\x50\xb8\x2e\x2e\x73\x68\x04\x01\x80\xc4\x01\x50\x31\xc0\xb8\x2e\x62\x69\x6e\x83\xc0\x01\x50\x89\xe3\x31\xc0\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80
이제 이 기계어를 skeleton 파일의 심볼릭 링크 파일 이름으로 사용해보겠습니다.
굿굿 좋네요.
여기서 무언가 생각해야합니다.
계산을 해봐야하죠.
아까 파일이름은 0xbffffff5 ~ 0xbffffffa에 저장되어있었습니다.
좀 더 확대해석하면, 파일 이름은 0xbffffffb - 파일이름 길이 ~ 0xbffffffb까지 저장된다는 말이 됩니다.
심볼릭 링크로 생성된 파일 이름의 길이는 NOP*50 + ShellCode(39) == 89입니다.
0x59이죠. 0xbffffffb - 0x59 == 0xbfffffa2입니다.
NOP바이트가 50글자이니 0xbfffffa2 ~ 0xbfffffd4 중에 아무대나 골라 RET 주소에 덮어주면 됩니다.
payload는 이렇습니다.
"./" + "\x90"*50 + "~~"(ShellCode), "A"*44 + "\xa2\xff\xff\xbf"
성공^^