백엔드 개발 PHP 튜토리얼 ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

Mar 21, 2019 pm 03:34 PM
thinkphp5 취약점 분석

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

1. 취약점 소개

2019년 1월 11일 ThinkPHP 팀은 안전하지 않은 동적 함수 호출로 인한 원격 코드 실행 취약점을 수정한 패치 업데이트를 출시했습니다. 이 취약점은 매우 유해하며 기본적으로 원격 코드를 실행할 수 있습니다. 여러 버전의 ThinkPHP에서 소스 코드 분석 및 검증을 수행한 후, Venus ADLab 보안 연구원들은 특히 영향을 받는 버전이 ThinkPHP 5.0-5.0.23의 정식 버전임을 확인했습니다.

2. 취약점 재현

로컬 환경에서는 ThinkPHP 5.0.22 정식 버전 + PHP5.5.38 + Apache를 사용하여 재현합니다. 환경을 설치한 후 그림과 같이 POC를 실행하여 시스템 명령을 실행합니다.

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

3. 취약점 분석

분석을 위해 먼저 공식 홈페이지에서 다운로드한 5.0.22 정식 버전을 사용합니다. 취약점의 핵심 포인트 찾기:

thinkphp/library/think/Request.php:518
로그인 후 복사

메소드 함수의 두 번째 if 분기에서는 외부에서 제어 가능한 데이터 $_POST[Config::get['var_method']가 도입되었습니다. var_method의 값은 _method입니다.

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

Request 클래스의 __construct 함수는 다음과 같습니다.

$options 매개변수는 제어 가능하므로 공격자는 이 클래스의 filter 속성, method 속성 및 get 속성의 값을 덮어쓸 수 있습니다. Request 클래스의 param 함수에서:

$this->mergeParam이 비어 있으면 $this->get(false)가 여기에서 호출됩니다. $this->get 함수 추적:

$this->input 함수는 함수 끝에서 호출되고 $this->get이 전달되며 $this->get의 값은 다음과 같습니다. 공격자가 제어할 수 있습니다. $this->input 함수 추적:

이 함수는 $this->getFileter를 호출하여 필터를 얻습니다. 함수 본문은 다음과 같습니다.

$this->필터 값은 생성자를 호출하여 공격자에 의해 재정의되고 제어됩니다. 값을 반환한 후 입력 함수에 들어갑니다.

filterValue 함수를 다음과 같이 봅니다. :

call_user_func 함수 호출에서 $filter를 제어할 수 있고, $value를 제어할 수 있습니다. 따라서 코드 실행이 발생할 수 있습니다.

취약점 유발 프로세스:

ThinkPHP5의 진입점에서 분석을 시작합니다:

thinkphp/library/think/App.php:77
로그인 후 복사

run 함수의 첫 번째 줄은 Request 클래스를 인스턴스화하고 이를 $request에 할당합니다. 그런 다음 RouteCheck($request,$config)를 호출합니다.

여기서 Route::check는 경로 감지를 위해 호출됩니다. 기능은 다음과 같습니다.

빨간색 글꼴 부분에 주목하세요. 변수 적용 범위에 대한 메소드 함수를 호출하는 처음의 첫 번째 단계에 해당합니다. 여기서 재정의해야 하는 속성은 $this->filter, $this->method, $this->get입니다. $request->method()의 반환 값은 $this->method이므로 이 값도 제어해야 합니다. 여기서 반환값은 $method에 할당되고, self::$rules[$method]의 값을 빼서 $rules에 부여합니다. 참고: THINKPHP5에는 공급업체 디렉터리의 일부 파일을 자동으로 로드하는 자동 클래스 로딩 메커니즘이 있습니다. 그러나 정식 버전과 코어 버전의 공급업체 디렉터리 구조가 다릅니다.

풀 버전의 디렉터리 구조는 다음과 같습니다.

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

코어 버전의 디렉터리 구조는 다음과 같습니다.

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

풀 버전에는 코어 버전보다 폴더가 여러 개 더 많은 것을 볼 수 있습니다. . 특별한 주의가 필요한 것은 think-captcha/src 폴더에 helper.php 파일이 있다는 것입니다:

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

여기서 thinkRoute::get 함수가 호출되어 경로 등록 작업을 수행합니다. 이 단계의 영향은 위에서 언급한 self::$rules의 값을 변경하는 것입니다. 이 경로를 통해서만 RCE를 수행할 수 있으며, 그렇지 않으면 성공하지 못합니다. 이것이 바로 정식 버전에만 영향을 미치고 코어 버전에는 영향을 미치지 않는 이유입니다. 이때 self::$rules의 값은 다음과 같습니다.

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

그리고 공격자의 컨트롤에서 반환된 $method의 값을 가져오면 $rules의 값이 이 경로의 규칙이 됩니다. 그런 다음 위의 단계로 돌아가서 $rules를 가져오고 수신 URL에 따라 $item 값을 가져옵니다. 따라서 $rules[$item] 값은 보안 문자 라우팅 배열이 되며 추가로 self::를 호출할 수 있습니다. parrule 함수. 함수 본문이 약간 길어졌습니다. 핵심 사항은 다음과 같습니다.

이때 전달된 $route 값은 thinkcaptchaCaptchaController@index입니다. 따라서 빨간색으로 표시된 if 분기를 입력합니다. 이 분기에서는 $result의 'type' 키에 해당하는 값이 'method'입니다. 그런 다음 $result는 계층별로 run 함수에 반환되고 $dispatch에 할당됩니다.

그런 다음 $dispatch를 self::exec 함수로 가져옵니다.

Request 클래스의 param 메소드를 호출하는 빨간색으로 표시된 분기를 입력하세요. 따라서 익스플로잇 체인의 세 번째 단계가 충족되어 명령이 실행됩니다.

Venstar ADLab 보안 연구원들은 ThinkPHP5.0-5.0.23의 각 버전을 분석한 결과 ThinkPHP5.0.2-5.0.23이 동일한 POC를 사용할 수 있는 반면 ThinkPHP5.0-5.0.1은 POC를 변경해야 한다는 사실을 발견했습니다. Route.php의 규칙 기능에 대한 작은 구현 차이가 있습니다.

ThinkPHP5.0-5.0.1 버전 thinkphp/library/think/Route.php:235, $type을 대문자로 변환:

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

ThinkPHP5.0.2-5.0.23 버전에서는 규칙 함수에서 $ type이 소문자로 변환되었습니다:

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

4. 패치 분석

ThinkPHP5.0.24에는 $this->method 판정이 추가되었으며 클래스 함수의 자유 호출이 더 이상 허용되지 않습니다.

ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청

5. 결론

사용자는 ThinkPHP 버전 5.0.24로 업그레이드하고 공격을 피하기 위해 디버그 모드를 활성화하지 않는 것이 좋습니다.

관련 추천: "PHP 튜토리얼"

위 내용은 ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Pagoda에 thinkphp5를 배포할 때 오류가 발생하면 어떻게 해야 합니까? Pagoda에 thinkphp5를 배포할 때 오류가 발생하면 어떻게 해야 합니까? Dec 19, 2022 am 11:04 AM

Pagoda에 thinkphp5를 배포할 때 보고된 오류에 대한 해결 방법: 1. Pagoda 서버를 열고 php pathinfo 확장을 설치하고 활성화합니다. 2. "RewriteRule ^(.*)$ index.php 콘텐츠로 ".access" 파일을 구성합니다. ?s=/$1 [QSA ,PT,L]”; 3. 웹사이트 관리에서 thinkphp의 pseudo-static을 활성화하면 됩니다.

thinkphp5 URL 재작성이 실패하면 어떻게 해야 합니까? thinkphp5 URL 재작성이 실패하면 어떻게 해야 합니까? Dec 12, 2022 am 09:31 AM

thinkphp5 URL 재작성이 작동하지 않는 해결 방법: 1. mod_rewrite.so 모듈이 httpd.conf 구성 파일에 로드되었는지 확인합니다. 2. AllowOverride None에서 None을 All로 변경합니다. 3. Apache 구성 파일 .htaccess를 "RewriteRule ^ (.*)$ index.php [L,E=PATH_INFO:$1]" 하고 저장하세요.

thinkphp5에서 요청된 URL을 얻는 방법 thinkphp5에서 요청된 URL을 얻는 방법 Dec 20, 2022 am 09:48 AM

요청된 URL을 얻는 thinkphp5의 방법: 1. 현재 URL 정보를 얻기 위해 "\think\Request" 클래스의 "$request = Request::instance();" 방법을 사용합니다. 도메인 이름을 포함한 전체 URL 주소를 얻으려면 "$request-> url()" 함수를 사용하세요.

thinkphp5 게시물이 값을 얻을 수 없으면 어떻게 해야 합니까? thinkphp5 게시물이 값을 얻을 수 없으면 어떻게 해야 합니까? Dec 06, 2022 am 09:29 AM

thinkphp5 게시물은 TP5가 strpos 함수를 사용하여 헤더의 콘텐츠 유형 값에서 app/json 문자열을 찾기 때문에 값을 얻을 수 없습니다. 해결 방법은 헤더의 콘텐츠 유형 값을 app/json으로 설정하는 것입니다.

thinkphp5 제목 표시줄 아이콘을 제거하는 방법 thinkphp5 제목 표시줄 아이콘을 제거하는 방법 Dec 20, 2022 am 09:24 AM

thinkphp5 제목 표시줄 아이콘을 제거하는 방법: 1. thinkphp5 프레임워크 공개에서 favicon.ico 파일을 찾습니다. 2. 파일을 삭제하거나 다른 사진을 선택하여 이름을 favicon.ico로 바꾸고 원본 favicon.ico 파일을 대체합니다.

thinkphp5에서 컨트롤러가 존재하지 않는다는 메시지가 표시되면 어떻게 해야 합니까? thinkphp5에서 컨트롤러가 존재하지 않는다는 메시지가 표시되면 어떻게 해야 합니까? Dec 06, 2022 am 10:43 AM

컨트롤러가 존재하지 않는다고 메시지를 표시하는 thinkphp5에 대한 해결 방법: 1. 해당 컨트롤러의 네임스페이스가 올바르게 작성되었는지 확인하고 올바른 네임스페이스로 변경합니다. 2. 해당 tp 파일을 열고 클래스 이름을 수정합니다.

ThinkPHP5에서 어제의 데이터를 쿼리하는 방법 ThinkPHP5에서 어제의 데이터를 쿼리하는 방법 Dec 05, 2022 am 09:20 AM

ThinkPHP5에서 어제의 데이터를 쿼리하는 방법: 1. ThinkPHP5 관련 파일을 엽니다. 2. "db('table')->whereTime('c_time', 'yesterday')->select();" 표현식을 통해 어제의 데이터를 쿼리할 수 있습니다. .

thinkphp5에서 오류 프롬프트를 설정하는 방법 thinkphp5에서 오류 프롬프트를 설정하는 방법 Dec 07, 2022 am 10:31 AM

thinkphp5에서 오류 프롬프트를 설정하는 방법: 1. 프로젝트 루트 디렉터리에 있는 public 폴더를 입력하고 index.php 항목 파일을 엽니다. 2. 디버그 모드 스위치에 대한 설명을 봅니다. 3. "APP_DEBUG" 상수 값을 조정합니다. 오류 메시지 프롬프트를 표시하려면 true로 설정합니다.

See all articles