|  |
| |
| Turtle1000 |
1.
1. NOP은 No Operation의 약자로 \x90을 의미합니다. \x41인 A와는 다르고요.
보통 NOP을 넣어주는 이유는 쉘코드가 들어간 위치를 '정확히' 알지 못할 때 입니다.
예를 들어드리면,
// 디렉토리 위치는 /home/user/vuln.c
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char str[256]; // dummy = 8;
strcpy(str, argv[1]);
printf("%s\n", str);
return 0;
}
위와 같은 코드가 있다고 가정해보겠습니다.(C 언어는 아신다고 가정했습니다.)
gcc vuln.c -o vuln -> 으로 컴파일을 하고,
gdb로 분석해보니 /home/user/vuln A*243 + (25바이트 쉘코드) + 리턴주소
의 리턴주소가 0xbffffabc 가 나왔습니다.(예를 들어서요.)
그런데 그냥 ./vuln A*243 ~ 으로 실행을 하면 Segmentation Fault 가 뜨게 됩니다.
자세히 설명은 못해드리겠지만, 프로그램 이름의 길이차이에 의해서 그런겁니다.
그렇기 때문에 실제 리턴주소는 18 바이트 차이가 나게됩니다.
하지만, 이런걸 계산하기는 귀찮겠죠 ? 그렇기 때문에 NOP을 쓰는 겁니다. 위의 코드구성을
./vuln NOP*243 + (25바이트 쉘코드) + 리턴주소 -> 로 구성하게 되면,
NOP*243 영역 즉, 243 바이트 만큼의 주소 오차가 있더라도 NOP을 타고서 쉘코드의 위치까지 가게되는 겁니다.
이것을 NOP Sled 라고 합니다.
살짝 잘못 알고 계신 것 같아서 좀 설명드렸구요. 아마 `python -c 'print ~'` 으로 구문을 넣으실텐데,
쉘코드가 메모리에 올라가는 것이 맞습니다. |
2014/02/09 |
|
| Turtle1000 |
2.
쉘코드는 보통... C언어 -> strace -> asm -> ... 의 과정을 거쳐서 만들 수 있는데,
어느정도 어셈을 할 줄 아신다면 정말 쉽고 간단하게 만들 수 있습니다.
또한, 운영체제마다 쉘코드는 다릅니다. |
2014/02/09 |
|
| Turtle1000 |
3.
쉘코드를 어떤식으로 올려서 사용하시는지 안써주셔서 두 가지 방법을 알려드리겠습니다.
1. char str[256]과 같은 변수에 넣어서 주소를 구하는 방법
ASLR이 걸려있지 않은 낮은 버전의 운영체제에서 구할 때는,
gdb를 이용해서 구할 수도 있고, 이게 어려우시면 소스코드를 그대로 복사해서
파일이름의 길이(길이가 같아야 합니다.)를 같게 한 후에
printf("%p\n", &str[242]); -> 쉘코드가 올라가는 곳을 찍어주면 됩니다.
2. 환경변수를 이용할 경우의 방법
보통 export 이름=`python -c 'print "\x90"*50 + "쉘코드"'` 와 같은 방식으로 많이 등록합니다.
이를 알아내기 위해서는,
void main(int argc, char *argv[])
{
printf("%p\n", getenv(argv[1]));
}
와 같은 소스코드를 작성하셔서 알아내시면 됩니다.
만약 정확한 위치를 알고싶다면,
#include <stdio.h>
int main(int argc, char *argv[])
{
char *ptr = argv[1];
ptr += (strlen(argv[0]) - strlen(argv[2]));
printf("%p\n", ptr);
return 0;
}
./프로그램명 환경변수명 ./공격할프로그램명 -> 을 수행하시면 정확한 쉘코드의 위치가 나옵니다.
(NOP이 필요없어지게 됩니다.) |
2014/02/09 |
|
| Turtle1000 |
4.
취약한 함수들은 버퍼의 경계값을 검사하지 않습니다.
즉, 리턴을 넘어가더라도 값을 입력할 수 있다는 것이죠.
쉘코드를 올리는 방법은 매우 많습니다.
할당된 버퍼(char str[256] 같은)에 올리는 방법.
이때는 "\x90"*243 + 쉘코드 + 리턴주소 -> 와 같이 구성됩니다.
할당된 버퍼가 너무 작아서(char str[4]) 리턴 뒤에 쉘코드를 넣어줄 때,
이때는 "A"*8 + 리턴주소 + 쉘코드 -> 와 같이 구성하고, 뒤의 쉘코드 주소를 써주면 됩니다.
마찬가지로 NOP을 넣는 이유는 정확한 쉘코드의 위치를 알 수 없을때겠죠 ? |
2014/02/09 |
|
| Turtle1000 |
마지막으로,
카페에서 BOF 글 쓰고 있습니다 ~ 차근차근 보시면서 모르는 거 있으면 물어보세요 ~
자기소개 부분에 있어요 ~ |
2014/02/09 |
|
| APlusHacker |
터틀1000님 감사합니다
큰 도움 됬습니다.! |
2014/02/12 |
|