LFI2RCE via Eternal waiting

제로부터 영웅이 될 때까지 AWS 해킹 배우기 htARTE (HackTricks AWS Red Team Expert)!

다른 방법으로 HackTricks를 지원하는 방법:

기본 정보

기본적으로 PHP에 파일이 업로드되면 (기대하지 않더라도) **php[a-zA-Z0-9]{6}**와 같은 이름의 임시 파일이 /tmp에 생성됩니다. 그러나 일부 도커 이미지에서 생성된 파일에 숫자가 포함되지 않은 것을 본 적이 있습니다.

로컬 파일 포함에서 해당 업로드된 파일을 포함시키면 RCE를 얻을 수 있습니다.

기본적으로 PHP는 단일 요청에서 20개의 파일만 업로드할 수 있습니다(/etc/php/<version>/apache2/php.ini에 설정됨):

; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20

또한, 잠재적인 파일 이름의 수는 62*62*62*62*62*62 = 56800235584입니다.

기타 기술

다른 기술은 PHP 프로토콜을 공격하는 데 의존합니다(경로의 마지막 부분만 제어하는 경우에는 할 수 없습니다), 파일의 경로를 공개하는 것, 예상 파일을 남용하는 것, 또는 PHP가 세그멘테이션 오류를 발생시켜 업로드된 임시 파일이 삭제되지 않도록 하는 것입니다. 이 기술은 제로데이를 찾아야 하는 것 없이 매우 마지막 기술과 매우 유사합니다.

영원한 대기 기술

이 기술에서 상대 경로만 제어하면 됩니다. 파일을 업로드하고 LFI가 결코 끝나지 않도록 만들면, "충분한 시간"이 생기게 되어 업로드된 파일을 브루트 포스하여 업로드된 파일 중 하나를 찾을 수 있습니다.

이 기술의 장점:

  • 포함된 상대 경로만 제어하면 됩니다

  • nginx나 로그 파일에 대한 예상치 못한 수준의 액세스가 필요하지 않습니다

  • 세그멘테이션 오류를 발생시키기 위해 0일이 필요하지 않습니다

  • 경로 공개가 필요하지 않습니다

이 기술의 주요 문제점은:

  • 특정 파일이 존재해야 합니다(더 많을 수도 있음)

  • 잠재적인 파일 이름의 엄청난 양: 56800235584

  • 서버가 숫자를 사용하지 않는 경우 총 잠재적인 양은: 19770609664

  • 단일 요청에서 기본적으로 최대 20개의 파일만 업로드할 수 있습니다.

  • 사용된 서버의 병렬 워커의 최대 수

  • 이 제한과 이전 제한들은 이 공격을 너무 오래 지속시킬 수 있습니다

  • PHP 요청에 대한 시간 초과. 이상적으로는 영원히 지속되거나 PHP 프로세스를 삭제하지 않고 임시 업로드된 파일을 삭제해야 합니다. 그렇지 않으면 이것도 고통스러울 것입니다

그래서, 어떻게 하면 PHP 포함을 끝없이 만들 수 있을까요? 단순히 /sys/kernel/security/apparmor/revision 파일을 포함시킴으로써 가능합니다 (안타깝게도 Docker 컨테이너에는 없습니다).

다음을 호출하여 시도해보세요:

php -a # open php cli
include("/sys/kernel/security/apparmor/revision");

Apache2

기본적으로, Apache는 150개의 동시 연결을 지원합니다. https://ubiq.co/tech-blog/increase-max-connections-apache/를 따르면 이 숫자를 최대 8000까지 늘릴 수 있습니다. PHP를 해당 모듈과 함께 사용하려면 다음을 따르세요: https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04.

기본적으로 (내 테스트에서 확인할 수 있듯이), PHP 프로세스는 영원히 지속될 수 있습니다.

간단한 계산을 해봅시다:

  • 149개의 연결을 사용하여 149 * 20 = 2980개의 임시 파일을 웹쉘로 생성할 수 있습니다.

  • 그런 다음, 마지막 연결을 사용하여 잠재적인 파일을 무차별 대입할 수 있습니다.

  • 10개의 요청/초 속도로 시간은 다음과 같습니다:

  • 56800235584 / 2980 / 10 / 3600 ~= 530 시간 (50% 확률로 265시간)

  • (소수점 없이) 19770609664 / 2980 / 10 / 3600 ~= 185시간 (50% 확률로 93시간)

이전 예제에서 다른 클라이언트를 완전히 DoS하는 것에 유의하세요!

Apache 서버가 개선되어 4000개의 연결을 악용할 수 있다면 (최대 수의 절반까지), 3999*20 = 79980 파일을 생성할 수 있고, 시간은 약 19.7시간 또는 6.9시간 (10시간, 3.5시간 50% 확률)으로 줄어들 것입니다.

PHP-FMP

일반적인 php 모듈 대신 PHP 스크립트를 실행하기 위해 웹 페이지가 PHP-FMP를 사용하는 경우 (웹 페이지의 효율성을 향상시키므로 일반적으로 찾을 수 있음), 기술을 향상시킬 수 있는 다른 방법이 있습니다.

PHP-FMP는 **/etc/php/<php-version>/fpm/pool.d/www.conf**에서 request_terminate_timeout 매개변수를 구성할 수 있습니다. 이 매개변수는 PHP에 대한 요청이 종료되어야 하는 최대 시간을 나타냅니다 (기본적으로 무한하지만 매개변수가 주석 처리되면 30초). PHP가 요청을 처리하는 동안 지정된 시간이 지나면 종료됩니다. 이는 즉, PHP 처리가 중지되어 임시 파일이 삭제되지 않을 수 있음을 의미합니다. 따라서 요청이 그 시간 동안 계속되도록 만들 수 있다면, 삭제되지 않는 수천 개의 임시 파일을 생성할 수 있으며, 이는 그들을 찾는 프로세스를 가속화시키고 모든 연결을 소비하여 플랫폼에 DoS가 발생할 확률을 줄일 수 있습니다.

따라서 DoS를 피하기 위해 가정하면 공격자가 한 번에 100개의 연결만 사용하고 php-fmp에 의한 php 최대 처리 시간인 (request_terminate_timeout**)이 30초라고 가정합니다. 따라서 초당 생성될 수 있는 임시 파일의 수는 100*20/30 = 66.67입니다.

그런 다음, 10000개의 파일을 생성하려면 공격자가 필요한 시간은: 10000/66.67 = 150초 (100000개의 파일을 생성하려면 시간은 25분이 될 것입니다).

그런 다음, 공격자는 이러한 100개의 연결을 사용하여 검색 무차별 대입을 수행할 수 있습니다. 300개의 요청/초 속도를 가정하면 이를 악용하는 데 필요한 시간은 다음과 같습니다:

  • 56800235584 / 10000 / 300 / 3600 ~= 5.25 시간 (50% 확률로 2.63시간)

  • (100000개의 파일로) 56800235584 / 100000 / 300 / 3600 ~= 0.525 시간 (50% 확률로 0.263시간)

네, EC2 중간 크기 인스턴스에서 100000개의 임시 파일을 생성하는 것이 가능합니다:

타임아웃을 트리거하기 위해서는 취약한 LFI 페이지를 포함하면 충분합니다. 그렇게 하면 영원한 포함 루프에 들어갑니다.

Nginx

기본적으로 Nginx는 동시에 512개의 병렬 연결을 지원하는 것으로 보입니다 (이 숫자는 향상될 수 있습니다).

Last updated