728x90

1. JAVA 시큐어코딩가이드(안행부_2012.09)

 

1.1 제 1절 입력데이터 검증 및 표현

 

소프트웨어 개발 보안이란?

 

SW 개발과정에서 개발자 실수, 논리적 오류 등으로 SW에 내포될 수 있는 보안 취약점의 원인을 최소화하는 한편 안전한 SW를 개발하기 위한 일련의 보안 활동을 의미한다.

광의적 의미로는 SW 개발생명주기(SDLC:분석->설계->구현->테스트->유지보수)의 각 단계별로 요구되는 보안 활동을 의미하며 협의의 의미로는 구현단계에서 보안약점을 제거하기 위한 "시큐어코딩"을 의미한다.

 

국내의 경우 2009년부터 개발보안 관련 연구가 진행되면서 2012년 SW 보안약점 시범 진단을 수행되었으며 SW 보안약점 제거/조치 성과에 따라 2012년 6월에 행안부 "정보시스템 구축/운영/지침"이 개정/고시됨으로써 법적으로 의무화되었다. 또한 최근 2013년 개정/고시된 "안정행정부고시 제2013-26호"에 따르면 적용 대상이 확대 및 의무화되고 있다.

 

 

구분

설명

비고

대상

정보시스템 감리대상 정보화사업

단계적 확대

-2012.12월 사업규모 40억 이상

-2014.1월 사업규모 20억 이상

-2015.1월 감리대상 전사업

범위

소스코드(신규개발 전체, 유지보수로 변경된 부분)

상용 SW제외

기준

SW 보안약점 기준(SQL삽입등 47개 항목)

진단기준

진단도구

감리법인이 진단도구 사용시, 국정원장이 인증한 도구 사용

2014년 1월부터 적용

진단원

감리법인은 SW보안약점 진단 시, 진단원을 우선적으로 배치

감리대상외 사업은 자체적으로 SW보안약점 진단/제거 결과 확인

표 1 최근 SW 개발보안관련 법률 개정/고시

 

가이드 목적

 

정보시스템 구축/운영 지침에 따라 전자정부 관련 정보화사업 수행 시 안전한 SW 개발을 위한 Java 기반 시큐어코딩 기법 제시

 

가이드 구성

 

전자정부서비스 개발 시 가장 많이 사용되는 개발언어인 Java 기반의 정보시스템 개발 시 고려해야 할 보안 약점(83개)설명과 보안대책 이해를 위한 코딩 예제(Bad/Good)를 제시함

 

 

No

유형

설명

대표적 보안약점

1

입력데이터 

검증 및 표현

프로그램 입력값에 대한 검증 누락 혹은 부적절한 검증, 데이터의 잘못된 형식지정으로 발생할 수 있는 보안 약점

SQL 삽입, 크로스사이트 스크립팅 등 26개

2

보안 기능

보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리등)을 적절하지 않게 구현 시 발생할 수 있는 보안약점

부적절한인가, 중요정보 평문저장 등 24개

3

시간 및 상태

동시 또는 거의 동시 수행을 지원하는 병렬 시스템, 하나 이상의 프로세스가 동작하는 환경에서 시간 및 상태를 부적절하게 관리하여 발생할 수 있는 보안 약점

경쟁조건, 제어문을 사용하지 않는 재귀함수 등 7개

4

에러처리

에러 처리하지 않거나, 불충분하게 처리하여 에러정보에 중요정보가 포함될때 발생할 수 있는 보안약점

취약한 패스워드 요구조건, 오류메시지를 통한 정보노출 등 4개

5

코드 오류

타입변환 오류, 자원(메모리 등)의 부적절한 반환 등과 같이 개발자가 범할 수 있는 코딩오류로 인해 유발되는 보안약점

널 포인터 역참조, 부적절한 자원해제 등 7개

6

캡슐화

중요한 데이터 또는 기능성을 불충분하게 캡슐화하였을 때 인가되지 않는 사용자에게 데이터 누출이 가능해지는 보안약점

제거되지 않고 남은 디버거코드, 시스템 데이터 정보노출등 8개

7

API 오용

의도된 사용에 반하는 방법으로 API를 사용하거나 보안에 취약한 API를 사용하여 발생할 수 있는 보안 약점

DNS Lookup에 의존한 보안결정, 널 매개변수 미조사 등 7개

표 2 안행부 7개분류 83개 보안약점

 

1.1.1 SQL 삽입

 

분류

입력 데이터 검증 및 표현

정의

-DB 와 연동된 웹 어플리케이션에서 입력 값 검증을 하지 않을 경우 공격자가 입력 폼 혹은 URL 파라미터에 SQL 구문을 삽입 및 실행하여 DB 정보를 열람하거나 조작할 수 있는 취약점을 말한다.

안전한 코딩기법

-PreparedStatememt 클래스와 하위 메서드 executeQuery(), execute(), executeUpdate()를 사용한다.

-PreparedStatement를 사용할 수 없다면 입력값 필터링 처리를 적용한다. 필터링 기준은 SQL 구문 제한, 특수문자 제한, 길이제한 등을 복합적으로 사용한다.

표 3 SQL 삽입

 

1.1.2 자원 삽입(Improper Control of Resource Identifier)

 

분류

입력 데이터 검증 및 표현

정의

-외부 입력 값을 검증하지 않고 시스템자원에 대한 식별자로 사용하는 경우 공격자는 입력 값 조작을 통해 시스템이 보호하는 자원에 임의로 접근하거나 수정할 수 있고 잘못된 입력값으로 시스템 자원 사이에 충돌이 발생할 수 있다.

안전한 코딩기법

-외부 입력 값을 자원(파일, 소켓의 포트) 식별자로 사용하는 경우, 적절한 검증을 거치도록 하거나 사전에 정의된 리스트(화이트리스트 방식)에서 선택되도록 작성한다.(단, 화이트리스트에 위험한 자원이 포함되어서는 안 된다.)

-외부 입력 값이 파일이 경우 경로 탐색(Directory Traversal) 문자를 제거한다. 

표 4 자원 삽입

1.1.3 크로스 사이트 스크립트(Cross Site Scripting)

분류

입력 데이터 검증 및 표현

정의

-검증되지 않은 외부 입력이 동적 웹페이지 생성에 사용될 경우 전송된 동적 웹 이지를 열람하는 접속자의 권한으로 부적절한 스크립트가 실행될 수 있다.

안전한 코딩기법

-Reflected XSS의 경우 사용자 입력 값에서 <,>,&,',"와 같은 특수 문자를 문자변환함수나 메서드를 사용하여 이스케이프처리한다.

-Stored XSS의 경우, 즉 HTML 태그를 지원해야 하는 게시판에서는 사전에 정의된 리스트(화이트리스트방식)만 허용되도록 한다.(단, 화이트리스트에 위험한 태그가 포함되어서는 안 된다.)

- 보안성이 검증된 API를 사용하여 위험한 문자열을 제거한다.

표 5 XSS

 

OSWASP에서 제공하고 있는 보안 API: https://www.owasp.org/index.php/Esapi#tab=Downloads

특수 문자를 이용한 공격 스크립트와 같은 외부 입력 문자열을 이용한 공격을 효과적으로 차단할 수 있다. 다운로드 링크로 접속하여 Java 용 ESAAPI를 다운로드 하면된다.

 

 

그림 1 OWASP XSS 보안 API

그림 2 OWASP XSS 보안 API

 

 

또 다른 보안 XSS 보안 API는 josephconnell에서 제공하는 API가 있다.

josephconnell에서 제공하고 있는 보안 API: http://josephoconnell.com/java/xss-html-filter/

 

그림 3 OWASP XSS 보안 API

 

 

1.1.4 운영체제 명령어 삽입(OS Command Injection)

분류

입력 데이터 검증 및 표현

정의

-적절한 입력 값 검증을 거치지 않은 사용자 입력 값이 운영체제 명령 일부 혹은 전부로 구성되어 있는 경우 시스템 명령이 실행되어 권한 상승이나 시스템 동작 및 운영에 영향을 미칠 수 있다. 

안전한 코딩기법

-웹 인터페이스를 통해 서버내부로 시스템 명령어를 전달시키지 않도록 어플리케이션을 구성한다.

-외부에서 전달되는 값을 그대로 시스템 내부 명령어로 사용하지 않는다.

-외부에서 시스템 명령어를 전달받아야 하는 경우 사전에 정의된 리스트(화이트리스트 방식: 단 화이트리스트에 위험한 명령어가 포함되어서는 안 된다)만 적용되도록 한다.

그림 4 OS 커맨드 인젝션

 

1.1.5 위험한 형식파일 업로드(Unrestricted Upload of File with Dangerous Type)

분류

입력 데이터 검증 및 표현

정의

-서버측에서 실행될 수 있는 스크립트 파일(asp,aspx,jsp,php)이 업로드 및 실행가능 할 경우 공격자가 시스템 내부 명령어를 실행하거나 외부와 연결하여 시스템을 제어할 수 있다.

안전한 코딩기법

-업로드 파일의 타입과 크기를 제한하고 업로드 디렉터리를 웹 서버의 다큐먼트에 외부에 설정한다.

업로드 파일 타입 설정 시 사전에 정의된 리스트(화이트리스트방식:단 화이트리스트에 위험한 확장자가 포함되어서는 안된다.)만 업로드 되도록 하고, 확장자도 대소문자 구분 없이 처리하도록 한다.

-공격자의 웹을 통한 직접 접근을 차단한다.

-업로드 디렉터리의 파일 실행 여부를 설정할 수 있는 경우 실행 속성을 제거한다.

그림 5 위험한 형식의 파일 업로드

 

1.1.6 신뢰되지 않는 URL 주소로 자동 접속 연결(URL Redirection to Untrusted Site, Open Redirect)

분류

입력 데이터 검증 및 표현

정의

-사용자로부터 입력되는 값을 리다이렉션 파라미터의 값으로 사용하는 경우 적절한 입력 값 검증이 없으면 피싱(phishing)공격에 노출될 수 있다.

안전한 코딩기법

-리다이렉션 파라미터의 값은 사전에 지정된 리스트(화이트리스트방식)로 관리하고 검증한 다음 연결되도록 한다.

그림 6 Open Redirection

 

1.1.7 XQuery 삽입(XQuery Injection)

분류

입력 데이터 검증 및 표현

정의

-XQuery를 사용하여 XML 데이터에 대한 동적 쿼리를 생성할 때 사용하는 외부 입력 값에 대한 적절한 입력 값 검증이 없으면 공격자 쿼리 구문을 임의로 조작하여 XML DB를 조회하거나 조작할 수 있다.

안전한 코딩기법

-XQuery에 사용되는 외부 입력 값에 대하여 특수 문자 및 쿼리 예약어를 화이트 리스트 방식(단 화이트리스트에 위험한 예약어가 포함되서는 안된다)으로 필터링하고 XQuery에 사용되는 쿼리문은 스트링을 연결하는 형태로 구성하지 않고 파라미터화된 쿼리문을 사용한다.

표 6 XQuery 삽입

 

1.1.8 XPath 삽입(XPath Injection)

분류

입력 데이터 검증 및 표현

정의

-외부 입력 값 검증 없이 외부 입력 값을 XPath 쿼리문 생성을 위한 문자열로 사용하게 되면 공격자에 의해 조작된 쿼리문이 생성 및 실행되어 인가되지 않은 데이터를 열람할 수 있다.

안전한 코딩기법

-XPath 사용되는 외부 입력 값에 특수문자(", [, ], /, =, @ 등) 및 쿼리 예약어를 화이트리스트 방식(단 화이트리스트에 위험한 예약어가 포함되어서는 안된다)으로 필터링하고 파라미터화된 쿼리문을 지원하는 XQuery를 사용한다. 

표 7 XPath 삽입

 

1.1.9 LDAP 인젝션(LDAP Injection)

분류

입력 데이터 검증 및 표현

정의

-LDAP 쿼리문이나 결과에 외부 입력 값이 부분적으로 적절한 검증 없이 사용되면 공격자는 조작된LDAP 쿼리문을 실행 할 수 있다.

안전한 코딩기법

-위험문자에 대한 검증 없이 외부 입력 값을 LDAP 질의어 생성에 사용하면 안된다.

-DN과 필터에 사용되는 사용자 입력 값에 특수문자(DN에 사용되는 특수문자 '\', 필터에 사용되는 특수문자 '=, +, <, >,# , ;, \')는 이스케이프 처리하여 특수문자가 아닌 일반 문자로 처리되도록 한다.

표 8 LDAP 삽입

 

1.1.10 크로스사이트 요청 위조(Cross-Site Request Forgery)

분류

입력 데이터 검증 및 표현

정의

-특정 웹 사이트에 대해 사용자가 인지하지 못한 상황에서 사용자의 의도와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)의 요청을 하게 하는 공격을 말한다. 

안전한 코딩기법

-입력화면 폼 작성 시 GET 방식보다는 POST 방식을 사용한다.

-입력화면 폼과 해당 입력을 처리하는 프로그램 사이에 토큰을 사용하여 공격자의 직접적인 URL 사용이 동작하지 않도록 처리한다.

-특히 중요한 기능에 대해서는 사용자 세션 검증과 재 인증을 유도한다.

표 9 CSRF

 

1.1.11 디렉터리 경로 조작(Path Traversal)-상대 디렉터리 경로 조작(Relative Path Traversal)

분류

입력 데이터 검증 및 표현

정의

-외부 입력 값에 의해 "디렉터리 경로 문자열"이 생성될 경우 입력 값 검증이 적절하게 이루어지지 않으면 공격자에 의해 디렉터리 경로가 조작되어 시스템 정보 누출 혹은 서비스 장애 등의 위험이 발생할 수 있다.

안전한 코딩기법

-외부 입력 값으로 파일 디렉터리 경로가 생성되지 않도록 한다. 필요 시에는 외부 입력 값에 경로 탐색 문자(",/,\)를 필터링 한다.

-외부의 입력을 받아 들이되 내부적인 처리는 미리 정의해놓은 데이터를 사용하도록 코딩한다.

표 10 상대 디렉터리 경로 조작

 

1.1.11 디렉터리 경로 조작(Path Traversal)-절대 디렉터리 경로 조작(Absolute Path Traversal)

분류

입력 데이터 검증 및 표현

정의

-외부 입력 값이 파일 시스템을 조작하는 경로를 직접 제어할 수 있거나 영향을 끼치면 위험하다. 사용자 입력 값이 파일 시스템 작업에 사용되는 경로를 제어하는 것을 허용하면 공격자가 응용프로그램에 치명적인 시스템 파일 또는 일반 파일을 접근하거나 변경할 수 있다.

안전한 코딩기법

-외부 입력 값을 통해 파일이름 생성  접근을 허용하지 말고외부 입력에 따라접근이 허용된 파일의 리스트에서 선택하도록 한다.

표 11 절대 디렉터리 경로 조작

 

1.1.12 HTTP 응답 분활(HTTp Response Splitting)

분류

입력 데이터 검증 및 표현

정의

-사용자 입력 값이 HTTP 응답 헤더에 포함되어 사용자에게 다시 전달될 경우 입력 값에 CRLF(Carriage Return, Line Feed, 개행문자) 특수 문자가 필터링이 없으면 HTTP 응답이 분활되어 실행될 수 있다. 이 경우 공격자는 개행문자를 이용하여 첫번째 응답을 종료 시키고 두번째 응답에 악의적인 코드를 삽입하여 실행 시킬 수 있다.

안전한 코딩기법

-외부 입력 값을 HTTP 응답 헤더에 포함시킬 때 CRLF를 필터링하거나 적절한 인코딩기법을 적용한다.

표 12 HTTP 응답 분활

 

1.1.13 정수 오버플로우(Integer Overflow/Wraparound)

분류

입력 데이터 검증 및 표현

정의

-정수형 변수의 오버플로우는 정수값이 증가하면서 Java에서 허용된 가장 큰 값보다 더 커져서 실제 저장되는 값은 의도하지 않게 아주 작은 수이거나 음수가 될 수 있다. 특히 반복문 제어, 메모리 할당, 메모리 복사 등을 위한 조건으로 사용자가 입력 값을 사용하고 그 과정에서 정수 오버플로우가 발생하는 경우 보안상 문제를 유발할 수 있다.

안전한 코딩기법

-언어/플랫폼 별 정수타입의 범위를 확인하여 사용한다. 정수형 변수를 연산에 사용하는 경우 결과값이 범위 체크하는 모듈을 사용한다. 

-특히 외부 입력값을 동적으로 할당하여 사용하는 경우 변수의 값 범위를 적절한 범위내 존재하는지 확인한다.

표 13 정수 오버플로우

 

1.1.14 보호 메커니즘을 우회할 수 있는 입력값 변조(Reliance on Untrusted Input in a Security Decision)

분류

입력 데이터 검증 및 표현

정의

-인증이나 인가와 같은 보안 결정이 입력 값(쿠키, 환경 변수, 히든 필드)에 기반으로 수행되는 경우 공격자는 입력 값을 조작하여 응용프로그램의 보안을 우회할 수 있음

안전한 코딩기법

-상태 정보나 민감한 데이터 특히 사용자 세션정보와 같은 중요 정보는 서버에 저장하고 보안 확인 절차도 서버에서 실행한다.

-보안설계 관점에서 신뢰할 수 없는 입력 값이 어플리케이션 내부로 들어올 수 있는 지점과 보안결정에 사용되는 입력 값을 식별하고 제공되는 입력 값에 의존할 필요가 없는 구조로 변경할 수 있는지 검토한다.

표 14 보호 메커니즘 우회 

 

1.1.15 SQL삽입공격: JDO(SQL Injection JDO)

분류

입력 데이터 검증 및 표현

정의

-외부 입력 값을 적절한 검증 없이 JDO(Java Date Object) API의 SQL 혹은 JDOQL 질의문 생성을 위한 문자열로 공격자 의도한 조작된 질의문이 생성 및 실행될 수 있다. 

안전한 코딩기법

-JDO 질의문 생성시에는 상수 문자열만을 사용하고 Query.execute() 실행 시 파라미터화된 쿼리문을 사용한다.

표 15 SQL 삽입:JDO

 

1.1.16 SQL삽입공격: Persistence(SQL Injection Persistence)

분류

입력 데이터 검증 및 표현

정의

-J2EE Persistence API를 사용하는 응용프로그램에서 외부 입력값을 적절한 검증 없이 사용하면 공격자가 의도한 조작된 질의문이 생성 및 실행될 수 있다.

안전한 코딩기법

-질의문 생성 시 상수 문자열만을 사용하고 Javax.persistence.Query.setParameter() 메서드를 사용하여 인자값을 설정한다.

표 16 SQL삽입:Persistence

 

1.1.17 SQL삽입공격: mybatis Data Map(SQL Injection mybatis Map)

분류

입력 데이터 검증 및 표현

정의

-외부 입력 값이 질의어의 인자값으로만 사용되지 않고 질의 명령어에 연결되는 문자열로 사용되면 공격자가 의도한 조작된 질의문이 생성 및 실행될 수 있다.

안전한 코딩기법

-외부 입력으로부터 위험 문자나 의도하지 않았던 입력을 제거하는 코드를 삽입한다.

-mybatis Data Map 파일의 인자를 받는 질의 명령어 정의시에 문자열 삽입 인자($...$)를 사용하지 않는다. 즉 #<인자이름># 형태의 질의문을 사용한다.

표 17 SQL삽입:mybatis Data Map

 

1.1.18 LDAP 처리(LDAP Manipulation)

분류

입력 데이터 검증 및 표현

정의

-LDAP 질의문이나 결과로 외부 입력값이 적절한 검증없이 사용되면 LDAP 질의문이 실행될 때 공격자가 의도한 조작된 질의문이 생성 및 실행될 수 있다.

안전한 코딩기법

-외부 입력 값에 대한 유효성 검증 후 사용해야 하며 LDAP 사용 시 질의문을 제한하여 허용된 레코드만 접근하도록 해야 한다.

표 18 LDAP 처리

1.1.19 시스템 혹은 구성 설정의 외부제어(External Control of System or Configuration Setting)

분류

입력 데이터 검증 및 표현

정의

-시스템 설정이나 구성 요소를 외부에서 제어할 수 있으면 공격자에 의해 악용될 위험이 있다.

안전한 코딩기법

-외부 입력을 Connection.setCatalog() 메서드의 인자 값을 생성하는데 사용하지 않도록 한다. 불가피하게 사용해야 한다면 외부 입력을 화이트리스트 방식으로 관리 한다.

표 19 시스템 혹은 구성 설정의 외부 제어

 

1.1.20 크로스 사이트 스크립팅:DOM

분류

입력 데이터 검증 및 표현

정의

-외부 입력 값이 적절한 검증 없이 웹 페이지 생성에 사용되면 악의적인 HTML 스크립트 코드가 클라이언트에게 실행 될 수 있다.

안전한 코딩기법

-JSP의 document.write()와 같이 JSP의 DOM 객체 출력을 수행하는 메서드 인자 값을 외부 입력 값으로 사용할 경우 위험 문자를 필터링 하여야 한다.

-보안 API로 위험 문자를 제거한다.

표 20 DOM-XSS

 

1.1.21 동적으로 생성되어 수행되는 명령어 삽입(Eval Injection)

분류

입력 데이터 검증 및 표현

정의

-외부 입력 값이 적절한 검증 없이 동적으로 수행되는 스크립트 혹은 프로그램 명령어로 사용되면 공격자가 원하는 임의의 작업을 수행할 위험이 있다.

안전한 코딩기법

-외부 입력이 eval()함수의 인자로 사용될 경우 외부 입력 값에서 위험 문자를 제거한다.

-ESAPI for Javascruipt 등의 보안 API를 사용하여 외부 입력 값을 검증한다.

표 21 Eval Injection

 

1.1.22 프로세스 제어(Process Control)

분류

입력 데이터 검증 및 표현

정의

-신뢰되지 않은 소스나 신뢰되지 않은 환경으로부터 라이브러리를 적재하거나 명령을 실행하면 악의적인 코드가 실행될 위험이 있다.

안전한 코딩기법

-프로그램에서 라이브러리 적재 시 절대 경로를 사용한다.

표 22 프로세스 제어

1.1.23 안전하지 않은 리플렉션(Unsafe Reflection)

분류

입력 데이터 검증 및 표현

정의

-외부 입력 값을 동적 클래스 적재 시 인자로 받을 경우 적절한 검증이 없으면 악의적인 클래스가 적재 및 실행될 위험이 있다.

안전한 코딩기법

-외부 입력 값을 적재할 클래스로 입력 받지 않고 사전에 지정한 화이트리스트 방식에 의해 관리한다.

표 23 안전하지 않은 리플렉션

 

1.1.24 무결성 점검 없는 코드 다운로드(Code without Intergrity Check)

분류

입력 데이터 검증 및 표현

정의

-원격으로부터 소스 코드 혹은 실행 파일을 무결성 검증 없이 다운로드 시 host server 변조 혹은 DNS spoofing 혹은 전송 시 소스코드 변조로 공격자가 의도한 공격이 실행될 위험이 있다.

안전한 코딩기법

-SW 자동 업데이트와 같이 다운로드에 대한 코드 제공 시에는 코드에 대한 암호화 시그니처를 사용하고 클라이언트가 시그니처를 검증하도록 한다.

표 24 무결성 점검 없는 코드 다운로드

1.1.25 SQL 삽입공격:Hibrate

분류

입력 데이터 검증 및 표현

정의

-외부 입력 값을 적절한 검증 없이 Hibrate API의 SQL 질의문 생성을 위한 문자열로 사용할 경우 공격자가 의도한 질의문을 생성 및 실행할 위험이 있다.

안전한 코딩기법

-질의문 생성 시 상수 문자열만을 사용한다. 

표 25 SQL Injection:Hibrate

 

1.1.26 보안결정을 신뢰할 수 없는 입력 값에 의존(Reliance on Untrusted Input in a Security Decision)

분류

입력 데이터 검증 및 표현

정의

-인증이나 인가와 같은 보안 결정이 입력 값(쿠키, 환경 변수, 히든 필드)에 기반으로 수행되는 경우 공격자는 입력 값을 조작하여 응용프로그램의 보안을 우회할 수 있음

안전한 코딩기법

-상태 정보나 민감한 데이터 특히 사용자 세션정보와 같은 중요 정보는 서버에 저장하고 보안 확인 절차도 서버에서 실행한다.

-보안설계 관점에서 신뢰할 수 없는 입력 값이 어플리케이션 내부로 들어올 수 있는 지점과 보안결정에 사용되는 입력 값을 식별하고 제공되는 입력 값에 의존할 필요가 없는 구조로 변경할 수 있는지 검토한다.

표 26 보안결정을 신뢰할 수 없는 입력 값에 의존

 

refers

http://codedragon.tistory.com/1212(안전행정부고시)

 

http://www.securitya.kr/eduwiz/bb/bbs/board.php?bo_table=c403&wr_id=12


반응형

+ Recent posts