카테고리 없음

[DreamHack] Return Address Overwrite 시스템 해

qkrdldks04 2025. 4. 8. 15:30

* 잘 모르겠어서 스터디장님 라이트업 참고했습니다!

우분투 파이어폭스에서 문제를 열고 c코드를 살펴봤다.

 

 

main() 함수 scanf()에서 NULL 없이 문자열 입력받기 때문에 버퍼 오버플로우 취약점이 존재한다.

그렇다면 익스플로잇 코드를 통해 buf 다음에 있는 리턴 주소를 덮어주면 될 것 같다. 

 

 

파일 실행 후 a를 길게 입력했더니 세그멘터이션 오류가 발생하여 코어가 덤프됐다고 떳다.

 

 

함수가 실행될 때, buf[0x28]만큼 공간 + 함수 리턴을 위한 8바이트(SFP)까지 포함해서
총 0x30(=48바이트) 만큼의 스택 공간을 확보한다는 것을 알 수 있다.

>  buf(40) + SFP(8) = 48바이트 = 0x30만큼 스택에서 공간 필요

 

 

익스플로잇 할 때도  0x30을 채워줘야 리턴 주소에 접근할 수 있기에 이에 맞춰 코드를 작성했고

remote의 포트번호는 문제 서버 포트 번호에 따라 작성하면 된다.

이렇게 하면 buf 공간에 0x30, sfp 에 0x8이 채워지고 쉘 함수가 return 주소에 할당된다.

 

+) 대부분 x86-64 아키텍처는 리틀 엔디언을 사용하기에 get_shell()  함수의 주소를 리틀 엔디언 형식인 p64() 함수 이용함 

 

 

그런데 계속 이런 오류가 발생해서 지피티를 돌렸더니 "Input: " 이라는 프롬프트가 실제 서버에서 출력되지 않았는데 sendlineafter()가 그걸 기다리다가 EOF(파일 끝) 상태가 되어 종료돼서 오류가 난 것이었다.

 

> 실패 원인

1. sendlineafter() 문제 : Input 문자열이 정확히 일치해야 샌드가 작동하는데 실제 출력 공백이 없거나, 개행(\n)이 있거나, 다른 문자인코딩일 수도 있음

2. 서버가 너무 빠르게 EOF 발생시키는 경우: 위 오류 화면에서 서버가 다 입력 받지 못했는데 connection을 끊은 것을 확인 할 수 있음

 

따라서 Input: 문자열을 없애고 sendline()으로 수정해줬다.

 

 

수정본으로 익스플로잇 공격을 시도해 플래그를 얻었다!