Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/password123456/setup-wordpress-with-security-best-practice
Configuration AuditingWeb SecurityLearning & Education
GitHubpassword123456/setup-wordpress-with-security-best-practice

setup-wordpress-with-security-best-practice

WordPress 설치 보안 강화를 위한 종합 가이드: 관리자 사용자 변경, HTTPS 적용, 플러그인 보안, 파일 권한, 정적 기업 사이트를 위한 서버 구성을 다룹니다.

저장소 보기

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
29432년 전Kitploit 검토 완료

보안 모범 사례를 적용한 WordPress 설정

Hits

이 문서는 사용자와 상호작용하지 않는 WordPress로 개발된 웹 애플리케이션에 적합한 목적으로 작성되었습니다. 주로 기업 브랜드 페이지, 다양한 정적 뷰, 채용 페이지 및 유사한 사이트를 대상으로 합니다.

오픈 커뮤니티와 같이 사용자가 등록하고 자유롭게 사이트를 사용하는 웹사이트의 경우 이 문서의 일부 항목이 적용되지 않을 수 있습니다. 이 점을 염두에 두고 읽어주시기 바랍니다.

이 문서는 WordPress 보안에 필요한 모든 내용을 포함하지 않습니다.

그러나 이 가이드를 기반으로 보안 위험 평가 및 취약점 대응이 가능한 수준의 일반적이고 상세한 정보를 포함하고 있습니다.

도움이 되셨다면 추가 개선을 위해 "star"🌟를 눌러주세요.


목차

  • 1. 기본 WordPress 관리자 사용자 이름이 변경되었는지 확인
  • 2. WordPress에서 사용자 역할 및 권한이 적절히 관리되는지 확인
  • 3. 사용자 등록이 비활성화되었는지 확인
  • 4. 플러그인 파일 편집기가 비활성화되었는지 확인
  • 5. 사용하지 않는 불필요한 플러그인이 비활성화되었는지 확인
  • 6. WordPress가 WordPress 관리자를 포함하여 HTTPS만 사용하도록 구성되었는지 확인
  • 7. IP 접근 제한(ACL)이 적용되었는지 확인
    • 7.1. WordPress 관리자에 IP 접근 제한이 적용되었는지 확인
    • 7.2. JSON REST API 기능에 대한 IP 접근 제한 또는 비활성화
    • 7.3. XML-RPC API 기능 비활성화
    • 7.4. WP-Cron 비활성화 또는 기능 제한
  • 8. 보안 WordPress를 위한 시스템 구성
    • 8.1. 수명 종료(EOL)되지 않은 WordPress 및 PHP 버전 사용 확인
    • 8.2. WordPress에 필요한 PHP 확장만 활성화되었는지 확인
    • 8.3. 파일 업로드 기능이 있는 플러그인의 보안 확인
    • 8.4. PHP 함수 및 설정이 적절히 구성되었는지 확인
    • 8.5. 웹 서버가 루트가 아닌 사용자로 실행되는지 확인 - 서버 애플리케이션을 위한 고유한 권한 없는 사용자 및 그룹
    • 8.6. PHP-FPM이 루트가 아닌 사용자로 실행되는지 확인 - 서버 애플리케이션을 위한 고유한 권한 없는 사용자 및 그룹
    • 8.7. WordPress 홈 디렉터리의 보안 구성 확인
    • 8.8. 쓰기 가능한 디렉터리에서 PHP 실행이 비활성화되었는지 확인
    • 8.9. 웹 서버가 도메인 기반 호스트 헤더에만 응답하는지 확인
    • 8.10. 완료된 웹 서버 구성
  • 9. WordPress 보안 업데이트 확인
  • 10. WordPress 정기 보안 취약점 검사 확인

1. 기본 WordPress 관리자 사용자 이름이 변경되었는지 확인

WordPress를 설치할 때 설정 과정에서 변경하지 않으면 기본 관리자 사용자 이름은 "admin"입니다. "admin" 계정 이름은 널리 알려져 있으므로 다른 이름으로 변경해야 합니다. 관리자 사용자 이름으로 계속 "admin"을 사용하면 공격자가 "admin"을 사용하여 무차별 대입 공격을 시도하여 WordPress 사이트에 접근할 수 있습니다.

공격자가 WordPress 관리자 계정에 접근하면 웹사이트에 대한 완전한 제어권을 갖게 됩니다. 기본 WordPress 관리자 사용자 이름은 다른 이름으로 변경되어야 합니다.

감사:

  • 기본 WordPress 관리자 사용자 이름이 여전히 "admin"으로 설정되어 있는지 확인합니다.

조치:

  • 사용자 이름이 "admin"인 경우 즉시 덜 예측 가능한 사용자 이름으로 변경합니다.
  1. 관리자 계정을 사용하여 WordPress 관리자 대시보드에 로그인합니다.
  2. 대시보드 패널에서 "사용자" 영역으로 이동하여 "새 사용자 추가"를 클릭합니다.
  3. 양식을 작성하고 "역할" 드롭다운 메뉴에서 "관리자"를 선택합니다 (강력한 웹 비밀번호를 사용하고 제공된 비밀번호 강도 표시기를 사용하여 새 비밀번호가 충분히 강력한지 확인하십시오).
  4. 완료되면 "새 사용자 추가" 버튼을 클릭합니다.
  5. 새 WordPress 관리자 사용자 이름으로 다시 로그인합니다.
  6. 다시 "사용자" 영역으로 이동합니다.
  7. 사용자 목록에서 이전 "admin" 사용자 이름을 선택하고 드롭다운 메뉴에서 "삭제"를 선택합니다.
  8. 이전 관리자를 삭제할 때 이전 "admin" 사용자 이름으로 작성된 게시물에 대해 묻는 메시지가 표시됩니다.
    • "모든 게시물 및 링크 속성을 다음으로 지정:" 옵션을 선택하고 새 관리자를 선택합니다.
    • 모든 설정이 완료되면 "삭제 확인"을 클릭합니다.

참고:

  • 항상 사용자 이름과 다른 "표시 이름"을 사용하십시오. 실제 사용자 이름이 콘텐츠 작성자의 표시 이름으로 사용되면 해커가 사용자 이름을 쉽게 식별하고 계정을 표적으로 삼을 수 있습니다.

2. WordPress에서 사용자 역할 및 권한이 적절히 관리되는지 확인

기본적으로 WordPress에는 "관리자", "편집자", "작성자", "기여자", "구독자"의 다섯 가지 사용자 역할이 있습니다.

이러한 역할을 통해 적절한 권한을 할당하여 사용자가 웹사이트에서 수행할 수 있는 작업을 제어할 수 있습니다. 사용자 역할과 권한이 적절히 관리되지 않으면 사용자가 불필요하게 중요한 기능에 접근하여 심각한 보안 위험을 초래할 수 있습니다.

감사:

  • WordPress 사용자 역할과 권한이 웹사이트의 필요에 맞게 조정되었는지 확인합니다.
  • 모든 사용자 역할을 검토하여 웹사이트의 현재 운영 정책과 일치하는지 확인합니다.

조치:

  • 웹사이트의 필요에 따라 사용자 역할을 할당하고 관리합니다.
  • 일반적으로 WordPress는 관리자 1명, 편집자 1명, 작성자 1명으로 운영되어야 합니다.
  • 불필요한 관리자 계정을 제거하거나 필요한 경우 권한을 축소합니다.
  • 변경 사항에 맞게 최신 상태를 유지하도록 사용자와 해당 역할을 정기적으로 검토합니다.

참고:

  • 대부분의 경우 회사 블로그, 채용 페이지, 브랜드 사이트, 프로모션 사이트 등 사용자 상호작용이 적고 콘텐츠가 주로 전시되는 서비스 중심 웹사이트에서는 "관리자", "편집자", "작성자"와 같은 역할로 충분합니다.

3. 사용자 등록이 비활성화되었는지 확인

WordPress에는 내장 사용자 등록 기능이 포함되어 있습니다. 이 기능은 기본적으로 비활성화되어 있지만 관리자가 활성화할 수 있습니다.

이 기능이 활성화되면 누구나 등록하고 잠재적으로 WordPress 관리자 대시보드에 접근할 수 있어 보안 문제가 발생할 수 있습니다. 오픈 커뮤니티로 운영되지 않는 대부분의 웹사이트에서는 사용자 등록 기능이 필요하지 않으므로 비활성화된 상태로 유지해야 합니다.

감사:

  • 사용자 등록이 비활성화되어 있는지 확인합니다. 사용자 등록 페이지에 접속을 시도하여 확인할 수 있습니다.
  1. 웹 브라우저 사용

    • https://yourwordpress.com/wp-login.php?action=register 로 이동합니다.
    • 사용자 등록이 비활성화된 경우 "User registration is currently not allowed." 메시지가 표시됩니다. 3.1!
  2. curl 사용

    • 사용자 등록이 비활성화되면 비활성화된 페이지로 리디렉션됩니다.```

curl -i -k "https://yourwordpress.com/wp-login.php?action=register"

(response) HTTP/1.1 302 Moved Temporarily cache-control: no-cache, no-store, must-revalidate, max-age=0 content-type: text/html; charset=UTF-8 server: Apache content-length: 0 ... location: https://yourwordpress.com/wp-login.php?registration=disabled

root@kitploit:~
**조치:**
- 사용자 등록이 활성화되어 있으면 비활성화합니다.
- '누구나 등록 가능' 체크 해제
![3.2!](https://assets.kitploit.com/production/public/readmes/6586/46991061b1bec392d06e00e986f048c6369b8db2c9e5a6b30f4f66dbc9b862d1.png)


## 4. 플러그인 파일 편집기 비활성화 확인
공격자가 WordPress 관리자 계정에 침입하면 웹사이트를 완전히 제어할 수 있습니다.
내장된 "편집기" 기능을 통해 테마 및 플러그인의 코딩을 편집하고, 악성 스크립트를 업로드하고, 사이트를 훼손하고, 사용자에게 스팸을 보내는 등의 작업을 수행할 수 있습니다.

이 편집기를 통한 일반적인 해킹에는 SQL 인젝션, SEO 스팸 해킹, 일본어 SEO 스팸이 있습니다.

**감사:**
- 파일 편집기가 비활성화되어 있는지 확인합니다.
- 모양 > 편집기 또는 플러그인 > 플러그인 편집기를 통해 편집기에 접근할 수 있는지 확인합니다.

**조치:**
- 파일 편집기가 활성화되어 있으면 다음 단계를 따라 비활성화합니다.

1. 파일 관리자 또는 FTP를 사용하여 wp-config.php 파일에 접근합니다.
2. 편집을 위해 wp-config.php 파일을 엽니다.
3. 파일 하단으로 스크롤합니다(기본 wp-config.php를 사용하는 경우).
4. 다음 줄을 찾습니다.
`
/* That’s all, stop editing! Happy publishing. */
`
5. 이 줄 위에 다음 코드를 추가합니다.
`
define('DISALLOW_FILE_EDIT', true);
`
6. 변경 사항을 저장하고 편집기를 닫습니다.
7. WordPress 대시보드로 돌아가 편집기 옵션이 더 이상 표시되지 않는지 확인합니다.


## 5. 사용하지 않는 불필요한 플러그인이 비활성화되었는지 확인
WordPress의 많은 취약점은 플러그인 보안 문제에서 비롯됩니다.
플러그인은 오픈소스이므로 공격자가 취약점을 찾아 악용하기 쉽습니다.
사용 중인 플러그인을 최신 상태로 유지하고 사용하지 않는 플러그인을 비활성화하여 잠재적인 악용을 방지하는 것이 중요합니다.

**감사:**
- 사용하지 않는 불필요한 플러그인이 비활성화되었는지 확인합니다.
- 사용하지 않고 불필요한 플러그인이 비활성화되었는지 확인합니다.

**조치:**
- 다음 단계에 따라 사용하지 않는 불필요한 플러그인을 비활성화합니다.

**플러그인 체크 - PCP 사용:**
- PCP: https://wordpress.org/plugins/plugin-check
1. 플러그인 체크(PCP) 설치 및 활성화:
   - WordPress 관리자 대시보드로 이동합니다.
   - 플러그인 > 새로 추가로 이동합니다.
   - “Plugin Check”를 검색하여 설치하고 활성화합니다.

2. 플러그인 검사 실행:
   - WordPress 대시보드에서 Plugin Check 메뉴로 이동합니다.
   - 검사할 플러그인을 선택하고 스캔을 실행합니다.

3. 스캔 결과 분석:
   - PCP는 플러그인의 코드를 분석하고 다음을 포함한 보고서를 제공합니다:
     - 코드 표준 준수: 플러그인이 WordPress 코딩 표준을 얼마나 잘 준수하는지.
     - 보안 문제: 잠재적인 취약점 또는 악성 코드.
     - 성능 문제: 웹사이트 성능에 미치는 영향.
     - 호환성 문제: 플러그인이 다른 플러그인 및 테마와 호환되는지 여부.

4. 문제가 있는 플러그인 식별:
   - 보고서에서 심각한 보안 취약점, 악성 코드 또는 다수의 코딩 표준 위반이 강조되면 해당 플러그인은 '의심스러운' 것입니다.
   - 불필요한 외부 요청을 하거나 과도한 데이터베이스 쿼리를 실행하는 플러그인에 주의하십시오.

5. 문제 해결:
   - 업데이트하거나 플러그인 페이지에서 문제를 찾아 해결하십시오.
   - 심각한 보안 문제가 있는 플러그인은 사용하지 마십시오. 필요한 경우 대체 플러그인을 찾으십시오.

**플러그인 관리:**
1. 플러그인 선택:
   - 공식 저장소 사용, 리뷰 및 평점 확인, 개발자 신뢰성 확인
   - 알 수 없거나 확인되지 않은 플러그인을 사용하지 마십시오.

2. 정기적인 업데이트
   - 최신 보안 패치를 적용하려면 플러그인을 최신 상태로 유지하십시오.

3. 사용하지 않는 플러그인 비활성화 및 삭제
   - 비활성 플러그인도 보안 위험이 될 수 있으므로 사용하지 않으면 제거하십시오.
   - 플러그인 최소화: 필수 플러그인만 사용하십시오.


## 6. WordPress 관리자를 포함하여 WordPress가 HTTPS 전용으로 구성되었는지 확인
오늘날 대부분의 웹사이트는 SSL(HTTPS)을 통해 운영되도록 구성됩니다.
그러나 일부 웹 서버는 여전히 HTTP와 HTTPS 연결을 모두 처리하도록 잘못 설정될 수 있습니다.
이로 인해 두 프로토콜을 통해 WordPress에 접근할 수 있어 보안 위험이 발생합니다. WordPress 관리자를 포함하여 WordPress는 HTTPS만 사용하도록 강제해야 합니다.

**감사:**
- WordPress 관리자를 포함하여 HTTPS로만 접근 가능하도록 구성되었는지 확인합니다.
- 웹 서버의 VirtualHost 구성을 확인하여 HTTP VirtualHost가 설정되지 않았는지 확인합니다.

**조치:**
- HTTP 접근이 가능한 경우 먼저 웹 서버 설정을 검토하고 수정합니다.
- 서버에 HTTP VirtualHost가 있는 경우 HTTPS로 리디렉션하거나 HTTP VirtualHost를 삭제합니다.
- 필요한 경우 "FORCE_SSL_ADMIN" 기능을 활성화하여 WordPress 관리자에 HTTPS 접근을 강제합니다.

**FORCE_SSL_ADMIN 활성화 단계:**
1. 파일 관리자 또는 FTP를 사용하여 wp-config.php 파일에 접근합니다.
2. 편집을 위해 wp-config.php 파일을 엽니다.
3. 파일 하단으로 스크롤합니다(기본 wp-config.php를 사용하는 경우).
4. 다음 줄을 찾습니다.
`
/* That’s all, stop editing! Happy publishing. */
`
5. 이 줄 위에 다음 코드를 추가합니다.
`
define('FORCE_SSL_ADMIN', true);`
`
6. 변경 사항을 저장하고 편집기를 닫습니다.
WordPress 대시보드로 돌아가 다시 로그인하여 WordPress 관리자가 HTTPS로만 접근 가능한지 확인합니다.

**웹 서버에서 HTTP를 HTTPS로 리디렉션:**
1. Apache:
    ```
    <VirtualHost *:80>
        ServerName yourwordpress.com
    
        RewriteEngine On
        RewriteCond %{HTTPS} off
        RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    </VirtualHost>
    ```
2. Nginx:
    ```
    server {
        listen 80;
        server_name yourwordpress.com;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    ```
WordPress와 WordPress 관리자가 HTTPS로만 접근 가능하도록 함으로써 웹사이트의 보안을 크게 강화하여 데이터를 보호하고 무단 접근을 방지할 수 있습니다.

## 7. IP 접근 제한(ACL)이 적용되었는지 확인
IP 접근 제한이 적용되었는지 확인합니다.

WordPress를 안전하게 운영하려면 WordPress 관리자를 포함한 특정 URL에 IP 접근 제한을 적용하여 원치 않는 사용자, 컴퓨터 및 봇의 접근을 차단하는 것이 필수적입니다. 여기에는 허용된 IP 주소(예: 관리자 IP)에서만 접근을 허용하는 것이 포함됩니다. 또한 공격 표면을 최소화하기 위해 사용하지 않는 기능을 비활성화해야 합니다.

보호할 URL에는 WordPress 관리자, 사용자 등록(wp-signup.php), JSON REST API 및 XML-RPC 기능이 포함됩니다.

이 보안 가이드는 사용자 상호 작용이 적고 콘텐츠가 주로 표시되는 회사 블로그, 채용 페이지, 브랜드 사이트, 프로모션 사이트와 같은 서비스 지향 웹사이트를 대상으로 합니다.

IP 접근 제한을 구현하면 무단 접근의 위험을 크게 줄이고 웹사이트의 전반적인 보안을 강화할 수 있습니다.


### 7.1. WordPress 관리자에 IP 접근 제한이 적용되었는지 확인합니다.
WordPress 관리자 접근 경로는 wp-login.php 또는 /wp-admin 형태로 고정되어 있어 권한이 없는 사용자가 쉽게 접근할 수 있습니다.
관리자 페이지에 대한 무단 접근을 방지하기 위해 IP 접근 제한이 적용되었는지 확인합니다.

**감사:**
- WordPress 관리자에 IP 접근 제한이 적용되었는지 확인합니다.
- 대부분의 경우 이는 웹 서버(Apache, Nginx)에서 구성됩니다.

**조치:**
- IP 접근 제한이 적용되지 않은 경우 구현합니다.
- 다음은 Apache 및 Nginx 웹 서버를 사용하여 IP 접근 제한을 적용하는 방법입니다.

**WordPress 관리자에 IP 접근 제한 적용:**
- /wp-admin, wp-login.php 

1. Apache:
    ```
   # Files Directive 
    <Files "wp-login.php">
        Require ip 10.10.77.49  # Replace with your IP address
    </Files>
    
    # FilesMatch Directive
    <FilesMatch "^wp-login\.php$">
        Require all granted
    </FilesMatch>

   # Directory, Files Mixing Directive
    <Directory /www/vhosts/yourwordpress>
        Require all granted
        AllowOverride None
        <Files "wp-login.php">
            Require ip 10.10.77.49  # Replace with your IP address
        </Files>
    </Directory>
   
   # Location Directive
    <Location "/wp-admin">
        Require ip 10.10.77.49  # Replace with your IP address
    </Location>
    
    <Location "/wp-login.php">
        Require ip 10.10.77.49  # Replace with your IP address
    </Location>
    ```
2. Nginx:
    ```
    location /wp-admin {
        allow 10.10.77.49;  # Replace with your IP address
        deny all;
    }
    
    location ~* \wp-login.php {
        allow 10.10.77.49;  # Replace with your IP address
        deny all;
    }
    ```


### 7.2. IP 접근 제한 또는 JSON REST API 기능 비활성화
WordPress는 두 가지 REST 기능(xmlrpc, json rest api)을 제공하며 WordPress 설치 시 기본적으로 활성화됩니다.
REST API는 WordPress 데이터 유형에 대한 엔드포인트를 제공하여 게시물이나 데이터 쿼리, 리소스 수정, 편집, 삭제 등의 작업을 위해 사이트와 원격으로 상호 작용할 수 있습니다.

대부분의 WordPress에서 REST API 기능은 필수적이지 않습니다.
활성화하면 WordPress가 DDoS 공격에 노출될 수 있으며 리소스 소비 및 사이트 속도 저하를 초래할 수 있습니다.

**감사:**
- JSON REST API 기능이 활성화되어 있는지 확인합니다. (기본값: 활성화됨)```
# curl -i -k https://yourwordpress.com/wp-json

(response)
HTTP/1.1 200 OK
cache-control: no-cache, no-store, must-revalidate, max-age=0
content-type: text/html; charset=UTF-8
...
Server: Apache

{"name":"mywordress","description":"".......................

수정 방법:

  • REST API가 필요하지 않다면 비활성화하세요. 간단한 플러그인 설치를 통해 비활성화할 수 있습니다.
  • REST API를 사용하는 경우, 허용된 IP에서만 접근할 수 있도록 IP 접근 제한을 적용하세요.

"Disable REST API" 플러그인 설치 및 활성화:

  1. 워드프레스 관리자 대시보드로 이동합니다.
  2. 플러그인 > 새로 추가로 이동합니다.
  3. "Disable REST API"를 검색하여 설치 및 활성화합니다.
  4. 활성화되면 플러그인이 자동으로 워드프레스 사이트의 REST API 기능을 비활성화합니다.

JSON REST API에 대한 IP 접근 제한:

  1. Apache의 경우:
    root@kitploit:~
    <Location "/wp-json">
        Require ip 10.10.77.49  # Replace with your IP address
    </Location>
    
  2. Nginx의 경우:
    root@kitploit:~
    location ~ ^/wp-json/ {
        allow 10.10.77.49;   # Replace with your allowed IP address
        deny all;
    }
    

7.3. XML-RPC API 기능 비활성화

JSON REST API와 마찬가지로, 대부분의 워드프레스 설치에서 필요하지 않으므로 XML-RPC API를 비활성화하는 것이 좋습니다.

REST API가 필요하다면 JSON REST API를 대신 사용하는 것이 권장됩니다.

XML-RPC에는 두 가지 주요 약점이 있습니다:

  • 무차별 대입 공격:

  • 공격자는 xmlrpc.php를 사용하여 가능한 많은 사용자 이름/비밀번호 조합으로 워드프레스 로그인을 시도합니다.

  • xmlrpc.php 내의 한 메서드는 공격자가 단일 명령(system.multicall)을 사용하여 수백 개의 비밀번호를 추측할 수 있게 합니다.

  • 핑백을 통한 서비스 거부 공격:

  • 2013년에 공격자는 약 2500개 워드프레스 사이트의 xmlrpc.php를 통해 핑백 요청을 보냈습니다.

  • 이는 공격자에게 사실상 무제한의 IP 주소 집합을 제공하여 1억 개 이상의 워드프레스 사이트 네트워크에 걸쳐 서비스 거부 공격을 분산시킬 수 있으며, 해당 사이트를 손상시킬 필요가 없습니다.

XML-RPC가 활성화되어 있으면 여전히 이러한 공격에 악용될 수 있습니다.

감사:

  • XML-RPC API 기능이 활성화되어 있는지 확인합니다. (기본값: 활성화)```

curl -i -k https://yourwordpress.com/xmlrpc.php

(response) HTTP/1.1 405 Method Not Allowed Date: Mon, 25 Jun 2018 08:30:24 GMT Server: Apache Allow: POST Content-Length: 42 Content-Type: text/plain; charset=UTF-8

XML-RPC server accepts POST requests only.

root@kitploit:~
**조치 방법:**
- 플러그인을 사용하여 XML-RPC 기능 비활성화

**"Disable XML-RPC-API" 플러그인 설치 및 활성화:**
1. WordPress 관리자 대시보드로 이동합니다.
2. 플러그인 > 새로 추가로 이동합니다.
3. "[Disable XML-RPC-API](https://wordpress.org/plugins/disable-xml-rpc-api/)"를 검색하여 설치하고 활성화합니다.
4. XML-RPC-API가 비활성화되었습니다.

**XML-RPC 핑백 공격에 관하여:**

1. XML-RPC가 활성화되었는지 확인
    ```
    # curl -i -k https://yourwordpress.com/xmlrpc.php
    
    (response)
    HTTP/1.1 405 Method Not Allowed
    Date: Mon, 25 Jun 2018 08:30:24 GMT
    Server: Apache
    Allow: POST
    Content-Length: 42
    Content-Type: text/plain; charset=UTF-8
     
     
    XML-RPC server accepts POST requests only.
    ```
2. 사용 가능한 XML-RPC 메서드 검색
    ```
    (request)
    POST /xmlrpc.php HTTP/1.1
    Host: yourwordpress.com
    Content-Length: 135
    
    <?xml version="1.0" encoding="utf-8"?>
    <methodCall>
        <methodName>system.listMethods</methodName>
        <params></params>
    </methodCall>
    
    
    (response)
    HTTP/1.1 200 OK
    cache-control: no-cache, no-store, must-revalidate, max-age=0
    ...
    Server: Apache
    Content-Length: 4272
    Content-Type: text/xml; charset=UTF-8
    
    <?xml version="1.0" encoding="UTF-8"?>
    <methodResponse>
        <params>
            <param>
                <value>
                    <array><data>
                        <value><string>system.multicall</string></value>
                        <value><string>system.listMethods</string></value>
                        <value><string>system.getCapabilities</string></value>
                        <value><string>demo.addTwoNumbers</string></value>
                        <value><string>demo.sayHello</string></value>
                        <value><string>pingback.extensions.getPingbacks</string></value>
                        <value><string>pingback.ping</string></value>
                        <value><string>mt.publishPost</string></value>
                        ...
                        <value><string>wp.getUsersBlogs</string></value>
                    </data></array>
                </value>
            </param>
        </params>
    </methodResponse>
    
    ```
3. 핑백 실행
    - 핑백 공격의 성공 여부와 구체적인 확인 방법은 설명되지 않았습니다.
    ```
    (request)
    POST /xmlrpc.php HTTP/1.1
    Host: yourwordpress.com
    Content-Length: 303
    
    <?xml version="1.0" encoding="UTF-8"?>
        <methodCall>
        <methodName>pingback.ping</methodName>
            <params>
                <param>
                    <value><string>call-back url for pingback result</string></value>
                </param>
                <param>
                    <value><string>https://yourwordpress.com/</string></value>
            </param>
        </params>
    </methodCall>
    
    
    (response)
    HTTP/1.1 200 OK
    ...
    Server: Apache
    Content-Length: 370
    Content-Type: text/xml; charset=UTF-8
    
    <?xml version="1.0" encoding="UTF-8"?>
    <methodResponse>
      <fault>
        <value>
          <struct>
            <member>
              <name>faultCode</name>
              <value><int>0</int></value>
            </member>
            <member>
              <name>faultString</name>
              <value><string></string></value>
            </member>
          </struct>
        </value>
      </fault>
    </methodResponse>
    ```


### 7.4. WP-Cron 비활성화 또는 기능 제한
WordPress에서 WP-Cron(wp-cron.php)은 예약된 게시물 발행, 플러그인/테마 업데이트 확인, 알림 이메일 전송 등의 작업을 자동화하는 데 사용됩니다.

WP-Cron은 기본적으로 페이지가 로드될 때마다 예약된 작업 목록을 확인하는 방식으로 작동합니다.
문제는 페이지 로딩이 많을 때 발생합니다.

WP-Cron 작업이 각 페이지 로드 시 수행되므로 반복적인 접근이 많아지면 그에 따라 WP-Cron 호출이 증가합니다. 결과적으로 시스템 리소스가 부족해져 사이트 속도가 느려지거나 중단될 수 있습니다.
이는 실제로 발생하는 현상이며, WordPress를 대상으로 한 취약점 공격에서 자주 악용됩니다.

WP-Cron이 필요하지 않다면 비활성화하는 것이 좋습니다.
필요하다면 로컬 호스트로만 접근을 제한하십시오.

**감사:**
- WP-Cron이 활성화되었는지 확인합니다. (기본값: 활성화)```
# curl -i -k https://yourwordpress.com/wp-cron.php

(response)
HTTP/1.1 200 ok
Date: Mon, 25 Jun 2018 08:30:24 GMT
Server: Apache
Allow: POST
Content-Length: 42
Content-Type: text/plain; charset=UTF-8

해결 방법:

  • WP-Cron을 사용하지 않는다면 비활성화하세요.
  • 사용 중이라면 다음 옵션 중 하나를 적절히 적용하세요.
    1. "ALTERNATE_WP_CRON"을 활성화하고 wp-cron.php에 IP 접근을 제한하세요.
    2. 시스템 cron(crontab) 또는 다른 대체 방법을 사용하여 cron 작업을 실행하세요.

WP-Cron 비활성화 단계:

  1. 파일 관리자 또는 FTP를 사용하여 wp-config.php 파일에 접근하세요.
  2. wp-config.php 파일을 편집하기 위해 여세요.
  3. (기본 wp-config.php를 사용하는 경우) 파일 하단으로 스크롤하세요.
  4. 다음 줄을 찾으세요: /* That’s all, stop editing! Happy publishing. */
  5. 이 줄 위에 다음 코드를 추가하세요: define('DISABLE_WP_CRON', true);
  6. 변경 사항을 저장하고 편집기를 닫으세요.
  7. Apache 및 Nginx 웹 서버를 사용하여 IP 접근 제한을 적용하세요.
    1. Apache의 경우:
      root@kitploit:~
      # Files Directive 
      <Files "wp-cron.php">
          Require ip 127.0.0.1  # localhost only
      </Files>
      
      # FilesMatch Directive
      <FilesMatch "^wp-cron\.php$">
          Require ip 127.0.0.1  # localhost only
      </FilesMatch>
      
      # Location Directive
      <Location "/wp-cron.php">
          Require ip 127.0.0.1  # localhost only
      </Location>
      
    2. Nginx의 경우:
      root@kitploit:~
       location = /wp-cron.php {
           allow 127.0.0.1;
           deny all;
           access_log off;
           log_not_found off;
       }
      

"ALTERNATE_WP_CRON" 활성화 단계:

  1. 파일 관리자 또는 FTP를 사용하여 wp-config.php 파일에 접근하세요.
  2. wp-config.php 파일을 편집하기 위해 여세요.
  3. (기본 wp-config.php를 사용하는 경우) 파일 하단으로 스크롤하세요.
  4. 다음 줄을 찾으세요: /* That’s all, stop editing! Happy publishing. */
  5. 이 줄 위에 다음 코드를 추가하세요: define( 'ALTERNATE_WP_CRON', true );
  6. 변경 사항을 저장하고 편집기를 닫으세요.
  7. Apache 및 Nginx 웹 서버를 사용하여 IP 접근 제한을 적용하세요.
    1. Apache의 경우:
      root@kitploit:~
      # Files Directive 
      <Files "wp-cron.php">
          Require ip 127.0.0.1  # localhost only
      </Files>
      
      # FilesMatch Directive
      <FilesMatch "^wp-cron\.php$">
          Require ip 127.0.0.1  # localhost only
      </FilesMatch>
      
      # Location Directive
      <Location "/wp-cron.php">
          Require ip 127.0.0.1  # localhost only
      </Location>
      
    2. Nginx의 경우:
      root@kitploit:~
       location = /wp-cron.php {
           allow 127.0.0.1;
           deny all;
           access_log off;
           log_not_found off;
       }
      

예시: 시스템 cron(crontab) 사용:

  • 적용하기 전에 먼저 WP-Cron을 비활성화하세요.```

vim /etc/crontab

.. ... */10 * * * * curl http://yourwordpress.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

*/10 * * * * cd /var/www/yourwordpress.com/htdocs; php /var/www/yourwordpress.com/htdocs/wp-cron.php?doing_wp_cron > /dev/null 2>&1

Also can use WP-Cli

*/10 * * * * cd /var/www/example.com/htdocs; wp cron event run --due-now > /dev/null 2>&1

root@kitploit:~
**wp-cron.php를 사용한 DoS 공격 수행에 관하여:**
- wp-cron.php에 과도한 양의 요청을 전송합니다.
- 이로 인해 스크립트가 과도한 리소스를 소비하여 결국 서버가 과부하됩니다.
![7.4.1!](https://assets.kitploit.com/production/public/readmes/6586/b1647fd6883b8d7b3178e7f042290fada6614e9de11a4e6e256f435902b12633.png)
![7.4.2!](https://assets.kitploit.com/production/public/readmes/6586/07d6a5d1794a3ba03177b78f63631eb5fb8f8f6092d6156965535847636d2769.png)


## 8. 보안 WordPress를 위한 시스템 구성
WordPress의 안전한 운영을 위해서는 웹 서버의 적절한 구성과 백엔드 구성 요소의 강화가 필요합니다. 
다음은 확인 및 구현해야 할 몇 가지 필수 항목입니다.

### 8.1. EOL(수명 종료)이 아닌 WordPress 및 PHP 버전 사용 확인
보안 WordPress 설치를 유지하려면 수명 종료(EOL)가 아닌 WordPress 및 PHP 버전을 사용하는 것이 필수적입니다. 
EOL 버전은 더 이상 지원되지 않으며 보안 업데이트를 받지 못하므로 웹사이트가 패치되지 않은 보안 문제에 취약해집니다.

지원되는 버전을 사용하면 발견된 취약점이 신속히 해결되어 잠재적인 공격으로부터 사이트를 보호할 수 있습니다. 
WordPress 및 PHP 버전을 확인하고 업데이트하려면 다음을 수행해야 합니다.

**감사:**
- 현재 WordPress 및 PHP 버전이 EOL이 아닌지 확인합니다.

**수정:**
- EOL이 아닌 WordPress 및 PHP 버전을 설치하고 실행합니다. 
- 2024년 5월 기준 지원되는 WordPress 버전은 6.5 이상입니다. 지원되는 PHP 버전은 8.1, 8.2, 8.3입니다.
- 웹 호스팅 서비스를 사용하는 경우 버전 전환 기능을 활용하여 WordPress와 PHP 모두 지원되는 버전을 실행하고 있는지 확인하십시오.

**2024년 5월 기준 EOL 현황**
 1. PHP: [supported-versions](https://www.php.net/supported-versions.php)
    - 현재 지원되는 버전: 8.1, 8.2, 8.3
 2. WordPress: [current-releases](https://wordpress.org/download/releases/)
    - 현재 지원되는 버전: 6.5 시리즈

**예: RockyLinux 8.5의 PHP**
- RockyLinux 8.5에서 사용 가능한 기본 PHP 버전은 7.2, 7.3, 7.4입니다.
    ```
    # dnf module list php
    Rocky Linux 8 - AppStream
    Name         Stream          Profiles                           Summary                       
    php          7.2 [d]         common [d], devel, minimal         PHP scripting language        
    php          7.3             common [d], devel, minimal         PHP scripting language        
    php          7.4             common [d], devel, minimal         PHP scripting language        
    
    Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled
    
    # dnf module enable php:7.4
    ==============================================================================================
     Package               Architecture         Version               Repository             Size
    ==============================================================================================
    Enabling module streams:
     httpd                                      2.4                                              
     php                                        7.4                                              
    
    Transaction Summary
    ==============================================================================================
    
    Is this ok [y/N]: y
    Complete!
    ```
- PHP 7은 이미 수명 종료(EOL)되었습니다. PHP 8로 업그레이드하는 것이 좋습니다.
- PHP 8은 REMI 저장소에서 설치할 수 있습니다.
- REMI를 사용하여 PHP 8.2를 활성화하고 설치하는 방법의 예는 다음과 같습니다.
    ```
    # Install PHP 8.2 in Rocky Linux 8
    
    # dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
    # dnf -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
    # dnf -y install yum-utils
    # dnf module reset php
    # dnf module install php:remi-8.2
    Last metadata expiration check: 0:00:39 ago on Tue 13 Dec 2022 07:19:26 AM UTC.
    Dependencies resolved.
    =======================================================================================================================================
     Package                       Architecture        Version                                             Repository                 Size
    =======================================================================================================================================
    Installing group/module packages:
     php-cli                       x86_64              8.2.0-1.el8.remi                                    remi-modular              5.4 M
     php-common                    x86_64              8.2.0-1.el8.remi                                    remi-modular              1.3 M
     php-fpm                       x86_64              8.2.0-1.el8.remi                                    remi-modular              1.9 M
     php-mbstring                  x86_64              8.2.0-1.el8.remi                                    remi-modular              574 k
     php-xml                       x86_64              8.2.0-1.el8.remi                                    remi-modular              254 k
    Installing dependencies:
     httpd-filesystem              noarch              2.4.37-51.module+el8.7.0+1059+126e9251              appstream                  41 k
     libxslt                       x86_64              1.1.32-6.el8                                        baseos                    249 k
     oniguruma5php                 x86_64              6.9.8-1.el8.remi                                    remi-safe                 212 k
    Installing weak dependencies:
     nginx-filesystem              noarch              1:1.14.1-9.module+el8.4.0+542+81547229              appstream                  23 k
    Installing module profiles:
     php/common
    Enabling module streams:
     httpd                                             2.4
     nginx                                             1.14
     php                                               remi-8.2
    
    Transaction Summary
    =======================================================================================================================================
    Install  9 Packages
    
    # dnf update
    # dnf install php
    Last metadata expiration check: 0:00:23 ago on Tue 13 Dec 2022 07:29:55 AM UTC.
    Dependencies resolved.
    =======================================================================================================================================
     Package                       Architecture       Version                                               Repository                Size
    =======================================================================================================================================
    Installing:
     php                           x86_64             8.2.0-1.el8.remi                                      remi-modular             1.8 M
    Installing dependencies:
     apr                           x86_64             1.6.3-12.el8                                          appstream                128 k
     apr-util                      x86_64             1.6.1-6.el8.1                                         appstream                104 k
     httpd                         x86_64             2.4.37-51.module+el8.7.0+1059+126e9251                appstream                1.4 M
     httpd-tools                   x86_64             2.4.37-51.module+el8.7.0+1059+126e9251                appstream                108 k
     libsodium                     x86_64             1.0.18-2.el8                                          epel                     162 k
     mailcap                       noarch             2.1.48-3.el8                                          baseos                    38 k
     mod_http2                     x86_64             1.15.7-5.module+el8.6.0+823+f143cee1                  appstream                153 k
     rocky-logos-httpd             noarch             86.3-1.el8                                            baseos                    24 k
    Installing weak dependencies:
     apr-util-bdb                  x86_64             1.6.1-6.el8.1                                         appstream                 23 k
     apr-util-openssl              x86_64             1.6.1-6.el8.1                                         appstream                 26 k
     php-opcache                   x86_64             8.2.0-1.el8.remi                                      remi-modular             633 k
     php-pdo                       x86_64             8.2.0-1.el8.remi                                      remi-modular             166 k
     php-sodium                    x86_64             8.2.0-1.el8.remi                                      remi-modular             105 k
    
    Transaction Summary
    =======================================================================================================================================
    Install  14 Packages
    
    Total download size: 4.8 M
    Installed size: 14 M
    Is this ok [y/N]: y
    
    # php -v
    PHP 8.2.0 (cli) (built: Dec  6 2022 14:26:47) (NTS gcc x86_64)
    Copyright (c) The PHP Group
    Zend Engine v4.2.0, Copyright (c) Zend Technologies
        with Zend OPcache v8.2.0, Copyright (c), by Zend Technologies
    ```
**참고:**
- REMI 저장소에서 PHP 설치에 대한 자세한 지침은 다음을 참조하십시오: [rpms.remirepo.net](https://rpms.remirepo.net/)
- WordPress와 PHP 호환성에 관한 문서: [php-compatibility-and-wordpress-versions](https://make.wordpress.org/core/handbook/references/php-compatibility-and-wordpress-versions/)


### 8.2. WordPress에 필요한 PHP 확장만 활성화되어 있는지 확인
WordPress 사이트에 필요한 PHP 확장만 활성화되어 있는지 확인하십시오. 
불필요한 확장은 웹사이트의 공격 표면을 증가시키고 WordPress를 보안 취약점에 노출시킬 수 있습니다. 

필요한 확장만 활성화하면 잠재적 위험을 최소화하고 전반적인 보안을 향상시킬 수 있습니다.

아래는 WordPress 사이트가 제대로 작동하는 데 필요한 확장입니다. **(보안 강화 목적에 맞는 목록이 아닙니다.)**

| 확장       | 설명                                                                                                                                                                                                                                        |
|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| json      | 다른 서버와의 통신 및 JSON 형식 데이터 처리에 사용됩니다.                                                                                                                                                                     |
| mysqli    | 데이터베이스 상호 작용을 위해 MySQL에 연결합니다.                                                                                                                                                                                                       |
| curl      | 원격 요청 작업을 수행합니다.                                                                                                                                                                                                                |
| dom       | 텍스트 위젯 콘텐츠 검증 및 IIS7+ 자동 구성에 사용됩니다.                                                                                                                                                                         |
| exif      | 이미지에 저장된 메타데이터 작업에 사용됩니다.                                                                                                                                                                                                              |
| fileinfo  | 파일 업로드의 mimetype 감지에 사용됩니다.                                                                                                                                                                                                           |
| hash      | 비밀번호 및 업데이트 패키지를 포함한 해싱에 사용됩니다.                                                                                                                                                                                         |
| igbinary  | 표준 PHP 직렬화 도구의 대체품으로 성능을 향상시킵니다.                                                                                                                                                                    |
| imagick   | 미디어 업로드를 위한 더 나은 이미지 품질을 제공합니다. 자세한 내용은 WP_Image_Editor를 참조하십시오. Ghost Script도 사용 가능한 경우 스마트 이미지 크기 조정(작은 이미지용) 및 PDF 썸네일 지원을 제공합니다.                                                      |
| intl      | 형식 지정, 변환, 인코딩 변환, 달력 작업, 정렬, 텍스트 경계 찾기, 로케일 식별자, 시간대 및 그래핀 작업 등 로케일 인식 작업을 가능하게 합니다. |
| mbstring  | UTF8 텍스트를 적절히 처리하는 데 사용됩니다.                                                                                                                                                                                                                 |
| openssl   | 다른 호스트로의 SSL 기반 연결에 사용됩니다.                                                                                                                                                                                                              |
| pcre      | 코드 검색에서 패턴 일치 성능을 향상시킵니다.                                                                                                                                                                                        |
| xml       | 타사 사이트의 XML 파싱 등에 사용됩니다.                                                                                                                                                                                             |
| zip       | 플러그인, 테마 및 WordPress 업데이트 패키지의 압축 해제에 사용됩니다.                                                                                                                                                                             |
| bc        | 2147483647 소수 자릿수까지 모든 크기와 정밀도의 숫자를 지원하는 임의 정밀도 수학을 위한 확장입니다.                                                                                                                             | 
| filter    | 사용자 입력을 안전하게 필터링하는 데 사용됩니다.                                                                                                                                                                                                            |
| image     | Imagick이 설치되지 않은 경우 GD 그래픽 라이브러리가 이미지 조작을 위한 기능적으로 제한된 대체재로 사용됩니다.                                                                                                                             |
| iconv     | 문자 집합 간 변환에 사용됩니다.                                                                                                                                                                                                            |
| shmop     | PHP가 Unix 공유 메모리 세그먼트를 읽고, 쓰고, 생성하고, 삭제할 수 있도록 하는 사용하기 쉬운 함수 집합입니다.                                                                                                                            |
| simplexml | XML 파싱에 사용됩니다.                                                                                                                                                                                                                              |
| sodium    | 서명을 검증하고 안전한 임의 바이트를 제공합니다.                                                                                                                                                                                           |
| xmlreader | XML 파싱에 사용됩니다.                                                                                                                                                                                                                              |
| zlib      | Gzip 압축 및 압축 해제.                                                                                                                                                                                                                                |

필수 확장은 다음에서 확인할 수 있습니다: [WordPress Hosting Handbook: PHP Extensions](https://make.wordpress.org/hosting/handbook/server-environment/#php-extensions)

**감사:**
- WordPress 사이트에 필요한 PHP 확장만 활성화되어 있는지 확인합니다.

**수정:**
- 불필요한 확장을 제거하십시오. 때로는 사이트에 필요하지 않은 확장이 플러그인과 함께 설치될 수 있습니다.
- 현재 활성화된 PHP 확장을 확인하려면 **php.ini** 파일을 검토하거나 **phpinfo()** 함수를 사용하여 모든 활성 확장을 나열할 수 있습니다.

![8.2!](https://assets.kitploit.com/production/public/readmes/6586/1e270a242227b8dc8fa965765c69b7927b170de108acdbe1fad91455e484e615.png)

- 필요하지 않은 특정 확장은 잠재적 보안 문제를 방지하기 위해 비활성화해야 합니다. 
- 예를 들어, exif, fileinfo, imap, soap, pdo_sqlite, opcache와 같은 확장은 적절히 사용되지 않고 활성화된 상태로 남겨질 경우 악용될 수 있습니다.
- 웹 호스팅 서비스를 사용하는 경우 많은 제공업체에서 PHP 확장 활성화 또는 비활성화를 포함한 PHP 설정을 변경할 수 있는 사용하기 쉬운 인터페이스를 제공합니다. 이러한 기능을 사용하여 확장을 효과적으로 관리할 수 있습니다.


### 8.3. 파일 업로드 기능이 있는 플러그인의 보안 확인
파일 업로드 기능이 있는 플러그인은 적절히 보호되지 않으면 심각한 보안 위험이 될 수 있습니다. 파일 업로드 기능의 취약점으로 인해 공격자가 웹 셸을 업로드하여 전체 시스템을 손상시킬 수 있습니다. 따라서 모든 파일 업로드 기능에는 유효성 검사 및 삭제 메커니즘이 포함되어야 합니다.

이것이 중요한 이유는 무엇입니까?
1. 확장자 검증:
   - 서버는 허용된 유형의 화이트리스트에 대해 파일 확장자를 검증하여 악성 파일 업로드를 방지해야 합니다.

2. MIME 유형 확인:
   - 파일의 MIME 유형이 예상 유형과 일치하는지 확인하여 추가 보안 계층을 제공해야 합니다.

3. 업로드 경로 제한:
   - 검증 없이 업로드된 파일에 직접 액세스할 수 있는 노출된 경로가 없도록 해야 합니다.

파일 업로드 취약점은 공격자가 실행 코드를 업로드하고 임의 명령을 실행할 수 있는 직접적인 경로를 제공하기 때문에 특히 위험합니다. 파일 업로드 취약점은 SQL 인젝션과 같은 다른 보안 결함에 비해 식별 및 악용이 더 쉬운 경우가 많습니다.

**감사:**
- WordPress 사이트에서 파일 업로드 기능이 있는 플러그인을 식별합니다.
- 이러한 플러그인이 업로드된 파일에 대해 확장자 및 MIME 유형 검증을 포함한 적절한 검증 검사를 구현하는지 확인합니다.

**수정:**
- 파일 업로드 기능이 있는 플러그인에 적절한 검증이 없는 경우 보안을 강화하거나 플러그인을 제거하십시오.
- 다음은 파일 업로드 기능이 있는 인기 WordPress 플러그인과 파일 검증 처리 방법의 예입니다.

**예: 파일 업로드 처리가 있는 인기 WordPress 플러그인**

1. Contact Form 7
   - Contact Form 7은 WordPress에서 가장 널리 사용되는 양식 플러그인 중 하나입니다. 확장자 및 MIME 유형 검증이 포함된 기본 파일 업로드 기능을 제공합니다.**허용된 확장자 및 MIME 유형 확인 코드:**

function wpcf7_allowed_file_extensions() { // Default allowed file extensions $allowed_file_extensions = array( 'jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'txt', 'csv', 'rtf', 'html', 'zip' ); return $allowed_file_extensions; }

function wpcf7_handle_upload( $file ) { $allowed_mime_types = wpcf7_allowed_file_extensions(); $file_type = wp_check_filetype( $file['name'] );

root@kitploit:~
 // Check if the file type is allowed
 if ( ! in_array( $file_type['ext'], $allowed_mime_types ) ) {
     return new WP_Error( 'wpcf7_upload_failed', __( 'File type is not allowed.', 'contact-form-7' ) );
 }

 // Handle the file upload
 $upload = wp_handle_upload( $file, array( 'test_form' => false ) );

 // Check if the upload was successful
 if ( isset( $upload['error'] ) ) {
     return new WP_Error( 'wpcf7_upload_failed', $upload['error'] );
 }

 return $upload;

}

root@kitploit:~
Contact Form 7에서 `wpcf7_allowed_file_extensions()` 함수는 허용된 파일 확장자 목록을 반환하며, `wpcf7_handle_upload()` 함수는 업로드를 진행하기 전에 파일 확장자가 이 목록에 있는지 확인합니다.

2. WPForms
   - WPForms는 허용된 파일 유형을 확인하여 파일 업로드를 처리합니다.

   **WPForms 예제 코드:**
root@kitploit:~
function wpforms_get_file_types() {
    // Return an array of allowed file types
    return array( 'jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx' );
}

function wpforms_process_file_upload( $file ) {
    $allowed_file_types = wpforms_get_file_types();
    $file_type = wp_check_filetype( $file['name'] );

    if ( ! in_array( $file_type['ext'], $allowed_file_types ) ) {
        return new WP_Error( 'wpforms_upload_failed', __( 'File type is not allowed.', 'wpforms' ) );
    }

    $upload = wp_handle_upload( $file, array( 'test_form' => false ) );

    if ( isset( $upload['error'] ) ) {
        return new WP_Error( 'wpforms_upload_failed', $upload['error'] );
    }

    return $upload;
}
```

3. WooCommerce

  • WooCommerce도 업로드 처리 코드에서 직접 허용된 파일 확장자를 정의하고 확인합니다.

WooCommerce 예제 코드:

root@kitploit:~
 function woocommerce_handle_upload( $file ) {
     $allowed_file_types = array( 'jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx' );
     $file_type = wp_check_filetype( $file['name'] );

     if ( ! in_array( $file_type['ext'], $allowed_file_types ) ) {
         return new WP_Error( 'woocommerce_upload_failed', __( 'File type is not allowed.', 'woocommerce' ) );
     }

     $upload = wp_handle_upload( $file, array( 'test_form' => false ) );

     if ( isset( $upload['error'] ) ) {
         return new WP_Error( 'woocommerce_upload_failed', $upload['error'] );
     }

     return $upload;
 }
 ```

**예제: 악성 파일 업로드 플러그인**
- 악성 플러그인은 순수해 보일 수 있지만 fileinfo 확장을 악용하여 보안 검사를 우회할 수 있습니다:
 ```
 <?php
 /*
 Plugin Name: Simple Malicious Upload
 Description: A plugin with hidden malicious file upload capability.
 Version: 1.0
 */
 
 function simple_file_upload_menu() {
     add_menu_page('File Upload', 'File Upload', 'manage_options', 'file-upload', 'simple_file_upload_page');
 }
 
 add_action('admin_menu', 'simple_file_upload_menu');
 
 function simple_file_upload_page() {
     ?>
     <h1>File Upload</h1>
     <form method="post" enctype="multipart/form-data">
         <input type="file" name="uploaded_file" />
         <input type="submit" name="upload_file" value="Upload" />
     </form>
     <?php
 
     if (isset($_POST['upload_file'])) {
         simple_handle_file_upload();
     }
 }
 
 function simple_handle_file_upload() {
     if (!empty($_FILES['uploaded_file']['tmp_name'])) {
         $file_tmp = $_FILES['uploaded_file']['tmp_name'];
         $file_name = basename($_FILES['uploaded_file']['name']);
 
         // Using fileinfo to check MIME type
         $finfo = finfo_open(FILEINFO_MIME_TYPE);
         $mime_type = finfo_file($finfo, $file_tmp);
         finfo_close($finfo);
 
         // Insecure handling: allows any PHP files to be uploaded
         if ($mime_type === 'text/plain' || $mime_type === 'application/x-php') {
             $upload_dir = wp_upload_dir();
             $upload_file = $upload_dir['path'] . '/' . $file_name;
 
             // Move the uploaded file to the uploads directory
             if (move_uploaded_file($file_tmp, $upload_file)) {
                 echo "File uploaded successfully.";
             } else {
                 echo "File upload failed.";
             }
         } else {
             echo "Invalid file type.";
         }
     }
 }
 ?>
 ```
**익스플로잇 설명:**
- 악성 플러그인은 MIME 유형이 `application/x-php.`인 경우 PHP 파일을 업로드할 수 있습니다.
- 공격자는 이 기능을 사용하여 PHP 웹 셸을 업로드할 수 있습니다.
- 업로드되면 공격자는 파일의 URL에 접근하여 임의의 명령을 실행할 수 있습니다.

**예제: PHP 웹 셸 코드**```
<?php
if (isset($_GET['cmd'])) {
 echo "<pre>";
 system($_GET['cmd']);
 echo "</pre>";
}
?>

공격 시연

  1. 웹 셸 업로드:
    • 공격자는 플러그인의 업로드 폼을 통해 webshell.php를 업로드합니다.
  2. 웹 셸 접근 및 사용:
    • 공격자는 http://yourwordpress.com/wp-content/uploads/webshell.php에서 웹 셸에 접근합니다.
    • http://yourwordpress.com/wp-content/uploads/webshell.php?cmd=ls로 이동하여 임의 명령을 실행할 수 있습니다.

참고:

  • 이 예시는 파일 업로드 기능이 있는 플러그인이 어떻게 오용될 수 있는지 설명하기 위한 것입니다.
  • 적절한 검증 및 이스케이프 처리를 보장하면 잠재적인 악용을 방지하고 WordPress 사이트의 보안을 유지할 수 있습니다.
  • 위 플러그인 코드는 교육 목적으로만 제공됩니다.

8.4. PHP 함수 및 설정이 제대로 구성되었는지 확인

PHP 함수와 설정이 올바르게 구성되면 WordPress 사이트의 보안을 크게 강화할 수 있습니다. 잘못 구성된 설정은 원격 코드 실행, 정보 노출, 세션 하이재킹 등 다양한 취약점에 사이트를 노출시킬 수 있습니다. 이러한 함수를 비활성화하거나 적절히 구성하여 PHP를 강화하는 것이 중요합니다.

왜 중요한가?

  1. 원격 코드 실행:

    • allow_url_fopen과 같은 설정과 exec 같은 함수는 원격 코드 실행을 가능하게 하여 시스템 손상으로 이어질 수 있습니다.
  2. 정보 노출:

    • display_errors 및 expose_php 같은 옵션은 서버 설정에 대한 민감한 정보를 유출하여 공격자가 취약점을 찾기 쉽게 만듭니다.
  3. 세션 보안:

    • session.cookie_secure 및 session.cookie_httponly와 같은 적절한 세션 관리 설정은 세션 쿠키가 클라이언트 측 스크립트를 통해 접근되거나 안전하지 않은 채널을 통해 전송되는 것을 방지합니다.

감사:

  • 아래 나열된 안전하지 않은 PHP 함수와 설정이 적절히 구성되고 강화되었는지 확인하십시오.

수정:

  • 다음 PHP 설정과 함수를 검토하고, WordPress 사이트의 안전한 운영과 기능을 모두 보장하도록 조정하십시오.
  1. allow_url_fopen:

    • 함수가 URL을 통해 파일을 열고 읽을 수 있도록 허용합니다.
    • 활성화되면 file_get_contents(), fopen(), include(), require() 같은 함수가 FTP 또는 HTTP를 통해 원격 위치에서 데이터를 검색할 수 있습니다.
    • WordPress 및 많은 WordPress 플러그인은 다양한 기능을 위해 allow_url_fopen이 필요할 수 있습니다.
    • 하지만 이 설정을 항상 활성화할 필요는 없습니다.
    • 보안상 필요할 때만 활성화하는 것이 좋습니다.
      root@kitploit:~
      ; (선택사항) allow_url_fopen이 필요하지 않으면 비활성화
      
       allow_url_fopen = Off
      
  2. display_errors:

    • PHP 오류를 출력의 일부로 화면에 출력할지 결정합니다.
    • 오류를 표시하면 서버 환경 및 애플리케이션에 대한 민감한 정보가 노출되어 공격자가 취약점을 악용하는 데 사용할 수 있습니다.
      root@kitploit:~
      ; WordPress 웹사이트에 PHP 오류가 표시되지 않도록 비활성화
      
      display_errors = Off
      
  3. expose_php:

    • PHP가 HTTP 헤더에 자신의 존재와 버전을 알릴지 제어합니다.
    • 이 정보를 노출하면 공격자가 취약한 PHP 버전을 식별하는 데 도움이 될 수 있습니다.
      root@kitploit:~
      ; HTTP 응답 헤더에서 PHP 버전 노출 방지
      
      expose_php = Off
      session.cookie_secure
      
  4. session.cookie_secure:

    • 세션 쿠키가 안전한 HTTPS 연결을 통해서만 전송되도록 보장하여 전송 중 가로채기를 방지합니다.
      root@kitploit:~
      ; 세션 쿠키가 HTTPS를 통해 전송되도록 설정
      
      session.cookie_secure = On
      session.cookie_httponly
      
  5. session.cookie_httponly:

    • 세션 쿠키를 JavaScript에서 접근할 수 없게 만들어 사이트 간 스크립팅(XSS) 공격의 위험을 완화합니다.
      root@kitploit:~
      ; 세션 쿠키를 JavaScript에서 접근 불가능하게 설정
      
      session.cookie_httponly = On
      

예시: 다음은 실제 WordPress에서 비활성화된 PHP 함수 목록입니다.``` system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail

root@kitploit:~
### 8.5. 웹 서버가 루트 사용자가 아닌 계정으로 실행되도록 보장 - 서버 애플리케이션을 위한 고유하고 권한이 없는 사용자 및 그룹
대부분의 경우 웹 서버는 "www-data"(Debian/Ubuntu) 또는 "apache"(RHEL/CentOS)와 같은 사용자로 실행됩니다.

이러한 사용자는 서버에 특별한 권한이 없는 전용 서비스 계정이며, 웹 서버 작업자 프로세스가 사용할 사용자와 그룹을 지정하는 데 사용됩니다.

이러한 사용자에게 시스템 권한이 있거나 루트로 실행 중인 경우 변경해야 합니다.

**감사(Audit):**
- 웹 서버 프로세스를 실행 중인 사용자를 확인합니다. (특히 웹 서버 작업자 프로세스입니다.)

1. Apache의 경우:
    ```
    # ps -ef | grep httpd
    root     2257     1  0 Apr08 ?        00:00:01 /usr/local/apache/bin/httpd -k start
    apache   5678  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
    apache   5679  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
    apache   5680  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
    apache   5681  1234  0 Apr08 ?        00:00:00 /usr/sbin/httpd -k start
    ```

2. Nginx의 경우:
    ```
    # ps -ef | grep nginx
    root      626653       1  0 Apr08 ?        00:00:00 nginx: master process /usr/sbin/nginx
    nginx     626654  626653  0 Apr08 ?        00:00:00 nginx: worker process
    nginx     626655  626653  0 Apr08 ?        00:00:00 nginx: worker process
    nginx     626656  626653  0 Apr08 ?        00:00:00 nginx: worker process
    nginx     626657  626653  0 Apr08 ?        00:00:00 nginx: worker process
    ```

**수정(Remediation):**
- 웹 서버는 권한이 없는 전용 계정으로 실행되어야 합니다.
- 대부분의 경우 "www-data", "apache", "nginx", "nobody", 또는 "daemon"과 같은 일반적으로 사용되는 계정 중 하나가 사용됩니다.

1. Apache의 경우:
    ```
    # vim /etc/httpd/httpd.conf
    ..
    ...
    User www-data
    Group www-data
    ..
    ...
    ```

2. Nginx의 경우:
    ```
    # vim /etc/nginx/nginx.conf
    ..
    ...
    user daemon;
    ```

**참고(Note):**
- 웹 서버의 프로세스 사용자는 셸 로그인 권한이 없어야 합니다.  ```
  # cat /etc/passwd | grep -i www-data
  www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

8.6. PHP-FPM이 루트가 아닌 사용자로 실행되도록 보장 - 서버 애플리케이션을 위한 고유한 권한 없는 사용자와 그룹

WordPress는 PHP로 구축되었으므로, PHP 코드를 제대로 실행하기 위해 올바른 시스템 구성이 필요합니다.

WordPress에서 PHP 코드 실행은 FastCGI 프로세스 관리자인 PHP-FPM에 의해 관리됩니다. PHP-FPM의 안전한 작동을 보장하려면 권한이 없는 전용 서비스 계정으로 실행되어야 합니다.

일반적으로 웹 서버 프로세스 계정과 PHP-FPM 계정은 동일한 계정으로 설정됩니다. 그러나 보안 강화를 위해서는 별도의 계정으로 실행하는 것이 좋습니다.

두 가지 이유는 다음과 같습니다:

  1. 프로세스 분리:

    • 웹 서버와 PHP-FPM을 별도의 계정으로 실행하면 프로세스가 분리됩니다.
    • 이는 한 서비스의 손상이 다른 서비스에 영향을 미칠 위험을 줄입니다.
    • 공격자가 웹 서버 프로세스에 접근하더라도 PHP-FPM에 반드시 접근할 수 있는 것은 아니며, 그 반대의 경우도 마찬가지입니다.
  2. 최소 권한 원칙:

    • 각 서비스에 전용의 권한 없는 계정을 사용하면 최소 권한 원칙을 준수할 수 있습니다.
    • 이는 각 서비스가 가진 권한과 접근을 제한하여 보안 취약점이나 침해로 인한 잠재적 피해를 최소화합니다.

감사:

  • PHP-FPM 프로세스를 실행하는 계정을 확인하십시오.```

ps -ef | grep php-fpm

root 1234 1 0 12:00 ? 00:00:01 php-fpm: master process (/etc/php-fpm.conf) php-fpm 5678 1234 0 12:00 ? 00:00:00 php-fpm: pool www php-fpm 5679 1234 0 12:00 ? 00:00:00 php-fpm: pool www php-fpm 5680 1234 0 12:00 ? 00:00:00 php-fpm: pool www php-fpm 5681 1234 0 12:00 ? 00:00:00 php-fpm: pool www

root@kitploit:~
**수정 방법:**
- PHP-FPM은 권한이 없는 전용 계정으로 실행되어야 합니다.
- 대부분의 경우 사용되는 계정은 "php-fpm"입니다.

**PHP-FPM 프로세스 계정 변경:**```
# vim /etc/php-fpm.d/www.conf # Adjust the path based on your PHP version
...
user = php-fpm
group = php-fpm
listen.owner = php-fpm 
listen.group = php-fpm 

PHP-FPM 프로세스 계정은 쉘 로그인 권한을 가져서는 안 됩니다.```

cat /etc/passwd | grep php-fpm

php-fpm❌999:999:PHP-FPM:/run/php:/usr/sbin/nologin

root@kitploit:~
**참고:**
- PHP-FPM 프로세스와 웹 서버 프로세스에 서로 다른 사용자 계정을 사용하는 것이 보안 관점에서 바람직합니다.
- 보안 측면에서 어느 것이 더 나은지 질문받을 경우, 서로 달라야 합니다. 이 맥락에서 동일한 실행 계정을 사용하지 마십시오.


### 8.7. WordPress 홈 디렉터리의 안전한 구성 보장

웹 서버를 안전하게 운영하려면 WordPress 홈 디렉터리의 소유권과 권한을 적절히 구성하는 것이 중요합니다.

대부분의 경우 WordPress 파일 및 디렉터리의 소유권과 권한은 웹 서버의 프로세스 계정과 일치하도록 설정됩니다.
이 구성은 웹 서버가 웹 루트의 파일에 접근하고 오류 없이 작동할 수 있게 합니다.

그러나 이 구성은 안전하지 않습니다.

예를 들어, 웹 서버 프로세스가 'apache'이고 웹 루트 디렉터리와 파일 모두 'apache'가 소유한 경우 심각한 취약점으로 이어질 수 있습니다.
공격자는 이러한 취약점을 악용하여 WordPress 홈 디렉터리 내의 중요 파일 및 디렉터리에 무단 접근할 수 있습니다.

**일반적인 취약점 예시:**
- 웹 서버 프로세스 계정과 홈 디렉터리(웹 루트) 및 파일이 모두 'apache'가 소유한 경우:
- 웹사이트의 취약점 및 시스템에 대한 외부 접근(예: 웹쉘)이 있는 경우, 공격자는 웹 루트 내에서 다양한 작업을 수행할 수 있습니다:
  1. 웹 루트 내의 파일 또는 디렉터리를 생성, 수정 또는 삭제합니다.
  2. 웹 접근 로그를 수정, 삭제 또는 생성하는 등 조작합니다. (일부 환경 제외)
  3. 로그인된 사용자의 활성 세션 쿠키에 접근할 수 있습니다. (특히 취약한 환경에서)

이러한 위험을 완화하려면 WordPress 홈 디렉터리의 소유권과 권한을 적절히 조정하는 것이 중요합니다.

**수정 방법:**
- 홈 디렉터리(웹 루트) 및 파일의 소유자를 'root:root'로 설정합니다. (웹 서버 프로세스 계정과 동일하게 설정하지 마십시오)
- 디렉터리 및 파일의 기본 UMASK는 022입니다. (디렉터리: 755, 파일: 644)
- 웹 서비스에 의한 파일 업로드 등 쓰기 권한이 필요한 디렉터리의 경우 해당 디렉터리의 소유자를 웹 서버 프로세스 계정으로 설정합니다.

**WordPress에서 일반적으로 쓰기 권한이 필요한 디렉터리:**```
/wp-content/uploads
/wp-content/cache
/wp-content/wflogs (when using security plugins like Wordfence)
/wp-content/upgrade (used during the WordPress upgrade process)

위의 복구 조치에 따라 홈 디렉토리의 소유권과 권한을 구성한 후, WordPress 홈 디렉토리의 출력은 다음과 같습니다:

예시: WordPress 홈 디렉토리``` drwxr-xr-x 5 root root 4096 May 27 2024 . drwxr-xr-x 3 root root 4096 May 27 2024 .. -rw-r--r-- 1 root root 418 May 27 2024 index.php -rw-r--r-- 1 root root 19935 May 27 2024 license.txt -rw-r--r-- 1 root root 7346 May 27 2024 readme.html -rw-r--r-- 1 root root 7106 May 27 2024 wp-activate.php drwxr-xr-x 9 root root 4096 May 27 2024 wp-admin -rw-r--r-- 1 root root 351 May 27 2024 wp-blog-header.php -rw-r--r-- 1 root root 2328 May 27 2024 wp-comments-post.php -rw-r--r-- 1 root root 4973 May 27 2024 wp-config-sample.php -rw-r--r-- 1 root root 2755 May 27 2024 wp-config.php drwxr-xr-x 8 root root 4096 May 27 2024 wp-content -rw-r--r-- 1 root root 3940 May 27 2024 wp-cron.php drwxr-xr-x 25 root root 12288 May 27 2024 wp-includes -rw-r--r-- 1 root root 2496 May 27 2024 wp-links-opml.php -rw-r--r-- 1 root root 3300 May 27 2024 wp-load.php -rw-r--r-- 1 root root 51556 May 27 2024 wp-login.php -rw-r--r-- 1 root root 8403 May 27 2024 wp-mail.php -rw-r--r-- 1 root root 24568 May 27 2024 wp-settings.php -rw-r--r-- 1 root root 30869 May 27 2024 wp-signup.php -rw-r--r-- 1 root root 4620 May 27 2024 wp-trackback.php -rw-r--r-- 1 root root 3065 May 27 2024 xmlrpc.php

root@kitploit:~
**In case php-fpm and web server process accounts are different (Separate Permissions)**

웹 서버 프로세스 계정이 "apache"이고 php-fpm 프로세스 계정이 "php-fpm"인 경우.

WordPress에서 쓰기 권한이 필요한 디렉터리(예: /wp-content/uploads)의 권한을 변경합니다.
- 소유자: php-fpm
- 그룹: apache
- 디렉터리 권한: 775 (필요시 755)

**File and Directory Structure**

필요한 디렉터리에 대해 "php-fpm"과 "apache" 계정이 모두 쓸 수 있도록 쓰기 권한을 설정합니다.```
ex) /service/wordpress/www
├── index.php             (root:root, 644)
├── license.txt           (root:root, 644)
├── readme.html           (root:root, 644)
├── wp-activate.php       (root:root, 644)
├── wp-admin/             (root:root, 755)
├── wp-blog-header.php    (root:root, 644)
├── wp-comments-post.php  (root:root, 644)
├── wp-config-sample.php  (root:root, 644)
├── wp-config.php         (root:root, 644)
├── wp-content/           (root:root, 755)
│   ├── plugins/          (root:root, 755)
│   ├── themes/           (root:root, 755)
│   ├── uploads/          (php-fpm:apache, 775)
│   │   ├── 2024/         (php-fpm:apache, 775)
│   │   └── ...           (php-fpm:apache, 775)
│   └── ...               (root:root, 755)
├── wp-cron.php           (root:root, 644)
├── wp-includes/          (root:root, 755)
├── wp-links-opml.php     (root:root, 644)
├── wp-load.php           (root:root, 644)
├── wp-login.php          (root:root, 644)
├── wp-mail.php           (root:root, 644)
├── wp-settings.php       (root:root, 644)
├── wp-signup.php         (root:root, 644)
├── wp-trackback.php      (root:root, 644)
└── xmlrpc.php            (root:root, 644)

요약

  1. 웹 서버 워커 프로세스 계정: "www-data" 또는 "apache" 또는 "nginx"
  2. PHP-FPM 프로세스 계정: "php-fpm"
  3. WordPress 디렉터리 설정:
    • 홈 디렉터리:
      • 소유권: root:root
      • 디렉터리 권한: 755
      • 파일 권한: 644
    • 쓰기 필요한 디렉터리
      • 소유권: "php-fpm:www-data"
      • 디렉터리 권한: 775 (필요 시 755)

이렇게 설정하면 웹 서버와 PHP-FPM의 권한을 분리하고, 홈 디렉터리의 소유권 및 권한 설정을 올바르게 적용하여 보안을 강화할 수 있습니다.

이 방법은 WordPress뿐만 아니라 웹 콘텐츠를 제공하는 모든 웹 서버 구조에 적용됩니다.

8.8. 쓰기 가능 디렉터리에서 PHP 실행 비활성화 확인

파일 업로드가 가능한 디렉터리에서 PHP 실행을 비활성화하는 것은 안전한 환경을 유지하는 데 중요합니다.

쓰기 권한이 있는 업로드 디렉터리는 공격자가 웹 셸과 같은 악성 스크립트를 업로드하여 서버를 손상시킬 수 있는 잠재적인 대상입니다.

왜 이것이 중요한가요?

  1. 웹 셸 공격 완화:

    • 업로드 디렉터리에서 PHP 스크립트 실행을 차단하면 서버 전체가 손상될 수 있는 웹 셸 공격의 위험을 완화합니다.
  2. 공격 표면 감소:

    • 파일 쓰기가 가능한 디렉터리에서 PHP 실행을 비활성화하면 공격 표면이 줄어들어 공격자가 취약점을 악용하기 어려워집니다.
  3. 보안 모범 사례 준수:

    • 적절한 권한 및 실행 설정을 보장하는 것은 보안 모범 사례와 일치하여 추가적인 방어 계층을 제공합니다.

감사:

  • 쓰기 가능한 디렉터리(예: 업로드 디렉터리)가 PHP 스크립트 실행을 방지하도록 구성되었는지 확인합니다.

해결 방법:

  • 웹 서버(Apache 또는 Nginx)를 구성하여 /wp-content/uploads 디렉터리와 같은 쓰기 권한이 있는 디렉터리에서 PHP 실행을 비활성화합니다.

구성 단계

  1. 업로드 디렉터리에서 파일 다운로드 설정
    • Apache의 경우:
      root@kitploit:~
      <Location "/wp-content/uploads">
          SetHandler application/octet-stream
      </Location>
      
    • Nginx의 경우:
      root@kitploit:~
      location /wp-content/uploads {
          default_type application/octet-stream;
      }
      
  2. 업로드 디렉터리에서 PHP 실행 비활성화
    • Apache의 경우:
      root@kitploit:~
      <Location "/wp-content/uploads">
          php_flag engine off
          # or alternatively
          php_value engine 0
      </Location>
      
       <Location "/wp-content/uploads">
           <FilesMatch "\.php$">
               SetHandler none
               Require all denied
           </FilesMatch>
       </Location>
       
       <Directory "/var/www/html/yourwordpress/wp-content/uploads">
           # Disable PHP execution
           <FilesMatch "\.php$">
               SetHandler none
               Require all denied
           </FilesMatch>
       </Directory>
      
    • Nginx의 경우:
      root@kitploit:~
      location /wp-content/uploads {
          location ~ \.php$ {
              fastcgi_pass off;
          }
      }
      
       location /wp-content/uploads {
           location ~ \.php$ {
               deny all;
           }
       }
      

이러한 구성은 PHP 파일이 /wp-content/uploads 디렉터리에 업로드되더라도 실행될 수 없도록 하여 잠재적인 공격을 방지합니다.

구성 지시어 설명

  1. SetHandler application/octet-stream:

    • 파일을 이진 스트림으로 처리하도록 강제하여 실행 대신 다운로드하도록 유도합니다.
  2. php_flag engine off / php_value engine 0:

    • 지정된 디렉터리에 대해 PHP 엔진을 비활성화하여 PHP 스크립트가 실행되지 않도록 합니다.
  3. SetHandler none:

    • 일치하는 파일에 대한 핸들러를 해제하여 PHP로 처리되지 않도록 합니다.

참고:

  • 위 설정은 이미지 파일 표시에 영향을 주지 않습니다.
  • 예를 들어, /wp-content/uploads 디렉터리에 있는 이미지 파일은 태그를 사용하여 여전히 접근 가능하고 올바르게 표시됩니다:``` Example Image
root@kitploit:~
이러한 구성을 적용하면 잠재적인 스크립트 실행 취약점으로부터 업로드 디렉터리를 크게 강화할 수 있습니다.


### 8.9. 웹 서버가 도메인 기반 호스트 헤더에만 응답하도록 보장
웹 서버를 안전하게 보호하려면 서버의 IP 주소로 직접 요청하는 것이 아닌 도메인 이름으로 요청하는 경우에만 응답하도록 하는 것이 중요합니다.

이는 VirtualHost 지시문의 적절한 구성을 통해 달성할 수 있습니다.

대부분의 경우 웹 서비스는 `https://yourwordpress.com`과 같은 도메인 이름을 통해 접근됩니다. 웹 서버는 이 요청을 수신하여 적절한 콘텐츠를 제공합니다. 이 동작을 강제하려면 올바른 Host 헤더가 있는 요청에만 응답하도록 웹 서버를 구성해야 합니다.

**IP 기반 접근 허용 시 잠재적 보안 위험**
1. 서비스 열거:
   - 공격자는 IP 주소를 사용하여 서버에서 실행 중인 서비스를 열거할 수 있으며, 이로 인해 취약점을 발견하고 악용할 위험이 증가합니다.
2. 민감한 정보 노출:
   - 잘못 구성된 서버는 IP를 통해 접근할 때 공개적으로 접근할 수 없어야 하는 디렉터리, 파일 또는 기타 민감한 정보를 노출할 수 있습니다.
3. 보안 제어 우회:
   - IP 기반 접근은 도메인 기반 접근에 대해서만 적용되는 보안 조치를 우회하여 잠재적인 무단 접근으로 이어질 수 있습니다.

**감사:**
- 웹 서버가 도메인 기반 요청에만 응답하도록 구성되어 있고 직접 IP 주소 접근에는 응답하지 않는지 확인합니다.

**수정:**
- 웹 서버가 지정된 도메인에 기반한 요청만 처리하고 다른 요청은 적절히 거부하거나 리디렉션하도록 구성합니다.

**구성 단계**
1. 기본 VirtualHost 구성
   - 지정되지 않은 모든 요청을 포착하여 403 Forbidden을 반환하거나 리디렉션하는 기본 VirtualHost를 생성합니다.

       **Apache의 경우:**
       ```
        <VirtualHost _default_:80>
            DocumentRoot /var/www/html/yourwordpress
            ...
            <Location />
                Require all denied
            </Location>
    
        <VirtualHost _default_:443>
            DocumentRoot /var/www/html/yourwordpress
            ...
            SSLEngine on
            SSLCertificateFile /path/to/ssl/certificate.crt;
            SSLCertificateKeyFile /path/to/ssl/private.key;
            ...
            <Location />
                Require all denied
            </Location>
        </VirtualHost>     
       ```
       **Nginx의 경우:**
       ```
       server {
           listen 80 default_server;
           return 403;
       }
    
       server {
           listen 443 ssl default_server;
           ...
           ssl_certificate /path/to/ssl/certificate.crt;
           ssl_certificate_key /path/to/ssl/private.key;
           ...
           return 403;
       }
       ```

2. 도메인 기반 VirtualHost 구성
   - 도메인에 대해 구성된 VirtualHost가 있는지 확인합니다.
   
    **Apache의 경우:**
    ```
    <VirtualHost *:80>
        ServerName yourwordpress.com
        ...
        Redirect permanent / https://yourwordpress.com/
    </VirtualHost> 
   
    <VirtualHost *:443>
        ServerName yourwordpress.com
        DocumentRoot /var/www/html/yourwordpress
        ...
        SSLEngine on
        SSLCertificateFile /etc/httpd/to/ssl/certificate.crt;
        SSLCertificateKeyFile /etc/httpd/to/ssl/private.key;
        ...
    </VirtualHost>    
    ```
    **Nginx의 경우:**
    ```
    server {
        listen       443 ssl;
        server_name  yourwordpress.com;
        root         /var/www/html/wordpress;
        ...
        ssl_certificate /path/to/ssl/certificate.crt;
        ssl_certificate_key /path/to/ssl/private.key;
        ... 
    ```

3. 테스트
   - `yourwordpress.com`에 대한 기본 VirtualHost 및 도메인 기반 VirtualHost 생성입니다. 
   - `yourwordpress.com`에 대한 기본 VirtualHost 및 도메인 기반 VirtualHost를 생성한 후, 도메인 기반이 아닌 요청(https://ip)에 대해서는 접근이 거부되어(403 오류) 403 오류 화면이 표시됩니다.
  

    ```
     $ curl -i -k http(s)://10.10.66.88
       
     HTTP/1.1 403 Forbidden
     Server: nginx
     Date: Mon, 03 Jun 2024 23:23:13 GMT
     Content-Type: text/html
     Content-Length: 162
     Connection: keep-alive
        
     <html>
     <head><title>403 Forbidden</title></head>
     <body bgcolor="white">
     <center><h1>403 Forbidden</h1></center>
     <hr><center>nginx</center>
     </body>
     </html>
    
       
     $ curl -i -k https://yourwordpress.com
     HTTP/1.1 200 OK
     Server: nginx
     Date: Mon, 03 Jun 2024 23:32:12 GMT
     Content-Type: text/html; charset=utf-8
     Content-Length: 9
     Connection: keep-alive
        
     Hello, yourwordpress.com
    ```

   - 서버 간 통신이나 동일한 IP 서브넷 내 통신이 필요한 경우 특정 IP 주소의 접근을 허용하도록 기본 VirtualHost를 구성할 수 있습니다.

이러한 구성을 구현하면 웹 서버가 도메인으로 전송된 요청에만 응답합니다.


### 8.10. 완료된 웹 서버 구성
다음은 보안 지침을 포함한 완료된 웹 서버 구성의 예입니다. WordPress 웹 서버 환경에 맞게 조정하여 사용하십시오.

1. Apache
    ```
    <VirtualHost _default_:80>
        DocumentRoot /var/www/html/yourwordpress
   
        ErrorLog /var/log/httpd/http.ip.error.log
        CustomLog /var/log/httpd/http.ip.access.log combined
   
        <Location />
            Require all denied
        </Location>

    <VirtualHost _default_:443>
        DocumentRoot /var/www/html/current/public
   
        ErrorLog /var/log/httpd/https.ip.error.log
        CustomLog /var/log/httpd/https.ip.access.log combined
   
        # SSL Configuration
        SSLEngine on
        SSLCertificateFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.crt
        SSLCertificateKeyFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.key
        SSLSessionTimeout 1d
        SSLSessionCache shared:MozSSL:10m
        SSLSessionTickets off
    
        SSLProtocol TLSv1.2 TLSv1.3
        SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
        SSLHonorCipherOrder off
   
        <Location />
            Require all denied
        </Location>
    </VirtualHost>    
   
    <VirtualHost *:80>
        ServerName yourwordpress.com
        Redirect permanent / https://yourwordpress.com/
    </VirtualHost> 
    
    <VirtualHost *:443>
        ServerName yourwordpress.com
        Protocols h2 http/1.1
        DocumentRoot /var/www/html/current/public
   
        ErrorLog /var/log/httpd/https.yourwordpress.com.error.log
        CustomLog /var/log/httpd/https.yourwordpress.com.access.log combined
    
        # SSL Configuration
        SSLEngine on
        SSLCertificateFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.crt
        SSLCertificateKeyFile /etc/httpd/conf.d/cert/yourwordpress.com_ssl.key
        SSLSessionTimeout 1d
        SSLSessionCache shared:MozSSL:10m
        SSLSessionTickets off
    
        SSLProtocol TLSv1.2 TLSv1.3
        SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
        SSLHonorCipherOrder off
    
        <Directory /var/www/html/current/public>
            Options -Indexes FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>

        # Deny PHP execution in uploads directory
        <Directory "/var/www/html/current/public/wp-content/uploads">
            <FilesMatch "\.php$">
                SetHandler none
                Require all denied
            </FilesMatch>
        </Directory>
   
        # PHP Serving 
        ProxyPassMatch ^/(?!wp-content/uploads/.*\.php$)(.*\.php(/.*)?)$ unix:/var/run/php-fpm/php-fpm.sock|fcgi://localhost/var/www/html/current/public
        #ProxyPassMatch ^/(?!wp-content/uploads/.*\.php$)(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/current/public
    
        # Favicon
        <Location "/favicon.ico">
            ErrorDocument 404 "Not Found"
            SetEnvIf Request_URI "^/favicon\.ico$" no_log
        </Location>
    
        # Robots.txt
        <Location "/robots.txt">
            Require all granted
            SetEnvIf Request_URI "^/robots\.txt$" no_log
        </Location>
    
        # Restrict access to wp-cron.php
        <Files "wp-cron.php">
            Require all denied
            Require ip 127.0.0.1
        </Files>
    
        # Restrict access to wp-json
        <Location "/wp-json/">
            Require all denied
            Require ip 127.0.0.1 
            Require ip 10.10.77.49
            Require ip 10.10.71.20
        </Location>
    
        # Restrict access to wp-admin
        <Location "/wp-admin">
            Require all denied
            Require ip 10.10.77.49
            Require ip 10.10.71.20
        </Location>
    
        <Files "wp-login.php">
            Require all denied
            Require ip 10.10.77.49
            Require ip 10.10.71.20
        </Files>
    
        # Deny access to hidden files
        <FilesMatch "^\.">
            Require all denied
        </FilesMatch>
    </VirtualHost>
    ```
2. Nginx
    ```
    server {
        listen       80 default_server;
        listen       443 default_server ssl http2;
    
        error_log    /var/log/nginx/http.ip.error.log;
        access_log   /var/log/nginx/http.ip.access.log  main;
    
        ssl_certificate /etc/nginx/conf.d/cert/yourwordpress.com_ssl.crt;
        ssl_certificate_key /etc/nginx/conf.d/cert/yourwordpress.com_ssl.key;
        ssl_session_timeout 1d;
        ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
        ssl_session_tickets off;
    
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
        ssl_prefer_server_ciphers off;
    
        location / {
             deny all;
        }
    }
    
    server {
        listen       443 ssl http2;
        server_name  yourwordpress.com;
        root         /var/www/html/wordpress;
    
        error_log    /var/log/nginx/https.yourwordpress.com.error.log;
        access_log   /var/log/nginx/https.yourwordpress.com.access.log  main;
    
        ssl_certificate /etc/nginx/conf.d/cert/yourwordpress.com_ssl.crt;
        ssl_certificate_key /etc/nginx/conf.d/cert/yourwordpress.com_ssl.key;
        ssl_session_timeout 1d;
        ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
        ssl_session_tickets off;
    
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
        ssl_prefer_server_ciphers off;
    
    
        location = /favicon.ico {
            log_not_found off;
            access_log off;
        }
    
        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }
    
        # Restrict to access Wordpress Cron
        location = /wp-cron.php {
            allow 127.0.0.1;
            deny all;
            access_log off;
            log_not_found off;
        }
    
       # Restrict to access json rest-api
       location ~ ^/wp-json/ {
            allow 127.0.0.1;    		# Allow localhost
            allow 10.10.77.49;		    # Allow myip
            allow 10.10.71.20;       # Allow myip
            deny all;
            access_log off;
            log_not_found off;
        }

        # Restrict to access Wordpress Admin
        location = /wp-admin {
            allow 10.10.77.49;		    # Allow myip
            allow 10.10.71.20;       # Allow myip
            deny all;
        }
        
        location ~* \wp-login.php {
            allow 10.10.77.49;		    # Allow myip
            allow 10.10.71.20;       # Allow myip
            deny all;
        }
    
        # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
        # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
        location ~ /\. {
            deny all;
        }
    
        # Deny access to any files with a .php extension in the uploads directory
        location /wp-content/uploads {  
            location ~ \.php$ {
                deny all;
            }
        }
        # Other example
        # location ~* /(?:uploads|files)/.*\.php$ {
        # 		deny all;
        # }
    
        # Rewrite rules, sends everything through index.php and keeps the appended query string intact
        location / {
            try_files $uri $uri/ /index.php$is_args$args;
        }
    
        # Serving PHP
        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\\.php)(/.+)$;
            # fastcgi_pass   127.0.0.1:9000; 					 # With php-cgi (or other tcp sockets):
            fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;   # With php-fpm (or other unix sockets):
            fastcgi_index index.php;
            include /etc/nginx/fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            expires max;
            log_not_found off;
        }
    
    }
    ```


## 9. WordPress 보안 업데이트 보장
WordPress는 취약점이 발견되면 새 버전 업데이트를 릴리스하여 보안 취약점을 해결합니다.

예를 들어 WordPress 6.5.2에서 보안 취약점이 발견되면 버전 6.5.3에서 해결되어 배포됩니다.

보안 업데이트는 버전별로 관리되지 않으므로 보안 취약점을 해결하려면 정기적인 버전 업데이트가 필요합니다.

업데이트에 대한 공식 WordPress 릴리스 정보를 참조하십시오:
[WordPress Releases](https://wordpress.org/download/releases/)

**수정:**
- WordPress를 정기적으로 업데이트하십시오.
- WordPress는 버전별로 업데이트(보안 업데이트 포함)를 관리하지 않습니다.
- 2024년 5월 20일 기준으로 버전 6.5만 유지 관리 중입니다.

**참고:**
- 베타, 야간 빌드 및 기타 Subversion 체크아웃은 지원되지 않습니다.
- 공식 WordPress 릴리스가 아닌 포크된 제품이나 버전 사용을 피하십시오.
- 지원되는 버전 문서: [Supported Versions](https://wordpress.org/documentation/article/supported-versions/) 


## 10. WordPress 정기 보안 취약점 점검 보장

WordPress는 콘텐츠 관리 시스템(CMS) 소프트웨어입니다. 
패키지 소프트웨어이므로 보안 취약점은 주로 구성 요소(코어 파일, 플러그인, 테마 등)에서 발생합니다.

특정 요구 사항에 맞게 개발된 맞춤형 웹 애플리케이션과 달리 WordPress에 적합한 방법을 사용하여 보안 취약점을 식별하고 해결해야 합니다.

WordPress로 구축된 웹사이트가 사용자 정의가 많이 되지 않았고 WordPress의 특성을 유지하고 있다면 WPScan을 사용하여 보안 취약점을 쉽게 확인할 수 있습니다.

WPScan은 부분적으로 유료 소프트웨어이지만 기본 무료 등급에는 기능 제한이 없습니다. 이를 통해 WordPress 보안 취약점을 정기적으로 확인하고 대응할 수 있습니다.

**수정:**
- WPScan(또는 WordPress를 스캔할 수 있는 유사한 도구)을 사용하여 정기적인 취약점 점검을 수행하십시오.
- 취약점이 발견되면 확인하고 이를 제거하기 위해 필요한 조치를 수행하십시오. 대부분의 경우 업데이트를 통해 해결됩니다.
- [WPScan 사용자 문서](https://github.com/wpscanteam/wpscan/wiki/WPScan-User-Documentation)를 참조하십시오.
- WordPress에서 흔히 발견되는 일반적인 취약점에 대한 자세한 정보: [Extending WordPress Common Security Vulnerabilities](https://learn.wordpress.org/tutorial/extending-wordpress-common-security-vulnerabilities/)

**WPScan:**```
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.22
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[+] URL: https://yourwordpress.com/ [192.168.10.100]
[+] Started: Fri May 24 14:39:06 2024

Interesting Finding(s):

[+] Headers
..
...
 |  - content-security-policy: upgrade-insecure-requests
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

..
...
[+] XML-RPC seems to be enabled: https://yourwordpress.com/xmlrpc.php
 | Found By: Link Tag (Passive Detection)
 | Confidence: 30%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/

..
...

[+] Finished: Fri May 24 14:39:48 2024
[+] Requests Done: 187
[+] Cached Requests: 7
[+] Data Sent: 56.32 KB
[+] Data Received: 605.595 KB
[+] Memory used: 276.602 MB
[+] Elapsed time: 00:00:42

다음 읽기

  • 보안 모범 사례를 적용한 Squid 프록시 설정
도구 다운로드
번호역할설명관리 직원
1관리자모든 WordPress 기능에 대한 전체 액세스 권한이 있으며 사이트의 모든 콘텐츠를 관리할 수 있습니다.시스템 관리자
2편집자다른 사용자의 게시물을 관리 및 게시하고 콘텐츠를 편집 및 게시할 수 있습니다.운영 서비스 관리자, 내부 콘텐츠 기여자
3작성자자신의 게시물을 작성 및 게시하고 자신의 게시물을 편집할 수 있는 권한이 있습니다.내부 콘텐츠 기여자
4기여자콘텐츠를 작성할 수 있지만 게시할 수는 없습니다. 게시물은 관리자가 검토하고 게시합니다.내부 콘텐츠 기여자
5구독자사이트에 로그인하여 개인 프로필을 관리할 수 있지만 콘텐츠를 작성하거나 편집할 수 없습니다.내부 콘텐츠 기여자
  • open_basedir:

    • PHP가 특정 디렉터리 내에서만 파일에 접근할 수 있도록 제한합니다.
    • 이는 공격자가 서버의 민감한 파일에 접근하는 것을 방지할 수 있습니다.
      root@kitploit:~
      ; PHP 파일 접근을 지정된 디렉터리로 제한
      open_basedir = "/path/to/your/web/root"
      

    예시:

    • 웹 루트가 /var/www/html인 경우 open_basedir을 다음과 같이 설정하십시오:
      root@kitploit:~
      open_basedir = "/var/www/html:/tmp"
      
      이 구성은 PHP가 /var/www/html 디렉터리와 임시 디렉터리 /tmp 내의 파일에만 접근하도록 허용합니다.
      
  • disable_functions:

    • 공격에 자주 악용되는 PHP 함수입니다.
    • 이러한 함수를 비활성화하면 명령 주입 및 원격 코드 실행을 포함한 다양한 유형의 공격 위험을 완화할 수 있습니다.
      root@kitploit:~
      ; 잠재적으로 위험한 PHP 함수 비활성화
      
      disable_functions = "system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail"
      

    비활성화된 함수 설명:

    • system, exec, shell_exec, passthru:

      • 시스템 명령 실행을 허용하여 명령 주입 공격에 악용될 수 있습니다.
    • mysql_list_dbs:

      • MySQL 서버에서 데이터베이스 목록을 검색하여 추가 공격을 위한 정보 수집에 사용될 수 있습니다.
    • ini_alter:

      • 런타임에 PHP 구성을 변경하여 보안 설정을 변경할 수 있습니다.
    • dl:

      • PHP 확장을 동적으로 로드하여 악성 코드를 도입하는 데 사용될 수 있습니다.
    • symlink, link:

      • 심볼릭 링크나 하드 링크를 생성하여 파일과 디렉터리를 부적절하게 조작하는 데 악용될 수 있습니다.
    • chgrp:

      • 파일의 그룹 소유권을 변경하여 접근 권한을 변경할 수 있습니다.
    • leak:

      • 메모리 누수를 테스트하는 데 사용되지만 서버 리소스를 소비하는 데 악용될 수 있습니다.
    • popen:

      • 프로세스에 파이프를 열어 명령 실행에 악용될 수 있습니다.
    • apache_child_terminate:

      • Apache 프로세스를 종료하여 서비스를 중단시킬 수 있습니다.
    • virtual:

      • Apache 전용으로 다른 URL을 포함하는 데 사용되어 보안 위험이 있습니다.
    • mb_send_mail:

      • 이메일을 전송하여 스팸 메일 발송에 악용될 수 있습니다.