카테고리 없음

스택에 ASLR이 걸려있고 NX가 없을 때 argv로 nopsled가 가능할까요

진모씨 2014. 1. 18. 04:07

스택에 ASLR이 걸려있고 NX가 없을 때 argv로 nopsled가 가능할까요?

네! 가능해요.


일반적으로 한 argv 값 안에 엄청 긴 문자열이 들어가게 되면 argument list too long 이라는 게 뜨게 되지만, 여러개로 나눈다면 달라져요.

물론 argc를 체크한다면 그러면 안되겠죠..


아래는 간단한 프로그램의 결과에요. 프로그램 내용은..


#include <stdio.h>


int main(int argc, char **argv) {

 

    char **framep;


    asm("movl %%ebp, %0" : "=r" (framep));

    char** framepp;

    framepp = framep;

 printf("argc: %p\n", &argc);

 printf("argv: %p\n", &argv);

 printf("argv[1]: %p\n", &argv[1]);

 printf("ebp-argv[1]: 0x%x\n", (char**)(framepp)-&argv[1]);

 sleep(1);

 return 0;

}

이에요. 1초를 쉬는 이유는 그 뒤에 stack의 할당 범위를 알아내기 위해서죠.

ebp 는 알아낼필요 없더라구요. :(


아래는 결과에요.

parallels@ubuntu:~$ ./argsled `python -c 'print "A"*100000'` `python -c 'print "A"*100000'` `python -c 'print "A"*100000'` `python -c 'print "A"*100000'` `python -c 'print "A"*100000'` & sleep 0.2; grep stack /proc/$(pgrep argsled)/maps

[1] 10757

argc: 0xfff0b690

argv: 0xfff0b694

argv[1]: 0xfff0b728

ebp-argv[1]: 0xffffffd8

ffeed000-fff88000 rw-p 00000000 00:00 0                                  [stack]


네, 스택의 끝부분인 fff88000 에서 argv[1]의 주소인 fff0b728을 빼본다면 510168 이 나올거에요.

저는 500000개만큼의 A를 넣어줬죠. 거기다가 널바이트(argv 구분자)를 합하면 500005개를 넣었네요. 거기다가 프로그램의 실행 이름, ./argsled의 길이를 합하면 500014가 되는군요.

중간에 널바이트가 끼는데, 이 부분은 아래의 표를 참고하시면 될거에요.

[nop*10][0~255][0] 의 옵코드에요.


보시다시피 스택도 이런식으로 밀 수가 있습니다.

이걸 활용할 요긴할 곳을 꼽자면..


cgi에서 프로그램을 실행할 때 argv형태로 넘겨주게 됩니다. 주소의 QUERY_STRING부분을요.

만약 스택 오버플로우가 일어나는 상황에서 스택에 쉘코드를 올려놓고 실행할 수 있는 상황이라면, aslr이 걸려있을 때 이 방법을 쓰면 되겠죠?