먼저 orc.c 를 열어보자. 오크란다;ㅎㅎ
이전 문제들 보단 소스가 꽤나 복잡다. 약간 소스 해석이 필요할 듯 싶다.
쭉쭉 읽히지 않음..
extern char **environ
: 먼저 extern은 환경변수의 주소값을 저장하는 것이다. 환경변수에 관련된 내용이 나올 것이라 예상함.
if(argc <2){
printf("argv error\n");
exit(0);}
: main함수 인자를 입력하지 않으면 에러가 뜨도록.
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
: 먼저 memset함수를 보자. 이 함수는 메모리의 값을 어떠한 상수값으로 채우는 함수이다. 주로 작업전 초기화할 때 사용됨.
함수 레퍼런스이다. memset(void *ptr, int c, size_t n)
void *ptr 은 초기화 시킬 주소 포인터
inc c 는 초기화 시킬 값
size_t n 은 초기화 시킬 값의 사이즈이다.
이에 착안하여 소스를 다시 보면,
environ 즉 환경변수값들을 다 0으로 채워 넣는다는 말이다. 환경변수에 셸을 올리는 eggshell을 못쓰도록 막는 소스라고 볼 수있음.
나야 어차피 eggshell을 애초에 사용하지 않아서 크게 제한될 문제는 없었음..
(뭔가 그냥 구현된 소스로 넣고 돌린다는게 마음에 안들었음.)
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);}
strcpy(buffer, argv[1]);
printf("%s\n",buffer);
스택 영역에만 공격하라는 말이다. argv[1]이 buffer로 복사되니까.
argv[1][47]은 리턴어드레스의 첫 바이트를 가르킬 것이다. 고것이 \xbf 여야 한다는건
스택영역에서만 공격을 하라 이말이다.
이에 착안하여 공격을 하자. 또 argv[2]에 넣으면 뚫릴것 같다.
페이로드는 이럼
argv[1]에 올리는 페이로드: [NOP 44] [RET(argv[2] 주소)]
argv[2]에 올리는 페이로드: [NOP 10만개] [shellcode]
argv[2]의 주소를 RET에 넣으면 되는데
구하는 방법이 두가지다.
하나는 gdb로 esp 레지스터를 추적하여 구하는 방법
하나는 소스코드에 argv[2] 주소를 출력하는 코드를 추가하여 구하는 방법.
해보니 차이가 10정도 난다.
nop이 10만개라서 크게 의미 없다.
'IT 그리고 정보보안 > Write-up' 카테고리의 다른 글
LOB Level 6 (Wolfman) (0) | 2021.04.12 |
---|---|
LOB Level 5 (Orc) (0) | 2021.04.12 |
LOB Level 3 (Cobolt) (0) | 2021.04.11 |
LOB Level 2 (Gremlin) (0) | 2021.04.11 |
LOB Level 1 (Gate) (0) | 2021.04.11 |