오늘 해결한 문제는 fsb 문제!
(fsb)
포멧스트링 공격이라..!
기사 공부하면서 배웠던 내용이지만 직접 해보는 건 처음이라 다시 많이 찾아보면서 공부하였다.
단순히 메모리값을 노출시키는데 그치지않고 값 또한 변조할 수 있다는 사실을 알았다.
문제의 소스코드!
(소스코드)
pw와 key를 같게 해야하니 key를 변조 시키면 되겠다 라는 생각이 들었다.
key는 /dev/urandom 에서 랜덤한 값을 8바이트 가져온다.
fsb 공격의 기회를 4번 주는데 풀면서 이해했는데 왜 4번을 준지 이해했다.
GOT를 overwrite할 수도 있지만 4번을 준 이유는 pw와 key를 같게 하게 해서 풀으라는 문제 출제자의 의도인듯 했다.
처음에 당황했던 것은 찾아보면서 공부할 때는 버퍼가 모두 스택에 있었던 경우라서 버퍼에 직접 주소를 입력할 수 있고 그 주소를 직접 덮어썻는데 문제에서는 버퍼가 전역변수로 설정되어있어 스택에 존재하지 않는다...
그렇기에 스택에 key값의 버퍼 주소를 직접 적어주고 그 주소를 이용해 key값을 덮어 써야한다.
key의 자료형은 unsigned long long 이기에 8바이트 한번에 4바이트씩 덮어 쓸수 있으므로 2번 해야한다. 따라서 4번의 공격 기회를 준것이다.
스택에서 사용할 수 있는 주소를 보자!
(사용할 수 있는 주소)
0xffedb0 주소에 먼저 key값의 주소를 적을 것이다.
(key값 주소 적기)
포멧스트링 공격을 하고 메모리를 살펴보면
(fsb공격 후 메모리)
key 주소가 덮여 쓰여진 것을 확인 할 수 있다.
(key주소)
key주소+4바이트 주소를 적어준다.
(완성)
이제 두 주소를 이용해 원하는 값을 적고 pw입력할 때 그 값을 입력할 것이다.
처음에는 0101010101010101 를 입력하려고 했다.
(key 덮어쓰기)
이렇게 덮어쓰면 key 첫 4바이트에 01010101 이 덮어쓰여지는 것을 볼 수 있다.
(key 변조)
하지만 pw를 입력하는데에 문제가 있었다.
입력할 때 strtoull 함수를 이용한다.
입력한 수를 코드를 보면 인자로 10을 주어 입력된 문자열을 10진수로 인식하여 unsigned long long 자료형에 맞추어 숫자로 바꾸어준다.
그런데 어셈블 코드가 좀 수상했다.
(strtoull 근방 코드)
31바이트를 오른쪽으로 움직인다. 부호를 신경써서. 즉 0이나 1 밖에 나올 수 없다.
0101010101010101 를 만들기 위해 값을 입력해보겠다.
(테스트)
eax와 edx에 값이 잘 들어가는 것을 볼수 있다.
(잘 들어간 값)
그런데 그 뒤 코드들 때문에 4바이트가 날아간다...
(0이 되버림)
즉,,, key 주소 다음 4바이트에 있는 값이 0이되거나 ffffffff 이 되야한다.
검색을 해보던 중 해결할 만한 방법을 찾아냈다.
(0 입력)
20번째 위치 인자 주소에 출력된 바이트 수를 입력한다. 여기서는 출력되는게 없으므로 0바이트!
(입력된 0바이트)
key값을 전부 0으로 만들고 0을 입력할 것이다.!
자! 그럼 공격을 해보자!
(key 주소 입력)
(key+4 주소 입력)
주소를 입력하고 그 주소에 있는 값을 0으로 덮어쓴다.
(key 값)
(key+4 값)
그 후 0을 입력하면 성공!~
(성공!)
쉘을 획득했다.
(문제 해결)
'WarGame > 500 Project' 카테고리의 다른 글
(60/500) pwnable.kr - crypto1 (0) | 2017.08.27 |
---|---|
(59/500) pwnable.kr - dragon (0) | 2017.08.17 |
(57/500) pwnable.kr - ascii_easy (2) | 2017.08.09 |
(56/500) pwnable.kr - asm (0) | 2017.07.14 |
(55/500) pwnable.kr - uaf (0) | 2017.07.12 |