LFI2RCE via Eternal waiting
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
기본적으로 PHP에 파일이 업로드되면 (예상하지 않더라도) **php[a-zA-Z0-9]{6}
**와 같은 이름의 임시 파일이 /tmp
에 생성됩니다. 그러나 일부 도커 이미지에서는 생성된 파일에 숫자가 포함되지 않는 경우도 보았습니다.
로컬 파일 포함에서 업로드된 파일을 포함할 수 있다면 RCE를 얻을 수 있습니다.
기본적으로 PHP는 단일 요청에서 20개의 파일만 업로드할 수 있도록 허용합니다 (설정은 /etc/php/<version>/apache2/php.ini
에 있습니다):
또한, 잠재적인 파일 이름의 수는 62*62*62*62*62*62 = 56800235584입니다.
다른 기술들은 PHP 프로토콜을 공격하는 데 의존합니다(경로의 마지막 부분만 제어할 경우에는 불가능합니다), 파일의 경로를 노출시키거나, 예상되는 파일을 악용하거나, PHP가 세그멘테이션 오류를 겪도록 하여 업로드된 임시 파일이 삭제되지 않게 만드는 것입니다. 이 기술은 마지막 기술과 매우 유사하지만 제로 데이를 찾을 필요가 없습니다.
이 기술에서는 상대 경로만 제어하면 됩니다. 파일을 업로드하고 LFI가 끝나지 않도록 만들면, 우리는 "충분한 시간"을 가지게 되어 업로드된 파일을 브루트 포스하고 찾을 수 있습니다.
이 기술의 장점:
포함된 내부의 상대 경로만 제어하면 됩니다.
nginx나 로그 파일에 대한 예상치 못한 접근 수준이 필요하지 않습니다.
세그멘테이션 오류를 일으키기 위해 0일이 필요하지 않습니다.
경로 노출이 필요하지 않습니다.
이 기술의 주요 문제는 다음과 같습니다:
특정 파일이 존재해야 합니다(더 있을 수 있습니다).
미친 양의 잠재적 파일 이름: 56800235584
서버가 숫자를 사용하지 않는다면 총 잠재적 양은: 19770609664
기본적으로 단일 요청에서 20개 파일만 업로드할 수 있습니다.
사용된 서버의 최대 병렬 작업자 수.
이 제한은 이전의 제한들과 함께 이 공격이 너무 오래 지속되게 만들 수 있습니다.
PHP 요청의 타임아웃. 이상적으로는 이 요청이 영원해야 하거나 임시로 업로드된 파일을 삭제하지 않고 PHP 프로세스를 종료해야 합니다. 그렇지 않으면 이것도 문제가 될 것입니다.
그렇다면, 어떻게 PHP 포함을 끝나지 않게 만들 수 있을까요? 파일 **/sys/kernel/security/apparmor/revision
**을 포함하기만 하면 됩니다 (불행히도 Docker 컨테이너에서는 사용할 수 없습니다...).
그냥 호출해 보세요:
기본적으로 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시간 (265시간에 50% 확률)
(숫자 없이) 19770609664 / 2980 / 10 / 3600 ~= 185시간 (93시간에 50% 확률)
이전 예제에서 우리는 다른 클라이언트를 완전히 DoS하고 있다는 점에 유의하세요!
Apache 서버가 개선되고 4000개의 연결을 남용할 수 있다면, 3999*20 = 79980
파일을 생성할 수 있으며, 시간은 약 19.7시간 또는 6.9시간으로 줄어들 것입니다 (10시간, 3.5시간 50% 확률).
정상적인 php 모듈 대신 웹 페이지가 PHP-FMP를 사용하여 PHP 스크립트를 실행하는 경우 (이것은 웹 페이지의 효율성을 향상시키므로 일반적으로 발견됩니다), 기술을 개선하기 위해 할 수 있는 다른 것이 있습니다.
PHP-FMP는 **/etc/php/<php-version>/fpm/pool.d/www.conf
**에서 request_terminate_timeout
매개변수를 구성할 수 있게 해줍니다.
이 매개변수는 PHP에 대한 요청이 종료되어야 하는 최대 초 수를 나타냅니다 (기본값은 무한하지만, 매개변수가 주석 해제되면 30초). PHP가 요청을 처리하는 동안 지정된 초 수가 지나면, 요청이 종료됩니다. 이는 요청이 임시 파일을 업로드하고 있었던 경우, php 처리가 중단되었기 때문에, 해당 파일이 삭제되지 않을 것을 의미합니다. 따라서 요청이 그 시간을 지속할 수 있다면, 삭제되지 않는 수천 개의 임시 파일을 생성할 수 있으며, 이는 파일을 찾는 과정을 가속화하고 모든 연결을 소모하여 플랫폼에 대한 DoS 확률을 줄입니다.
따라서 DoS를 피하기 위해 공격자가 동시에 100개의 연결만 사용할 것이라고 가정해 보겠습니다. php-fmp의 PHP 최대 처리 시간은 30초입니다. 따라서 초당 생성할 수 있는 임시 파일의 수는 100*20/30 = 66.67
입니다.
그런 다음, 10000개의 파일을 생성하기 위해 공격자는: **10000/66.67 = 150초
**가 필요합니다 ( 100000개의 파일을 생성하는 데는 25분이 소요됩니다).
그런 다음 공격자는 이 100개의 연결을 사용하여 브루트 포스 검색을 수행할 수 있습니다. **** 300 req/s의 속도를 가정할 때, 이를 활용하는 데 필요한 시간은 다음과 같습니다:
56800235584 / 10000 / 300 / 3600 ~= 5.25시간 (2.63시간에 50% 확률)
(100000개의 파일로) 56800235584 / 100000 / 300 / 3600 ~= 0.525시간 (0.263시간에 50% 확률)
예, EC2 중간 크기 인스턴스에서 100000개의 임시 파일을 생성하는 것이 가능합니다:
타임아웃을 트리거하기 위해서는 취약한 LFI 페이지를 포함하는 것만으로도 충분하므로, 영원한 포함 루프에 들어갑니다.
기본적으로 Nginx는 동시에 512개의 병렬 연결을 지원하는 것으로 보이며 (이 숫자는 개선될 수 있습니다).
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)