[웹보안] SQL Injection

Posted in SW개발 // Posted at 2019. 1. 28. 12:51
728x90

SQL 인젝션은, 웹 보안 하면 가장 대중적으로 언급되는 공격 기법입니다. 

XSS와 함께 쌍두마차급으로 유명한 기법이지요. 꽤 오래전에, 이 공격에 대한 글을 한번 다룬적이 있는데요. 벌써 12년도 더 전이네요. 그때나 지금이나 SQL 인젝션의 공격기법이든 방어기법이든 크게 달라진 것이 없어 보입니다.

[웹 보안 시리즈] 2. SQL INJECTION

(대부분의 웹해킹이 그렇듯이) 웹 개발의 기본을 잘 이해하고 있다면, SQL 인젝션은 쉽게 이해하고 시도해 볼 수 있으리라 판단됩니다. 이 해킹 공격을 도와주는 자동화 툴도 쉽게 구할 수 있고요.

SQL 인젝션은 손쉽게 공격을 해 볼 수 있는 반면에 공격이 성공했을때그 파급력을 상당할 수 있습니다.

지금부터 알아볼 사례들을 보면, 이 진부한 공격기법이 아직까지 기승을 부리고 있다는 것을 알 수 있습니다.

SQL 인젝션 해킹 사례

먼저 SQL 인젝션으로인한 해킹 사례를 집어 보자. 국내의 비교적 최근에 발생한 가장 유명한 두 가지 사례를 먼저 알아보자.

사례1) '여기어때' 해킹


https://news.joins.com/article/21628794

2017년 3월, 유명한 숙박앱인 '여기 어때'가 해킹을 당했다. 대량의 고객 정보와 고객의 투숙정보가 해커에게 유출되었으며 이 중 수천명에게 '모텔서 즐거우셨나요?'라는 식의 협박성의 민망한 문자가 전송되었다고 한다.

기사에 따르면, 이 사건은 보안이 허술한 특정 웹 페이지를 대상으로 SQL 인젝션 공격을 시도해서 관리자 세션을 탈취하고 이 정보로 관리 페이지에 위장 로그인하여 고객의 개인정보를 유출했다고 한다.

‘여기어때’ 개인정보 99만건 유출…‘SQL인젝션’ 공격이 원인


사례2) '뽐뿌' 해킹

'여기 어때'  사건으로부터 약 2년전(2015년 9월), 커뮤니티 사이트로 유명한 '뽐뿌'에서도 SQL 인젝션 공격으로 200만명 가량 개인정보가 유출된 사례가 있었다.


http://www.korea.kr/policy/pressReleaseView.do?newsId=156081058

이러한 개인정보 유출은 해당 사이트에 대한 피해뿐만 아니라, 이미 유출된 개인정보가 언제 어떤 식으로 다시 악용되어 2차 피해로 이어질지 알 수 없다는 것이 더욱 문제이다.

사례3) 해외 사례

SQL 인젝션 해킹 사례는 비단 국내에만 있는 것이 아니다.

2015년, 해커그룹 어나미머스가 WTO 웹사이트를 SQL 인젝션으로 공격해 각 나라의 직원 개인정보를 탈취한 사건이 있었다.
어나니머스, WTO 웹사이트 공격…직원 정보유출


또한 2014년, 영국의 유명 여행 웹사이트가 SQL 인젝션 공격으로 신용카드 번호가 유출되었다고 한다.> 英정보위원회 SQL인젝션 공격 경고…피해사례 발생


그리고 2011년에는 소니가 해커집단(Lulzsec)으로부터 조롱당한 일이 있었는데, 이때도 역시 SQL 인젝션 기법이 사용되었다고 한다.
미국 FBI, 소니 해킹 용의자 검거


이외에도 조금만 찾아보면 SQL 인젝션으로 인한 다양한 해킹 사례를 확인할 수 있다.


SQL 인젝션 공격 비중

앞서 XSS와 함께 SQL 인젝션은 쌍두마차 격으로 웹에서 빈번히 일어나는 해킹 기법이라고 했다. 2016년 펜타시큐리티에서 발표한 '웹 공격 동향 보고서'를 살펴 보자

전체 해킹 시도 중, SQL 인젝션이 45% 즉 절반에 가까운 비중을 차지했다. 펜타시큐리티 측은 2016년 발생한 웹공격 사례 4건 중 3건이 SQL 인젝션과 XSS 기법으로 수행됐다는 조사결과를 발표했다.

그리고 글로벌 CDN업체인 CDNetworks의 '2016년 4분기 웹 공격 분석 보고서'를 보면 SQL 인젝션이 두 번째로 많이 시도되는 해킹 기법이라는 조사 결과를 내놨다.


SQL 인젝션의 위상(?)은, OWASP TOP 10에서도 확인할 수 있다.

OWASP Top 10은 2013년에 이어 개정한 2017년 버전에서도 '인젝션'이 랭킹 1위로 포지셔닝 하고 있다. 물론 OWASP에서 말하는 인젝션은 SQL 인젝션을 포함한 모든 유형의 인젝션을 일컫는다.


SQL 인젝션 개념

SQL 인젝션은, 웹 애플리케이션이 데이터베이스와 연동하는 모델에서 발생 가능하다.

이용자의 입력값이 SQL 구문의 일부로 사용될 경우, 해커에 의해 조작된 SQL 구문이 데이터베이스에  그대로 전달되어 비정상적인 DB 명령을 실행시키는 공격 기법이다.


[출처: 행정안전부 시큐어 코딩 가이드]


SQL 인젝션 공격 목적 및 영향

SQL 인젝션은 DB에 비정상적인 쿼리가 실행되도록 하여 다음과 같은 목적을 달성하고자 한다.

1. 인증 우회
SQL 인젝션 공격의 대표적인 경우로, 로그인 폼(Form)을 대상으로 공격을 수행한다. 정상적인 계정 정보 없이도 로그인을 우회하여 인증을 획득할 수 있다.

2. DB 데이터 조작 및 유출
조작된 쿼리가 실행되도록 하여, 기업의 개인정보나 기밀정보에 접근하여 데이터를 획득할수 있다. 또한 데이터 값을 변경하거나 심지어 테이블을 몽땅 지워버릴 수도 있다.

3. 시스템 명령어 실행
일부 데이터베이스의 경우 확장 프로시저를 호출하여 원격으로 시스템 명령어를 수행할 수 있도록 한다. 시스템 명령어를 실행할 수 있다면 해당 서버의 모든 자원에 접근하고 데이터를 유출, 삭제 할 수 있다는 말이 된다.


SQL 인젝션 공격 원리와 유형

SQL 인젝션은 데이터베이스 명령어인 SQL 쿼리문에 기반하여 공격을 수행한다. 공격에 이용되는 쿼리문은 문법적으로는 지극히 정상적인 SQL 구문이다. 다만 실행되지 말아야 할 쿼리문이 실행되어 공격에 이용되는 것이다.

SQL 인젝션은 최소한 다음의 조건을 충족해야 공격이 가능하다.

조건 1) 웹 애플리케이션이 DB와 연동하고 있다.

조건 2) 외부 입력값이 DB 쿼리문으로 사용된다.

웹 애플리케이션이 위 두 조건 중, 하나라도 충족하지 않는다면 SQL 인젝션 공격은 무용지물이 될 것이다. 그러나 현재의 대부분 웹 애플리케이션은 위 두가지 조건을 대부분 충족한다. 그래서 대부분의 경우 SQL 인젝션은 유효한 공격 기법이 될 것이다.


SQL 인젝션 공격 유형과 공격 기법

1. (일반적인) SQL 인젝션

굳이 '일반적인'이라는 용어는 붙일 필요가 없으나, 이어서 소개할 Blind SQL 인젝션과 구분하기 위함이다. 일반적인 SQL 인젝션 공격은 다음의 형태로 수행된다.

1) 쿼리 조건 무력화(Where 구문 우회)
Where 구문은 SQL에서 조건을 기술하는 구문이다. Where 조건에 기술된 구문이 '참(true)'이 되는 범위만 쿼리 결과로 반환된다.

해커는 이 Where 조건이 무조건 참이 되도록 쿼리를 조작하여 Where 조건을 우회하게 만든다.

예를 들어, 다음과 같이 로그인을 처리하는 동적쿼리가 있다고 가정하자. 외부 입력값인 UserID와 Password가 쿼리문의 일부로 사용되고 있다.

SQL = "Select * From Users"

       + " Where UserID = '"+ UserID +"' And Password = '" + Password + "'"

먼저 SQL 구문의 주석(Comment)을 의도적으로 삽입하여 Where 조건을 무력화 시킬 수 있다. 다음과 같이 UserID 값에 주석을 삽입하면 주석 이하의 구문은 실행되지 않게 되어 admin이라는 계정의 패스워드를 몰라도 인증을 통과하게 된다. (admin이라는 ID는 이미 알고 있다고 가정한다. 그리고 -- 는 MS SQL Server의 주석이다. MySQL의 경우 #을 사용해야 한다.)

[ 외부 입력값 ]
UserID: admin'--
Password: 아무거나

[ 실행되는 쿼리문 ]
Select * From Users Where UserID = 'admin'-- And Password = '아무거나'

또한 항상 참이 되도록 Boolean 식을 구성하여 Where 조건을 무력화 시킬 수 있다. 다음과 같이 Password 값에 참(true)인 조건이 or 로 연결되도록 삽입하면 or 조건으로 인해 쿼리의 결과가 무조건 참이되어 없는 계정과 다른 패스워드라 할지라도 (여기서는 test라는 계정은 실제 db에 없는 계정임) 인증을 통과하게 된다.

[ 외부 입력값 ]
UserID: test
Password: 1234' or '1'='1

실행되는 쿼리문 ]
Select * From Users Where UserID = 'test' And Password='1234' or '1'='1'

이와 같은 방식을 이요하여 인증을 우회하기도 하지만, 직접 데이터베이스 내용을 조작할 수도 있다. 다음과 같이 ;(콜론)으로 명령어를 연결하면 한 줄로 된 두 개이상의 명령어를 연속해서 기입할 수 있는데 여기에 테이블을 삭제하거나 수정하는 조작된 쿼리문을 삽입할 수 있다.

[ 외부 입력값 ]
UserIDadmin' ; DELETE From Users--
Password아무거나

실행되는 쿼리문 ]
Select * From Users Where UserID = 'admin' ; DELETE From Users -- And Password='아무거나'


2) 고의적 에러 유발후 정보 획득
또다른 기법으로는 의도적으로 SQL 구문 에러를 유발하여 웹 애플리케이션이 내뱉은 오류 정보에 기반하여 유용한 정보를 알아 차린다. 그 정보는 연속되는 또 다른 공격의 소재로 사용되기도 한다.

기본적으로 웹 애플리케이션은 쿼리 수행 중 오류가 발생하면 DB오류를 그대로 브라우저에 출력한다. 이 오류 정보를 통해 DB의 스키마 정보나 데이터가 유출될 수 있다.

가령, SQL 쿼리문에서 UNION 은 두 테이블의 결과를 합치는 명령어이다. UNION으로 합쳐지는 두 테이블은 컬럼 갯수가 일치해야만 오류가 나지 않는다. 아래와 같이 컬럼 1개만 가진 대상 테이블을 가정하여 UNION 구문을 삽입해 보자.

[ 외부 입력값 ]
UserID: testUNION SELECT 1 --
Password아무거나

실행되는 쿼리문 ]
Select * From Users Where UserID = 'test' UNION SELECT 1 -And Password='아무거나'

테스트용 Users 테이블은 4개의 컬럼으로 구성되어 있다. 따라서 위의 쿼리문이 실행되면 다음과 같은 오류가 발생하여 브라우저에 노출된다.

"UNION, INTERSECT 또는 EXCEPT 연산자를 사용하여 결합된 모든 쿼리의 대상 목록에는 동일한 개수의 식이 있어야 합니다." (SQL Server 기준)

컬럼 수가 몇개인지 모르는 해커는 하나부터 둘,셋,.. 늘리면서 입력을 반복해서 시도해 볼 것이다. 마침 4개의 UNION SELECT를 하는 순간 오류가 발생하지 않음을 알고 이 기능의 원본 쿼리가 반환하는 컬럼의 수가 4개인 것을 알게 된다. (참고로 MS SQL Server에서는 UNION 되는 컬럼끼리 데이터 타입이 충돌나면 타입 오류를 발싱시키므로 컬럼 타입을 맞출 필요가 있다.)

[ 외부 입력값 ]
UserIDtest' UNION SELECT 1,1,1,1 --
Password아무거나

실행되는 쿼리문 ]
Select * From Users Where UserID = 'test' UNION SELECT 1,1,1,1 -And Password='아무거나'

이렇게 알아낸 컬럼 수를 기반으로 다음과 같이 시스템 테이블의 정보를 조회해 볼 수 있다. 다음의 쿼리가 실행되도록 SQL 구문을 주입하면 현재 데이터베이스에 존재하는 모든 테이블 목록을 볼 수 있다.
(아래 쿼리는 SQL Server 기준이다. 만일 MySQL이라면 information_scheme 데이터베이스의 테이블들을 사용하면 된다.)

Select * From Users Where UserID = 'test' UNION SELECT name, object, 1,1 FROM sys.tables -And Password='아무거나'

위와 같이 테이블 리스트 조회에 성공했다면, 테이블 목록 중 구미가 당기는 테이블을 선택해서 그 테이블에 저장된 데이터를 획득할 수 있다. 다음의 예에서는 결제(Payment)로그가 담긴 PaymentLog 테이블의 UserID와 카드 번호 유출을 시도하는 쿼리이다.

Select * From Users Where UserID = 'test' UNION SELECT UserID, CardNo, 1, 1 FROM PaymentLog -And Password='아무거나'

물론 이렇게 공격에 성공하려면 컬럼명도 알고 때론 타입도 알아야 할 경우가 생긴다. 과거에 정리했던, 아래의 글에서 컬럼명을 알아내거나 타입을 알아내는 방법을 참고하도록 한다.

[웹 보안 시리즈] 2. SQL INJECTION


3) 시스템 명령어 실행
MS SQL Server의 경우 시스템 명령을 실행할 수 있는 확장 프로시저를 제공한다. xp_cmdshell 프로시저를 이용한다. 다음과 같이 UserID 값에 ;(콜론)으로 xp_cmdshell 실행 구문을 연결하고 이후 구문은 주석처리 되도록 하여 윈도우 C 드라이버를 탐색하는 명령을 보낸다. 이 계정에 유효한 권한이 주어져 있다면 어떤 시스템 명령도 내릴 수 있게 된다.

[ 외부 입력값 ]
UserIDadmin' ; EXEC master.dbo.xp_cmdshell 'cmd.exe dir c:'--
Password: 아무거나

[ 생성된 쿼리문 ]
Select * From Users Where UserID = 'admin' ; EXEC master.dbo.xp_cmdshell 'cmd.exe dir c:'-- And Password='아무거나'

참고로 각 DBMS마다 SQL 구문이 조금식 차이가 나므로, SQL 인젝션 공격시 해당 DBMS가 지원하는 구문을 잘 알고 사용해야 한다. 다음의 사이트에서 각 DBMS별로 서로 상이한 구문을 상세히 안내하고 있으니 참고 바란다.

> SQL Injection Cheat Sheet


2. Blind SQL 인젝션

앞서 일반적인 SQL 인젝션 공격에서는 쿼리 조건을 무력화하여 인증을 우회하거나, 출력된 에러 내용에 기반하여 DB의 스키마 정보를 획득한 후, 쿼리 결과에 정보를 붙여서(UNION) 데이터를 유출하거나 시스템 명령어를 삽입하는 형태로 공격이 진행되었다.

그러나 만일 공격하는 대상 웹페이지가 어떠한 오류도 출력하지 않고 쿼리 결과 리스트도 제공하지 않는다면 이러한 공격 패턴으로는 해킹에 성공하기가 쉽지 않다. (다시말해, 에러 내용으로 DB 정보를 유추할 수도 없고, 쿼리 결과 데이터를 제공하지 않기 때문에 UNION 같은 쿼리를 삽입하여 데이터를 붙여 볼 수도 없는 것이다.)

이럴 경우, 유용하게 사용할 수 있는 공격 기법이 바로 Blind SQL 인젝션이다. 

한마디로, Blind SQL 인젝션은 쿼리 결과의 참/거짓으로부터 DB값을 유출해 내는 기법이다.

이 공격을 수행하려면, 먼저 웹 애플리케이션에서 쿼리 결과에 대해 참/거짓을 반환하는 요소를 찾아야 한다. 예를 들어 'ID 찾기'나 '게시판 검색'과 같은 기능에서 참/거짓을 판별하는 요소를 찾을 수 있다.


1) Boolean-based Blind 공격
가령 어느 웹사이트가 게시판 검색이라는 기능을 제공할 경우, 다음과 같이 참/거짓의 반환을 테스트 해 볼 수 있다.

[ 외부 입력값 ]
제목검색hello' AND 1=1-- (유효한 검색단어와 항상 참이되는 조건 부여)

[결과]
게시판 검색됨  --> 참(true)이으로 간주

---


[ 외부 입력값 ]
제목검색hello' AND 1=2--  (유효한 검색단어와 항상 거짓이 되는 조건 부여)

[결과]
게시물 검색 안됨 --> 거짓(false)으로 간주

'hello'라는 검색어에 항상 참인 조건(1=1)을 AND로 조합하니까 정상적으로 결과가 반환되었다. 반면 동일한 검색어(hello)에 항상 거짓인 조건(1=2)을 AND로 조합하니가 구성하니 게시판 검색이 되지 않았다. 이 둘을 참과 거짓의 반응으로 간주할 수 있다.

즉 핵심은 게시판 검색 기능을 참/거짓을 반환하는 요소로 사용할 수 있다는 점이다. 여기에 AND 조건으로 해커가 알고 싶은 쿼리 조건을 삽입해서 그 결과로부터 정보유출이 가능한 것이 Blind SQL 인젝션 공격 기법이며 이중에서도 AND 조건에 논리식을 대입하여 참/거짓 여부를 알아내는 방식을 Boolean-based Blind 공격이라 한다.

2) Time-based Blind 공격
앞서 게시판 검색에서는 검색 결과의 유,무로 참/거짓을 판별할 수 있었다. 그러나 어떤 경우에는 응답의 결과가 항상 동일하여 응답결과만으로는 참/거짓을 판별할 수 없는 경우가 있을 수 있다.

이럴때는 시간을 지연시키는 쿼리를 주입하여 응답 시간의 차이로 참/거짓 여부를 판별할 수 있다.

게시판 검색 시나리오에서 Time-based Blind 공격을 시도해 보자.

MS SQL Server 환경

[ 외부 입력값 ]
(DB의 시스템 계정이 sa 인지 판별하는 구문 삽입. 여기에서 검색어(hello)는 중요하지 않음)
제목검색: hello' ;  IF SYSTEM_USER='sa' WAITFOR DELAY '00:00:5'-- 

[실행되는 쿼리]
SELECT * FROM TB_Boards WHERE Title = 'hello' ;  IF SYSTEM_USER='sa' WAITFOR DELAY '00:00:2'

[결과]
1) 응답이 5초간 지연됨 -> 참(true) --> 시스템 계정이 sa임
2) 응답이 즉시 이뤄짐 -> 거짓(false) --> 시스템 계정이 sa가 아님

My SQL 환경

[ 외부 입력값 ]
(DB의 시스템 계정이 sa 인지 판별하는 구문 삽입. 여기에서 검색어(hello)는 중요하지 않음)
제목검색: hello AND sleep(5)#

[실행되는 쿼리]
SELECT * FROM TB_Boards WHERE Title = 'hello' AND sleep(5)

[결과]
1) 응답이 5초간 지연됨 -> 참(true) --> hello 검색어가 존재함
2) 응답이 즉시 이뤄짐 -> 거짓(false) --> hello 검색어가 존재하지 않음


이렇듯 Time-based Blind 공격은 쿼리 지연을 유도해 응답 시간에 걸리는 시간으로 참/거짓을 판별하게 함으로써 DB의 유용한 정보를 캐낼 수 있게 된다.

정리하자면, Blind SQL 인젝션은 쿼리 결과가 참일때와 거짓일때의 서버의 반응 만으로 데이터를 얻어낼 수 있는 SQL 인젝션 공격 기법이다. 이 기법은 많은 조건에 대한 비교과정을 거쳐야 의미있는 정보를 얻을수 있기 때문에, 거의 모든 경우 자동화 툴을 사용해서 공격이 진행된다.


Blind SQL 인젝션 공격 시나리오

해커는 게시판 검색 기능을 이용하여 회원 테이블의 비밀번호를 알아내고자 한다. 이미 다양한 공격 시도로 회원 테이블명이 Users라는 것을 알고 있거나 유추했다고 가정한다.

1. (앞서 해 본 것 처럼) 해커는 게시판 검색 기능으로 참/거짓을 판별할 수 있다는 것을 알아 냈다.

2. 해커는 회원 테이블에서 특정 회원의 비밀번호를 알아내고자 다음과 같은 쿼리를 주입한다.

(DB는 MS SQL Server 라고 가정함)

[ 외부 입력값 ]
hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 90

[ 실행되는 쿼리문 ]
SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 91

회원 테이블에서 'admin'이라는 계정의 패스워드를 알아 내려고 한 해커는....

항상 참(true)을 반환하는 조건(여기서는 게시판 제목 검색에 'hello'라는 검색어) 뒤에 AND 조건으로 회원 테이블의 패스워드에서 첫 문자를 가져와서 아스키코드로 변환하여 그 결과를 아스크 코드값과 비교한다. 먼저 대소분자 여부를 알아내기 위해 아스크 코드 91 보다 큰지 검사한다.

아스키코드 90은 대문자 'Z'의 아스키 값으로 이 값보다 크다는 말은 패스워드 첫 글자가 소문자로 구성되었다는 의미가 된다.(아스키 코드 테이블 참조)

패스워드 첫 글자가 소문자인 것을 알아낸 해커는 계속해서 다음과 같은 공격을 연속적으로 시도한다.

SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 110 -- true


SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 115 -- false


SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 113 -- false


SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 111 -- true


SELECT * FROM TB_Boards WHERE Title = 'hello' AND ASCII(LEFT((SELECT Password From TB_Users WHERE UserID = 'admin'), 1)) > 112 -- false

이렇게 총 6번을 시도해 본 결과, 패스워드 첫 글자가 소문자 'P' 라는 것을 알게 된다.
(111보다 크다는 조건에서는 true 값을, 112보다 크다는 조건에서는 false를 반환했으니 결과는 112로 영어 소문자 p가 되는 것이다)

이런식으로 한 글자씩 아스키값을 비교해서 전체 패스워드를 알아 나가는 방식으로 공격이 수행된다. 

SQL 인젝션 공격 실습

[ 경고 ]
허가 받지 않은 사이트에 해킹을 시도 하는 것은 불법입니다.
DVWA와 같이 테스트를 목적으로 셋팅된 사이트에 모의 해킹을 시도해야 법적 문제가 업습니다.


SQL 인젝션 취약성 판단

SQL 인젝션 공격을 시도하기 전에 공격 대상 웹 애플리케이션이 SQL 인젝션에 취약한지 먼저 알아 보는 것이 좋다. 보통 자동화 툴을 통해 스캐닝을 한번 쭉 해 보면 쉽게 알 수 있지만 간단한 테스트로도 알아 볼 수 있다. 

제일 간편하게 알아 볼 수 있는 방법은 사용자 입력값에 '(싱글쿼터)를 주입해 보는 것이다.

만일 싱글쿼터를 입력했는데, 사이트가 오류를 내 뱉으면 SQL 인젝션에 취약하다는 의미가 된다. 공격 대상 웹 애플리케이션의 다음과 같은 입력요소에 싱글쿼터 주입을시도해 볼 수 있다.

- 로그인 창
- 게시판 검색창
- 사이트 전역 검색창
- GET URL의 파라메타값
- 기타 외부입력값으로 보이는 모든 곳


DVWA 사이트에서 SQL 인젝션 공격 실습

1) (일반적인) SQL 인젝션 공격 실습

로컬에 셋팅된 DVWA 사이트(http://localhost/dvwa)를 브라우저로 접속하고 로그인(admin / password) 한다. 만일 DVWA 사이트에 접속되지 않는다면 XAMPP Control Panel에서 Apache와 MySQL 이 시작되었는지 확인한다.

DVWA 사이트가 로컬에 셋팅되지 않았다면, 다음 글을 참고하여 로컬 환경을 마련한다.

> [웹보안] 로컬 환경 셋팅과 툴 설치

DVWA 사이트에 접속하면 다음 화면과 같이 SQL Injection과 SQL Injection(Blind) 메뉴를 볼 수 있다. 먼저 SQL Injection 메뉴를 들어가서 SQL 인젝션 공격을 시도 해보자.

DVWA 사이트의 Security 레벨을 Low로 설정하는 것을 잊지 말자. Security 레벨에 대해서는 다음의 글을 참고한다.

https://m.mkexdev.net/426

이 페이지는 User ID를 입력하면 회원 정보를 간단히 출력하는 기능을 제공한다.
(DVWA 데이터베이스는 1~5까지의 User ID가 기본적으로 저장되어 있다. 1~5 중 아무거나 입력해서 테스트 해 보면 출력 결과를 볼 수 있다)

User ID라는 외부 입력값을 주입할 수 있는 기능을 찾았으니 이 페이지가 SQL 인젝션에 취약한지 먼저 테스트 해 본다. 앞서 설명 했듯이, '(싱글쿼터)를 입력해서 응답을 보니 오류 메시지가 출력되는 것을 확인할 수 있다. 따라서 이 페이지는 SQL 인젝션에 취약한 것을 확인한 것이다.

이제 User ID에 공격용 SQL 구문을 삽입해 보자. DVWA 사이트는 MySQL DB를 사용하므로 MySQL용 SQL 구문을 사용해야 한다.

다음은 SQL 구문 삽입에 대한 결과를 설명한다

1' or 1=1#  (결과)모든 User 정보가 노출되어 버림(조건이 항상 참이 되어 버려 모든 행(row) 출력)

1' union select 1,1# (결과)오류 없음. 즉 컬럼 갯수가 두개라는 것을 알아냄

1' union select schema_name, 1 from information_schema.schemata# (결과)서버의 데이터베이스 이름이 모두 노출됨

1' union select table_name, column_name from information_schema.columns where table_schema = 'dvwa'# (결과)dvwa 데이터베이스에 포함된 테이블과 컬럼이름이 모두 노출됨.

(MySQL의 information_schema는 해당 서버의 모든 DB의 메타정보를 저장해둔 데이터베이스이다. UNION 구문을 주입하여 information_schema에 있는 각종 정보를 조회해 볼 수 있다.)

이제 앞서 공격을 통해, dvwa라는 DB에 users라는 테이블이 있으며 이 테이블의 컬럼들을 모두 알아 내었다. 마지막 공격 테스트로 다음과 같이 users 테이블에 user 이름과 password를 조회해 보자

1' union select user,password from users# (결과) users 테이블의 모든 사용자에 대한 이름, 패스워드가 노출됨


2) Blind SQL 인젝션 공격 실습

이제 DVWA 사이트에서 Blind SQL Injection 메뉴로 이동하자. SQL Injection 메뉴와 동일하게 User ID를 입력받는 페이지가 로딩된다.

여기에 '(싱글쿼터)를 입력해보자. 

이번에는 아무런 오류가 나지 않는다. 즉 SQL 인젝션 공격에 취약한지 일단을 알기 힘들다.

그리고 정상적인 User ID를 입력해도 '아이디가 존재한다'는 안내 메시지만 노출될 뿐 특별한 추가 정보를 보여주진 않는다.

그렇다면 이제 이 페이지가 참/거짓을 판별할 수 있는 요소인지 테스트 해 보자. User ID에 다음과 같이 입력하고 결과를 보자.

1' AND a=b# (결과) User ID가 없다는 결과를 출력함

1' AND a=a# (결과) User ID가 존재한다는 결과를 출력함

존재하는 ID인 1을 입력하고 AND 조건으로 항상 참(true)이되거나 거짓(false)이 되는 조건을 주입하니까 그 결과로 서로 다른 결과를 보여준다. 여기서 우리는 이 페이지가 Blind SQL 인젝션에 활용할 수 있는 즉 참/거짓을 반환하는 요소임을 눈치 챌 수 있다.

이제 다음과 같이 Time based 공격을 시도해 보자.

1' AND sleep(5)# (결과) 응답시간이 5초가 걸림

6' AND sleep(5)# (결과) 즉각 응답함

존재하는 ID일 경우, 응답에 5초가 걸리는 것으로 보아 이 조건은 참이 되어 1이라는 ID가 존재한다는 의미가 된다. 반면 6을 입력하면 거짓이 되어 그 뒤의 조건인 sleep(5)가 실행되지 않아 즉각 반환하게 된다. 결국 여기서 우리는 6이라는 User ID는 존재하지 않는다는 것을 알 수 있다.

이제 참/거짓을 판별할 수 있는 요소를 이용해서 유용한 정보를 캐내어 보자

User ID가 1인 사람의 first_name을 알아 내는 과정을 시도해보자. 아래처럼 차례대로 입력해서 결과를 보자.

1' and ascii(substr(select first_name from users where user_id='1'), 1, 1) > 91# (결과) false

1' and ascii(substr(select first_name from users where user_id='1'), 1, 1) > 110# (결과) false

1' and ascii(substr(select first_name from users where user_id='1'), 1, 1) > 100# (결과) false

1' AND ascii(substr((select first_name from users where user_id='1'), 1, 1)) > 95# (결과) true

1' AND ascii(substr((select first_name from users where user_id='1'), 1, 1)) > 97# (결과) false

1' AND ascii(substr((select first_name from users where user_id='1'), 1, 1)) > 96# (결과) true

96보다는 크고(true) 97보다는 크지 않는 아스키코드의 문자는 바로 'a'가 된다. 이렇게 first_name의 첫 글자를 알아 내었다. 이런식으로 두번째, 세번째 글자를 하나씩 알아낼 수 있게 된다.


3) 툴을 이용한 자동화된 Blind SQL 인젝션 공격 실습

앞서 수동으로 Blind SQL 인젝션 공격을 시도해 보았다. first_name 하나만 알아내는데도 많은 비교 과정을 거쳐야 한다. 따라서 이와같은 공격은 툴로 자동화해서 시도하면 공격 효율이 훨씬 높아진다.

SQL 인젝션에 가장 흔히 사용되는 툴인 SQL Map를 사용해 볼 것이다.

[ SQL Map 설치(윈도우) ]

1) 파이썬 설치(SQL Map는 2.6.x 또는 2.7.x 버전에서만 동작함)

2) http://sqlmap.org 에서 ZIP 파일 다운로드 받아서 압축풀기

3) 명령프롬프트(cmd.exe)에서 해당 폴더로 이동 후 명령어 실행
    ex) python sqlmap.py --help

SQL Map 으로 다음의 명령을 실행할 것이다.

python sqlmap.py -u "공격 대상 URL" --cookie="사이트 쿠키값"

여기서 공격 대상 URL은 DVWA 사이트의 Blind SQL Injection 메뉴에서 User ID를 입력하고 전송(Submit)한 URL이 되며, 쿠키 정보는 크롬 브라우저 개발자도구(F12)에서 확인 가능하다.
(DVWA 사이트는 인증을 해야 들어갈 수 있기 때문에 인증값인 쿠키가 필요하다.)

이 명령어를 채워서 다음과 같이 공격을 시작해 보자.

python sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="security=low; _ga=GA1.1.1921041872.1534152252; PHPSESSID=8dknegkogthdhj1ibr615f9iqn"

다음과 같은 콘솔 결과를 확인할 수 있다.

콘솔의 내용을 보면, id라는 GET 파라메타를 이용해서 AND Boolean-based Blind 공격이 가능할 것 같다는 메시지를 확인할 수 있다. 그리고 데이터베이스가 MySQL 같아 보이며, 다른 DBMS에 대한 공격은 건너 뛸 것인지 물어보고 있다. 여기서 Y(기본값)를 입력하고 엔터를 친다.

그러면 다음과 같이 선택을 요구한다.

for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n]

MySQL 대한 모든 테스트를 포함할 것인지 두는 것인데 역시 Y(기본값)을 선택하고 다시 엔터를 친다.

이제 SQLMap이 공격을 자동을 수행한다. 중간중간에 옵션에 대한 질문이 나오면 기본값(Y)로 해서 계속 진행한다.

최종적으로 다음과 같이, id 파라메타가 취약하다는 것을 알리며 다른 파라메타를 계속 테스트 할 것인지 물어본다. 

GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N]

여기서는 N(기본값)을 선택하고 계속 진행하면 최종 결과가 다음과 같이 나타난다.

id 파라메타를 이용해서 boolean-based blind와 error-based, AND/OR time-based blind 공격이 가능하다고 알려 주고 있으며 웹서버의 종류와 버전, 개발언어, DBMS 종류와 버전을 알려준다.

이제 SQL 인젝션 공격이 가능하다고 나왔으니 본격적으로 공격을 시도해 보자.

DB 명 알아내기
다음 명령어를 실행해서 DB 명을 알아 낼 수 있다.

python sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="security=low; _ga=GA1.1.1921041872.1534152252; PHPSESSID=8dknegkogthdhj1ibr615f9iqn" --current-db

명령이 실행되면 콘솔 출력에 다음과같이 DB명이 나타난다.

current database:    'dvwa'

테이블명 알아내기
DB명을 알아 냈으니 이번에는 다음의 명령어로 해당 DB에 존재하는 테이블들을 조사해 보자.

python sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="security=low; _ga=GA1.1.1921041872.1534152252; PHPSESSID=8dknegkogthdhj1ibr615f9iqn" -D dvwa --table

결과를 보면 dvwa 데이터베이스에는 guestbook과 users라는 테이블이 존재한다는 것을 확인할 수 있다.

테이블에 저장된 데이터 알아 내기
users가 회원테이블임을 직감하고 이 테이블의 내용을 획득하고자 한다. 다음의 명령어를 실행한다.

python sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit" --cookie="security=low; _ga=GA1.1.1921041872.1534152252; PHPSESSID=8dknegkogthdhj1ibr615f9iqn" -T users --dump

결과는 users 테이블에 저장된 모든 회원정보가 나타난다. 샘플 화면에는 admin, Brown 이라는 사용자가 있고 패스워드가 해시된 형태로 저장되어 있음을 확인할 수 있다.

이어서 SQLMap은 다음과 같이 해시된 패스워드를 사전 공격(Dictionary Attack)으로 크래킹 시도를 할 것인지 물어본다. 이때 어떤 사전(Dictionary)파일을 사용할 것인지 확인한다. 모두 기본값으로 계속 진행한다.

해시된 패스워드를 사전 공격으로 하나씩 크래킹을 시도한다.

공격 시도가 완료되었다. 결과를 보면 users 테이블의 모든 내용이 출력되었으며 해시된 패스워드도 크래킹되어 평문으로 노출되었다. 그리고 친절하게도 csv 파일로 저장했다고 알려 주고 있다.

테스트 시나리오 이지만, 이런 식으로 회원테이블이 유출되면 정말 끔찍할 것이다.


SQL 인젝션 대응 방안

SQL 인젝션 공격에 대응하기 위한 방법들을 알아보자. 여러 측면에서 전방위적인 대응이 필요하겠으나 여기서는 기술적인 부분만 다루도록 한다. 다음은 3가치 축으로 정리해 본 모습이다.


웹 방화벽(WAF) 도입

웹 방화벽은 HTTP/HTTPS 응용 계층의 패킷 내용을 기준으로 패킷의 보안성을 평가하고 룰(Rule)에 따라 제어한다. SQL 인젝션의 룰(Rule)을 설정하여 공격에 대비할 수 있다.

1. 물리적 웹 방화벽
기업의 규모가 어느정도 되거나 보안이 중시되는 환경 또는 예산이 충분한 환경에서는 물리적인 전용 WAF 사용을 권장한다. 어플라이언스 형태의 제품을 사용하거나 SECaaS 형태의 클라우드 기반의 솔루션을 도입할 수도 있다.

2. 논리적 웹 방화벽(공개 웹 방화벽)
전용 웹방화벽 장비를 도입할 여력이 되지 않는다면, 공개 웹방화벽을 고려해 볼 만 하다. 대부분 공개 웹 방화벽은 물리적인 장비가 아닌 논리적인 구성으로 웹 방화벽 역할을 수행한다.

윈도우 서버 환경에서는 WebKnight, 아파치 서버 환경에서는 ModSecurity를 사용할 수 있다.

ModSecurity는 OWASP(세계적인 웹 보안 커뮤니티) 에서 무료 탐지 룰(CRS)을 제공하며 이를 통해OWASP TOP 10 취약점을 포함한 웹 해킹 공격으로부터 홈페이지(웹서버) 보호가 가능하다.

WebKnight는 웹서버 앞단에 필터(ISAPI) 방식으로 동작, 웹서버로 들어오는 모든 웹 요청에 대해 사전에 정의한 필터 룰에 따라 검증하고 SQL 인젝션 공격 등을 사전에 차단 할 수 있다

- 웹서버 보안 강화 안내서 (->바로가기)


시큐어 코딩

1. 입력값 유효성 검사

모든 웹 보안 영역에서는 외부 입력값에 대한 대전제가 하나 있다.

모든 외부 입력값은 신뢰하지 말라

SQL 인젝션에서도 마찬가지이다. 외부에서 들어오는 모든 입력값은 모두 의심의 대상이다.
여기서 외부 입력값은 이용자가 직접 타이핑한 값일 수도 있지만 직접 타이핑 하지 않더라도 Burp Suite와 같은 프록시 툴을 이용하여 중간에 값을 변조할 수 있는 외부 값도 포함된다. (가령 게시판에서 게시물 번호와 같은..)

SQL 인젝션의 가장 기본적인 대응 전략은 바로 입력값의 유효성을 검사하는 것이다. 입력값 검증에는 두 가지 방식이 존재한다.

1) 블랙 리스트 방식
SQL 쿼리의 구조를 변경시키는 문자나 키워드를 제한하는 방식이다. 아래와 같은 문자를 블랙리스트로  미리 정의하여 해당 문자를 공백 등으로 치환하는 방식으로 방어한다.

DBMS 종류에 따라 쿼리의 구조를 변경시키거나 쿼리문의 일부로 사용되는 문자 필터링

(특수문자) ' , " , = , & , | , ! , ( , ) , { , } , $ , % , @ , #, -- 등

(예 약 어) UNION, GROUP BY, IF, COLUMN, END, INSTANCE 등

(함 수 명) DATABASE(), CONCAT(), COUNT(), LOWER() 등


2) 화이트 리스트 방식
블랙리스트 방식보다 보안성 측면에서는 훨씬 강력한 방법이다. 블랙리스트 방식에서는 금지된 문자 외에는 모두 허용하지만 화이트리스트 방식에서는 허용된 문자를 제외하고는 모두 금지하는 방식이다. 

지정된 문자만을 허용하기 때문에 웹 애플리케이션의 기능에 따라 화이트리스트를 다르게 유지해야 할 필요가 생긴다. 그리고 

참고로 화이트 리스트를 정의할 때에는 개별 문자를 일일이 하나씩 모두 정의하는 것보다 정규식을 이용해서 범주화/패턴화 시키는 것이 유지보수에 더 유리하다.


2. 동적 쿼리 사용 제한

1) 동적 쿼리 금지
웹 애플리케이션이 DB와 연동할 때 정적쿼리만 사용한다면 SQL 인젝션을 신경 쓸 필요가 없다. 하지만 현실적으로 동적 쿼리를 사용하지 않을 수 없을 것이다. 근래의 웹 애플리케이션은 모두 사용자와 상호작용하며 동적인 기능을 기반으로 하기 때문에 동적 쿼리 사용은 거의 필수에 가깝다.

2) 매개변수화된 쿼리(구조화된 쿼리) 사용
동적 쿼리를 정적쿼리 처럼 사용하는 기법이다. 쿼리 구문에서 외부 입력값이 SQL 구문의 구조를 변경하지 못하도록 정적구조로 처리하는 방식인데 이를 파라메타화된(매개변수화된) 쿼리라 한다.

자바 환경에서 JDBC API를 사용하는 경우, 구조화된 쿼리를 지원하는 PreparedStatement를 사용할 수 있다. 닷넷에서는 SqlCommand를 사용하면 파라메타화된 쿼리를 사용할 수 있다.

[ 참고 ]
OWASP의 SQL 인젝션 대응 문서를 보면 각 언어별로 파라메타화된 쿼리 사용을 위한 가이드와 코드 샘플을 안내하고 있으니 참고하기 바란다.

SQL Injection Prevention Cheat Sheet


(일부 발췌)
Language specific recommendations:

Java EE – use PreparedStatement() with bind variables
.NET – use parameterized queries like SqlCommand() or OleDbCommand() with bind variables
PHP – use PDO with strongly typed parameterized queries (using bindParam())
Hibernate - use createQuery() with bind variables (called named parameters in Hibernate)
SQLite - use sqlite3_prepare() to create a statement object

추가로 행정안전부에서 발간한 시큐어코딩 가이드를 보면 자바 기준에서 JDBC, MyBatis, Hibernate 사용환경에서 안전한 코딩 기법을 제시하고 있으니 참고 바란다.

> 시큐어 코딩 가이드


3. 오류 메시지 출력 제한

1) DB 오류 출력 제한
DB의 오류 정보를 그대로 이용자에게 노출해서는 안된다. DB 오류 정보에는 개발자들이 쉽게 디버깅할 수 있도록 내부 정보를 상세히 알려주는 경우가 많다. 해커는 이 정보를 바탕으로 DB 구조를 파악하고 데이터 유출을 시도할 것이다. 따라서 DB 오류가 적나라하게 이용자에게 노출되지 않도록 커스텀 오류 페이지를 제공해야 한다.

2) 추상화된 안내 메시지
또한 너무 자세한 안내 메시지도 주의할 필요가 있다. 가령 로그인을 실패 했을 때, ID가 틀렸는지 Password가 틀렸는지 꼭 집어 알려줄 필요가 있을까? 오히려 이 정보는 해커들에게 공격의 범위를 좁혀주는 결과로 이질 수 있다. 단지 '로그인 정보가 일치하지 않습니다'와 같이 추상적인 메시지가 (약간의 사용성을 해치더라도) 더 나을  때도 있다.


DB 보안

1. DB 계정 분리
관리자가 사용하는 DB 계정과 웹애플리케이션이 접근하는 DB 계정은 반드시 분리되어야 한다. 간혹  귀찮다는 이유로 관리자의 DB계정을 여기저기 다 사용하는 경우가 있다. 반드시 분리 하도록 한다.

2. DB 계정 권한 제한
웹 애플리케이션이 DB에 액세스하는 전용 계정을 생성하고 이 계정에는 최소 권한 원칙에 입각하여 꼭 필요한 권한만 할당한다. 과연 웹애플리케이션에서 DROP TABLE와 같은 DML을 실행할 필요가 있는가? 아마 대부분은 필요치 않을 것이다. 또한 웹에서 DB의 기본 프로시저나 확장 프로시저를 호출할 필요가 있는가도 따져 볼 일이다.

웹 애플리케이션이 제공하는 기능만 수행가능하도록 권한을 제한한다.

참고로 필자의 과거 경험을 보자면, 모든 DB 액세스는 저장 프로시저로만 가능하도록 하고 계정 권한은 해당 프로시저들의 실행 권한만 부여한 적이 많았다.

또 한가지 팁은, SELECT 권한과 INSERT, UPDATE, DELETE 권한을 분리하여 서로 다른 계정으로 접근하도록 구성할 수도 있다. 이 경우 SELECT 권한으로 SQL 인젝션 공격이 들어와도 데이터베이스를 업데이트 할 수 없게 된다.

3. 기본/확장 저장 프로시저 제거
데이터베이스가 설치될때 기본적으로 포함된 프로시저들을 꼭 필요한 경우가 아니라면 제거하는 것이 좋다. 가령 MS SQL Server의 xp_cmdshell 프로시저는 db에서 시스템 명령어를 실행할 수 있도록 하는 확장 프로시저이다. 거의 대부분의 웹 애플리케이션에서는 이러한 확장 프로시저를 호출할 필요가 없을 것이다.


취약점 점검과 모니터링

1. 지속적 취약점 점검
SQL 인젝션 취약점을 정기적으로 점검해야 한다.

모의 해킹을 시도하거나 웹 취약점 점검 툴을 이용해 주기적인 취약점 점검이 권장된다.

비즈니스가 활발히 진행되는 만큼 웹사이트의 업데이트도 빈번할 것이다. 간단한 이벤트 페이지라고 하더라도 DB연동을 하는 경우, 언제나 SQL 취약점에 노출될 수 있다는 것을 명심해야 한다. 

다른 모든 곳에 보안을 튼튼해 해 뒀더라도, 이벤트 페이지 하나 때문에 해킹을 당하는 수가 빈번히 있음을 주의해야 할 것이다.

2. 로깅과 모니터링
SQL 인젝션은 많은 경우 오류를 유발시키거나 동일한 페이지나 기능을 반복적으로 호출하는 형태로 공격이 이뤄진다. 따라서 유달리 500 오류가 많이 발생하거나 동일한 IP에서 동일한 페이지를 반복적으로 호출할 경우 요주의 대상으로 주의깊에 살펴야 한다.

이상현상에 대한 기준과 임계를 설정하고 해킹 시도로 판단될 시, 즉각 알림이 전송되어 바로 조사가 가능한 체계를 갖추는 것이 좋다.

[ 참고 ]

OWASP에서는 SQL 인젝션 공격에 대응하는 가이드를 제공하고 있다. 이 페이지에서 보다 상세한 방어 기법을 확인할 수 있다

SQL Injection Prevention Cheat Sheet


[웹보안] 브루트 포스(BRUTE FORCE) 공격

Posted in SW개발 // Posted at 2019. 1. 23. 22:30
728x90

INTRO

불과 '반년 전 즈음(2018.06)에 브루트 포스(Brute Force) 공격이 대형 은행을 겨냥 시도되었습니다.

이 사건은 (적어도 당시에는) 다행히 실제 금전적인 피해로 까지는 이어지지는 않은 것 같네요.

공인인증서나 OTP가 해킹된 것이 아닌만큼 출금/이체와 같은 서비스는 건드리지 못했을 겁니다.

하지만 정보유출이라는 측면에서는 꽤나 성공적이여서 고객 정보 56,000건이 유출되었다고 합니다.

유출된 고객의 개인 정보를 악용해 2차 피해가 어떤 식으로 유발될지는 알 수 없는 노릇이죠.

보다 자세한 내용은, 다음의 KBS 보도 영상과 관련 기사를 참고하기 바랍니다.


80년대 초에 성행 했다던 브루터포스 공격은, 구식 공격기법이라는 인식과 너무 단순한 공격기법이라는 측면에서 기술이 발전한 근래에는 많이 행해지지 않을 것 같지만 드문드문 사례가 보이네요.


아래에 링크는 '2017년에 발생한 워드 프레스를 대상으로한 대규모 분산 무차별 대입 공격'에 대한 기사입니다.

마치 DDoS처럼 공격에 동원된 IP 수도 많고 각 IP가 막대한 수의 공격을 행했다는 기사를 확인할 수 있습니다. 이 기사에는 공격에 대한 대비책도 안내하고 있으니 참고하면 좋을 것 같습니다.

워드프레스를 대상으로 대규모 무차별 대입 공격(Brute Force Attack) 발생


그리고 '2014년에는 iCloud 해킹으로 헐리우드 스타들의 사적인 누드 사진들이 인터넷으로 배포'되는 사건이 있었습니다. 이 역시 브루터 포스 공격이 기반이 된 해킹 사례로 언급되는 듯 합니다.

Apple Patches Brute Force Password-Cracking Security Hole in iCloud


그리고 꽤 오래전 우리나라에서 발생한 재미있는 에피소드가 있는데요...

1993년 '청와대 해킹사건'때 김재열이란 분이 수동으로 브루터포스 공격을 시도해 국제심판소의 PC통신 비밀번호를 알아 내었다고 합니다. (이때 국제심판소의 비밀번호는 무려 '12345'이였다고 하네요.)

> '국내 해커1호' 김재열의 인생유전


브루터 포스 공격은 단순하고 식상한 기법인 듯 하지만, 지금 이순간에도 많이 행해지고 있는 공격 기법입니다. 또한 공격이 성공했을 경우 파급력이 상당하기 때문에(내 계정을 해커가 장악했다고 생각해 보세요 =.=) 보안 개발자가 절대로 간과해서는 안될 것입니다.

브루터 포스 공격의 정확한 원리와 공격 방법, 대응 방안을 잘 숙지하시기 바랍니다.


1. 브루트 포스(Brute Force) 공격이란?

당신은 지금껏 살면서, 

누군가의 비밀번호를 알아 내기 위해 임의로 접근을 시도해 본 적이 없었는가?

그것이 자물쇠 비밀번호이든, 휴대폰 비밀번호이든, 웹사이트 비밀번호이든 말이다. 만일 그런적이 있다면, 당신은 이미 브루트포스 공격을 해 본 경험이 있는 것이다.

컴퓨터 분야의 브루터포스(Brute Force)란 용어는 '억지 기법(무차별 대입해 억지로 문제를 푸는)'이라 해석되며 개념적으로 아주 단순한 공격 기법이다..

특정 암호를 풀기 위해 임의의 문자의 조합을 하나씩 대입해 보는 공격 기법이다.

브루터포스 공격은 암호를 사용하는 모든 곳에 행해질 수 있다. 

암호가 걸린 파일, SSH 접속, FTP 접속, 웹사이트 회원 로그인 등이 그 대상이 될 수 있다.

다만, 이 글에서는 웹 사이트 회원 로그인에 대한 공격과 방어에 초점을 맞출 것이다.

브루터 포스 공격을 위해, 임의의 문자열을 생성/조합하고 대입하는 방법으로는 다음과 같이 두 가지로 형태로 나눌 수 있다.


1.1 브루터 포스 공격을 위한 문자열 생성 및 대입 방법

1.1.1 무작위 순차 대입

브루터포스의 무차별 대입이라는 특징을 그대로 구현하는 것으로, 조합 가능한 모든 문자열을 순차적으로 하나씩 모두 대입해 보는 것이다. 그야말로 무식하게 암호가 일치할때 까지 모든 경우의 수를 조합해 대입을 시도한다.

이론상으론 공격에 충분한 시간만 주어진다면 (모든 문자에 대한 조합을 시도해 볼 수 있기 때문에) 언젠가는 비밀번호를 맞히게 될 것이다.

다만 현실적으로는 암호의 길이와 복잡도의 증가에 따라 공격에 걸리는 시간이 기하급수적으로 늘어나므로 무조건 성공한다고 보기 어렵다.

무작위 순차 대입의 공격의 소요 시간을 줄이기 위해 미리 정의된 문자열 목록을 이용하기도 하는데, 이어서 알아보자.


1.1.2 사전(Dictionary) 대입

상당한 시간이 소요되는 무작위 순차 대입 방식 단점을 극복/보완하는 방법으로, 미리 정의된 문자열 목록을 대입하는 방법이다.

사전 파일을 이용한 공격이라고 해서 '사전 공격(Dictionary Attack)' 이라 한다..

미리 정의된 비밀번호 사전(Dictionary)을 준비하여 하나씩 대입해 보는 방식이다. 여기서 사전(Dictionary)파일은 그동안 통계적으로 많이 사용되어 오거나, 사람들이 흔히 사용할법한 비밀번호 조합을 미리 목록 형태로 정의해 둔 파일이다.

사람들은 의외로 단순한 비밀번호를 많이 사용하며 또한 여러 서로 다른 사이트에 걸쳐 동일한 비밀번호를 사용하기도 한다.

이런 환경에서, 사전 대입 방식은 브루터 포스 공격에 소요되는 시간을 극적으로 줄이면서도 공격 성공률을 높이는 아주 효율/효과적인 공격 기법이다.

비밀번호에 대한 '사전(Dictionary) 파일'은 인터넷에서 아주 쉽게 구할 수 있다.

예를 들어, 구글 검색엔진에 'password dictionary file'이라고 검색하면 수 많은 비밀번호 목록을 얻을 수 있다.


1.2 Brute Force in OWASP TOP 10 2017

OWASP TOP 10에서도 브루터포스 공격과 관련한 보안 위험 항목을 제시하고 있다.

TOP 10의 2위에 포지셔닝한 'A2. 취약한 인증'에서 브루터 포스 위협을 언급하고 있다.



2. 브루트 포스(Brute Force) 공격 실습

[ 경고 ]

허가 받지 않은 사이트에 해킹을 시도 하는 것은 불법입니다.

DVWA와 같이 테스트를 목적으로 셋팅된 사이트에 모의 해킹을 시도해야 법적 문제가 업습니다.


앞서 언급한 청와대사건의 김재열씨처럼,
스스로 추측한 비밀번호를 사용해 수동으로 브루터포스 공격을 시도해 볼 수 있다. 즉 직접 사이트에 접속해서 로그인 해 보는 것이다.

아마 공격자는 지인이나 다른 사람의 아이디 몇개 정도는 이미 알고 있을 것이며, 그들에게 의미있는 숫자나 문자(생일 or 전화번호 or 이성친구 이름 등)를 추가로 알고 있다면 이를 바탕으로 직접 로그인을 시도해 볼 수 있다.

또한 흔히 관리자 계정으로 사용되는 admin 이나, master와 같은 아이디와 1234, qwer과 같은 비밀번호로 직접 로그인을 시도해 볼수도 있을 것이다.

그러나 정말 의심되는 아이디와 비밀번호가 있는게 아니라면, 수동 공격은 매우 비효율적이다. 

부분의 브루터포스 공격은 툴을 이용한 자동화된 공격을 수행한다.

이제부터 툴을 이용해 브루터포스 공격을 실습해 보자.

해킹에 사용되는 툴의 설치와 사용법은 아래 링크에서 확인할 수 있다.

[웹보안] 로컬 환경 셋팅과 툴 설치


2.1 무차별 대입 공격 시도

2.1.1 DVWA 사이트 접속

먼저 XAMPP Control Panel을 실행해서 Apache 웹서버와 MySQL 데이터베이스를 시작한다.

서비스가 정상적으로 시작되었다면, http://localhost/dvwa 로 접속하여 DVWA 사이트로 접속한다.

로그인 창이 뜨면 DVWA의 기본 계정인 'admin / password'를 입력하고 로그인 한다.

로그인 후, 좌측 메뉴에서 DVWA Security를 클릭하고 Security Level을 Low로 변경한다.

[ DVWA의 Security Level ]

DVWA는 4단계(Low-Medium-High-Impossible)의 Security Level을 제공한다.

보안 조치가 전혀 이뤄지지 않은 Low 단계부터 점차 보안성이 강화되어 취약점으로부터 안전한 Impossible 단계까지 총 4단계로 구성되어 있다.

각 단계별로 방어 전략이 다르며 단계가 높을 수록 더 안전한 코드로 구현되어 있다.

이렇게 단계를 구분하고 각 단계별로 안전한 코드 구현을 안내하여 모의 해킹과 방어에 대한 학습을 보다 용이하도록 지원하고 있는 것이다.



Security Level 설정을 마쳤으면, 다시 좌측 메뉴에서 Brute Force 를 클릭한다.

이 메뉴에수는 Brute Force 공격을 시도해 볼 수 있도록 개발된 로그인 폼을 제공한다.


2.1.2 Burp Suite 실행

Burp Suite를 실행해서 Temporary project를 기본값으로 하여 생성한다.

DVWA 사이트의 로그인 요청에 대한 패킷을 캡쳐할 것이다.

패킷 캡처를 하기 위해서는 브라우저에 프록시 설정이 되어 있어야 한다.

[웹보안] 로컬 환경 셋팅과 툴 설치에서 브라우저의 프록시 설정을 참고해서 설정하자.

앞에서, 접속한 DVWA 사이트의 Brute Force 메뉴에서 admin / 1234로 로그인 해 본다.

이 로그인 요청 패킷이 Burp Suite에 의해 캡쳐되었을 것이다. 

Proxy메뉴 HTTP history 탭에서 해당 요청을 Intruder로 보낸다. (해당 요청을 우클릭하여 'Send to Intruder'를 선택한다.)

그리고 Burp Suite의 Intruder 메뉴를 클릭한다.

Intruder 메뉴Positions 탭에서 아래와 같이 password 부분만 § 로 감싸준다.(§로 감싼 부분은 다른 값으로 치환되는 부분임을 지정한다. 일종의 변수인 셈이다.)

처음엔 많은 부분이 §로 감싸져 있을 것이다. 우측의 'Clear §' 버튼을 클릭해서 §로 감싼 부분을 모두 제거하고 password 값(여기서는 1234)만 선택하여 우측의 'Add §' 버튼을 클릭한다. 그러면 password 값만 §로 감싸질 것이며 이 부분의 값이 계속 대입되면서 요청이 전송됨을 의미한다.

다음으로 Payloads 탭으로 가서 Payload type를 Brute forcer로 선택한다.

Brute forcer로 선택하면 아래 화면에 Character set가 자동으로 생성되어 있는 것을 확인할 수 있다.

기본값은 'abcdefghijklmnopqrstuvwxyz0123456789'로 되어 있다. 

Character set에 문자열은 브루터포스 공격의 무작위 순차 대입을 위한 기준 문자이다. 이 기준 문자가 많으면 많을 수록 공격 시도 횟수와 시간은 증가한다. 그만큼 많은 조합을 시도해야 하기 때문이다.

우리는 이미 admin의 비밀번호가 'password'라는 것을 알고 있다.

테스트 시간 단축을 위해서 Character set 값을 'adoprsw'로 변경한다. 그리고 길이를 8으로 변경한다.

(이렇게 기준 문자열을 줄여도 조합의 수는 꽤 크다. Payload count를 보면 5,764,801라고 나와 있는데 총 조합 가능한 문자열의 수이다. 즉 이만큼의 요청이 발생한다는 의미이기도 하다.)

이제 설정이 마무리 되었다. 

우측 상단에 있는 'Start attack' 버튼을 클릭해서 공격을 시작해 본다.


브루터포스 공격을 시작하면 다음과 같이 자동으로 문자열을 조합해서 하나씩 요청을 보내게 된다. 여기서 조합된 문자열은 앞서 설정한 패스워드 값('$로 감싸진 값)에 하나씩 대입된다.

언젠가는 password로 조합된 문자열을 보내게 될 것이며 이때 응답의 상태나 응답의 크기가 상이한 요청이 바로 공격에 성공한 것일 가능성이 크다. 

요청에 대한 응답의 구조는 웹 사이트마다 다를 수 있으므로 그 결과고 획일적이지는 않을 것이다.

DVWA에서는 로그인 성공과 실패시 페이지 내용이 조금 상이하므로 응답의 크기(Length)가 다른 것이 공격에 성공한 요청이 된다.


2.2 사전(Dictonary) 공격

이번에는 미리 정의된 패스워드 목록 파일(사전 파일)을 가지고 공격을 시도해 보자.

패스워드 사전은 인터넷에 많이 있지만, 여기서는 간단하게 테스트 하기 위해 다음과 같이 직접 생성한다.(아래와 같이 입력하고 pass.txt 파일로 저장한다.)

[pass.txt의 내용]

123456
qwer1234
password
iloveyou

그리고 아래 화면과 같이, Payload type을 'Simple list'로 변경하고 그 아래에 Simple list 파일을 'Load'하여 앞서 생성한 pass.txt 파일을 불러 온다. 

파일을 정상적으로 불러 왔으면 우측 상단의 'Start attack' 버튼을 클릭해서 공격을 시작한다.


공격 결과를 보면 아래와 같이 password 문자열로 보낸 요청의 응답은 다른 요청과 비교해 응답 길이(Length)가 다른것을 확인할 수 있다. 또한 응답된 html 에서도 로그인 성공시 나타나는 문구가 보인다.

즉 해커는 공격이 성공하여 password가 비밀번호 인 것을 알게 된 것이다. 이제 부터 admin 계정의 권한으로 사이트에 해를 입힐 수 있게 된 것이다.


3. DVWA에서 브루터 포스 공격에 대응하는 방법 알아보기

앞서, DVWA에서는 Security Level을 4단계로 구분하여 각 단계별로 강화된 보안성을 제공한다고 하였다. DVWA에서는 브루트포스 공격을 어떤 식으로 방어하는지, 각 단계별로 살펴보자.


3.1 Low 단계

아무런 보안 조치가 이뤄지지 않은 매우 취약한 상태이므로 당연히 어떠한 방어 코드도 구현되어 있지 않다.


3.2 Medium 단계

DVWA Security 메뉴에서 단계를 Medium으로 변경하고 다시 Brute Force 메뉴로 와서 잘못된 정보로 로그인을 시도해 보자. 

로그인 실패시 응답 시간이 (Low 단계에 비해) 좀더 오래 걸린다는 것을 느낄 수 있다.

하단의 'View Source' 버튼을 클릭해서 소스를 보면 아래와 같이 로그인 실패시 약 2초간 시간 지연을 두고 있다. 

이는 자동화된 브루터 포스 공격의 시간을 지연시킴으로써 공격 시간을 더디게 만들기 위해서이다.


3.3 High 단계

이번에는 Security 레벨을 High로 변경하고 다시 시도해 보자. 로그인 실패시 응답시간이 빠르기도 하고 느리기도 할 것이다.

코드를 보면 다음과 같이 구현되어 있다. 

로그인 실패시 시간 지연을 획일적으로 2초로 하지 않고, 0~3초 사이에 랜덤한 값으로 지정하고 있다.

이는 획일된 반응 시간은 해커로 하여금 지연시간을 추측할 수 있게 만들고 해커는 추측된 지연 시간을 감안해 공격을 자동화 할 수 있기 때문이다. 즉 보다 보안성이 강화되었다고 할 수 있겠다.


3.4 Impossible 단계

가장 보안조치가 강력하게 구현된 단계이다.

로그인 실패를 시도해 보면 다음과 같은 안내 문구가 나타난다. 15분 동안 계정이 잠겼다는 내용이다.

소스코드를 보면 High 단계의 랜덤 지연 시간에 더하여, 로그인 횟수와 최종 로그인 시간을 DB에 저장하여 계정 잠금의 기준으로 삼고 있다. 코드 구현은 보다 복잡해 졌지만 사이트의 안전성은 높아졌다.

지금까지 DVWA에서 브루트 포스 공격을 어떻게 대응하는지 살펴 보았다. 이를 포함하여 전방위적인 보안 대첵을 이어서 알아보자.


4. 브루트 포스(Brute Force) 공격 대응 방안

웹 보안을 위한 조치사항은 주로 웹 서비스를 제공하는 기업 입장에서 대응해야 하지만 브루트 포스 공격은 웹 사이트를 이용하는 이용자 역시 주의를 기울일 필요가 있다.

따라서 이용자 관점과 기업 관점의 두 가지 측면에서 대응 방안을 살펴 보자.


4.1 이용자 관점 대응 방안

4.1.1 안전한 패스워드 사용

오랜동안 사람들은 기억하기 편하다는 이유로 허술한 비밀번호를 사용해 왔다.

'이거 실화냐?' 가장 많이 쓰이는 쉬운 암호 12가지


허술한 자물쇠로 자신의 집이나 금고를 보호하고 싶지는 않을 것이다. 온라인 세상에서 탄탄한 자물쇠를 다는 첫번째 방법은 안전한 비밀번호를 사용하는 것이다.


1) 길고 복잡한 비밀번호 사용

비밀번호는 길면 길수록 그리고 복잡하면 복잡할수록 알아내기 힘들다. 

무작위 대입 방식의 브루트 포스 공격은 가능한 문자열 조합을 순차적으로 모두 시도해 보는 것이기 때문에 비밀번호가 길고 복잡해 질 수록 공격에 소요되는 시간은 기하급수적으로 늘어난다

따라서 가장 기본적인 대응방안은 길고 복잡한 비밀번호를 사용하는 것이다.

아래의 사이트에서 비밀번호의 안전성을 테스트 해 볼 수 있다.

https://howsecureismypassword.net/

아래 화면은 비밀번호 '1234'로 테스트 해 본 결과이다. 암호가 크래킹되는데 걸리는 시간이 'INSTANTLY(즉시)' 이다. 그리고 비밀번호가 숫자로만 이뤄졌고 매우 짧다고 경고하고 있다.


다음으로 비밀번호를 길고 복잡하게 'dnpqqhdks@7#9'로 테스트 해 볼 결과이다. 비밀번호를 알아 내는데 엄청난 시간이 소요되므로 안전하다고 알려 주고 있다.


2) 유추하기 힘든 패스워드 사용

일반적으로 사람들은 자신이 기억하기 쉽게 하기 위해, 자신의 개인 정보와 비밀번호를 연관시키는 경우가 많다.

예를 들어 자신의 생일, 기념일, 차량번호, 휴대전화번호 같은 것들을 비밀번호로 사용한다.

이런 개인적 의미의 비밀번호는, 특히 그(그녀)를 알고 있는 누군가는 쉽게 유추할 수 있는 비밀번호이다. 기억하기 바란다. 가장 흔한 브루터 포스 공격은 당신 지인의 행위일 수도 있다는 것을...

또한 개인정보와 연관되지 않더라도 쉽게 유추할 수 있는 비밀번호가 있는데, 아래와 같이 통계적으로 많이 사용되어온 의미있는 단어들이다.

football, qwertyuiop, 123qwe, iloveyou, rainbow, alaska, ....

이런 단어들의 목록은 인터넷에서 아주 쉽게 구할 수 있다.

'사전 공격'에서 사용되는 파일에는 수천만개 이상의 비밀번호 조합이 존재한다. 따라서 유추하기 힘든 자신만의 비밀번호 조합을 사용하는 것이 좋다.


4.1.2 서로 다른 사이트에는 서로 다른 비밀번호 사용

우리은행 해킹 사례에서도 보듯이 서로 다른 사이트에 동일한(또는 거의 유사한) 비밀번호를 사용하는 것은 피해가 확대되는 결과로 이어진다.

한 사이트에서 탈취한 계정 정보는 다른 사이트의 브루터 포스 공격용 '사전(Dictionary)'으로 사용된다.

따라서 서로 다른 사이트라면 서로 다른 비밀번호 사용을 권장한다.

다만 필자도 이게 얼마나 귀찮은 건지 잘 알고 있다. 서로 다른 비밀번호는 기억하기 쉽지 않다. 필자의 경우에도 서로 다른 비밀번호를 사용하다가 비밀번호를 잊어 먹어 애먹은 적이 한두번이 아니다.

그나마 보완책이라면, 서로 다른 비밀번호를 생성하더라도 일종의 자신만의 규칙과 패턴을 사용하는 것이다. 물론 그 패턴은 쉽게 유추되지 않는 것이어야 한다.

---

결국 이용자들은 스스로 자신을 보호하기 위해 '안전한 비밀번호'를 사용해야 한다.

KISA 에서는 안전한 비밀번호 사용을 위해 안내서를 제공하니 아래 링크를 참조하기 바란다.

패스워드 선택 및 이용 안내서 바로가기


4.2 기업 관점 대응 방안

4.2.1 안전한 패스워드 규칙

앞서 '이용자 관점'에서도 언급한바 있는데, 비밀번호를 길고 복잡하게 만들도록 규칙을 강제하는 것이다. 또한 이용자의 공개된 개인정보가 비밀번호로 사용되는 것을 경고할 필요가 있다.

이용자가 알아서 복잡하고 유추 불가능한 비밀번호를 생성해 주면 고맙겠지만, 그렇지 않은 경우도 많으니 아예 규칙으로 강제하는 것이다. 현재 많은 사이트들에서 비밀번호 복잡성 규칙을 강제하고 있다

[ ISMS 인증체계에서의 비밀번화 관리 기준 ]

ISMS 인증체계에서도 '보호대책 요구사항'에 '비밀번호 관리'라는 인증 기준을 두고 있다.

ISMS에서 안내하는 안전한 비밀번호 규칙은 아래와 같다.

- 문자, 숫자, 특수문자 중 2종류 이상을 조합하여 최소 10자리 이상 길이로 구성

- 문자, 숫자, 특수문자 중 3종류 이상을 조합하여 최소 8자리 이상 길이로 구성

- 유추 가능한 비밀번호 설정 제한: 연속된 숫자, 생일, 전화번호 등


4.2.2 로그인 시도 횟수 제한

브루터포스 공격은 임의의 문자열을 무차별 대입해 보는 공격이므로 많은 로그인 시도와 로그인 실패를 반복하게 된다. 따라서 자동화되고 반복적인 시도를 불가능하게 만들기 위해 로그인 실패가 누적될 경우, 특별한 조치를 취하는 것이다. 이때 조치는 다음과 같은 형태가 될 수 있다.


1) 계정 잠금

로그인 실패가 일정 횟수 이상이 되면 더 이상 로그인 시도를 할 수 없도록 계정을 잠그는 것이다.

이렇게 하면, 자동화된 툴로 수 많은 로그인 시도를 할 수 없거나 힘들게 되어 공격 성공율이 엄청 떨어지게 된다.

잠긴 계정을 푸기 위해서는, 일정 시간이 지나면 자동으로 풀어주거나 추가 본인 확인을 거쳐 풀어주는 방식이 있다.


2) 캡챠 요구

앞의 계정 잠금 보다는 조금 완화된 방법이다. 로그인에 반복적으로 실패할 경우, 캡챠를 같이 입력하도록 한다. 아래 화면은 네이버의 로그인 실패 후, 캡챠가 나타나는 상황을 보여준다.


브루터 포스공격의 자동화되고 반복적인 로그인 시도 자체를 불가능하게 하여 이 공격의 기본 매커니즘을 흔들어 버리는 것이다. 이 방식은 공격자의 공격 의지를 상당히 깍아 내리므로 아주 효과적이라 하겠다.


4.2.3 다중 인증

ID, PASSWORD 이외에 추가 인증 수단을 제공하는 방식이다. 이 글에서 말하는 '다중 인증'은 일반적인 보안에서 말하는 '2 factor 인증'과는 그 개념을 구분하고자 한다.

'2 factor 인증'은 지식 기반인 비밀번호외에 소유기반인 휴대전화, OTP, 보안카드 또는 생체기반인 지문과 같은 인증 요소를 둘 이상 결합한 인증 방식을 말한다.

반면 여기서 말하는 '다중 인증'은 ID, PASSWORD외에 추가로(그게 무엇이든) 입력 받도록하는 인증 방식을 말한다.


1) 기기 인증

ID, PASSWORD 뿐만 아니라 로그인을 시도하는 기기도 인증하는 방식이다. 현재 이 블로그 서비스 제공하는 업체인, 티스토리도 기기 인증을 지원한다.

관리자 모드에서 기기인증을 활성화 할 경우, 한번도 접속한적 없는 기기에서 로그인을 시도하면 다음 화면과 같이 기기 인증을 받도록 되어 있다.

해커의 경우, 정상 이용자의 기기와는 다른 기기에서 로그인을 시도 할 것이기 때문에 로그인 시도를 할 수가 없게 될 것이다.

주의할 점은, 기기 인증시 기준값이 되는 기기의 고유값을 HTTP Request 정보에만 의존한다면 (비보안 HTTP 환경에서는) 해커가 얼마든지 그 값을 변조할 수 있으므로 주의를 요한다.


2) 캡차 추가

앞서 계정 잠금 후, 캡챠를 사용할 수도 있지만, 처음부터 로그인 시 캡챠를 같이 요구할 수도 있다.

아래 그림은 워드 프레스의 로그인 폼에 캡챠가 적용된 모습인데, 이와 같이 로그인 할 때 캡챠를 함께 사용하는 것이다.

이 캡챠의 경우, 매번 캡챠의 문자가 바뀌는 형식인데, 브루터포스 공격을 시도할 때 문자가 매번 바뀌기 때문에 공격을 자동화 시키기 아주 힘들어진다. 

물론 캡쟈 자체의 보안성이 높아야 하는 것은 당연하다.


요즘은 네이버나 구글과 같은 대형 인터넷 업체에서 무료로 캡챠를 사용할 수 있도록 제공하니 참고 바란다.

네이버 캡챠 API

구글 reCAPTCHA


주의할 것은, 캡챠 사용은 보안성을 높일지 몰라도 이용자의 사용 편의성은 상당히 떨어뜨리게 된다.
(특히 자주 로그인 해야 하는 사이트인 경우) 로그인 할 때마다 캡챠 문자를 입력해야 한다면, 그것처럼 귀찮은 것이 또 있으랴.

이 방식은 관리자 로그인과 같이 보안이 보다 더 중요한 환경에 적용해 볼 만 하다.


3)기타 추가 인증 수단

앞서 이 글에서의 '다중인증'과 보안에서의 '2 factor 인증'을 구분하길 원했지만 2 factor 인증을 다중인증 수단으로 사용할 수도 있다.

예를 들어 로그인 시 ID/PASSWORD 외에 OTP 번호를 요구하거나 메일 인증을 추가할 수도 있다.

'2 factor 인증'을 사용하면 브루터 포스 공격을 거의 완전하게 방어 할 수 있을 것이다.

하지만 (정말 보안이 중요한 곳이 아니라면) 사용 편의성이 너무 떨어지기 일반적인 사이트에서 로그인 보안으로는 좀 과한 느낌이 있다.


4.2.4 강력한 로깅과 모니터링

지금까지 알아본 많은 방어책들이 잘 갖춰져 있다 하더라도 운영 중 모니터링은 필수 요소이다. 

모니터링을 하려면 로그인 요청과 실패에 대한 사항을 기록하고 감시해야 한다.

그리고 이상 현상에 대한 임계치를 설정하고 임계치에 도달 할 경우, 관라지에게 자동으로 Alerting 되도록 모니터링 체계를 구축하는 것이 바람직 하다.

또한 이렇게 모니터링해서 이상현상이 감지되면, 공격용으로 의심되는 IP에 대한 조사 및 블럭킹 등 적극적인 조치가 뒤따라야 한다.


브루터 포스 공격에 대한 방어책을 상세히 알아 보았다. 앞서 장황한 설명의 핵심은 다음 세 가지로 정리할 수 있겠다.

1. 안전한 패스워드 사용 (길고 복잡하고 추측하기 힘든 패스워드)

2. 공격 자동화 저지 (다양한 방법 존재)

3. 공격 시도 탐지 (모니터링과 알림)


지금까지 알아본바와 같이, 기업 입장에서 브루터 포스 공격에 대비해 다양한 방어 수단을 구현할 수 있다. 한가지 생각해 볼 문제는, 웹 사이트의 성격에 맞는 보안성을 제공해야 한다는 것이다.

보안은 항상 트레이드 오프(Trade off)가 존재한다. 대부분 보안성이 올라가면 성능 또는 사용성(편의성)이 떨어지게 마련이다. 기업이 서비스하는 웹 사이트의 성격에 맞는 보안성과 잘 조율된 성능, 사용성을 동시에 만족시키는 것이 필요하다 하겠다.


[웹보안] 로컬 환경 셋팅과 툴 설치

Posted in SW개발 // Posted at 2019. 1. 17. 12:15
728x90

INTRO

이 글에서는,
웹보안을 공부하고 해킹을 실습해 볼 수 있는 툴을 알아보고 설치 방법을 간단히 안내 하고자 합니다. 

사실 웹보안 시리즈를 연재하고자 마음을 먹고서는, 개요부터 쭉~ 한번 훓고 가려 했는데요.
개요 작성에는 시간이 좀 더 필요할 것 같아서, 바로 본론으로 들어갑니다.

중간에 틈이 나면 전반적인 개요을 한번 다뤄볼까 합니다.

미리 말씀드리자면,
개요에서는 웹 보안의 중요성이나 해킹사례, OWASP Top 10과 같은 국제적 참고자료와 웹 보안 관련한 국내 현황과 법률 사항 등 전반의 내용을 다룰 예정입니다.

사실 과거(2006년)에 웹 보안 글을 몇개 끄적인 적이 있습니다. 
당시에서 큰 보부를 가지고 웹보안 전반을 다룰려고 했으나, 그러질 못했네요.

이번에는 인생의 숙제(?)라 생각하고 웹 보안 전반을 다뤄보고자 합니다.

과거 글들은 아래 링크를 참고하세요.(지금 다시 보니 글에 미숙한 점이 많이 보이네요 ^^;)


자 이제 본론으로 들어갑니다.

저의 개발 환경은 '64bit 윈도우 10 Pro' 환경입니다. 이 글에서 소개하는 툴들은 다른 환경(Linux, OS X)에서도 동작가능합니다. 다만 여기서는 윈도우 환경만 설명합니다.

많은 툴들이 있겠지만, 여기서는 앞으로 제가 진행할 웹 보안 Article에서 사용될 몇 가지에 대해서만 알아봅니다. 만일 여기서 소개되지 않은 툴을 제 글에서 다룬다면, 툴 설명을 별도로 추가하겠습니다.

참고로 이 글에서는 설치 과정을 세세하게 설명하지는 않습니다. 설치와 관련된 사항은 이미 인터넷에 많은 자료가 있으니 참고 바랍니다. 물론 그럼에도 설치 문제를 해결하지 못한 경우 편하게 댓글로 문의 주세요.

좋은 도구는 높은 생산성과 직결합니다. 아래 소개한 도구를에 익숙해지길 바랍니다.

---------------------------------------------------------------------------------------------------------------

1. XAMPP (Cross-platform Apache, MariaDB, PHP, Perl)

XAMPP는 APM(Apache, PHP, MySql) 환경구축을 한번에 할 수 있도록 하는 패키지 프로그램이다.

아래 설명할 DVWA 사이트가 PHP와 MariaDB로 구현되어 있는데, 이 사이트를 로컬 PC 구동시키기 위해서 APM 환경이 필요하다.


1.1 XAMPP 다운로드 및 설치

아래 사이트로 가서 XAMPP 설치파일을 다운로드 받는다.

www.apachefriends.org


각 OS 별로 설치 프로그램을 제공하는데, 필자의 경우 현재 시점의 최신 버전의 윈도우용 설치파일을 받아서 설치했다.

(현재 시점 최신 버전) XAMPP for Windows 7.3.0 (PHP 7.3.0)


다운받은 파일을 기본 설정으로 하고 '다음 > 다음 ..' 하여 설치한다.

(설치 과정중 Select Components 단계에서, 불필요한 환경을 제외할 수 있다. 필자 역시 Apache, MySQL, PHP외에 불필요한 것은 설치에서 제외 시켰다)

(그리고 설치 경로를 기억해 두자. 기본값으로 설치했다면 'C:\xampp' 일 것이다)


1.2 XAMPP Control Panel 을 통한 서비스 제어

XAMPP 설치가 완료되면 XAMPP Control Panel이라는 관리패널이 실행된다.

XAMPP Control Panel은 서비스들을 컨트롤 할 수 있는 관리 기능을 제공하는 프로그램이다.

(참고로 XAMPP Control Panel이 실행되면 윈도우 트레이 아이콘에 자동 추가 되므로 창을 닫아도 프로그램이 종료되는 것은 아니다. 프로그램을 종료하려면 트레이 아이콘을 우측 클릭하여 Quit 하면 된다.)

(또한 XAMPP Control Panel 프로그램을 종료(quit)한다고 해서 Apache나 MySQL이 같이 종료되는 것은 아니다. 이 프로그램은 말 그대로 편의성을 위해 별도로 제공되는 GUI 기반 프로그램일 뿐이다)

위 화면에서 보는바와 같이, Apache와 MySQL을 구동(Start)시키자.

브라우저에서 http://127.0.0.1 로 접속해보자. 다음 그림과 같이 XAMPP 대시보드가 로딩된다면 성공적이다.


1.3 설치 및 구동 실패 해결

설치 과정이나 설치 후 Apache, MySQL을 구동 시킬때 제대로 동작하지 않는 경우가 종종있다.

이는 대부분 XAMPP가 사용하는 포트와 서비스가 충돌되기 때문이다.


1.3.1 아파치 구동 실패

Apache 웹서버의 경우 기본 80포트를 사용하는데, 이미 로컬 PC에 80포트가 사용되고 있는 경우 Apache 웹 서버를 시작할 수 없다. (필자의 경우에도 로컬 PC에 IIS 웹서버가 동작중인데 80포트를 사용하는 사이트가 있어서 포트를 변경하였다.)

80 포트를 이용하는 서비스를 찾아서 포트를 변경하던지 해당 서비스를 중지 시키던지 한다. 

다음 명령어를 통해 현재 로컬 PC의 포트와 서비스 PID를 확인할 수 있으니 참고하자.

netstat -ano

(XAMPP Control Panel 에서도 바로 포트를 확인할 수 있도록 기능을 제공한다. 관리 패털의 우측 상단에 있는 'Netstat' 버튼을 클릭하면 포트와 PID 확인이 가능하다.)


1.3.2 MySQL 구동 실패

로컬 PC에 MySQL이 이미 설치되어 있는 경우, path 관련 오류(MySQL Service detected with wrong path)가 나면서  MySQL이 구동되지 않을 것이다.

될수 있으면 기존 설치된 MySQL을 제거하는 것이 가장 단순한 해결 방법이다.

관리자 계정으로 cmd(명령프롬프트)를 실행하고 다음의 명령어로 해당 MySQL을 제거하면 된다.
(기존 MySQL에 있는 오브젝트들은 미리 백업 받아 두는 것이 좋다)

sc delete mysql 

만일 기존에 설치된 MySQL과 XAMPP의 MySQL을 동시에 같이 사용하고 싶을 경우, 다음의 글을 참고하자. (포트와 서비스 명을 서로 다르게 하여 두개의 MySQL 인스턴스를 띄우는 방식이다.)

http://emjaywebdesigns.com/xampp-and-multiple-instances-of-mysql-on-windows/


1.4 DVWA를 위한 XAMPP 셋팅

1.4.1 dvwa 데이터베이스 생성

XAMPP 웹(http://127.0.0.1)에 접속하여 상단의 phpMyAdmin 메뉴로 이동한다.

phpMyAdmin은 웹으로 MySQL을 관리할 수 있는 프로그램이다. 상단의 '데이터베이스' 메뉴로 이동하여 dvwa라는 이름으로 새 데이터베이스를 만든다.


1.4.2 php.ini 파일 수정

'C:\xampp\php\php.ini' 파일에서 다음 값이 Off로 되어 있다면 On으로 변경하고 저장한다

allow_url_fopen=On

allow_url_include=On

이 설정이 필요한 이유는, dvwa 사이트에서 url include을 사용하기 때문이다. 

Apache 웹서버를 재기동 하면 변경된 설정 값이 반영된다.


2. DVWA(Damn Vulnerable Web Application)

DVWA는 그 약자에서도 알 수 있듯이 의도적으로 취약하게 만든 웹 사이트이다. 

보통 웹해킹을 공부하고 직접 시도해 볼려면 여의치가 않다. 임의의 공개된 사이트에 테스트로 해킹을 시도 했다가는 법률적 제재를 받을 수도 있다.

그렇다고 직접 개발하기도 만만치가 않다.

DVWA는 PHP/MySQL 기반으로 제작된 웹 애플리케이션으로, 웹 해킹 기술을 직접 실습하고 공격 대응 방안을 학습하기 위한 목적으로 제작되었다.

다음은 DVWA 사이트에서 발췌한 설명이다.

DVWA (Damn Vulnerable Web App)는 PHP / MySQL 웹 애플리케이션으로 취약합니다. 주요 목표는 보안 전문가가 법률 환경에서 자신의 기술과 도구를 테스트하고 웹 개발자가 웹 응용 프로그램을 보호하는 과정을 더 잘 이해할 수 있도록 지원하고 교사 / 학생이 강의실 환경에서 웹 응용 프로그램 보안을 가르치고 배우도록 돕는 것입니다 .


2.1 DVWA 다운로드 및 설치

아래 주소로 이동하여 DVWA-master.zip 파일을 다운로드 받는다

http://www.dvwa.co.uk/


다운 받은 파일의 압축을 풀고 DVWA-master 폴더의 하위 내용물들을 모두 다음의 위치로 옮긴다

C:\xampp\htdocs\dvwa 

(XAMPP 웹으로 접속 가능하도록 htdocs 폴더 하위에 dvwa라는 이름의 폴더를 생성하여 그 아래로  DVWA-master 폴더 내용을 이동(or 복사) 한다.)

파일들이 정상적으로 이동되었다면, 다음의 주소로  dvwa 사이트에 접속할 수 있다.

http://127.0.0.1/dvwa


위 주소로 최초 접근하면 다음과 같은 Setup 화면이 나오고 추가 설정을 해 줘야 한다.

여기서 빨간색으로 나온 부분을 모두 잡아줘야 사용이 가능해 진다.

reCAPTCHA key 가 설정되지 않아서 빨간색으로 표시되어 있다. 키를 발급 받는 방법을 알아보자.


2.2 reCAPTCHA key 발급 받기

DVWA에서 캡챠 관련 공격을 테스트 하기 위해 필요한 설정이다. reCAPTCHA 키를 받기 위해서 다음의 주소로 접속한다

www.google.com/recaptcha/admin


구글 계정으로 로그인해야 키 발급이 가능하다. 로그인 후 다음 그림과 같이 입력하고 폼을 제출한다.

폼을 제출하면 Site Key와 Secret key가 생성된다. 이 두 키 값을 dvwa 설정 파일에 등록해야 한다.


2.3 설정 파일 수정

먼저 config 폴더에 있는 config.inc.php.dist 파일 이름에서 '.dist'을 제거한다.

config.inc.php.dist --> (파일명 변경) --> config.inc.php


2.3.1 reCAPTCHA key 설정

config.inc.php 파일을 열어서 다음의 내용을 설정한다. 앞서 발급받은 key들을 다음과 같이 알맞게 지정한다.

$_DVWA[ 'recaptcha_public_key' ]  = '(Site Key 값 입력)';

$_DVWA[ 'recaptcha_private_key' ] = '(Secret key 값 입력);


2.3.2 DB 접속 패스워드 수정

config.inc.php 파일의 DB 패스워드를 다음과 같이 패스워드를 공백으로 변경한다.

$_DVWA[ 'db_password' ] = '';

이제 dvwa 설정이 완료되었다. 앞서 접속한 dvwa 설정화면을 새로고침 해보면 reCAPTCHA key 가 녹색으로 표시된것을 확인할 수 있다.


2.4 데이터베이스 생성

마지막으로 dvwa 데이터베이스에 관련 오브젝트들을 생성한다.

설정화면에서 'Create / Reset Database' 버튼을 클릭해서 관련 테이블등을 생성하자

dvwa로 해킹 실습을 해 보다가 데이터를 초기화 하고 싶으면 언제든이 Reset 할 수도 있다.


2.5 DVWA 사이트 접속

이제 DVWA를 위한 모든 설정이 완료되었다.

http://127.0.0.1/dvwa/ 로 접속하여 사이트를 확인해 보자

로그인 창이 뜨면 admin / password로 입력한다. 다음 그림과 같이 DVWA 사이트를 확인할 수 있다.

사이트를 한번 쭉 훓어 보기 바란다.



3. Burp Suite 설치

웹 사이트 테스트 및 해킹 용도로 자주 사용되는 웹 프록시 프로그램이다.웹 요청을 프록시를 경유하도록 만들어서, 중간에 패킷을 가로채어 조사하고 변조해 볼 수 있다.

Burp Suite는 프록시 기능을 넘어, 실제 웹 해킹을 자동화 해서 수행할 수 있는 기능도 제공한다.

유료와 무료 버전이 존재하며 우리는 무료인 커뮤니티 버전을 설치한다.


3.1 Burp Suite 다운로드 및 설치

아래 주소로 이동하여 커뮤니티 버전의 설치 파일을 다운로드 받아서 설치한다.

https://portswigger.net/burp/communitydownload


3.2 브라우저 프록시 설정

3.2.1 프록시 설정 확인

Burp Suite는 기본 8080 포트로 프록시 역할을 수행한다. 다음 그림은 Burp Suite를 실행해서 Proxy 옵션을 확인하는 화면이다. 여기서 프록시 리스닝 포트를 변경할 수 있지만 여기서는 기본값을 사용한다.


3.2.2 브라우저에 프록시 설정하기

필자가 사용하는 구글 크롬 브라우저를 기반으로 프록시 설정을 알아본다.

크롬 브라우저의 설정화면으로 이동한다. 상단의 '설정 검색'에서 '프록시' 라고 검색한다.

'프록시 설정 열기'를 하여 LAN 설정에서 프록시 서버 사용을 활성화하고 IP(localhost)와 포트(8080)를 입력한다.


이렇게 브라우저에 프록시가 설정되면, 이제부터는 모든 웹 요청과 응답은 이 프록시를 경유하게 된다.

* 주의

웹 해킹을 실습하지 않을 때는 프록시 서버를 비활성화 시켜 놓는 것이 좋다.

그렇지 않으면 일반 사이트 접속이 원활하지 않을 수 있다.


이로써 기본적인 툴 설치와 환경 설정이 완료 되었다. 이제부터 본격적으로 웹보안 공부를 시작해 보도록 하자


수고 하셨습니다~~~~~~~~~~~~~~~~


설정 파일의 외부화(Spring Cloud Config)

Posted in SW개발 // Posted at 2018. 3. 29. 12:27
728x90

12 Factor App 원칙에서는...
애플리케이션의 환경설정 정보를 코드로부터 분리하여 외부화하는 것을 그 원칙 중 하나로 제시하고 있다.

이는 환경에 따라 달라지는 설정 정보를 소스로부터 분리하여 둘 간의 결합도를 낮추어 유지보수성을 좋게하기 위한 설계 원칙이다.

이런 관점에서, 가장 최악의 선택은 설정정보를 소스코드의 상수로 관리하는 것이다.
요즘 왠만한 프로젝트에서는 상수기반 설정정보를 잘 사용하지는 않는다.

* 설정정보를 소스코드에서 분리시키기

설정 정보를 별도의 소스코드와 분리된 별도의 파일로 관리하는 것이 일반적이다.

스프링 부트 기반으로 볼 때, 
application.properties 또는 application.yml 파일에 설정정보를 관리한다.

단, 이 방식도 (설정파일이) 프로젝트에 포함된 경우라면, 설정정보의 변경이 필요할 경우, 애플리케이션 전체를 다시 빌드하고 배포해야 하는 종속성 문제가 생긴다.

(설정정보를 프로파일로 구분할 수 있는 것도 하나의 해결책이긴 하지만, 이는 프로파일의 종류가 정해진 경우에는 유용하나, 동일한 프로파일내에서의 변경사항은 여전히 종속성 문제를 내포하고 있다)


* 설정정보를 배포 패키지에서 분리시키기

설정정보 파일을 애플리케이션 배포 패키지에서 분리시키기 위한 방법이 몇 가지 존재하긴 한다.

자바 기반 프로젝트로 보면,
1) 애플리케이션 실행 시, 설정정보 파일 위치를 옵션에 명시
2) @PropertySource 어노테이션으로 설정정보 파일 위치 명시
3) 시스템 자체의 환경설정 정보를 읽어오는 System.getProperties() 사용하기

이 중 1)번 방식을 선호하기는 하지만, 이 또한 설정정보 변경이 발생하면 애플리케이셔을 중지했다가 다시 구동해야 하는 종속성 문제가 발싱한다.


* 설정정보를 원격 서버에서 제공하기

Spring Cloud 프로젝트에서 제공하는 Spring Cloud Config 서버를 활용하면 원격지 서버에서 설정정보를 서비스 할 수 있게 해준다.

그리고 설정정보를 동적으로 변경하여 (애플리케이션의 재빌드나, 재구동 없이) 실시간으로 반영시킬 수 있도록 하는 메커니즘을 제공하며 git이나 svn 기반으로 설정정보의 버전 관리를 지원해 준다.


* Spring Cloud Config 서버-클라이언트 구현

1. git 저장소와 설정파일 생성

1) git 저장소 생성
여기서는 설정정보 저장소로 로컬 git을 사용하기로 한다. git 을 설치하고 git 저장소를 init 명령어로 지정한다.

> git init


2) 설정파일 생성
다음의 규칙으로 설정파일 이름을 지정하고 설정정보를 파일에 입력한다.

{applicationName}-{profile}.yml 또는 {applicationName}-{profile}.properties

3) 설정파일 커밋
생성한 설정파일을 git에 add하고 commit 한다.

> git status

> git add -A

> git commit -m "config file create"

4) Config 서버의 설정정보 확인
Config 서버에서 설정정보를 확인하기 위해서는 다음과 같은 규칙으로 접속한다.

http://{ConfigServer}/{applicationName}/{profile}

아래는 프로파일이 없는 경우와 dev 프로파일에 접속하는 예를 보여준다

> http://localhost:8888/my-service/default

http://localhost:8888/my-service/dev


2. Spring Cloud Config 서버 구현

1) Config 서버 프로젝트 생성

스프링 부트 프로젝트로 Config Server와 Actuator을 의존성으로 선택하고 생성한다.
(스프링 부트 2.0은 Spring Cloud Finchley.M9 버전을 사용한다)

2) Config 서버 설정
bootstrap.yml을 resource 폴더에 생성하고 다음과 같이 설정한다.

설정파일이 관리될 로컬 git 저장소를 지정하고, Config 클라이언트를 구분할 목적으로 서브디렉터리를 만들고 searchPaths로 서브디렉터리를 지정해 준다.

spring:
  application:
    name: config-service
  cloud:
    config:
      server:
        git:
          uri: file://{로컬 git 저장소 (루트) 경로}
          searchPaths: subdirectory1, subdirectory2, ..., subdirectory{N}

    

server:
    port: 8888 #Config Server Default Port


2. Spring Cloud Config 클라이언트 구현

1) Config 클라이언트 프로젝트 생성
스프링 부트 프로젝트로 Config Client를 의존성으로 선택하고 생성한다.
(스프링 부트 2.0은 Spring Cloud Finchley.M9 버전을 사용한다)

2) Config 클라이언트 설정
bootstrap.yml을 resource 폴더에 생성하고 다음과 같이 설정한다.

spring:
  profiles:
    active: dev
  application:
    name: sc-api-user-service
  cloud:
    config:       
       uri: http://localhost:8888 #Config 서버 uri
       fail-fast: false #Config Server와 연결이 되지 않으면 예외를 발생시키고 종료하려면 true

3) 설정 정보 사용하기
@Value 어노테이션을 사용하거나 @ConfigurationProperties 어노테이션을 사용하여 Config 서버로 부터 설정정보를 매핑하여 사용할 수 있다.


* Config 서버의 가용성

Config 서버가 1대 뿐이라면 SPOF(single point of failure, 단일장애지점)가 된다.
SPOF는 라이브환경에서는 언제나 재앙의 대상이 되곤 한다.

하지만 Config 서버의 구동방식을 보면 일반적인 SPOF에 비해 그 부담이 다소 적다.

1) 운영중 가용성
Config 서버와 연동하는 클라이언트는 최초 구동시에만 서버에서 설정값을 읽어온다.
이후 부터는 클라이언트 측에 로컬 캐시되어 더 이상 Config 서버와 통신하지 않는다.

다만, 설정정보가 갱신될 경우 클라이언트의 /actuator/refresh 엔드포인트를 사용해서 서버에서 새로운 값을 다시 읽어 오도록 하는데, 이때도 서버가 응답이 없다면 기존 로컬 캐시값을 사용한다


즉 Config 서버가 다운되었다고 하더라도 클라이언트들은 다운되거나 하지 않는다는 말이다.
(단 서버의 변경 값을 동기화하지 못할 경우, 일관성 문제는 생길 수 있다)


2) 최초 구동시 가용성
그렇다면, 클라이언트가 최초 구동될 때 Config 서버가 다운된 상황이라면 어떨까?
이때의 가용성을 위해서 fail-fast 값을 false(기본값)로 준 것이다.
fail-fast 값이 true로 설정되면, Config 서버와 연결하지 못하면 클라이언트는 구동되지 않게 된다.

어떤 선택이 더 나은지는 환경에 따라 다를 것이다.

만일 Config 서버가 이중화되어 있지 않은 상태에서 최소한의 가용성을 확보하기 위해서는 이 값을 false로 하는 것을 생각해 볼 수 있다.

즉 Config 서버가 다운된 상황에서도 클라이언트 프로그램은 구동되도록 하는 것이다.

물론 이렇게 하면 Config 서버로 부터 설정정보를 받아오지 못하는 문제가 생긴다.

이를 위해서 클라이언트에서는 동일한 설정정보를 자신의 설정파일에도 가지고 있으면 된다

이렇게 되면 Config 서버와 연결이 실패한 클라이언트는 동일한 설정을 자신의 설정파일로 부터 읽어 들이게 된다.

이것은 그야말로 최소한의 가용성 확보를 위한 전략이 될 것이다.


3) 보다 나은 가용성
Config 서버자체를 이중화하는 것이다.
로드밸런서를 두고 Config 서버를 이중화하면 장비 차원에서 가용성 확보가 된다.

이때 생각해 봐야 할 문제는 git 저장소의 동기화와 가용성 문제이다.

Config 서버를 이중화 할 경우에는,
로컬 git 저장소를 사용하지 말고 원격의 중앙 git 저장소를 사용하도록 한다.

 원격 git 저장소의 고가용성을 위해서는 다음 글을 참고 하자

https://about.gitlab.com/high-availability/


* 설정 정보의 실시간 동기화

Config 서버의 설정정보가 변경되면 이를 의존 하고 있는 클라이언트 프로그램들에게 알려줘야 하낟.

이때 사용되는 것이 @RefreshScope 어노테이션과 /actuator/refresh 엔드포인트이다.

이 두 작업은 클라이언트 측에서 수행되어야 한다.

실시간 동기화가 필요한 곳, 즉 설정정보를 엑세스 하는 클래스에 @RefreshScope 어노테이션을 붙여 준다.

그리고 클라이언트의 주소에 /actuator/refresh 엔트포인트로 POST (Body는 빈 값으로) 전송을 하면된다.

이렇게 하면 클라이언트 로컬에 캐시된 설정 정보를 Config 서버에서 가져온 값으로 즉시 갱신한다.

그러나 Config 서버에 의존하는 클라이언트가 상당히 많은 수일 경우, 모든 클라이언트의 /actuator/refresh 엔트포인트를 명시적으로 호출해 줘야 하기 때문에 유지보수가 까다로워 진다.

 Spring Cloud Bus를 사용하면 메시지 브로커를 통해 변경 이벤트를 구독하여 자동으로 모든 클라이언트에 변경 정보를 자동으로 동기화 할 수 있다.


-------------------------------------------

오랜만에 글을 쓸려니... 느무~~ 귀찮으니무다... 아...

글 쓰기 싫어서 큰일이다. 쩝...




SPA와 Social sharing(소셜 공유)

Posted in SW개발 // Posted at 2017. 6. 26. 12:47
728x90

"소셜 크롤러(Social crawler)는 자바스크립트를 실행하지 않는다"

얼마 전, 아키텍트로 지원했던 프로젝트에서 기술지원 요청이 들어왔다.

Ajax로 점철된(?) 페이지에 소셜 공유 기능을 추가해야 하는데, 여의치 않다는 것이다.
그래서 기술적 해결방안을 요청해 왔다.

해당 프로젝트는 일종의 SPA(Single Page Application) 구조로,
전통적인 웹 구현 모델인 서버랜더링 방식이 아니라 클라이언트 랜더링 방식을 채택하고 있었다.

즉 HTML/Javascript/CSS와 같은 정적 리소스를 먼저 브라우저에 랜더링 한 후, 필요한 비즈니스 데이터를 Ajax 통신으로 가져와서 DOM 제어를 하는 방식이다.

이런 구조의 대표적인 걸림돌(?)은 SEO(검색엔진최적화)나 Open Graph 프로토콜에 기반한 소셜 공유에 취약하다는 것이다.

서버에서 비즈니스를 처리하고 동적으로 생성된 HTML을 반환하는 것이 아니라, 아무런 동적 처리가 되지 않는 HTML을 먼저 반환하기 때문에, 웹 크롤러가 가져갈 수 있는 정보가 한정적이기 대문이다.

다시말해 대부분의 웹 크롤러는 자바스크립트를 실행하지 않기에, 자바스크립트를 사용해 동적으로 구성한 정보를 웹 크롤러에게 줄 방법이 없는 것이다.


이에 대한 기술적 해결 방안으로는, 크게 다음과 같은 두 가지 전략을 생각해 볼 수 있다.

1. 서버 랜더링 방식을 살짝 가미하기
소셜 공유를 위해서는 소셜 크롤러를 위한 메타 정보를 제공해야 한다.
해당 메타 정보는 비즈니스 처리가 된 동적 정보로 구성되어야 하기 때문에 서버 랜더링 방식으로 필요한 메타정보를 구성하는 방식이다.

그리고 페이지의 나머지 처리는 Ajax 통신을 통해 동적으로 구성한다.
이 방식은 서버랜더링 + 클라이언트랜더링 방식을 하이브리드 시켜 '꿩 먹고 알 먹는' 착각(?)을 주기도 한다.

이런 구조는 다음 사이트에서 구현하고 있는 듯 하다

> http://jakduk.com

이 방식의 단점 이라면, 클라이언트 랜더링 방식이라는 아키텍처 구조를 조금 흔들어야 한다는 것이며 Angular와 같은 Full SPA 구조에서는 적용하기 힘들다는 것이다.

이를 위해 다음과 같은 두 번째 방식을 권장한다.


2. 웹 크롤러를 위해 별도의 메타 정보 제공하기
이 방식은 다음의 사이트에 잘 설명되어 있다.

> https://rck.ms/angular-handlebars-open-graph-facebook-share/ 

기존 페이지나 아키텍처 구조를 건드리지 않고도 적용할 수 있는 훌륭한 방법이다.

동적으로 생성된 메타 정보를 반환하는 별도의 로직을 만들고,
페이지 요청이 웹 크롤러로부터 온 것이라면 웹 서버의 Rewrite 모듈을 사용해 요청을 다시 작성한다.

즉 일반 사용자는 원래 페이지에 접근하고 웹 크롤러는 동적 메타 정보를 제공하는 HTML을 반환받도록 하는 것이다.

이때 메타정보를 제공하는 로직은 HTML을 반환하는 REST API로 구현하거나 별도 서버 측 페이지로 구현할 수 있다.

--------------------------------------------------------------------------------------------------------

여러모로 비교해 봤을 때, 2번 방식이 보다 깔금하게 해결 할 수 있는 솔루션인 듯 하다.

그러나 이 글을 쓰는 목적은 다른데 있다.


3. 자바스크립트를 해석하는 웹 크롤러

근래 웹 아키텍처에 SPA(Single Page Application)가 많이 차용되는 추세이고, 특히 앱 스러운(App Like) 모바일 웹 환경에서는 SPA가 보다 효과적이다.

또한 Angular, Vue.js, React.js와 같은 SPA 프레임워크들이 인기가 치솟고 있으며, 하이브리드 앱 환경에서도 클라이언트 랜더링 방식이 심심찮게 적용되고 있다.

이렇듯 클라이언트 랜더링 방식이 기술적 트랜드로 자리매김 하고 있고 필드에서 많이 적용되고 있음에도 웹 크롤러는 아직 과거에 머물러 있다는 점을 꼬집고 싶다.

일부 브라우저 업계에서는 클라이언트 랜더링 방식에서 SEO 등의 적용을 위해 자바스크립트의 동작을 해석하는 웹 크롤러를 만들고 있다고는 한다. 그러나 현재까지도 대부분의 웹 크롤러는 단순히 URL을 호출하고 즉시 반환되는 HTML 덩어리에만 의존하고 있는 실정이다.

아무리 진보한 아키텍처라고 해도, 주변 환경이 이를 지원하지 않는다면 아키텍처의 훼손은 어쩔 수 없이 발생할 것이다.

개인적인 희망으로는, 웹 크롤러를 현실에 맞게 진화시켜 클라이언트 랜더링 방식에서도 SEO나 소셜 공유가 가능토록 해 주길 바란다.

혹여 망설여지는게,
표준적이고 범용적인 적용이 어려울 수도 있겠다 하는 것인데...

이것 역시 , 클라이언트 랜더링의 모든 커스텀 로직을 인식할 필요는 없고 초기화 함수 정도만 인식해 줘도 쉽게 풀릴 문제가 아닌가 한다.

크롤러의 발전을 기대하며...

참고> 페이스 북 클로러 테스트 페이지
다음 URL은 페이스북 크롤러가 소셜 공유를 했을 때 어떤 정보를 가져가는지 테스트 해보기 위한 도구이다.

https://developers.facebook.com/tools/debug/sharing



'SW개발' 카테고리의 다른 글

[웹보안] 로컬 환경 셋팅과 툴 설치  (5) 2019.01.17
설정 파일의 외부화(Spring Cloud Config)  (5) 2018.03.29
좋은 소프트웨어를 위한 기본기  (6) 2016.12.14
UI 디자인트렌드  (6) 2016.12.13
HTTP2-over-QUIC  (6) 2016.12.08

좋은 소프트웨어를 위한 기본기

Posted in SW개발 // Posted at 2016. 12. 14. 10:42
728x90

소프트웨어 위기(Software Crisis)라는 용어가 등장한지 50년 가까이 되었음에도 여전히 그 위기속에 생명을 유지하고 있는 소프트웨어가 간혹 발견된다.

이런 문제를 몇몇 자질이 낮은 개발자의 문제로 치부하는 경향도 발견되는데, 이는 문제의 본질을 흐리게 하고 근본원인의 해결을 할 수 없게 만드는 좋지 못한 접근법이다.

소프트웨어 위기에 내포된 문제점은 결국 돈과 시간, 만족도의 문제이다.

계획된 납기를 준수하지 못한채 예정된 예산보다 더 많은 돈을 지출하고도 불만족스러운 소프트웨어를 사용하게 되는 것이다.

소프트웨어 위기는 소프트웨어 개발에서의 공학적 접근의 필요성과 중요성을 강조하는 계기가 되었는데, 소프트웨어 공학의 목표라는 것이 결국에는 '한정된 자원(돈, 시간)으로 사용자가 만족하는 고품질의 소프트웨어를 생산하는 것'이란 점에서 돈과 시간, 만족도에 대한 문제해결의 접근법이라 할 수 있다.

각종 공학적 기법과 방법론, 관리체계를 기반으로 표준화를 통한 일관성과 호환성을 확보하고 자동화 툴을 사용하여 생산성 향상을 꾀하며 개발수명주기간 품질보증체계를 적용하여 개발초기부터 고품질 소프트웨어를 생산하도록 촉진하여 소프트웨어 위기라는 문제에 근본적으로 대응할 수 있게 된다.

기본적이고 이론적인 내용일 수 있으나, 항상 문제는 기본을 지키지 못한데서 발생한다는 것을 잊지말자.


'SW개발' 카테고리의 다른 글

설정 파일의 외부화(Spring Cloud Config)  (5) 2018.03.29
SPA와 Social sharing(소셜 공유)  (10) 2017.06.26
UI 디자인트렌드  (6) 2016.12.13
HTTP2-over-QUIC  (6) 2016.12.08
웹페이지 고속 랜더링 기술, 구글 AMP  (4) 2016.12.08

UI 디자인트렌드

Posted in SW개발 // Posted at 2016. 12. 13. 13:41
728x90

마치 역사가 반복되는 것처럼, 패션 스타일도 돌고 돌고 UI 디자인 트랜드도 돌고 도는 듯 하다.


디자이 트래드에 대한 이해는 다음 글들을 참고.

- http://blog.naver.com/youngdisplay/220690365967
- http://blog.naver.com/kosoodream/220769634590
- http://segrami.tistory.com/11


실제적인 모바일 UI/UX 설계 및 개발시 참고할 만한 가이드는 다음 사이트를 참고.

- Material Design Guide: https://material.google.com
- Material Design CheckList: https://developers-kr.googleblog.com/2014/10/material-design-on-android-checklist.html
- 모바일 UI 디자인 시 고려해야 할 가이드라인: https://brunch.co.kr/@chulhochoiucj0/9


모바일 SW 및 UX 사례연구.

- http://www.sw-eng.kr/member/customer/Webzine/BoardView.do?boardId=00000000000000046341&currPage=&searchPrefaceId=00000000000000020135&titOrder=&writeOrder=&regDtOrder=&searchCondition=TOT&searchKeyword=

- http://www.sw-eng.kr/member/customer/Webzine/BoardView.do?boardId=00000000000000045634&currPage=&searchPrefaceId=00000000000000020135&titOrder=&writeOrder=&regDtOrder=&searchCondition=TOT&searchKeyword=

- http://www.sw-eng.kr/member/customer/Webzine/BoardView.do?boardId=00000000000000045697&currPage=&searchPrefaceId=00000000000000020135&titOrder=&writeOrder=&regDtOrder=&searchCondition=TOT&searchKeyword=

HTTP2-over-QUIC

Posted in SW개발 // Posted at 2016. 12. 8. 17:12
728x90

구글의 인터넷 기술 기여는 놀라웁다.

그 중, 고성능 인터넷 프로토콜에 대한 영향력과 파급력도 굉장한 수준이다.

이미 SPDY가 HTTP/2의 표준화에 기여했으며, 이젠 UDP기반의 고속 통신 기술인 QUIC(Quick UDP Internet Connections)도 표준화될 움직임을 보이고 있다.

구글의 고성능 프로토콜 전략과 표준화 흐름은 다음과 같다.

QUIC의 고속 처리는 다음 그림 한장으로 가늠할 수 있다.

다음 슬라이드를 통해 좀더 구체적으로 참고.

=> http://www.slideshare.net/deview/quic-67614063


'SW개발' 카테고리의 다른 글

좋은 소프트웨어를 위한 기본기  (6) 2016.12.14
UI 디자인트렌드  (6) 2016.12.13
웹페이지 고속 랜더링 기술, 구글 AMP  (4) 2016.12.08
웹의 Native 化, PWA(Progressive Web Apps)  (6) 2016.12.08
HTTP/2 (고성능 HTTP)  (8) 2016.12.05

웹페이지 고속 랜더링 기술, 구글 AMP

Posted in SW개발 // Posted at 2016. 12. 8. 16:03
728x90

올해 구글 IO 2016에서 '구글이 제시한 미래의 웹'에서 PWA와 같이 언급된 것이 AMP(Accelerated Mobile Pages)이다.

AMP는 웹 페이지의 고속 처리를 위한 구글의 Best Practice가 집약된 기술이다.

구글 AMP가 집중하는 것은 오직 성능이다.

성능을 위해 외부 JS 삽입도 불허하고 인라인 CSS의 크기도 제한한다.
굳이 AMP 페이지에 이런 것들이 구현되어야 한다면 iframe으로 분리하라고 권고한다.

AMP Components

AMP 페이지에서는 HTML 태그에 대응되는 몇 가지 커스텀 Component를 제공하며 이를 반드시 사용해야 성능이 개선된다.

AMP Cache

AMP 페이지는 구글 봇에 의해 자동으로 구글 CDN에 캐싱되어 Middle mile 경유를 최소화하여 응답속도를 향상시키다.

AMP Validation

지금 개발하고 있는 페이지가 AMP 제약사항을 따르는지 검사해 주는 도구이다.
URL 뒤에 #development 해시태그를 추가하면 크롬 개발자 도구를 통해 그 유효성 검사 결과를 보여준다.


중요한 것은, (앞서 언급했듯이) AMP 페이지를 만들기 위해 강제되어야 하는 제약사항이 비현실적일 수도 있다는 것이다. 특히 사용자와의 상호작용이 많은 복잡한 웹 페이지를 만든다면 AMP적용이 녹록치 않을 것이다.

결국 "단순한 정적페이지의 고속화에 초점을 맞춘 기술"이니 만큼 취사 선택하길 권장한다.

자세한 것은 구글 사이트를 참고.
=> https://www.ampproject.org/
=> https://www.ampproject.org/learn/about-amp/
=> https://www.ampproject.org/docs/get_started/create/basic_markup


'SW개발' 카테고리의 다른 글

UI 디자인트렌드  (6) 2016.12.13
HTTP2-over-QUIC  (6) 2016.12.08
웹의 Native 化, PWA(Progressive Web Apps)  (6) 2016.12.08
HTTP/2 (고성능 HTTP)  (8) 2016.12.05
아키텍처의 출발점  (4) 2016.09.05

웹의 Native 化, PWA(Progressive Web Apps)

Posted in SW개발 // Posted at 2016. 12. 8. 15:28
728x90

구글에 의해 보다 구체화된 PWA(Progressive Web Apps)가 심심찮게 트랜드로 올라온다.

표준 웹 기술을 기반으로 모바일 환경에 최적화하려는 시도는 PWA 이전에도 많은 시도가 있었다.
PWA는 결국 이런 시도들이 하나의 개념과 기술셋으로 수렴된 결과로 이해할 수 있다.

다음 그림은 PWA의 개념을 한장의 도식으로 표현해본 것이다.

Hybrid App과는 서로 추구하는 사상과 컨셉이 달라서 굳이 비교할 필요가 없겠으나, 이 둘의 비교를 통해 PWA를 좀더 선명하게 이해할 수 있다.

결국 웹 기술을 기반으로 Native와 같은 사용자 경험을 제공한다는 것인데, 이때 중요한 것은 기존 웹의 컨셉을 여전히 계승한다는 것이다. 

한마디로 표현하자면, "웹의 사상을 유지한채 Native 化"  하자는 것. 

PWA을 실현하기 위해 사용되는 기술은 다음과 같은 것들이다.

* Web App Manifest: Native App 접근성 제공

* Service Worker: 오프라인 캐싱, 백그라운드 처리

* Push Notification: 푸시 알림


PWA Indication
위와 같은 기술요소를 사용하여 웹을 만들면 브라우저에 의해 해당 웹이 PWA인지 판별할 수 있게 된다.
브라우저가 PWA임을 인지하는 기준은 다음과 같다.
- HTTPS 사용
- Service Worker 사용
- Web App Manifest 사용

 현재 시점에서는 지원되는 브라우저가 한정되어 있다는 점 참고.

Case Study

국내 사례는 그렇게 많지 않은 듯 하다.
외국 사례 중 대표적으로 워싱턴포스터지의 모바일 웹앱을 들 수 있는데, 아무래도 모바일 사용성을 최적화 시킨 결과로 그 전에 비해 앱을 보다 많이 그리고 오랫동안 사용한다고 한다.
결국 앱의 사용성이 크게 증가하면서 앱에 접근하고 사용, 체류하는 시간이 길어지면서 고객 충성도가 올라간다는 것이다.


보다 상세한 내용은 구글 사이트를 참고.
=> https://developers.google.com/web/progressive-web-apps/
=> 
https://codelabs.developers.google.com/codelabs/your-first-pwapp/#0

'SW개발' 카테고리의 다른 글

HTTP2-over-QUIC  (6) 2016.12.08
웹페이지 고속 랜더링 기술, 구글 AMP  (4) 2016.12.08
HTTP/2 (고성능 HTTP)  (8) 2016.12.05
아키텍처의 출발점  (4) 2016.09.05
SW 아키텍처 마인드맵  (4) 2016.09.01

HTTP/2 (고성능 HTTP)

Posted in SW개발 // Posted at 2016. 12. 5. 11:02
728x90

머지않아 HTTP/2의 보편화가 예상된다.

웹 환경, 특히 모바일 기반 웹환경의 고속화에 실질적인 효익을 가져다 줄 HTTP/2는
이제 엔터프라이즈 웹 아키텍처 수립에 주요한 tactic이 될 것이다. 

HTTP/2에 대한 깔끔한 정리는 아래의 포스팅에서 확인 가능하다.

=> http://www.popit.kr/%EB%82%98%EB%A7%8C-%EB%AA%A8%EB%A5%B4%EA%B3%A0-%EC%9E%88%EB%8D%98-http2/


HTTP/2를 적용하기 위해서는 브라우저와 웹서버의 지원상황을 미리 체크해야 하며, 만일 웹 서버가 지원하지 않을 경우 웹서버에 HTTP/2 지원모듈을 설치할 수도 있다.

고무적인 것은, 대부분의 최신 모바일 디바이스의 브라우저는 이미 지원하고 있다는 것이다.

브라우저 지원 현황 보기 => http://caniuse.com/#feat=http2

아파치 지원모듈 => https://httpd.apache.org/docs/current/ko/mod/mod_http2.html
엔진엑스 지원모듈 => https://nginx.org/en/docs/http/ngx_http_v2_module.html

윈도우기반에서는 Windows 10, Windows Server 2016에서 지원된다고 하는데, 다음 글을 참고하자
=> https://blogs.iis.net/davidso/http2

참고로, 현재 TLS기반 HTTP/2만 지원해서 HTTPS 통신에 이를 사용할 수 있다고 한다.


아키텍처의 출발점

Posted in SW개발 // Posted at 2016. 9. 5. 11:46
728x90

변화경영연구소의 소장이셨던 고 구본형 선생의 유명한 책인 '익숙한 것과의 결별'에서는 다음과 같은 내용이 있다.

 

비전을 제대로 이해하기 위해서는 건축물을 연상하는 것이 가장 완벽한 동질성을 부여한다.

 

비전은 '미래의 설계도'라고 말하는 사람들이 많다. 그러나 나는 그 생각에 강하게 반대한다.

그것을 설계도라고 해석하는 데서부터 많은 오류가 발생한다는 것을 알고 있기 때문이다.

설계도는 전문가들을 위한 것이다. 보통 사람은 설계도를 보고 그 건물의 전체적 모습을 떠올릴 수 없다. 그것은 판독하기 어려운 수치와 기호일 뿐이다.

 

비전은 이해관계자 모두가 쉽게 그 모습을 머릿속에 떠올릴 수 있어야 하며,

그 모습의 아름다움 때문에 마음이 설레야 한다.

 

따라서 비전은 오히려 건물의 조감도와 흡사하다.

건물의 유려한 자태와 자재의 질감이 느껴져야 한다. 그리고 그 건물 속의 한 부분을 줌업시키면 그 속에 앞으로 자신이 거주하고 생활할 새로운 공간이 보인다. 이 건물이 만들어지면 이 아름다운 곳으로 이사올 것이다. 어둡고 추운 지금의 공간을 떠나 밝고 넓고 전망이 좋은 공간에서 생활하게 될 것이다. 

 

비전에 대해 설명하는 내용이지만, 문득 아키텍처의 출발점이 이와 같지 않을까 하는 생각이 든다.

 

IT 시스템을 위한 아키텍처의 1차적 목표 역시, 대형의 복잡한 시스템에 대한 합리적으로 이해가능한 청사진을 제공하는데 있다.

 

여기서 '이해가능한'의 대상은 시스템 구축에 참여하는 모든 이해관계자로 볼 수 있으며, 이 중 핵심 이해관계자는 바로 고객이 되므로 고객이 이해가능한 시스템의 청사진이어야 한다.

 

고객이 이해한다는 것은, 고객의 요구사항을 합리적으로 해결하는 청사진을 제공하는 것이며, 아키텍처 드라이버라는 용어로 불리우는 아키텍처 결정요인 중 비기능 요구사항에 해당하는 품질속성을 만족시키는 아키텍처가 훌륭한 아키텍처인 것이다.

 

품질속성이라는 것도 가용성/성능/보안/유지보수성과 같은 시스템적인 부분도 있지만, TimetoMarket/시스템수명/가격 등 비지니스적인 부분도 고려되어야 한다.

 

따라서 고객의 관점에서 비기능요구사항에 대한 만족스러운 청사진을 제공하는 것은 IT전문가들만 이해가능한 복잡한 설계도가 아닌 전체 조감도가 더 아키텍처에 근접한 것이 아닐까 한다.

 

 

다음 그림은 아파트 건축물의 조감도이다.

아파트는 주거공간이라는 가장 기본적인 기능적 요구사항 외에도 고객의 선택에 더욱 중요한 변수인 주변생활여건, 녹지공간, 전망, 해가 들어오는 방향, 역세권 등의 품질속성이 매우 중요한 축을 차지한다. 이런 요건은 전문 설계도 보다는 아래 그람과 같은 조감도가 더욱 많은 얘기를 해 준다.

 

 

 

 

물론 이해관계자 모두가 제시된 청사진을 기반으로 작업을 진행해야 하기에 설계자, 개발자, 유지보수자와 같은 IT전문가들이 아키텍처가 설계한 원칙을 준수하는데 동참시키기 위해서는 다양한 설계의 측면을 고려해야 한다. 그래서 아키텍처 뷰의 가이드로써 OMG의 4+1View, CMUSEI의 3View, 지멘스의 4View 같은 참조모델이 존재한다.

 

 

 

 

 

 

 

다음 그림은 아파트의 특정 가구에 대한 설계도이다.

이 설계도는 개별 세대의 방구조와 배치, 동선 등을 표현하는 좀더 세부적인 아키텍처에 해당한다. 또한 전문적인 기호와 수치는 또 다른 이해관계자(설계자, 시공업자 등)를 위해 제공되는 정보 상세한 설계 기준으로 사용된다.

 

 

 

현대 건축의 아버지라 불리우는, '르 코르뷔지에'는 다음과 같은 말을 했다고 한다.

우리는 돌, 나무, 시멘트를 사용하여 집을 짓고 건물을 만든다.

이것은 건축이다.

 

그런데 문득 그것이 내 마음을 사로잡고, 나를 감동시킨다.

그 순간 행복한 나는 이렇게 말한다.

 

"아~ 아름답군!". 아키텍처(Architecture)란 그런 것이다.

 

- 르 코르뷔지에, 19123 "Architecutre: From Prehistory to Post-Modernism"

 

 

IT 개발의 많은 요소들이 건축의 그것에서 차용되어왔다. IT 아키텍처 역시 건축물의 아키텍처 사상에 근원하고 있으며, 아키텍트라면 르 코르뷔지에와 같은 마인드를 가져야 하지 않을까 한다.

 

마지막으로 앞의 구본형 소장의 글을 SW아키텍처에 비유해 다음과 같이 무단 변경해 본다. 

 

SW아키텍처를 제대로 이해하기 위해서는 건축물을 연상하는 것이 가장 완벽한 동질성을 부여한다.

 

SW아키텍처는 '시스템의 설계도'라고 말하는 사람들이 많다. 그러나 나는 그 생각에 강하게 반대한다. 그것을 설계도라고 해석하는 데서부터 많은 오류가 발생한다는 것을 알고 있기 때문이다.

설계도는 전문가들을 위한 것이다. 보통 사람은 설계도를 보고 그 건물의 전체적 모습을 떠올릴 수 없다. 그것은 판독하기 어려운 수치와 기호일 뿐이다.

 

SW아키텍처는 이해관계자 모두가 쉽게 그 모습을 머릿속에 떠올릴 수 있어야 하며,

그 모습의 아름다움 때문에 마음이 설레야 한다.

 

따라서 SW아키텍처는 오히려 건물의 조감도와 흡사하다.

소프트웨어의 유려한 자태와 추상화된 고품질의 질감이 느껴져야 한다. 그리고 그 시스템 속의 한 부분을 줌업시키면 그 속에 서브 시스템이 생활할 새로운 공간이 보인다. 이 시스템이 만들어지면 이 아름다운 것을 사용할 것이다. 어둡고 추운 지금의 시스템을 떠나 밝고 넓고 전망이 좋은 시스템을 활용하게 될 것이다.

 

 

'SW개발' 카테고리의 다른 글

웹의 Native 化, PWA(Progressive Web Apps)  (6) 2016.12.08
HTTP/2 (고성능 HTTP)  (8) 2016.12.05
SW 아키텍처 마인드맵  (4) 2016.09.01
[용어] 풀 브라우징(Full Browsing)  (2) 2010.07.14
[용어] Wi-Fi  (2) 2010.07.14

SW 아키텍처 마인드맵

Posted in SW개발 // Posted at 2016. 9. 1. 11:57
728x90

SW 아키텍트가 알아야 할 지식체계에 대한 마인드 맵!!!

하나라도 소홀함이 없어야 할 것!

그리고 여전히 중요한 것은... 최적화, 테일러링, 프로젝트 상황에 맞는 아키텍처링.

'SW개발' 카테고리의 다른 글

HTTP/2 (고성능 HTTP)  (8) 2016.12.05
아키텍처의 출발점  (4) 2016.09.05
[용어] 풀 브라우징(Full Browsing)  (2) 2010.07.14
[용어] Wi-Fi  (2) 2010.07.14
[용어] 3G, 4G?  (4) 2010.07.14

[용어] 풀 브라우징(Full Browsing)

Posted in SW개발 // Posted at 2010. 7. 14. 15:43
728x90
글 작성일: 2010/02/04 . 옮긴 날: 2010/07/14

요즘 스마트 폰은 모두 풀 브라우징(Full Browsing)을 지원합니다

풀 브라우징의 정확한 뜻은 무엇일까요?

사전적으로만 봐도, 뭔가 완전하게(Fully) 읽혀내는(Browsing) 능력을 말하는 것 같은데요
실제 그 의미도 사전적 의미와 동일합니다

풀 브라우저는 '풀 인터넷 브라우저' 를 약어로써,
모바일 기기에서도 일반 PC에서와 같이 웹 사이트를 동일하게 이용할 수 있는 서비스를 말합니다

이는 예전 WAP(Wireless Application Protocol) 환경의 왑 브라우징(WAP Browsing)
비교되는데요.

과거 휴대폰으로 접속했던 '매직엔'을 모두 기억하실 겁니다
매직엔은 이동통신 사업자가 구축한 대표적인 무선 인터넷 사이트로 WAP 규격에 맞게 제작되었죠
풀브라우징 이전 시대에는 이렇듯 WAP 규격에 맞춘 제한 된 사이트만 이용가능했습니다

당시 WAP 기반 마크업 언어로는 대표적으로 WML(wireless markup language)이 있었고,  mHtml, Hdml 등이 있었습니다. 저도 한 때 이러한 마크업 언어로 무선 인터넷 서비스를 개발해 본 경험이
있는데요 휴대 단말기의 특성으로 제한된 정보만 표현할 수 있었습니다

반면 풀브라우징은 WAP 규격뿐만 아니라, HTML, CSS, Script 등 일반 PC 기반 웹 기술을 지원하게
되어 PC에서 보던 웹 사이트들을 그 크기 그대로 , 그리고 선명하게 브라우징하는 능력을 갖추게
되었습니다

결론적으로 모바일 기기에서도 일반 웹 사이트를 풀리 브라우징 할 수 있다.. 가 되겠습니다

'SW개발' 카테고리의 다른 글

HTTP/2 (고성능 HTTP)  (8) 2016.12.05
아키텍처의 출발점  (4) 2016.09.05
SW 아키텍처 마인드맵  (4) 2016.09.01
[용어] Wi-Fi  (2) 2010.07.14
[용어] 3G, 4G?  (4) 2010.07.14

[용어] Wi-Fi

Posted in SW개발 // Posted at 2010. 7. 14. 15:42
728x90
글 작성일: 2010/02/02 . 옮긴 날: 2010/07/14

'와이파이'라고 발음하는 Wi-Fi 는 무슨 뜻일까요?

아이폰으로 무선 통신을 할 경우 3G 혹은 Wi-Fi로 하게 됩니다
3G 통신일 경우 화면에 3G, WI-FI 통신일 경우 화면에 부채꼴 모양이 나타납니다
또한 보통 3G는 유료, WI-FI는 무료.. 라고 알고 있습니다

WI-FI를 위키백과에서 찾아보니,
'Wi-Fi(와이파이)는 홈 네트워킹, 휴대전화, 비디오 게임 등에 쓰이는 유명한 무선 기술의 상표 이름이다' 라고 되어 있습니다

뭔 말인지 정확히 와 닿지는 않네요?. 대략 무선 인터넷 기술 명칭이다.. 정도로 파악됩니다
사실 이 내용이 전부 이기도 합니다

WI-FI는 무선 인터넷의 한 방식으로,
1999년 미국 무선 랜 협회인 WECA(2002년 Wi-Fi로 변경) 가 표준으로 정한 IEEE802.11b 방식의 별칭
이라 합니다. 무선 랜을 하이파이 오디오처럼 편리하게 쓸 수 있다 는 뜻에서 '와이파이(Wi-Fi)' 라는
별칭으로 쓰기에 되었습니다

보통 유선 인터넷 회선이 있는 상태에서 무선접속장치(AP) 나 유무선공유기를 통해 유선신호를
무선신호로 변환하며 이를 무선랜카드(아이폰 내장)를 통해 데이터를 송수신 하게 됩니다

즉 기존 유선 인터넷 회선을 사용함으로 추가적인 비용이 들지 않는 것입니다

Wi-Fi의 단점으로는 이동 중 사용이 불가능하며 장치에 의한 전파의 송수신 거리가 짧아 특정 범위
내에서만 사용가능하다는 것입니다. 이러한 단점을 보완한 기술이 바로 와이브로(Wibro)인데,
시속 100km 속도로 이동중에도 사용이 가능하며 전파의 송수신 거리가 굉장히 늘어나 반면 Wi-Fi에
비해 통신속도가 느리다는 단점이 있습니다


Wi-Fi 와 WIPI
Wi-Fi는 '와이파이', WIPI는 '위피' 라 발음합니다
간혹 Wi-Fi를 '위피' 라고 발음하시는 분들이 있는데요

Wi-Fi와 WIPI는 완전 다른 개념입니다
Wi-Fi는 위의 설명처럼 무선 통신의 한 방식을 말하며 WIPI는 대한민국 표준 모바일 플랫폼을 말합니다

즉 통신사간 서로 다른 모바일 플랫폼의 표준화를 위해 프로그래밍 모델과 API에 대한 표준을 제공하는
모바일 개발 플랫폼을 WIPI 라 합니다

'SW개발' 카테고리의 다른 글

HTTP/2 (고성능 HTTP)  (8) 2016.12.05
아키텍처의 출발점  (4) 2016.09.05
SW 아키텍처 마인드맵  (4) 2016.09.01
[용어] 풀 브라우징(Full Browsing)  (2) 2010.07.14
[용어] 3G, 4G?  (4) 2010.07.14