워드프레스 플러그인 WP-Jobs 취약점 진단 본문
3. 워드프레스 개요
3.1. 개요
워드프레스(Wordpress)는 PHP 기반의 오픈소스 설치형 CMS(Content Management System) 컨텐츠 관리 시스템” 이다. 특징은 웹사이트, 블로그, 앱을 만들 수 있는 오픈소스 소프트웨어다. 누구나 쉽게 무료로 사용이 가능하며, 설치 및 간단한 설정으로 사용자들이 접근하기 쉽다.
기업 |
얼론사 |
공공기관 |
https://www.samsung.com/sec/home/ (삼성전자) |
http://www.bloter.net/ (블로터닷넷) |
http://www.seoul.go.kr/ (서울시) |
https://social.lge.co.kr (LG전자) |
https://www.cnet.co.kr/ (CNET 코리아) |
http://blog.ggtour.or.kr (경기 관광공사) |
https://skinnovation-if.com/ (SK이노베이션) |
http://blog.donga.com/ (동아일보 저널로그) |
http://jeju-sp.com/ (제주 첨단과학기술단지) |
표 3‑1 국내 워드프레스 구축 사이트 사례
개인 블로그부터 기업, 언론사, 공공기관 등의 29% 웹 사이트는 워드프레스를 사용 중이다. 사용자의 만족성을 높일 수 있게 45,000개 이상의 플러그인을 가지고 있다. 플러그인을 통해 온라인 상점, 갤러리, 메일링 리스트, 포럼, 분석기 등을 추가할 수 있다. 전 세계 6천만명의 사람들이 “홈”이라 부르는 웹 공간을 만들기 위해 워드프레스를 사용하고 있다.
4. WP-Jobs 플러그인 기능 소개
그림 4‑1 WP Jobs 플러그인 취약점
WP Jobs 플러그인은 채용 정보 플러그인이다. 채용 정보 추가, 온라인 취업 알선, 이력서 첨부, 이메일 알림, 지원자 관리 등을 사용할 수 있다. WP-Jobs 플러그인은 SQL 인젝션 취약점을 진단한다. SQL 인젝션 취약점은 2017년 6월 11일 발견 됐으며 최종 업데이트 버전은 1.8이다. 마지막 업데이트는 12개월 전(2018년 12월 23일 기준)이다.
5. WP-Jobs 플러그인 취약점 진단
그림 5‑1 WPScan 워드프레스 플러그인 취약점 탐색
WPScan은 루비(Ruby) 언어로 제작되었으며 워드프레스 최신 취약점, 플러그인, 테마 취약점 미패치를 데이터베이스화하여 보여주는 진단 도구다. 그림 5‑1의 실행 명령어 옵션은 --url [url 워드프레스 진단] --enumerate vp [취약한 플러그인 진단]을 나타낸다.
그림 5‑2 WPScan 워드프레스 플러그인 취약점 탐색 결과
그림 5‑2는 WP Jobs 플러그인 취약점 탐색 결과다. WP Jobs 플러그인의 버전 정보 “WP Jobs v1.4”, 취약점 패치 업데이트(Last update) 정보, SQL 인젝션 취약점의 정보를 알려주며 WP Jobs 플러그인 “WP Jobs v1.5”로 업데이트를 권고하고 있다.
그림 5‑3 WP Jobs 취약점 설명 화면 - 1
그림 5‑4 WP Jobs 취약점 설명 화면 - 2
취약점 정보에 따르면 그림 5‑3과 같이 관리자가 왼쪽의 ALL Jobs 메뉴에서 글 작성 후 그림 5‑4의 Job Applications에서 유니온(Union) SQL 인젝션 취약점이 발생한다.
유니온 SQL 인젝션은 두 가지 방식이 있다. 일반 유니온 SQL 인젝션과 유니온 ALL SQL 인젝션이다. 유니온 SQL 인젝션은 2개의 select문을 결합하여 정렬한 다음 중복 값을 제거하여 출력한다. 유니온 ALL SQL 인젝션은 2개의 select문을 결합한 것이다.
그림 5‑5 WP Jobs 인젝션 취약점 메뉴 선택
그림 5‑3과 같이 게시글 작성 후 Job Applications 메뉴에서 Filter by Job의 메뉴 선택을 눌러 SQL 인젝션 Test를 선택한다.
union all select null-- (에러 없음) union all select null, null-- (에러 없음) union all select null, null, null-- (에러 없음) union all select null, null, null, null-- (에러 없음) union all select null, null, null, null, null-- (에러 없음) union all select null, null, null, null, null, null-- (에러 발생) |
표 5‑1 유니온 쿼리 삽입 문
표 5‑1은 필드 값을 추출하는 쿼리 문이다. 쿼리 문을 그림 5‑5 WP Jobs 인젝션 취약점 메뉴 선택의 URL 창에 하나씩 삽입한다.
그림 5‑6 유니온 SQL 인젝션 취약점 검증
그림 5‑6 과 같이 Download Resume에 “No resume was attached” 구문이 출력된다. Job Applications의 필드(Filed)는 여섯 개다. 유니온 SQL 인젝션 취약점이 존재한다.
시스템 변수 및 함수 |
설명 |
database( ) |
데이터베이스 명을 알려주는 함수 |
user( ) |
현재 사용자의 아이디 |
System_user( ) |
최고 권한 사용자의 아이디 |
@@version( ) |
데이터베이스 서버의 버전 |
@@datadir( ) |
데이터베이스 서버가 존재하는 디렉터리 |
표 5‑2 시스템 변수 및 함수
표 5‑2를 사용하여 데이터베이스 서버의 정보를 파악한다.
표 5‑3 데이터베이스 서버 정보 파악 쿼리 문
표 5‑3의 SQL 쿼리 문을 URL 끝에 입력 후 엔터를 누른다.
그림 5‑7 데이터베이스 서버 정보 파악 결과
그림
5‑7과 같이 SQL 인젝션 공격을 시도하여 데이터베이스의 정보를 파악할 수 있다.
6. WP-Jobs 플러그인 대응방안
6.1. 시큐어 코딩
$job_id = $_REQUEST['jobid']; $jb_args = array( 'posts_per_page' => -1, 'orderby' => 'post_date', 'order' => 'DESC', 'post_type' => 'job', 'post_status' => 'publish', 'suppress_filters' => true);
$jobs = get_posts($jb_args); ?>
|
표 6‑1 wpjobs_applications.php 취약점 소스 코드 수정 전 1-1
WP Jobs 취약점 소스 코드는 wpjobs_applications.php에서 발생한다. 표 6‑1에서는 job_id 변수는 요청(Request)할 때 아무런 검증이 이루어지지 않고 있다.
$job_id = isset($_REQUEST['jobid']) ? sanitize_key($_REQUEST['jobid']) : null; $jb_args = array( 'posts_per_page' => -1, 'orderby' => 'post_date', 'order' => 'DESC', 'post_type' => 'job', 'post_status' => 'publish', 'suppress_filters' => true);
$jobs = get_posts($jb_args); ?> |
표 6‑2 wpjobs_applications.php 취약점 소스 코드 수정 후 1-2
Isset 함수를 사용하여 변수 설정을 검사한다. sanitize_key 함수는 워드프레스에서 사용하는 함수로 문자열을 변환 한다. sanitize_key 함수는 jobid 변수를 sanitize_key() 필터를 통해 키를 null 값으로 전달한다.
$tbl = $wpdb->prefix; $qry = "Select * from " . $tbl . "app_user_info "; if ($job_id <> "") { $qry .= " where app_job_id = " . $job_id; } $qry .= " Order by `app_id` Desc "; $users = $wpdb->get_results($qry); $i = 1; foreach ($users as $user) { ?> <tr> <td><?php echo $i; ?></td> <td><?php echo get_the_title($user->app_job_id); ?></td> <td><?php echo $user->app_name; ?></td> <td><?php echo $user->app_email; ?></td> <td><?php echo $user->app_phn; ?></td> </tr> |
표 6‑3 wpjobs_applications.php 취약점 소스 코드 수정 전 1 - 3
표 6‑3소스 코드는 쿼리와, 제목(app_title), 이름(app_name), 이메일(app_email), 핸드폰 번호(app_phn)는 사용자의 입력 값 검증이 없어 취약점이 발생한다.
<?php if (null !== $job_id) { $qry = "SELECT * FROM " . $wpdb->prefix . "app_user_info WHERE app_job_id = %d "; } else { $qry = "Select * from " . $wpdb->prefix . "app_user_info "; } $qry .= " ORDER BY `app_id` DESC "; $users = $wpdb->get_results($wpdb->prepare($qry, $job_id)); $i = 1; foreach ($users as $user) { ?> <tr> <td><?php echo $i; ?></td> <td><?php echo esc_html(get_the_title($user->app_job_id)); ?></td> <td><?php echo esc_html($user->app_name); ?></td> <td><?php echo esc_html($user->app_email); ?></td> <td><?php echo esc_html($user->app_phn); ?></td> <td> |
표 6‑4 wpjobs_applications.php 취약점 소스 코드 수정 전 1 - 4
표 6‑4의 소스 코드는 prepared 함수를 사용하여, 공격자가 임의로 입력한 쿼리 문이 데이터베이스에 적용되지 않도록 한다. 제목(app_title), 이름(app_name), 이메일(app_email), 핸드폰 번호(app_phn) 소스 코드에서 esc_html을 사용하여 특정한 특수 문자를 HTML 엔티티(Entty)로 변환한다.
'해킹 & 보안 > 웹 해킹' 카테고리의 다른 글
워드프레스 플러그인 WP-PostRatings 버그 바운티 (0) | 2018.12.30 |
---|