hw1
먼저 실행시켜보니 다음과 같은 메뉴형 문제다.
코드를 보려했더니 뭔가 걸려있는 것 같았다. 다 깨져서~ 나원참~ 아닌강 ㅎ;;
checksec으로 확인해보니 Canary랑 NX가 걸려있다.
Canary?
이전 ebp 전에 canary라는 랜덤 값을 함수 시작 전에 저장하고, 함수가 끝나기 전에 이 값이 변조됐는지 여부를 체크하는 메모리 보호 기법이다.
NX?
ROP
코드가 안보이니까 IDA를 통해 확인해보자!
v7은 FS로부터 0x28만큼 떨어진 곳에 저장된 값이다.
setvbuf // bss_start를 파일 스트림으로 하여 라인 마다 쓰여진다.
setvbuf // stdin으로 라인 마다 쓰여진다.
v3은 v5의 주소 값이고, v4에는 "%d"가 들어가 있다. v5에 값을 입력받는다. (v5가 num)
v5가 3일 경우에는 v6에 박스의 index 값을 입력받는다.
이 때 v6이 0x20 이하 이면서 boxbox[v6] 이면 v4는 *v6가 되며 edit(v6)로 넘어간다.
v5가 4일 경우에는 Box의 index를 v6에 입력받고 만약 v6가 0x20 이하이고 boxbox[v6]가 참이라면 v4는 *v6가 되고 view(v6)로 넘어간다.
v5가 1일 경우에는 v6에 Box의 index를 입력받고 v4 = *v6가 되고, add(v6)로 넘어간다.
v5가 2일 경우에는 앞의 과정은 모두 같고 delete(v6)로 넘어간다.
//대충 본 결과 v5는 num 입력이고, v6는 그 다음에 index 입력할 때 사용되는 것 같다. 그리고 v7은 뭔가 카니리 일 것 같다.
1번 add 함수
포인터 v1은 동적 할당된 buf를 가리킨다.
HIDWORD는 말 그 대로 상위 bit? word? 이다. size만큼 상위에는 read함수로 표준입력으로 받은 파일디스크립터의 내용을 buf에 읽고 반환값을 넣는다. 이 때 buf와 HIDWORD의 합은 0이다. read의 반환값은 파일에 읽을 데이터가 없을 시시 0이고 파일 읽기에 성공했다면 0보다 큰수를 반환한다. 즉 음수가 나올 수 없다.
그 다음을 보면 boxbox[a1]에 buf 값을 넣는다. (이 때 a1은 index이다. == v6)
그리고 박스의 길이를 v1에 입력받고, size만큼의 LODWORD에는 0을 입력한다.
size에 값을 입력받는데, size는 int형이 었는데 여기서 unsigned int형으로 형변환을 한다. 이 형변환 된 값이 0xfff보다 작거나 같을 경우 buf + 4에 size만큼 malloc을 하고 buf+10에 size를 저장한다.
putchar(62)는 > 를 출력한다.
그리고 표준입력으로 받은 파일 디스크립터를 buf +4에 unsigned int 형의 size만큼 읽는다.
: 1번 add함수를 실행시키면 buf+4에 size 값이 저장된다.
만약 size가 0xfff보다 크다면 delete(a1)으로 넘어간다.
add함수가 끝나면 0x28u 메모리의 값이 ^ v5(함수 시작 할 때의 0x28u)를 반환한다.
이를 통해 우리는 0x28u에 저장된 값이 canary임을 확신할 수 있다.
xor연산은 값이 완전히 똑같을 경우에만 0을 반환하기 때문이다.
UAF?
use and free의 약자로 malloc을 하고 free를 했을 때 그 heap영역에 있던 값은 초기화되지 않아서 같은 크기를 다시 동적 할당할 경우 그 전에 할당했던 곳을 할당해주는데 이 때 생기는 문제다.
2번 delete 함수
boxbox[index] + 4가 참일 경우, 이를 free 시킨다.
: free시켜도 이곳에 저장되어 있는 size값은 남아있다.
boxbox[index]도 free 시킨다.
그리고 boxbox[index]에는 0을 넣고 result == a1 == index를 반환한다.
3번 edit 함수
>을 출력하고 boxbox[index]+4에 boxbox[index]+10의 크기만큼 stdin을 파일디스크립터로 하여 읽는다.
4번 view 함수
> 출력하고 boxbox[a1]+4부터 출력한다.
+ 근데 왜 putchar 썼다가 printf 썼다가 하는거지?
getshell이라는 수상한 함수 발견!
system(/bin/sh)를 실행한다.
즉, 우리는 getshell을 실행시키면 된다는 사실!
[알아낸 사실]
- 0x28u에는 카나리 값이 저장되어 있다.
- boxbox[index] + 4부터 값을 저장한다.
[Exploit idea]
boxbox에 주소를 넣고,, view 같은걸 통해서 실행시키거나
boxbox에 카나리 주소를 넣고 view를 통해 카나리값을 확인하고 ROP를 하는데 카나리 값을 그대로 넣어주거나 ??
boxbox가 +4부터하는데 0이면 그 전 주소에서 시작 가능 아닌가??
다 떙떙떙! 이 문제는 UAF 문제다.
즉 boxbox+4에 getshell함수의 주소(0x400872)를 넣어주고 free한 뒤에 다시 add하고 view로 확인하구.. 실행은.. 어떻게 시킬지 모르겠따 ㅠ