FTZ 20 Level
ID : level20
Passwd : we are just regular guys
접속해서 ls 명령으로 파일과 디렉터리를 확인합니다.
cat 명령으로 hint를 열어봅니다.
fgets에서 크기 제한을 두어 Buffer Overflow는 통하지 않겠네요.
printf 함수는 printf(“서식 문자, 문자열”, 인자); 이런 식으로 사용합니다.
printf(“%d”, 1); 하면 1이 출력됩니다. ebp+8이 문자열일 것이고, ebp+12가 1일 것입니다.
즉, 서식 문자를 넣으면 ‘ebp+값’ 이 점점 커지면서 참조한다는 것입니다.
그렇다면 printf(“%d %d %d”, 1); 이렇게 쓰면 어떨까요?
ebp+12까지는 참조가 될 것입니다. 하지만 그 다음부터는 인자가 없어 이상한 값들을 참조할 것 같네요.
| bleh | SFP | RET | 상태에서 printf(“ASDF%d”, 123); 을 실행하면
| SFP | RET | ASDF%d 문자열 주소 | 123 | ? | bleh | SFP | RET |
이렇게 될 것입니다.
어쩌면 bleh의 메모리를 출력할 수도 있을 것 같네요!
이렇게 배열에 서식 문자를 넣어줬는데 메모리 값이 출력된 것 같아요. 저렇게 반복되는 구간이 있는데 저 부분이 혹시 %08x가 반복되는 부분이 아닐까 생각됩니다. 그럼 우리가 잘 아는 AAAA를 넣어서 확인해 봅시다.
41414141이 보입니다! 0000004f가 ebp+12, 4212ecc0이 ebp+16, 4207a750이 ebp+20, 그리고 bleh의 시작은 ebp+24겠죠.
여기서 알아야 할 게 있습니다. 바로 %n 이라는 서식 문자인데요. %n은 그 전에 쓰인 문자의 개수에 합을 받은 인자에 넣어줍니다.
ex)
int x;
printf(“ABCD%n”, &x);
printf(“%d”, x);
하면 4가 출력되는 것을 확인할 수 있습니다.
그럼 원하는 주소에 원하는 값을 넣을 수 있겠네요. 하지만 main 함수의 Return Address가 위치한 스택이 랜덤 스택이기 때문에 고정적인 주소를 넣어주어야 합니다.
바로 main 함수의 소멸자 부분 .dtors 인데요. main 함수가 끝나게 되면 .dtors 속성의 함수가 실행 되는데, 여기를 셸코드의 주소로 바꿔주는 것입니다.
attribute로 추가해준 함수가 없다면
__DTOR_LIST__
__DTOR_END__
구조를 가지게 됩니다.
__DTOR_END__ 의 주소를 바꿔줍시다.
그리고 주소를 바꿔주려면 %정수c %n 구조가 필요한데 여기서 메모리 주소는 너무 크기 때문에 반으로 나누어 넣어줘야 합니다.
우리는 소멸자의 위치, 셸코드를 등록해 놓은 환경변수 위치가 필요합니다.
소멸자의 위치를 찾아보도록 하겠습니다.
확인해보면 08049594라는 값이 있네요. 그럼 __DTOR_END__는 +4 위치 08049598일 것입니다.
그럼 2byte씩 나눠서 값을 넣기 위해 낮은 주소 : 0x08049598, 높은 주소 : 0x0804959a 라고 둡니다.
셸코드를 환경 변수에 등록해보겠습니다.
그리고 환경 변수의 주소를 구하는 코드를 짜고 컴파일 후 실행해봅시다.
페이로드 구성을 해봅시다.
“AAAA”+”\x98\x95\x04\x08”+”BBBB”+”\x9a\x95\x04\x08”+”%8x%8x%8x”+”%0xcc53을 넣을 수 있는 정수 값c”+”%n”+”%0xbfff를 넣을 수 있는 정수 값c”+”%n”
이렇게 된다면 %8x%8x%8x를 만난 후에는 bleh를 가리키고 있고, AAAA를 %정수c로 출력해서 %n을 쓸 준비를 합니다. %n으로 AAAA 다음 값인 0x08049598에 출력한 자릿수를 넣어줍니다. 마찬가지로 BBBB를 %정수c로 출력해서 %n로 BBBB 다음 값인 0x0804959a에 출력한 자릿수를 넣어줍니다.
그럼 0x08049598에 넣어줄 0xcc53을 10진수로 변환해보면 52,307이고, 0xbfff는 49151입니다.
AAAA~%8x%8x%8x까지가 4 + 4 + 4 + 4 + 8 + 8 + 8 이니까 40byte입니다. %n은 지금까지 출력한 자릿수를 이용하기 때문에 52307-40 한 값을 %정수c 부분에 넣어줘야 합니다.
“AAAA”+”\x98\x95\x04\x08”+”BBBB”+”\x9a\x95\x04\x08”+”%8x%8x%8x”+”%52267c”+”%n”+”%0xbfff를 넣을 수 있는 정수 값c”+”%n”
여기까지 나왔습니다.
그럼 40+52267을 다시 49151로 바꿔줘야 합니다. 근데 이미 40+52267 = 52307 이라는 숫자는 49151을 넘어섰습니다. 그러면 0xbfff가 아닌 0x1bfff를 만들어주면 됩니다.
0x1bfff : 114,687 여기서 이미 출력한 숫자를 빼주면 넣어야 할 값이 나오게 됩니다.
114,687 – 52,307 = 62,380.
“AAAA”+”\x98\x95\x04\x08”+”BBBB”+”\x9a\x95\x04\x08”+”%8x%8x%8x”+”%52267c”+”%n”+”%62380c”+”%n”
이겁니다!
payload : (python –c ‘print “AAAA”+”\x98\x95\x04\x08”+”BBBB”+”\x9a\x95\x04\x08”+”%8x%8x%8x”+”%52267c”+”%n”+”%62380c”+”%n”’; cat) | ./attackme
원본 파일에 공격을 시도하겠습니다.
exploit!
감사합니다.
'System&Write up > FTZ' 카테고리의 다른 글
FTZ level19 -> level20 Write up (0) | 2017.09.27 |
---|---|
FTZ level18 -> level19 Write up (0) | 2017.09.27 |
FTZ level17 -> level18 Write up (0) | 2017.09.27 |
FTZ level16 -> level17 Write up (0) | 2017.09.25 |
FTZ level15 -> level16 Write up (0) | 2017.09.25 |