[웹보안] 웹보안 1일차 - 오후


쌍용 강북 센터 모의해킹 및 웹보안


웹보안 관련 강의만 세번째 듣는다.


처음엔 KISA에서 듣고 두번쨰는 현대 모비스에서 듣고


세번째로 듣는데 내용은 대동소이 하다






1. 기술적 진단

 - 웹취약점 진단 vs 소스코드 진단



1)웹 취약점 진단


로그인

계정 및 암호 찾기

회원가입

회사소개

공지사항

현장소식



2) 소스코드 진단


정책자료 http://www.moi.go.kr

https://kisa.or.kr




---skip ---


웹취약점 진단기준


https://www.owasp.org

owasp top10, 10개


A1 ~ A10 (스캔레이의 룰정책에 보면 기본적으로 해당 정보가 있다)




진단 기준은 3년단위로 업데이트 된다. - 그러나 굵직한건 거의 동일 내용임



-----------skip -------------


HTTP 프로토콜

request

브라우저/http 프로토콜마다 request셋팅은 달라진다.


request 기타 메소드는 대부분 사용이 안되고 get/post만 가능 하게끔 구성 되어 있다.


restfull서비스 다 허용하면 공격자가 서버에 파일을 변경하거나 입력할 수도 있게 된다.


response (응답)

200: 정상응답

300:페이지이동

400:클라이언트 잘못된 요청

500: 서버쪽 에러


이러한 응답 코드를 노출하게 되면 공격자에게


어느 부분에서 에러가 났는지 알게 해주기 때문에


공격자에게 힌트를 줄 수가 있다.


에러 페이지는 알아서 잘 만들자.






--skip --


http://demo.testfire.net


kisa 관련 보안 수업때 항상 등장하는 사이트.





--skip--


Sql injection


1. 일반  sql 인젝션


http://demo.testfire.net


에서 로그인시에


ID는 대충 누가 봐도 관리자 아이디 일 것 같은 


admin 입력 후


pw는


싱글쿼테이션인 ' 이걸 넣어보고 날려보자


그럼 sql 에러 메세지와 함께 쿼리도 보여 준다


이때 pw입력을


'or'1'='1


이라고 넣어주면


sql에서는 


WHERE ID='admin' AND pw = ''or'1'='1' 


이라고 인식하여 true값을 리턴하게 되며


admin 계정으로 로그인이 된다.





만약 싱글쿼테이션이 url 인코딩되어 전송되는 경우


프록시툴을 이용하여 HTTP 요청을 가로채서 값을 바꾼 후에 전송 한다.




2.블라인드 인젝션


webGoat -- http://localhost./WebGoat/attack?Screen=13&menu=1100




이름의 첫글자가 어떤 글자인지 추측 한다  뒤의 90은 대문자인지 소문자인지 구별하기 위함이며


90보다 작은경우 대문자 90보다 큰 경우 소문자 라고 생각 할 수 있다.


90은 대문자 Z의 아스키 코드값 이다.

1
SELECT ASCII(SUBSTRING(name,1,1)) FROM pins WHERE cc_number = 4321432143214321 > 90
cs



->


1
101 and SELECT ASCII(SUBSTRING(name,1,1)) FROM pins WHERE cc_number = 4321432143214321 > 80
cs




이렇게 날렸을때 리턴되는 값이 밸리드인지 인벨리드인지 보고 글자를 판단 하도록 한다.


이런식으로 반복하다 어느정도 범위가 좁혀지면


1
101 and SELECT ASCII(SUBSTRING(name,1,1)) FROM pins WHERE cc_number = 4321432143214321 = 74
cs


이런식으로 날려준다


74에서 밸리드가 나온다면 아스키코드 74에 해당하는 글자가 4321432143214321라는 


계좌번호의 주인 이름의 첫글자 라는 것을 알 수 있다.


이런식으로 substring 뒤쪽의 숫자를 

1
2
3
ASCII(SUBSTRING(name,1,1)) 
ASCII(SUBSTRING(name,2,1)) 
ASCII(SUBSTRING(name,3,1))
cs


등으로 바꿔가면서  


한글자식 알아내면 해당 계좌번호의


주인 이름을 전부 알아 낼 수 있다.



다운로드 취약점


서버에 중요한 정보인 config 류의 파일이나


권한,DB접속 정보들이 있는 xml파일을 암호화 하거나 추가적인 권한조치를 취하지 않으면


다운로드 취약점이 발견되는 경우 해당 중요정보가 있는 파일을 다운 받아 해당 서버및 웹어플리케이션


중요정보를 공격자가 알 수 있게 된다




http://localhost./WebGoat/attack?Screen=57&menu=200


Bypass a Path Based Access Control Scheme

프록시툴을 이용해 특정 파일을 요청하는 패킷을 가로채


상대경로로 바꾼 후 톰캣 정보를 가져 올 수 있게 된다.


대충 프로젝트 몇개 하다보면 대부분의 웹어플리케이션의 폴더구조는


비슷비슷 하다는걸 알기 때문에 아래와 같이 추측이 가능 하다


ex) File=../../../tomcat/conf/tomcat-users.xml&SUBMIT=View+File


해당 파일의 정확한 위치를 알 수는 없지만 상대경로를 통해 올라가다 보면


얻어걸리기 때문에 중요 정보를 가져 올 수 있다.



서버보안 이전에 어플리케이션에서 저런 상대경로 요청을 막거나 중요 파일의 암호화를


하지 않은 경우 어렵지 않게 중요 정보가 공격자에게 노출 될 수 있다.




sql MAp 사용



sqlmap 타겟의 디비정보를 뽑아오는 유틸


파이썬기반이기 떄문에 파이썬을 설치 후 사용 하자


파이썬 2점대 버전으로 설치 하도록 하자



사용 방법에 대한 관련 블로그

https://brunch.co.kr/@leesmain/8




테스트 사이트


http://testphp.vulnweb.com



SQLMAP 명령어



 sqlmap.py -u http://testphp.vulnweb.com/AJAX/infoartist.php?id=1 -v 3



뒤에 옵션을 -all --batch 로 주면


모든 공격을 다함



Session 


http 는 stateless 프로토콜이다


그런데도 사용 하는 이유는 가볍고 빠르기 때문에


웹서비스에 적합하기 때문이다.


stateless이기 떄문에 클라이언트가 어떤놈인지 구분할줄 몰라서


http 에서 히든태그를 계속 날려줬었다


그런데 그건 보안에 취약하다


그러니까 히든태그에 담는 데이터를


넷스케이프에서 만든 쿠키에 담기 시작했다


그런데 사실 이것도 보안에 안좋음 


클라이언트 로컬에 저장하기 떄문이다. 게다가 문자열정보만 저장 할 수 있다.


정 쿠키를 쓸떄는 httpOnly를 사용 하도록 한다.


그러니까


세션에 담아서 사용 하도록 하자






tomcat server 같은 도메인(IP)에서 Port번호가 다르지만 세션을 공유하는 문제 해결 방법(로그인 튕김등)


진행중인 프로젝트가


각각의 모듈역할을 하는 war파일 3개를 하나의 was(톰캣)에 넣고 돌리는데


이런 프로젝트를 2개를 한 서버(서버컴퓨터)에 넣고 돌리니


하나를 로그인 하면


다른 하나의 로그인이 해제된다거나 하는 세션관련 문제가 생겼다.



일단 문제의 원인은 통신되는 데이터의 암호화를 위해 암호화에 필요한 키값을 세션에 넣고 로그인페이지로 날려주는데


항상 접속할때마다 키를 재사용하지 않기 위해 기존키값을 제거하고 새로운 키값을 만들어 낸다


물론 다른 세션도 삭제하고



그래서 8080포트를 쓰는 프로젝트 로그인 창을 띄우고


8082 포트르 ㄹ쓰는 프로젝트 로그인 창을 띄운 다움 8080포트를 쓰는 프로젝트 로그인을 하면


암호화키값이 맞지 않아 에러가 나고



각각 따로 로그인을 한 후 먼저 로그인한 프로젝트에서 메뉴이동을 하면 권한,사용자 세션이 날아가서


메뉴이동시 로그인만료가 되어 튕겨나가게 되는 것 이다.



또 열심히 구글링을 해서 방법을 찾았는데


내가 삽질한 시간보다 훨씬 간단한 해결방법이 있었다.


서버는 세션ID를 찾을때 특정 ID로 찾는데 이게 두 포트에서 사용되는 세션ID가 동일해서 생기는 문제였다



해결방법은 톰캣 context.xml 파일의


context 부분에 sessionCookieName="first_JSESSIONID"  이것과 같이 각각 프로젝트에 서로 다른 세션쿠키명을 적용시켜 주면 해결이 된다..



1
<Context crossContext="true" sessionCookieName="PROJECT1_JSESSIONID">
cs


이렇게 설정을 해주면 된다..


crossContext는 한 was에 war 3개가 서로 세션을 공유하기 위해 사용한 옵션이고


서로 다른 was에서 세션을 간섭하지 않게 하기 위해 세션쿠키네임 이라는 옵션을 추가해 주었다.


당연히 또다른 프로젝트에선 쿠키네임을 다른 것으로 설정해 주어야 한다.



하나의 was에 여러개의 프로젝트(컨텍스트)가 존재할 경우 일반적으론


서로간 세션의 공유가 되지 않는다. 


이때 각 컨텍스트간의 세션이 공유될 수 있는 방법을 알아보자.



1. 서버의 context.xml의 변경


1
2
3
4
5
6
7
8
9
10
<!-- The contents of this file will be loaded for each web application -->
<Context>
 
    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
 
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
cs


저 위의 컨텍스트를 아래와 같이 바꿔준다.


1
2
3
4
5
6
7
8
9
10
<!-- The contents of this file will be loaded for each web application -->
<Context crossContext="true">
 
    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
 
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
cs



2. server.xml 변경


1
 <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

cs


1
 <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" emptySessionPath="true"/>
cs


emptySessionPath="true" 를 추가 한다.



3. 세션 세팅


1
request.getSession().getServletContext().setAttribute("ssUserId", userId);

cs


기존의 방법에서 가운데 getServletContext()를 추가 하여 준다.


root로 지정되어 있지 않는 컨텍스트에선 

getServletContext("/sample") 와 같이 컨텍스트명을 지정하여 준다.



4. 세션 겟


1
String ssUserId =  (String) request.getSession().getServletContext().getContext("/").getAttribute("ssUserId");
cs


가지고 올땐 위와 같이 가져오며 루트가 아닌 컨텍스트에서 set 한 경우엔 getContext("/sample") 와 같이 컨텍스트 명을 넣어 사용 하면 된다.



+ Recent posts