학회_공부해요/기술_스터디

[Stealien] 버그헌팅: 취약점 체이닝의 중요

yenas0 2023. 11. 23. 02:42
반응형

 

https://ufo.stealien.com/2023-07-31/bughunting-vulnerability-chaining-ko

 

STEALIEN Technical Blog

버그헌팅: 취약점 체이닝의 중요성

ufo.stealien.com

 


No impact, No bug

버그헌팅에서는 이 취약점으로 어떤 악의적인 행위를 할 수 있는지 증명해야 한다. 대부분 CVSS점수를 이용해 취약점에 대한 평가를 하기 때문에 취약점을 악용할 수 있는 창의적인 아이디어를 생각해내어 시나리오를 만들어야 한다.

CVSS

: 사이버 보안에 미치는 취약점의 위험성을 나타내는 수치
: 공격자가 소프트웨어 취약점을 악용해 미칠 수 있는 영향도를 수치로 표현한다.

https://yozm.wishket.com/magazine/detail/2009/

 

 

 

Vulnerability Chaining

취약점 체이닝이란, 두 개 이상의 취약점을 연결하여 상대적으로 중요하지 않은 보안 이슈들을 결합해 강력한 공격 시나리오를 구축하는 방법.

여러 취약점을 찾아내야하기 때문에 분석 대상에 대한 깊은 이해를 필요로 한다. 

 

취약점 체이닝 방법론 요약

1. 시스템 이해: 시스템이 어떻게 작동하는지 전반적으로 이해하는 것이 중요

2. 세부적인 분석: 개별 취약점을 식별하고 이해하는 것이 중요

3. 시나리오 구축: 실제 공격 시나리오를 구축하고 시뮬레이션 필요

 

 

 

 

취약점 체이닝 예시 - 이윰빌더 원격 코드 실행 취약점

https://knvd.krcert.or.kr/detailDos.do?IDX=5789

 

보안 취약점 정보 포털

닫기 검색

knvd.krcert.or.kr

 

해당 취약점은 이윰빌더에서 경로 조작을 통한 LFI가 가능해 발생하는 RCE취약점이다.

LFI (Local File Inclusion)?
: 공격할 파일이 공격대상 서버에 있다는 의미
c.f. RFI (Remote File Inclusion): 공격할 파일이 원격지에 있다는 의미
=> 오픈 소스로 개발된 경우 디렉토리 구조가 알려져있어 위험하다

RCE(Remote Code Execution)?
: 원격 코드 실행
: 공격자가 조직의 컴퓨터나 네트워크에서 악성코드를 실행할 수 있는 공격.

 

 

 

 

취약점 종류 영향 심각도 CVSS 점수 CVE-ID
LFI 원격 코드 실행 High 7.2 CVE-2022-41158
제품 영향 받는 버전 환경
이윰빌더 4.5.3 및 이전 버전 리눅스

취약점 설명: 이윰빌더가 쿠키 값을 파일의 경로에 사용하는 것을 이용하여 원격 코드 실행이 가능한 취약점

 

 

이윰빌더

: 이윰빌더는 그누보드5를 프레임워크로 사용한 기능을 제공하는 국내 CMS 중 하나이다.

 

 

 

LFI Patch Analysis

https://github.com/eyoom/eyoom_builder_4/commit/4fa8436cf2691dae5064d7c187ffa90327d41042

▲ 이윰빌더 변경 파일 소스 보기

 

4.5.4 버전 이상에서는 위처럼 $unique_theme_id 변수 값에 숫자만 입력값으로 들어갈 수 있도록 정규식 필터링이 걸려있다.

즉, 위 버전보다 낮은 버전에서는 해당 변수값에 숫자 이외의 문자열이 들어갈 수 있다는 의미이다.

 

/**
 * 유니크 아이디 쿠키 생성
 */
if (get_cookie('unique_theme_id')) {
    $unique_theme_id = get_cookie('unique_theme_id');
} else {
    $unique_theme_id = date('YmdHis', time()) . str_pad((int)(microtime()*100), 2, "0", STR_PAD_LEFT);
    set_cookie('unique_theme_id',$unique_theme_id,3600);
}

$file = $this->tmp_path . '/' . $_SERVER['REMOTE_ADDR'] . '.' . $unique_theme_id . '.php';
if (file_exists($file)) {
    include_once($file);
    if ($is_shop_theme) {
        $arr['theme']       = $user_config['theme'];
    } else {
        $arr['shop_theme']  = $user_config['shop_theme'];
    }
}
$_config = $arr;

/**
 * 파일 생성 및 갱신
 */
parent::save_file('user_config', $file, $_config);

▲ 취약한 코드

 

 

쿠키 값으로 $unique_theme_id 값을 받아오고, 다시 그 값은 $file변수에 $unique_theme_id.php라는 확장자가 더해져 특정 파일의 경로가 삽입된다.

 

만약 해당 경로에 파일이 존재한다면, include_once($file)에서 파일이 include된다.

 

만약 공격자가 특정 경로에 php 파일을 생성하거나 이미 존재하는 PHP파일에 임의 명령어를 삽입할 수 있다면, 이 LFI 취약점을 이용해 그 PHP 파일을 불러와 임의 명령어를 실행할 수 있는 RCE취약점으로 연계할 수 있다.

 

하지만 실제로는 file_exists함수에서는 존재하지 않은 디렉터리의 상위경로에 접근이 불가하다.

 

$file 변수의 값이 결국 하단의 save_file 함수에 들어가게 되는데, save_file함수의 내용을 보면 PHP 파일의 내용으로 들어가게 되는 값들은 사용자가 직접 조작할 수 없어 보인다.

 

다만 $unique_theme_id값에 ../와 같은 문자열이 들어왔을 때 fopen함수에서 상위 경로에 파일이 쓰여질 수 있다는 사실을 알 수 있습니다.

 

/**
 * 배열을 지정한 파일로 저장 - 폴더에 웹서버의 쓰기 권한이 있어야 함
 */
public function save_file($outvar, $filename, $info=array(), $int=false) {
    $fp = @fopen($filename, 'w');
    $contents  = "<?php\n";
    $contents .= "if (!defined('_EYOOM_')) exit;\n";
    $contents .= "\$" . $outvar . " = array(\n";
    if ($info != NULL) {
        foreach ($info as $key => $value) {
            if (!is_array($value)) {
                // 키값으로 정수를 허용하지 않는다면
                if (!$int) {
                    if (!is_int($key)) {
                        $contents .= "\t\"" . $key . "\" => \"" . addslashes($value) . "\",\n";
                    }
                } else $contents .= "\t\"" . $key . "\" => \"" . addslashes($value) . "\",\n";
            } else {
                $arr = '';
                foreach ($value as $k => $v) {
                    if (!$int) {
                        if (!is_int($key)) {
                            $arr .= "\"" . $k . "\" => \"" . addslashes($v) . "\",";
                        }
                    } else $arr .= "\"" . $k . "\" => \"" . addslashes($v) . "\",";
                }
                if ($arr) {
                    $arr = substr($arr,0,-1);
                    $contents .= "\t\"" . $key . "\" => array(" . $arr . "),\n";
                }
            }
        }
    }

    $contents .= ");\n";
    @fwrite($fp, $contents);
    @fclose($fp);
    @chmod($filename, 0644);
}

$value값은 모두 addslashes()함수로 필터링 되고 있다. 그리고 $key값은 save_file() 함수 호출 전의 값을 확인해보면 이윰빌더의 설정 값($arr['theme'])에 해당한다. 이 값은 사용자 측에서 조작이 불가하다.

 

따라서 위의 코드만으로는 임의 파일 작성 취약점을 LFI와 RCE 취약점으로 연계할 수 없다.

 

 

Finding Arbitrary Code Injection

save_file() 함수에서 php 파일을 작성하고 있음을 알 수 있었다.

위에서는 이윰빌더의 설정 값을 받아서 작성하였지만 다른 곳에서는 사용자로부터 입력 값을 받아서 작성하는 곳이 있는지 Visual Studio Code에서 Go to References 기능을 이용할 수 있다.

 

우측의 많은 파일에서 save_file()함수를 사용한다.

이 파일들 중에서 하나쯤은 사용자로부터 받은 입력으로부터 값을 받는지 찾아볼 수 있다.

 

위에서 살펴본 save_file()함수를 다시 면밀히 살펴보면 $value 값은 addslashes()함수로 필터링하고 있지만, $key 값은 필터링하고 있지 않다. 만약 사용자가 $key 값을 조작할 수 있다면, 원하는 내용의 스크립트를 php파일에 삽입할 수 있게된다.

 


마치며

처음듣는 용어들이 많아서 중간중간 간략하게 정리해보았다.

본글에서 취약점에 대해서 자세한 설명이 나온 것은 아니지만 예시를 통해 어떻게 취약점 체이닝을 하는지, 어떻게 취약점을 찾고 시나리오로 연결하는지에 대한 과정이 잘 나와있어서 유익했다.

반응형