그냥 접속 시 Nah 출력되는 것을 확인하고 파일 다운로드 후 cat bof.c 으로 소스 먼저 확인해봤다.
32바이트 배열에 문자열을 입력 받고 ‘0xdeadbeef’와 ‘0xcafebabe’가 같으면 쉘을 획득할 수 있는 것 같다.
이때 gets() 를 사용해서 입력 버퍼 크기를 넘어서서 문자열을 입력 받을 수 있게 하는 것을 보아 bof 시켜 해결하는 문제임을 예측할 수 있었다.
따라서 bof 에 실행 권한 부여 후 gdb로 배열과 key 사이가 몇 바이트인지 확인해보기로 했다.
main <+15> 0xdeadbeef 넣는 것 확인,
func 까지 보고, 문제 해결 방법에는 크게 2가지가 있을 것 같다고 생각했다.
방법1. gdb 만 보고 스택 그린 후 오버플로우 시킬 바이트 판단하기
* lea : 주소 불러와서 연산하는 명령어
<func+29> lea 에서 gets() 호출함을 예측할 수 있고,
또 주의 깊게 볼 부분은 <func +40> cmp 이다.
ebp+0x8과 0xcafebabe 를 비교하기 때문에 ebp+0x8가 key 가 있는 위치일 것을 예상할 수 있다.
스택 그려보면
* SFP : 이전 EBP
ebp-44에서 lea 호출, 즉 gets() 를 호출해 buffer[32]에 입력을 받고, 52 바이트 만큼 오버플로우 시켜
ebp+8에 위치한 0xdeadbeef 를 0xcafebabe 로 변경하면 된다는 것을 알 수 있다.
방법2. cmp에 브레이크 포인트 걸어두고 버퍼 사이즈인 32바이트 만큼 문자열을 입력하고 실행한 후 메모리 확인하여 바이트 세기
'a' 를 32개 입력하여 실행해보고 gdb 로 확인해본 결과,
0x61616161 시작 위치부터 61이 32바이트가 제대로 들어간 것을 확인 할 수 있고,
0xdeadbeef까지 20바이트 더 입력이 필요한 것도 확인할 수 있다.
따라서 총 52 바이트를 오버플로우 시킨 후 0xcafebabe 를 입력하면 0xdeadbeef 위치에 0xcafebabe가 들어가 cmp 에서 if 를 통과할 수 있다.
단, 프로그램 실행에 인자로 들어가는 것이 아니라 실행 후 입력을 받는 것이므로
./bof $(python -c “print ‘a’*52 + ‘\xbe\xba\xfe\xca’”) 이런 식으로 입력하면 안된다는 것을 알게 되었다.
(python -c “print ‘a’*52 + ‘\xbe\xba\xfe\xca’”) | ./bof 이런식의 입력이 필요하다.
그런데 바로 저렇게 실행하면 프로그램이 바로 종료되기 때문에 cat 과 같은 표준 출력 명령어를 사용해서 프로그램이 종료되지 않고 대기하도록 만들어줘야 쉘을 이용할 수 있다.
따라서 (python -c “print ‘a’*52 + ‘\xbe\xba\xfe\xca’”; cat) | ./bof
쉘 따기는 성공, ls 로 여기에 flag 없다는 걸 확인하고
(python -c “print ‘a’*52 + ‘\xbe\xba\xfe\xca’”; cat) | nc pwnable.kr 9000 입력,
쉘 획득 후 ls로 flag 있는 것 확인 후 flag 획득!
'WARGAME > pwnable.kr [system]' 카테고리의 다른 글
[Toddler's Bottle] 6번 random (0) | 2019.11.28 |
---|---|
[Toddler's Bottle] 9번 mistake (0) | 2019.11.27 |
[Toddler's Bottle] 4번 flag (0) | 2019.11.19 |
[Toddler's Bottle] 2번 collision (0) | 2019.11.14 |
[Toddler's Bottle] 1번 fd (0) | 2019.11.14 |