난 정말 최고야 멋있어
CTFLearn - Favorite Color 본문
color.c 를 일단 봐보자
말도 안되는 개소리를 하고 있는 코드가 보인다..
vuln() 은 일반적인 방법으로는 무조건 0을 리턴하게 되서 무슨 색깔을 써놓아도 badboy 루틴으로 가게 된다 ㅋㅋ
gdb로 vuln 함수를 살펴보았다
대충 쓱 살펴보자... 좀 더 예쁘게 색칠을 해보자!!
사실 안해도 되는데 그냥 for문 좀 눈에 익힐겸 해봤다ㅋㅋ
딱보니 버퍼오버플로우 문제고.. 리턴값을 바꾸는 문제 같다
사실 중요한것은 어떻게 해야지 리턴값을 덮어쓸수 있는가인데...
이것은 간단한 esp 계산을 통해서 알 수 있다..
vuln 호출 직후의 esp 에 리턴값이 담겨져 있고 이 주소를 A라고 할때
이후 push ebp 를 통해 esp 의 위치는 A-4 가 된다
그 이후 mov ebp,esp 로 ebp 에 A-4 의 주소가 담기게 되는데...
이때 이후로부터.. 스택프레임이 정리되기 전까지 ebp 는 고정된 값을 가짐
즉 리턴 주소를 덮어 씌우기 위해서는
[ebp-30] = buf 이므로 30h + 4 만큼을 덮어쓴후 리턴주소 넣어주어야 한다!
이해를 돕기위해 표를 그려보았다
EBP-30: <buf> | EBP-29 | EBP-28 | EBP-27 |
.... 중간 생략 ....
|
|||
EBP | EBP+1 | EBP+2 | EBP+3 |
EBP+4: RETURN ADDRESS |
이때 [EBP-30]과 [EBP+3] 사이의 칸수는 34h 칸
리턴값으로 채울공간은 4칸
이제.. 조용히 문제를 풀 방법을 생각해보자!
gdb로 메인함수를 살펴보자
함수가 길어서 중요 부분만 떼왔다
<+111>에서 vuln 함수를 호출하는데 일반적인 경우에는 무조건 0을 리턴하므로 <+118>에서 항상 점프하게 된다
우리의 목표는 점프를 안하고 <+120> 의 위치로 이동하는 것이므로
vuln 함수의 리턴 주소가 0x08048657<+120> 이 되도록 만들어 주면되겠다
python -c "print 'a'*0x34 + '\x57\x86\x04\x08'" | ./color
이 쉘코드를 넣어주면?
쉘을 얻었다면서 플래그가 열리지 않는다!
... 이것 때문에 좀 삽질을 했는데 얻은 쉘로의 입력버퍼가 없어서 그런것이었다 ㅜㅜ
이것을 해결하기 위해서
(python -c "print 'a'*0x34 + '\x57\x86\x04\x08'" && cat) | ./color
이렇게 수정을 해주고 다시 실행 해보면?
플래그가 정상적으로 출력된다
flag{c0lor_0f_0verf1ow}