드림핵 ssp_001문제를 푸는 중 내 생각과는 다르게 스택이 구성되어 있는 것 같아 어셈을 확인해 정리하였다.
코드만 보고 생각한 스택 순서
int main(int argc, char *argv[]) {
unsigned char box[0x40] = {};
char name[0x40] = {};
char select[2] = {};
int idx = 0, name_len = 0;
...
}
문제의 코드 중 일부 내용이다. 변수가 box, name, select, .. 순서로 선언되어 있어, 스택은 주소값이 높은 곳에서 낮은 곳으로 자라니까 당연히 아래와 같은 순서로 선언되어있을 것이라 생각했다.
이를 이용해 카나리 릭을 해보려 했으나 제대로 되지 않았다. 이 구조가 아닌 것 같아 IDA로 확인해봤다.
IDA로 본 결과 위의 구조가 아니었다... 근데 저 v9는 따로 선언한 적이 없는데 0x8만큼 차지하고 있다.
검색해보니 __readgsdword(0x14u)는 카나리를 설정하는데 사용되는 함수라고 한다. 근데 그럼 카나리 크기가 0x8인 것 같은데 32bit환경에서 왜 카나리가 4바이트가 아닌 8바이트인지 모르겠다..
어셈을 보고 확인한 스택순서
case 문 이동 부분
while(1) {
menu();
read(0, select, 2);
switch( select[0] ) {
case 'F':
printf("box input : ");
read(0, box, sizeof(box));
break;
case 'P':
printf("Element index : ");
scanf("%d", &idx);
print_box(box, idx);
break;
case 'E':
printf("Name Size : ");
scanf("%d", &name_len);
printf("Name : ");
read(0, name, name_len);
return 0;
default:
break;
}
}
본 문제는 F를 선택하면 box에 값을 입력받고, P를 선택하면 box의 특정 인덱스 값을 보여주고, E를 선택하면 원하는 크기의 입력을 name에 전달할 수 있다.
어셈을 확인해보니 F는 0x46, P는 0x50, E는 0x45이므로, F를 선택하면 0x80487c6으로 이동하고, P는 0x80487eb, E는 0x8048824로 이동한다. 스택의 순서가 궁금한 것이기 때문에 F에서 box의 위치를 확인하고, E에서 name의 위치를 확인한다.
case 'F'에서 box의 스택위치 확인
box의 위치는 ebp - 0x88이다.
case 'E'에서 name의 스택위치 확인
name의 위치는 ebp - 0x48이다.
카나리 설정 부분
32bit 환경에서는 gs:0x14를 이용해 카나리 값을 설정한다고 한다.
(64bit는 fs:0x28)
보면 gs:0x14의 값을 eax에 저장하고, 이 저장한 값(eax의 값)을 ebp-0x8에 저장한다.
카나리 확인 부분
카나리 값을 확인하는 부분을 보면 ebp-0x8부터 4바이트(DWORD PTR이기 때문에)를 읽는 것을 알 수 있다. 나머지 4바이트는 더미값인 것 같다.
결론
왜 저런 순서인지 이유는 모르겠지만.... 문제를 풀면서 어셈을 보거나 IDA로 스택 위치를 확인할 필요가 있을 것 같다.
'CS > system' 카테고리의 다른 글
[System][Dreamhack] 메모리 보호기법 Mitigation: NX & ASLR (0) | 2022.11.25 |
---|---|
[System][Dreamhack] Exploit tech : Return to Shellcode (0) | 2022.09.06 |
[System][Dreamhack] bypass canary (0) | 2022.08.10 |
[System][Dreamhack] 메모리 보호 기법 memory mitigation - Stack Canary (0) | 2022.08.09 |
[System][Dreamhack] stack buffer overflow - 스택 버퍼 오버플로우 (0) | 2022.05.11 |