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를 실행하여 시스템 명령을 실행합니다.
3. 취약점 분석
분석을 위해 먼저 공식 홈페이지에서 다운로드한 5.0.22 정식 버전을 사용합니다. 취약점의 핵심 포인트 찾기:
thinkphp/library/think/Request.php:518
메소드 함수의 두 번째 if 분기에서는 외부에서 제어 가능한 데이터 $_POST[Config::get['var_method']가 도입되었습니다. var_method의 값은 _method입니다.
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에는 공급업체 디렉터리의 일부 파일을 자동으로 로드하는 자동 클래스 로딩 메커니즘이 있습니다. 그러나 정식 버전과 코어 버전의 공급업체 디렉터리 구조가 다릅니다.
풀 버전의 디렉터리 구조는 다음과 같습니다.
코어 버전의 디렉터리 구조는 다음과 같습니다.
풀 버전에는 코어 버전보다 폴더가 여러 개 더 많은 것을 볼 수 있습니다. . 특별한 주의가 필요한 것은 think-captcha/src 폴더에 helper.php 파일이 있다는 것입니다:
여기서 thinkRoute::get 함수가 호출되어 경로 등록 작업을 수행합니다. 이 단계의 영향은 위에서 언급한 self::$rules의 값을 변경하는 것입니다. 이 경로를 통해서만 RCE를 수행할 수 있으며, 그렇지 않으면 성공하지 못합니다. 이것이 바로 정식 버전에만 영향을 미치고 코어 버전에는 영향을 미치지 않는 이유입니다. 이때 self::$rules의 값은 다음과 같습니다.
그리고 공격자의 컨트롤에서 반환된 $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.0.2-5.0.23 버전에서는 규칙 함수에서 $ type이 소문자로 변환되었습니다:
4. 패치 분석
ThinkPHP5.0.24에는 $this->method 판정이 추가되었으며 클래스 함수의 자유 호출이 더 이상 허용되지 않습니다.
5. 결론
사용자는 ThinkPHP 버전 5.0.24로 업그레이드하고 공격을 피하기 위해 디버그 모드를 활성화하지 않는 것이 좋습니다.
관련 추천: "PHP 튜토리얼"
위 내용은 ThinkPHP5 코어 클래스 원격 코드 취약점 분석 요청의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

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

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

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

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

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

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

뜨거운 주제











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

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

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

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

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

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

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

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