System/Pwnable.xyz

misalignment Write-up

pyozzi 2020. 1. 19. 03:40

[그림 1] misalignment (50)

이전 문제에 sub,add 두 문제의 연장선같은 문제다.

sub,add,misalignment 세 문제 모두 단순 Arbitrary Write문제다.

 


Binary

[그림 2] file

64bit ELF 바이너리이며, Shared Object로 PIE가 걸려있음을 알 수 있다.

 

[그림 3] checksec

Full Mitigation이 적용되어 있지만 쫄지말자

출제자가 의도된 풀이로 인도하기 위한 장치라고 생각하면 된다.

 

[그림 4] win( )

win( )로 원샷 함수가 있기 때문에 간단한 익스가 가능하다.

 


Problem

[그림 5] main( )

먼저 빨간박스에서 Arbitrary Write가 가능하다.

v6,v7,v8 모두 scanf( )를 통해서 입력받고 있으며, v8값으로 저장주소의 인덱스 참조를 조정할 수 있다.

 

[그림 6] win( ) 실행 조건

그리고 win( ) 실행 조건은 *(v5+7)위치에 0xB0000000B5가 저장되어 있어야 한다.

여기서 포인트는 주소참조를 +7로 하고 있다는 점이다.

 

64Bit 운영체제의 Address Alignment(주소 조정)은 8Byte Boundary로 이루어진다. (32Bit에서는 4Byte)

따라서, v5[ ]와 같이 Index로 주소를 참조할 때 0x7FFF0008, 0x7FFF0010... 와 같이 8Byte간격으로만 참조된다.

 

이 때문에 문제 이름 misalignment처럼 아무리 0xB0000000B5를 저장해도 비교문에서는 항상 1Byte가 어긋나게 된다.

이 부분을 어떻게 해결해서 저 비교문을 참값으로 만드냐가 이번 문제의 핵심이다.

 


Solve

방법은 간단하다.

우리가 입력한 값이 초기화되지 않기 때문에 두번 나눠서 입력해주면 된다.

 

[그림 7] *(v5+7) 개념도

그림으로 표현하면 이런 느낌이다.

 

[그림 8] 메모리 뷰

실제 메모리에 저장된 모습은 위 모습과 같다.

 

[그림 9] win( ) 실행

*(v5+7)의 저장된 값(RDX)과 0xB0000000B5(RAX)가 같기 때문에 if문 내부의 win( ) 호출코드로 이동한 모습이다.

 

[그림 10] Solve