[하루한줄] CVE-2024-24684/CVE-2024-24685/CVE-2024-24686: libigl의 off 파일 파싱 중 발생한 세 가지 Stack Overflow 취약점
URL
Target
- libigl 2.5.0
Explain
libigl은 3D 지오메트리 처리에 사용되는 C++ 라이브러리로 게임 개발이나 3D 프린팅, 다양한 파일 포맷의 지오메트리 처리가 필요한 애플리케이션에서 사용되고 있습니다.
취약점은 off(object file format) 파일을 처리하는readOFF
함수에서 세 가지 Stack Overflow 발견되었습니다.
IGL_INLINE bool igl::readOFF(
FILE * off_file,
std::vector<std::vector<Scalar > > & V,
std::vector<std::vector<Index > > & F,
std::vector<std::vector<Scalar > > & N,
std::vector<std::vector<Scalar > > & C)
...
// First line is always OFF
[0] char header[1000];
...
[1] if(fscanf(off_file,"%s\n",header)!=1
|| !(
string(header).compare(0, OFF.length(), OFF)==0 ||
string(header).compare(0, COFF.length(), COFF)==0 ||
string(header).compare(0,NOFF.length(),NOFF)==0))
{
...
}
...
return true;
CVE-2024-24684는 헤더 파싱 중 발생한 취약점으로 header
크기가 1000 byte로 고정되어 있지만 공격자가 파일 헤더 첫 줄에 1000 byte보다 큰 off 파일을 보낼 경우 Stack Overflow가 발생합니다.
template <typename Scalar, typename Index>
IGL_INLINE bool igl::readOFF(
FILE * off_file,
std::vector<std::vector<Scalar > > & V,
std::vector<std::vector<Index > > & F,
std::vector<std::vector<Scalar > > & N,
std::vector<std::vector<Scalar > > & C)
{
...
for(int i = 0;i<number_of_vertices;)
{
[0] fgets(line, 1000, off_file);
double x,y,z,nx,ny,nz;
[1] if(sscanf(line, "%lg %lg %lg %lg %lg %lg",&x,&y,&z,&nx,&ny,&nz)>= 3)
{
...
}else if(
[2] fscanf(off_file,"%[#]",&tic_tac_toe)==1)
{
[3] char comment[1000];
[4] fscanf(off_file,"%[^\n]",comment);
}else
{
...
}
}
...
return true;
}
CVE-2024-24685는 off 파일의 vertex 파싱 중 발생한 취약점으로 [0]번에서 off 파일 한 줄을 읽고 vertex 좌표 형식일 경우 [1]번에서 좌표 데이터로 파싱 합니다.
만약, 좌표 형식이 아니라면 [2]번에서 주석(#
) 여부를 확인하고 주석일 경우 [3][4]번을 통해 comment 배열에 저장합니다.
따라서, 공격자는 파일 헤더 이후 주석의 길이가 1000 byte보다 큰 off 파일을 보내 Stack Overflow 트리거 할 수 있습니다.
template <typename Scalar, typename Index>
IGL_INLINE bool igl::readOFF(
FILE * off_file,
std::vector<std::vector<Scalar > > & V,
std::vector<std::vector<Index > > & F,
std::vector<std::vector<Scalar > > & N,
std::vector<std::vector<Scalar > > & C)
...
// Read faces
for(int i = 0;i<number_of_faces;)
{
std::vector<Index > face;
int valence;
[0] if(fscanf(off_file,"%d",&valence)==1)
{
...
}else if(
[1] fscanf(off_file,"%[#]",&tic_tac_toe)==1)
{
[2] char comment[1000];
[3] fscanf(off_file,"%[^\n]",comment);
}else
{
...
}
fclose(off_file);
return true;
}
CVE-2024-24686은 off 파일의 face 파싱 과정 중 발생한 취약점으로 [0]번에서 각 face를 이루는 vertex 개수를 확인합니다.
만약, 실패할 경우 [1]번에서 주석(#
) 여부를 확인하고 주석일 경우 [2][3]번을 통해 comment 배열에 저장합니다.
따라서, 공격자는 vertex 파싱 이후 주석의 길이가 1000 byte보다 큰 off 파일을 보내 Stack Overflow 트리거 할 수 있습니다.
Reference
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.