728x90
반응형
ZDI에서 거부당해서 그냥 깃허브 이슈에 올렸다
Code Analysis
void Capella::read(QFile* fp){
f = fp;
curPos = 0;
char signature[9];
read(signature, 8);
signature[8] = 0;
if (memcmp(signature, "cap3-v:", 7) != 0) {
throw Capella::Error::BAD_SIG;
}
// LOGD("read Capella file signature <%s>", signature);
// TODO: test for signature[7] = a-z
author = readString(); //issue
keywords = readString();
comment = readString();
...
}
char* Capella::readString()
{
unsigned len = readUnsigned();
char* buffer = new char[len + 1];
read(buffer, len);
buffer[len] = 0;
return buffer;
}
unsigned Capella::readUnsigned()
{
unsigned char c;
read(&c, 1);
if (c == 254) {
unsigned short s;
read(&s, 2);
return s;
} else if (c == 255) {
unsigned s;
read(&s, 4);
return s;
} else {
return c;
}
}
Capella 파일을 파싱할 때 readString() 함수를 거치게 되는데, 이때 문제가 발생함
- readUnsigned() 함수를 굉장히 특이하게 만들었는데, 0xff가 입력되면 그 뒤에 4자리를 읽어옴
- readUnsigned에서 max(0xffffffff)를 읽어 리턴하면, readString()함수에서 len = 0xffffffff가 됨
- new char[len+1]은 사이즈가 0인 메모리를 할당함
- buffer[len] = 0을 시도하면 buffer의 사이즈는 0인데도 0xffffffff영역에 접근하고자 하여 힙 오버플로우가 발생
그치만 익스플로잇 가능성은 없다.
Trigger
정적분석 - IDA
.text:0000000141C86010 ; _BYTE *__fastcall sub_141C86010(__int64)
.text:0000000141C86010 sub_141C86010 proc near ; CODE XREF: sub_140070BFD↑j
.text:0000000141C86010 ; DATA XREF: .pdata:0000000144A97AF0↓o
.text:0000000141C86010
.text:0000000141C86010 arg_0 = qword ptr 8
.text:0000000141C86010 arg_8 = qword ptr 10h
.text:0000000141C86010
.text:0000000141C86010 mov [rsp+arg_0], rbx
.text:0000000141C86015 mov [rsp+arg_8], rsi
.text:0000000141C8601A push rdi
.text:0000000141C8601B sub rsp, 20h
.text:0000000141C8601F mov rsi, rcx
.text:0000000141C86022 call sub_1400817F5
.text:0000000141C86027 mov ebx, eax
.text:0000000141C86029 lea ecx, [rbx+1] ; Size
.text:0000000141C8602C call j_j_j_??2@YAPEAX_K@Z
.text:0000000141C86031 mov r8d, ebx
.text:0000000141C86034 mov rdx, rax
.text:0000000141C86037 mov rcx, rsi
.text:0000000141C8603A mov rdi, rax
.text:0000000141C8603D call sub_140088226
.text:0000000141C86042 mov rsi, [rsp+28h+arg_8]
.text:0000000141C86047 mov rax, rdi
.text:0000000141C8604A mov byte ptr [rbx+rdi], 0
.text:0000000141C8604E mov rbx, [rsp+28h+arg_0]
.text:0000000141C86053 add rsp, 20h
.text:0000000141C86057 pop rdi
.text:0000000141C86058 retn
.text:0000000141C86058 sub_141C86010 endp
.text:0000000141C86058
.text:0000000141C86058 ; ---------------------------------------------------------------------------
.text:0000000141C86059 byte_141C86059 db 17h dup(0CCh)
readString의 Assembly
.text:0000000141C86029 lea ecx, [rbx+1] ; Size
이 부분에서 ecx에 0xffffffff+1을 저장하기 때문에 결국 0x00000000으로 저장된다 (만약에 rcx였다면 64bit이므로 터지지 않았을 것)
동적분석 - Windbg
ecx[rbx+1] 부분 이후에 rcx가 0000000000000000이 된 것을 알 수 있음
파일을 readString하는 부분을 0xffffffff로 조작한 파일을 museScore에 실행하면 터진다
지금은 패치 완료!
728x90
반응형
'Hacking > Window' 카테고리의 다른 글
[Mitigation] Window VS Linux (0) | 2024.11.27 |
---|---|
[IDA Pro] 사용법 정리 (3) | 2024.07.21 |
[ Domato ] 사용법 (4) | 2024.05.18 |
PE(Portable Executable) file format (0) | 2024.05.06 |
[Fuzzing] WinAFL을 이용한 개념정리 (2) | 2024.05.05 |