지난 포스팅 글에서
아파치 웹 서버의 설정파일을 통해서 인증을 구현해보았다.
이어서 인증 사용자를 추가하고 추가적으로
글로벌 설정 파일과 로컬 설정 파일, 웹 서버 설정 파일에 대해 간략히 이야기 해보겠다.

지난 글에서 설정한 내용에서 우리가
.htpasswd 파일에 정보를 이용해 인증에 사용할거라는 코드가 있었다.
이제 그 파일을 만들어주는 작업을 해주면 된다.

처음 파일을 만드는 경우와 기존에 있던 파일에 사용자를 추가하는데 있어서
코드가 조금 다르다.


처음에 파일을 만드는 경우
#> htpasswd -c /var/www/html/.htpasswd user1




(사용자 생성)



user1을 생성해 보았다.

이제 기존에 있던 파일에 사용자를 추가하는 작업을 해보겠다.

이미 만들어진 파일에 사용자를 추가하는 경우
#> htpasswd /var/www/html/.htpasswd user2
여기서 user2는 사용자 이름이다.



(사용자 추가)



사용자를 추가해보았다.

.htpasswd 파일에 추가해주었는데 이 파일을 확인해 보면



(.htpasswd 파일)



확인해보면 사용자 아이디와 비밀번호가 보인다.
(비밀번호는 보안상 해쉬값으로 저장되어있는 것을 확인 할 수 있다.)

이렇게 만든 파일이 인증에 정말 잘 적용되는지
접속해보겠다.



(인증 접속)




(성공)



인증에 성공되어
페이지에 접근할 수 있는 것을 확인 할 수 있다.

관리자 도구에서 확인해보면
Authorization 항목에 값이 추가되있는 것을 확인 할 수 있다.



(인증 코드)



이렇게 글로벌 설정 파일을 이용하여 웹 페이지 인증을 설정해보았다.
그렇다면
부분적으로 인증을 요구하고 싶다면 어떻게 할까?

예를 들어 전에 우리가 만들었던 auth 폴더에만 인증을 요구하도록..

그러기 위해서는 로컬 설정 파일을 이용하면 된다.
확인해보기 위해 우리가 설정했던 코드들을 원래대로 지워준다.
단, AllowOverride All 은 그대로 둔다.
오버라이드를 허용하겠느냐라는 말인데 허용을 해야
우리가 추가적으로 설정을 할 수 있다.


(수정)



그 후 웹서버를 재시작 시켜준다. :)



(웹 서버 재시작)



글로벌 설정 파일 중
/etc/httpd/conf/httpd.conf
파일의 404번 라인을 보면
.htaccess 파일을 추가적인 설정 파일로 적용 시킬 수 있다는 부분이 보인다.

->
.htaccess 파일이 있는 디렉터리부터 그 하위까지 영향이 있다.
이 파일이 존재하면 그 해당 디렉터리 아래부터 인증을 요구하게 된다.

이 기능을 이용하여 웹 인증을 부분적으로 적용시켜보겠다.
auth폴더에 들어가서 .htaccess 파일을 만들어준다.



(auth 폴더)




(.htaccess)


.htaccess 파일에는 우리가 저번에 사용하였던
코드를 그대로 넣어준다. (인증을 사용하겠다는 말이다.)
그렇게 하여 확인해보면
auth 폴더에 있는 login.php 페이지에 대해 인증을 요구하게 된다.



(인증 요구)



반면 다른 폴더에 있는 제로보드 게시판에 대하여는
인증을 요구하지 않는 모습을 확인 할 수 있다.




(인증 요구없음)



이로써 글로벌 설정과 로컬 설정을 인증 설정을 하면서
확인해 보았다.

다음 글에서는 파일 업로드 취약점을 공략하기 위해
php 파일을 업로드 해야하는데
이 기능이 막혀있었던 것을 우회하는 방법을 살펴볼 것이다.





해킹의 공격은 서버측에서의 악성코드 실행으로 이루어 질 수도 있다.
쉽게 말하면
악성코드, 파일을 만들어서 서버에 저장하고 서버에서 실행을 하여 공격하는 것이다.

이게 말이 될까?
어떻게 서버에 내가 파일을 저장하지?
사실 우리는 아주 흔하게 그런 일을 하고 있다.
바로 업로드 기능이다.
게시판 혹은 웹 상에 우리의 사진 혹은 파일을 올려본 적이 있을 것이다.
이렇게 되면 우리가 올린 파일이 서버에 저장이 되고
다른 사람들이 그 파일을 받는 것이다.

나쁜 해커들은 바로 이런 순수한 기능을 이용해 공격을 한다.
바로 악성 PHP파일을 업로드 시키고 그 파일을 실행시키는 것이다.
이러한 공격이 이루어 질 수 있는 조건이 있다.
1. PHP파일이 웹 서버에 존재한다.(업로드 가능, 혹은 어떤 방법으로든)
2. 그 PHP파일을 웹브라우저에서 접근할 수 있다.(직접참조 가능하다.)

이렇게 되면 나쁜 해커는 웹 브라우저에서 PHP파일을 접근하여 실행시키는 것이다.

이러한 공격과정을 살펴보기 위해 업로드 기능을 이해해보자.

우리는 먼저 PHP파일이 아닌 일반적인 사진 jpg 파일을 업로드 해볼 것이다.




(업로드 할 사진)




우리가 만든 제로보드에 보노보노를 업로드 해본다 :)



(보노보노 업로드)




(업로드 된 화면)



보노보노가 게시판에 업로드 되었다.

그렇다면 이 사진파일은 웹 서버 어디에 존재하는 걸까?

F12 키를 눌러 코드를 볼 수 있는데 여기에 이미지의 경로가 나온다.
바로 data/ 폴더에 있다는 것을 알 수 있다. :)



(파일 경로)




제로보드 폴더의 /data 폴더에 들어가보니
보노보노가 있다 :)



(파일 존재)




그렇다면 두 번째 조건인 웹브라우저에서 직접 참조가 가능할까?
웹브라우저에 파일의 경로로 접근해 보았다.




(파일 접근)




(실행 화면)




보노보노 사진에 직접 접근이 가능하였고
실행까지 된 모습이다.

즉, 두 조건이 성립하고 나쁜해커가 존재한다면 공격을 할 수 있는 부분이다.

나쁜 해커처럼 우리도 PHP 파일을 올려볼 것이다.
단순히 화면에 run php haha 문자가 출력되는 php 파일이다.




(php 파일 작성)




우리가 만든 php 파일을 게시판에 올려볼 것이다.




(php 업로드)




파일을 올리려 클릭을 해보니...



(업로드 제한)




PHP 파일은 올릴 수 없다고 뜬다.

게시판에서 조건을 걸어둔 것이다.
write_ok.php 파일을 열어서 확인해 보겠다.



(write_ok.php 파일 확인)




(php 파일 제한)




207번 라인을 보니 HTML , PHP 파일을 올리지 못하게 필터링 해두었다.

아주아주 기본적인 취약점을 막아놓은 것이다.
이 것은 유명한 공격이므로 이렇게 해놓는 것이 당연하다.

그렇다면 과연 나쁜 해커는 여기서 좌절할까?
머리를 굴리기 시작한다.

꼭 확장자가 php파일이어야할까?
확장자를 txt 파일로 변경해서 올려 보았다.




(txt 확장자)





(업로드)




(업로드 된 모습)




php파일이 아니므로 필터링에 걸리지 않고
txt 파일이 업로드 되었다.

여기서 이제 txt 파일을 직접 접근해보겠다.



(실행)




실행해보니 php파일이 실행 된것이 아니라
단순히 txt 파일이 실행되었다...

왜 이런 일이 일어났을까?

이것을 이해하려면 웹에대한 이해가 필요하다.
웹 아파치 서버의 글로벌 설정파일을 이해해야한다.

이야기를 시작해보겠다.
웹 서버에서 경로
/etc/httpd/conf.d 폴더에
php.conf 파일이 있다. 바로 conf.d폴더에 있는 것들이 글로벌 설정 파일이다.
먼저 왜 php파일이 확장자 .php인 파일만 php 실행이 되는지 확인해 보겠다.
php.conf 파일을 열어본다.



(php.conf 파일 확인)




(php.conf 파일)




17번, 18번 라인을 확인해보면 .php 가 보이는데 바로 이것이
.php 파일확장자는 php로 실행하라는 뜻이다.
여기에 .txt를 추가해서 확인해 보겠다.



(php.conf 파일 수정)




그러고 나서 아까 우리가 txt파일로 실행됬던 attack.txt 파일을 실행해보았다.
웹에서!



(php 실행)



php로 실행 되었다.

그렇다면 글로벌 설정 파일은 무엇일까?
위에서 본것에 의하면 웹 서버에서의 설정파일? 정도로 이해 할 수 있다.

이번에는 /etc/httpd 폴더에 있는
httpd.conf파일을 확인해보겠다.
바로 이 파일이 정확히 말하는 글로벌 설정 파일이라고 할 수 있는데
이 파일은 웹 서버가 실행되면 이 파일을 읽어 들여서 여기에 적혀있는데로
웹 서버를 실행시키는 것이다.
그렇기 때문에 글로벌 설정 파일이라고 부른다.
이 파일을 확인해 보겠다.



(httpd.conf)



여기에 보면 웹 서버 설정 내용들이 있다.
쭉 내려보면 210번 라인을 볼 수 있다.



(210번 라인)



이 라인의 코드를 보면 conf.d 폴더안에 있는  .conf 파일을 전부 실행시키는 코드이다.

웹 서버가 실행될때 이 파일이 실행되는데
이 파일 안에 코드에 의해 confd 폴더에 있는 .conf 파일이 전부 실행되므로 여기에
있는 파일들도 글로벌 설정 파일이라고 할 수 있다.

쉽게 말하자면 웹 설정 파일이 너무 기니까 부분별로 파일을 쪼개 놓은 것이다.

이 전까지 우리가 웹 코드에서 인증을 구현했었는데
웹 서버 자체에서 인증을 구현할 수도 있다.

한번 웹서버에서 인증을 설정해보겠다.
우리가 적용시킬 웹 페이지는 /var/www/html에 있는 페이지들에 대해서
인증을 적용 시켜볼 것이다.
그러므로 <Directory "/var/www/html"> 태그 안에 입력하면 된다.



(설정 적용 위치)



인증 설정을 하겠다.



(인증 설정)




인증 설정 후 웹 서버를 다시 시작해준다.



(웹서버 재 실행)



재실행 후 제로보드에 아까 그대로 들어갈 수 있었는데
지금은 사용자 인증을 해야 접속을 할 수 있게 나왔다.



(인증 요구)




다음에 이어서 웹에 대한 이해를 해보겠다 :)





저번에 이어서 세션 이야기를 마무리해보겠다.

세션을 사용하려면 페이지 시작할 때 session_start()를 넣어준다.

세션을 이용해 간단한 인증을 해볼것이다.
세션인증을 위한 세션값을 만들어야하는데
islogin 값으로 아이디와 비밀번호를 연결해 해쉬값으로 저장하고
name 값으로 아이디를 저장했다.



(세션인증값 설정)



로그인 해보겠다.



(로그인)





(세션 확인)



로그인 후 세션쿠키값을 확인 할 수 있다.
하지만
세션값으로 우리는 알아낼 수 없다.
세션 쿠키값에 저장된 값들은 서버에 있기 때문이다!

그렇다면 서버에 가서 세션에 우리가 설정해 놓은 값이 잘 저장되었는지 확인해 보겠다.



(세션값 확인)



우리가 설정한 대로 해쉬값과 아이디 값이 보인다.

그러면 전에 쿠키값을 이용한 간단한 인증을 한 것 처럼
세션도 똑같이 해보겠다.
DB를 지금은 다루지 않을 것이므로
간단하게 세션값이 있으면 인증을 성공시켜 줄 것이다.



(인증 코드)




(인증 성공)




그렇다면
세션값을 어떻게 파기 시킬까?
세션 값은 세션이 종료되면, 즉 웹브라우저가 닫히면 세션값이 파기된다.

그렇지 않고
웹 브라우저가 켜진 상태에서 세션값을 파기하려면??
session_dstroy() 함수가 php에 있다. (사용해보겠다.)



(session_destroy() 사용)




사용 후 확인해보니..



(세션 파일 존재)




세션 파일이 존재한다.
그 세션파일에 들어가보니 내용은 전부 사라져있다.

즉 파기할 때 session_destroy()만 사용하면 세션 파일은 사라지지 않고
그 세션 파일에 저장된 값들이 지워지는 것이다.

그렇다면 세션 파일까지 지워주려면?
쿠키값을 제거할 때랑 똑같다.



(세션파일 삭제)




즉 세션을 파기하려면
세션 내용도 지워줘야하지만 세션 쿠키도 지워주어야 한다.




웹 서버에서
사용자들을 어떻게 인증할까?

* 웹에서의 인증 특징
 - TCP통신을 한다. 일반적인 인증과 동일하게 진행할 수도 있다.
 - 웹의 특성상 세션을 유지하지 않는다.
 - 웹 서버 어플리케이션은 사용자 인증을 위한 인증 토큰을 발행한다.

인증 토큰에는 두가지가 있다.
1. 쿠키 (Cookie)
-> 보안에 취약하다.
-> 사용자 정보가 로컬 컴퓨터에 남는다.

2. 세션 (Session)
-> 쿠키의 보안 취약점을 개선하기 위해 나온 것이 세션이다.

그렇다면 이러한 인증 과정을 직접 확인해보겠다.
먼저 간단한 웹 인증페이지를 만들어 볼것이다.

auth 폴더를 따로 만들어서 여기서 작업을 하겠다.



(auth 폴더 생성)



vi 편집기를 이용해 login.php 파일을 작성한다.
#> vi login.php



(login.php)



간단하게 아이디와 비밀번호를 입력 받아
login_ok.php 파일에 전송해주는 페이지이다.



(페이지 모습)



그렇다면 이제 login_ok.php 파일을 만들어서
인증 과정을 만들어볼 것이다.

아직 DB를 손데지 않고 간단히 연관배열을 사용하여 인증을 해보겠다.

연관 배열 사용 테스트이다.
user1 ~ 3을 만들고 해당 비밀번호를 연관 배열로 설정한다.
그리고 입력받은 아이디의 비밀번호를 화면에 출력해보겠다. (테스트)



(login_ok.php)



이제 잘 동작하는지 체크해보겠다.
실행



(아이디 user1 입력)




(실행화면)



실행 화면에 user1의 비밀번호가 잘 출력된 것을 확인 할 수 있다.

이제 이 것을 사용하여 인증을 해보겠다.
php 언어에서 array_key_exists 함수를 사용해 해당 아이디에 관해 연관배열의 값이 있는지 체크하고
있다면 비밀번호가 입력받은 것과 일치하는지 체크해서 인증을 하겠다.



(login_ok.php)



결과 인증에 성공하면
로그인 성공이라고 팝업창을 띄우고
실패하면 실패라고 팝업창을 띄우는 script를 추가했다.

실행해서 확인해보겠다.



(접속)




(로그인 성공)






(로그인 실패)



비밀번호를 올바르게 입력했을 때 success가 뜨고
실패했을 때는 fail이라고 잘 떴다.

로그인 인증까지 확인했으니
이제 토큰 방법 중 하나로 쿠키를 사용해보겠다.
인증에 성공했을 경우에
쿠키를 추가해주는 코드를 추가해줄 것이다.
쿠키 설정 php 언어
setcookie("쿠키이름", "쿠키에 넣을 값", 유효기간, 쿠키값이 적용될 영역)
하나는 user_id의 쿠키 변수에 id를 그대로 사용했고
session_id 쿠키 변수에는 ID와 비밀번호를 연결해 해쉬함수로 바꾸어서 사용했다.



(쿠키 생성)




login.php 페이지에서
쿠키 값을 출력해보겠다. (쿠키값이 잘 설정되는지 확인하기 위하여)



(쿠키값 확인 코드)





실행



(실행 화면)




실행 화면을 보니 위에 우리가 설정해준 쿠키값이 잘 저장되 있는 것을 확인 할 수 있다.

F12 키를 눌러 관리자 모드에서 네트워크 부분으로 어떤 통신을 주고 받는지 확인 할 수 있는데
여기서 응답으로 쿠키 값을 보내준 것을 확인 할 수 있다.




(쿠키값 전달(응답))




혹은
관리자 모드에서 Console창에서도 확인 할 수 있다.
document.cookie
를 입력하면 나온다.


(저장된 쿠키값)




이제 이 쿠키값으로 인증을 해보겠다.
사실 이 쿠키값을 비교하여 일치하면 인증을 해주는 방식인데
우리는 여기서 간단하게 해보겠다.! ㅎㅎ
간단하게
쿠키값이 저장되어있다면!
로그인 을 해주도록 할 것이다.



(인증 코드 추가)





그렇게 하여 인증이 되면 해당 ID를 불러와 Welcome 페이지를 보여주고
인증이 안되었으면 로그인하는 페이지가 보이도록 하였다.

인증에 성공하면 아래와 같이 나온다.




(인증 성공)





(Console에서 확인)




콘솔에서도 확인 할 수 있다.

이렇게 편하고 좋은 쿠키가 보안에는 취약할 수 있다.
쿠키가 로컬 컴퓨터에 그대로 저장되기 때문에
만약 쿠키값으로 ID 혹은 패스워드를 그대로 사용하면
굉장히 위험하게 된다.

윈도우 IE에서 쿠키 값을 저장하는 곳을 확인해보겠다.
인터넷 옵션에 들어간다. 그 후 설정을 눌러준다.




(설정 클릭)




여기서 아래의 표시된 부분이
쿠키값이 저장되는 부분이다.




(쿠키 위치)




파일 보기를 누르면 해당 폴더가 열린다.




(쿠키 파일)





여기에는 쿠키파일 뿐 아니라 인터넷 임시 파일들도 저장되어 있다.

한번 로그인하여 우리의 소중한 쿠키가 어떻게 저장되는지 확인해 볼 것 이다.




(로그인)





(성공)



해당 폴더에 들어가서 확인해보니 우리가 방금 얻어온 쿠키값이 그대로 저장되 있는 것을
확인할 수 있다.



(쿠키값 파일)




이제 로그아웃 링크를 하나 만들어주어 쿠키값을 없애보도록 할 것이다.
만약 이 기능이 없다면
로그인이 한번 되면 적어도 하루 동안은 그 페이지 로그인 페이지를 볼 수 없다...

로그아웃 기능 추가!



(링크추가)



로그아웃에 하이퍼링크로 logout.php 페이지를 입력해놓았다.
우리는 logout.php 페이지에서 logout을 해줄 것이다.



(logout.php 파일 생성)




쿠키를 지우는 방법은 아까 setcookie 함수를 사용했던 것과 같다.
다만 쿠키값을 "" 빈 채로 설정하는 것이다.




(logout.php 코드)




다시 화면에 가보면 logout 링크가 되있는 것을 볼 수 있다.




(logout 추가)




버튼을 누르면
다시 login.php 페이지에서 로그인 화면을 볼 수 있다.




(로그인 페이지)




두 번째 토큰 방법으로 session이 있다.
이 session은 브라우저가 열려있을 때만 유효하고
닫히게 되면 session이 사라지는 특징이 있다.

중요한 특징은
서버에 저장된다는 것이다. (그렇기에 쿠키에 비해 안전하다고 할 수 있다.)

login_ok.php 파일에서
아까 만든 쿠키 설정은 주석으로 처리해 두고
세션 값을 설정해주겠다.
방법은
session_start();
를 입력하는 것이다.



(세션 추가 코드)




페이지에 접속하자마자 세션ID 쿠키를 만들어 준다.
바로 이게 session_start() 가 하는 일이다.

이 값을 확인해 보겠다.




(세션ID값 확인)




(콘솔에서 확인)



물론 콘솔에서도 확인 할 수 있다.

이 값은 아까 서버에 저장된다고 했었는데
그 위치는
/var/lib/php/session/ 에 파일로 존재하게 된다.
그렇기에 아까 확인했던 값이 파일 이름형태로
저장되있는 것을 확인 할 수 있다.



(세션 ID 위치)




세션ID가 설정되어있는 것 까지 확인했다.
이제 다음에
이 세션ID에 인증내용을 추가하는 기능을 만들어 확인하겠다.




오늘은 CSRF 공격을 공부했다.
CSRF는 변존 XSS 공격이다.
CSRF ( Cross Site Request Forgery )
변종 요청 공격이다.
스크립트를 사용하지 않고 html 태그를 사용하여 취약점을 공략한다.

이 공격을 해보기에 앞서서
HTML 코드를 분석해보는 단계부터 연습해 볼 것이다.

관리자 페이지에 들어간다.



(관리자 페이지)



회원 관리를 눌러준다.



(회원 관리 버튼)




여기서 게시판에 회원 가입한 회원들의 정보를 볼 수 있다.
또한 이 페이지에서 회원의 정보, 등급을 바꿀 수 있다.
그렇다면 이 페이지에서 어떤 변수들을 어느 페이지로 전달을 하여
회원 level을 수정할까?




(회원 관리 페이지)



소스보기로 들어간다.

먼저 form 태그를 찾아서 어디로 보내는지 그리고 변수를 확인했다.
보내는 곳은 admin_setup.php 파일이다.



(소스 코드)



(소스 코드)





(소스 코드)



여기 까지 레벨 수정에 필요한 변수들이었고
수정하기 버튼을 잘 보면 onclick으로 move_all() 함수가 설정 되있는 것을 볼 수 있다.
그렇다면 move_all() 함수를 살펴보자.



(move_all() 함수)



exec2에 moveall 이라는 값을 넣어주어 넘겨준다.!

여기까지 정리해보면 필요한 변수와 값은
page=1
group_no=1
exec=view_member
page_num=10
exec2=moveall
cart[] = 2 
movelevel=1 

먼저 GET 방식으로 변경해보겠다.
URL을 통해서 변수를 전달해준다.
admin_setup.php?page=1&group_no=1&exec=view_member&page_num=10&exec2=moveall&cart[]=2&movelevel=1



(url 입력)



(실행 결과)



실행 결과 사용자의 Level이 1로 상승된 것을 확인 할 수 있다.

이번에는 POST방식으로 변수를 넘겨보겠다.
그러기 위해 F12 관리자 모드에서
콘솔에 입력해주면 된다.
document.write("") 으로 입력해주면 페이지를 만들어서 보낼 수 있다.

조작한 Form
<form method=POST>
<input type=hidden name=page value=1>
<input type=hidden name=group_no value=1>
<input type=hidden name=exec value=view_member>
<input type=hidden name=page_num value=10>
<input type=hidden name=exec2 value=moveall>
<input type=hidden name=cart[] value=2>
<input type=hidden name=movelevel value=1>
<input type=submit value=전송>
</form>
이 내용을 전부 한줄로 만들어 보내는 것이 중요하다.
이 내용을 전부 한 줄로 만들어 콘솔에 입력해준다.



(POST 전달)




(Form 페이지)



입력을 하면 Form 페이지가 만들어진것을 확인 할 수 있고
여기서 전송버튼을 누르면 우리가 만들어준 변수들이 그대로
admin_setup.php로 전달되는 것이다.



(실행 결과)



실행 결과 역시 level1로 상승했다. ( 다시 9로 만들어준 상태였다.)

이번에는 회원 설정변경에 들어가서 레벨과 관리자 권한을 수정해보겠다.



(수정할 부분)



소스코드를 열어서 확인해보면



(소스 코드)




(소스 코드)



변경에 필요한 변수들을 쉽게 찾을 수 있다.

이 변수들을 이용해 아까와 마찬가지로
GET방식으로 정리하면
admin_setup.php?exec=view_member&exec2=modify_member_ok&group_no=1&member_no=2&page=1&keyword=&name=normal&level=1&is_admin=1



(GET방식)




(실행 결과)




실행 결과 역시 level1로 상승 되었다.

POST 방식도 아까와 같다.
<form method=POST>
<input type=hidden name=exec value=view_member>
<input type=hidden name=exec2 value=modify_member_ok>
<input type=hidden name=group_no value=1>
<input type=hidden name=member_no value=2>
<input type=hidden name=keyword value=>
<input type=hidden name=name value=normal>
<input type=hidden name=level value=1>
<input type=hidden name=is_admin value=1>
<input type=submit value=전송>
</form>
아까와 마찬가지로 한줄로 만들어서 작성해주면 된다.


(POST 전달)




(Form 페이지)



버튼을 누르면



(실행 결과)



실행 결과 레벨상승과 관리자 권한을 획득할 수 있다.

다시 원래 주제로 돌아가서
오늘은 CSRF를 이용하여 레벨1, 관리자 권한을 획득 할 것이다.
변조 요청으로
HTML 태그 중 <img> 태그를 이용할 것이다.

원리는 이렇다.
<img src=""> src에 우리가 원하는 변수와 값들을 GET방식으로 전달하는 url을 넣을 것이다.
만약
관리자가 이 글을 본다면
관리자의 신분으로 이 변수값들이 서버에 전달되게 되고
그렇게 되면 서버 입장에서는 관리자가 요청한 것으로 착각하게 되어
공격자의 레벨이 1로 상승하고 관리자 권한이 생기게 된다.

공격에 앞서 다시 attack 계정을 일반계정으로 바꾸어 두었다.



(일반 계정으로 전환)



attack 계정으로 로그인 한 후
게시판에 글을 작성한다.
CSRF 공격


(악성 HTML 태그 삽입)



그 후 관리자가 그 글을 읽기 까지 기다린다.



(관리자 확인)



관리자가 확인을 했다면
게임 끝이다.

이제 attack 계정은 관리자 계정이 되는 것이다.




(공격 확인)




이것이 변조 요청 공격
CSRF 공격이다. 바로 XSS의 변종 공격기법이라고 할 수 있다.




XSS( Cross Site Scripting )
- javascript를 이용한 대표적인 취약점이다.
  스크립트로 작성된 코드는 클라이언트의 웹브라우저에서 실행이 된다.

인터넷 웹 화면이 뜨는 과정은 웹 서버에서 우리 앞의 웹 브라우저로 코드가 날라오고 웹 브라우저는 그 코드를 실행하여 화면에 보여주는 것이다. 이 때 넘어오는 값에 스크립트 코드를 넣는 것이다.
 -> 주 타겟 : 불특정 다수(클라이언트)

ex) 예를 들어 게시판에 아래와 같은 글을 업로드 하는 것이다.
<script>alert("공격성공")</script>
(Enter가 들어가면 안된다.)
-> 공격을 하려면 자바스크립트로 원하는 코드를 만들 수 있어야한다.

스크립트 코드가 실행 되는지 확인하기 위하여 alert() 을 사용하여
코드가 실행 된다면 악의적인 코드가 실행될 가능성이 있다고 판단하여
취약점이라고 간주한다.

우리가 만든 제로보드 게시판에 XSS 공격을 해보겠다.



(스크립트 작성)




(게시판 화면)



게시판에 공격자의 글이 올라온 것을 확인 할 수 있다.

만약 이 글을 클릭한다면



(악성 코드 실행)



공격자가 작성한 스크립트 코드가 실행된다.



(글 화면)



글 내용에는 아무 글도 보이지 않는다.
왜냐하면 스크립트코드로 간주되었기 때문이다.

이런 방식으로 게시판 혹은 서버에 저장해두어 다른 사람들이 열람하여
코드가 실행되게 하는 방식을 Stored XSS 라고 한다.

다른 방법으로는 reflected XSS가 있다.

이 방법은 다음 XSS 취약점을 보면서 확인하겠다.
다음 XSS가 가능한 부분은 많지만
그 중에 회원가입란의 아이디 중복체크하는 페이지다.


(중복 체크 페이지)



이 페이지의 주소를 살펴보면
url을 통해서 값이 전달되고 있는 것을 확인 할 수 있는데
이 변수에 스크립트 코드를 넣어 실행하면
바로 실행이 된다.



(url을 통한 스크립트 코드)





(실행 화면)



실행하게 되면 IE에서
XSS를 발견하여 조치를 취해주었다.

우리는 공격을 확인 할 것이므로 잠시 이 설정을 해제해 주도록 하겠다.



(인터넷 옵션)



인터넷 옵션에서 보안탭을 들어간다.




(사용자 지정 수준 클릭)



사용자 지정 설정 수준에 들어가면
아래 부분에 XSS 필터 사용 항목이 있는데
사용 안 함으로 클릭해 주면 된다.



(사용 안함 클릭)



그런 상태로
아까와의 같은 url로 접속을 하면



(실행 화면)



스크립트 코드가 실행 된것을 확인 할 수 있다.

이 방식이 아까 Stored XSS와 다른 점은
저장되는게 아니라 바로 돌아온다. 입력된 그자리에서 실행된다는 것이다.


<script>alert(" target="_blank">http://100.100.100.129/zboard/check_user_id.php?user_id=<script>alert("xss")</script>
 링크를 활용해서 공격할 수 있다.
바로 이런 방법이 reflected XSS 이다.

이 공격을 더 유용하게 만드는 것은 shorten url 이다.
url을 짧게 만들어준다.



(shorten url)



그렇다면
XSS에 대한 대책은 어떤 것이 있을 까?

<script> 문을 게시 글 이외에
어떤 곳에서도 올리지 못하게 해두어야한다.

제로보드의 코드를 조금 수정해 보겠다.
게시판 글을 쓰는 곳에서 코드를 확인해보니
write_ok.php 파일로 데이터들을 전송하는 것을 확인 할 수 있다.



(보내는 곳 확인)



그렇다면
우리가 손봐야할 파일은
write_ok.php이다.



(write_ok.php 수정)



먼저 게시판 글쓰기의 소스코드를 확인해보면
게시 글이 변수 memo를 통해 넘어오는 것을 확인 할 수 있다.



(게시글 변수)



그러므로 우리는
write_ok.php 파일 맨 앞에
<script> 단어가 있으면 XSS 공격으로 간주하는 코드를 추가할 것이다.



(코드 추가)



코드 추가 후 공격을 해보겠다.



(XSS 공격)




(차단)



차단 된 것을 확인 할 수 있다.

하지만 방어가 있으면 다시 또 다른 공격을 하는 법..

이 코드를 우회할 수 있다면? (아주간단하게..)



(우회? 공격)



아주 간단하게 첫 script 를 대문자로 작성했다.



(우회 XSS 공격)




(공격 성공)



공격이 성공했다..
아주 간단하게 성공됬다.

이는 아까의 코드에서 문자열 검색에서 i를 추가해주면
대소문자 전부 체크해준다.



(코드 수정)



그렇게 되면



(우회 공격)




(차단)



간단한 우회도 차단할 수 있게 된다.

하지만 우회하는 방법은 수없이 많다.
그러므로 시큐어코딩(안전한코딩)이 쉬운 일은 아니다..!





설치한 아파치 서버의 기본 웹 홈 디렉터리는
/var/www/html 이다.

여기에 페이지를 만들고 확인 해 볼 것이다.



(기본 웹 홈 디렉터리)



이 위치에 exam.php 파일을 vi 편집기를 통해 만들어준다.



(exam.php 파일 생성)



* php 코드 문법
- php는 <?php  ?> 태그 안에 써준다.

<?php
 echo (출력 명령문)
 .  (문자열과 문자를 연결해주는 연산자 )
?>
변수는 앞에 $를 붙여준다.
string 변수에 문자열을 넣어서 출력해주는 코드를 적었다.



(간단한 PHP 코드)



이 파일을 실행 시키는 방법은 두 가지다.
1. php 실행기를 이용해서 실행한다.
2. 웹 브라우저를 통해 실행한다.

먼저 PHP실행기를 이용해 실행해 보겠다.
#> php exam.php



(PHP 실행한 모습)



두 줄을 적어보겠다.


(PHP 코드)



이 번에는 이 파일을 웹 브라우저에서 실행해보겠다.



(실행 모습)



위 코드는 두 줄로 나오지 않았는데
이건
웹브라우저에서랑 PHP 실행기에서의 명령문이 조금씩 다르다.
웹브라우저에서 줄바꾸는 명령어는 <br> 태그를 사용해야한다.




(<br> 태그 사용)



코드를 수정하고
웹페이지에서 실행하면



(실행결과)



두 줄로 나온다.

웹 페이지에서 변수를 전달하는 방법이 두 가지가 있다. (GET과 POST 방식)
1. GET
2. POST

GET 방식은 URL을 통해 변수를 전달한다.
확인을 위해 PHP 파일에서 GET 변수를 받아오겠다.
GET변수는 $_GET[변수이름] 으로 받아온다.



(php 코드)



URL에서 name변수에 kim을 입력해 전달해보니 kim이 출력되었다.



(실행 결과)



사실
GET이든 POST이든 배열의 형태로 담겨 넘어온다.
GET은 GET[] 배열에, POST는 POST[] 배열에
그리고 인덱스는 변수 이름이 된다.
그래서 GET[name] 에서 name이 인덱스 역할로 값 kim이 나온 것이다.
_GET 배열을 확인하려면
print_r( $_GET ) 으로 확인 하면 된다.




(배열 확인 코드)





(실행 결과)



실행 결과를 보면 변수에 담겨 넘어 오는 값들이
배열의 형태로 전달 되는 것을 확인 할 수 있다.

두 번째 전달 방식인 POST 형태를 확인해 보겠다.
POST는 URL 헤더가 아닌 패킷의 Body에 변수를 담아서 넘겨준다.

그렇기 때문에 url에 표시 되지 않는다.
POST로 전달하는 방법은 HTML의 Form 태그를 이용해서 보낼 수 있는 방법 하나이다.

간단한 Form 태그를 작성했다.



(간단한 Form 태그)




(실행 결과)



여기서 전달 방식을 지정해 줄 수 있는데 먼저
아까 했던 GET방식을 확인해 보겠다.



(method = "GET")



그리고 받아오는 php 파일에서 위에 두줄은 GET으로 아래 두줄은 POST변수에서 받아오도록
작성했다.



(받아오는 페이지)



값을 입력해서 submit 하면
아래와 같이 나온다.



(실행 결과)



위에서 GET으로 보냈으므로 url을 확인해보면
어떤 변수에 어떤 값이 들어가서 전달 되는지 확인 할 수 있다.
또, 아래 두개 POST변수에는 아무 값도 뜨지 않은 것을 확인 할 수 있다.

이번에는 POST로 전달해 보겠다.


(method = "POST")





(실행 결과)



실행 결과를 보면
아래 두 줄만 값이 전달되어 나온 것을 확인 할 수 있다.




제로보드 설정까지 완료했으므로
이제 제로보드를 이용하여
게시판을 만들어보겠다.

관리자 계정으로 로그인 하고
왼쪽 상단에 Add Group을 눌러준다.




(Add Group 클릭)



클릭 후 그룹 이름을 써주고
확인을 누른다. (기본으로 설정해준다.)



(그룹 생성)



그룹이 생성된 모습이다.



(그룹 생성 모습)



여기서 왼쪽 상단에 게시판 항목에 Add를 클릭한다.



(게시판 Add)



게시판 Add 입력 항목이다.
여기서 이름을 작성해주고
기본 보호 설정을 해제 해 줄것이다. (먼저 웹 취약점을 공부하기 위해서)




(게시판 작성 페이지)



HTML 설정을 모두 허용으로 바꾸어준다.



(HTML 설정)



업로드 기능을 체크하여 자료실 기능을 사용으로 바꾸어준다.




(업로드 허용)



그리고 게시판 생성을 누르면
아래와 같이 게시판이 생성된 모습이 보인다.



(게시판 생성 후 모습)



이 페이지는 게시판의 목록을 볼 수 있다.

방금 우리가 만든 게시판을 확인해보자.

Preview를 클릭하여 본다.



(게시판 모습)



우리가 제로보드를 이용하여 만든 게시판의 모습이다.

회원가입을 하여 글을 작성해보겠다.! (테스트)



(회원가입)



그 후 로그인 하여 글을 작성해보겠다.



(글 작성)



보면 글이 잘 써지는 걸 확인해 볼 수 있다.




(작성된 모습)



글 목록에서도 보인다!



(게시판 목록 모습)



여기까지 게시판을 만들었다.

이제 이 게시판을 이용하여 웹 취약점을 살펴 보겠다. :)





Web Hacking - 실습환경 웹서버 구축(제로보드)(1) 에 이어서 웹서버를 설정할 것이다.

install.php 경로로 들어오면 아래와 같은 화면이 나온다.




(707 퍼미션 요구 화면)



빨간 글씨로 707 퍼미션이 되어있지 않다고 나와있다.

zboard 디렉터리의 권한 설정을 해준다.
#> chmod 707 zboard



(권한 설정 화면)




위와 같이 설정이 잘되면
아래와 같이 빨간 글씨가 사라지고 설치 시작 버튼이 나온다.



(설치 시작 화면)



클릭을 해주면
아래와 같이 입력하는 란이 나오는데
여기서 아직 우리가 DB를 만들지 않았다.



(입력 화면)



zboard DB를 만들어보자!

먼저 mysql에 접속해준다.



(mysql 접속)



접속 후 show databases; 명령어를 이용하면
현재 있는 DB가 보인다.



(현재 DB)



여기서
create 명령어를 사용하여 zboard라는 DB를 만들어준다.



(DB 생성)



다시
show databases;
명령어를 이용하여 현재 DB를 확인해보면
zboard가 생성된 것을 확인 할 수 있다.



(생성된 DB)



자 생성해주고!
입력을 해주고
설정완료를 눌루면 다음과 같이 에러가 나온다.



(에러 화면)



위 에러는 우리가 지금 옛날 버젼의 zboard를 쓰기 때문에
쿼리 명령문중 바뀐 내용이 있기 때문이다.

우리는 그 명령문을 수정해 줄 것이다.

수정해줄 파일은
zboard 디렉터리 안에있는 schema.sql 파일이다.



(vi 편집기로 schema.sql 열기)




vi 편집기로 schema.sql 을 열어준다.

그리고 수정해주어야 할 것!

1. password varchar(20) -> password varchar(50)
옛날에는 20사이즈면 충분했지만 더 길어진 해쉬값으로 50까지는 늘려주어야한다.



(password 사이즈 수정)



파일 안에 있는 varchar 사이즈를 50으로 바꾸어준다 전부! (password만)

2. primary key는 default 값이 될 수 없다. 하지만 옛날 버젼에서는 가능했는지 다음과 같은 명령 구문이 들어있는데 이 둘이 충돌이 되기 때문에 삭제해주어야한다.
primary key는 사용할 것이기 때문에 default '0' 만 삭제해 준다.




(default '0' 삭제)




(삭제된 모습)



이렇게 primary key와 충돌하는 default 값을 전부 지워준다.

그렇게 되면 아래와 같이
에러없이 넘어갈 수 있다.

그러면 다음 칸에 아이디, 패스워드를 입력하고 [정보입력완료]를 누르면 된다.




(관리자 정보 입력)



그 후 관리자 계정과 비밀번호로 접속해 준다.


(관리자 계정 접속)



그러면 아래와 같이 관리자 페이지가 나온다.




(관리자 페이지)



여기까지가 제로보드 서버 구축 및 설정이다. :)


웹 해킹에 들어가기 앞서
웹서버를 구축할 것이다.
(취약점이 많은!)

그 취약점들을 먼저 공부해 볼 것이기 때문이다.

리눅스에서 웹서버를 구축하기 전에
리눅스의 방화벽을 전부 해제해 줄 것이다.
(실제 서버에서는 해제하면 안된다!, 하지만 우리는 공부할 것이기 때문에 해제해 주도록 한다!)

리눅스에는 방화벽이 두개가 있다.
1. iptables
2. SELinux
이렇게 두개다!

iptables를 삭제해 줄것이다.
/etc/sysconfig/iptables  를 삭제해준다.



(iptables 삭제)



SELinux를 해제해 줄것이다.

vi /etc/sysconfig/selinux 에 들어가서 (vi 편집기 이용)
SELINUX에 disabled로 고쳐준다.



(SELinux 해제)



잘 해제 되었는지 확인해본다.
iptables -L   (명령)
했을 때 체인 룰이 아무것도 안나오면 설정이 안되있는 것이다.


getenforce를 입력하였을 때
Disabled라고 나오면 해제된 것이다.


(해제 모습)



그 후 yum을 이용하여
httpd.i386
php.i386
php-mysql.i386
mysql.i386
mysql-server.i386

을 설치해준다.



(설치된 모습)



httpd를 실행시켜준다. (아파치 웹서버이다.)



(실행 모습)



netstat -ant로 확인해볼 수 있다. (웹서버 포트는 80번 포트)



(웹서버 실행중)



혹은
현재 실행중인 프로세스를 확인해서 확인할 수 도 있다.
명령어 #> ps -ef | grep httpd



(프로세스 확인)



그렇게 되면 외부 호스트에서 IP주소로 접속하였을 때
아파치 화면이 뜬다.



(아파치 화면)



이제 MySQL 실행시켜줄 것이다.
MySQL은 DB이다.

명령어 #> service mysqld start

netstat -ant로
3306이 열려있으면 실행된 것이다.



(MySQL 실행)



mysql에 접속해 보겠다.
#> mysql -u root
(처음 접속, 비밀번호 설정 안했을 때) 이렇게 들어간다.



(접속 화면)



접속이 되면
mysql>
이렇게 프롬프트가 바뀐다.

비밀번호를 설정해 주겠다.
명령어
#> mysqladmin -u root password (쓸 비밀번호)



(비밀번호 설정)



비밀번호를 설정한 후에는 접속 방법이 조금 다르다.

#> mysql -u root -p
이렇게 접속하면
비밀번호 입력하는 란이 나온다.
여기에 아까 설정해준 비밀번호를 입력하면 된다.


(비밀번호 입력 접속)



이제 제로보드를 설치할 환경이 다 갖추어 졌다.

제로보드를 /var/www/html  경로에 다운받아준다.
현재 제로보드가 tar형태이므로 풀어줄 것이다.
명령어
#> tar xvf zboard.tar



(타르 파일 풀기)




(푼 모습)



해제하고 나면 해당 경로에 디렉터리 하나와 파일 하나가 생긴다.



(풀린 모습)



여기서 /etc/php.ini  파일을 하나 고쳐줄 것이 있다.



(vi /etc/php.ini )



vi 편집기를 이용해 들어와서
아래 표시된 부분을 On으로 고친다.



(고쳐진 모습)



그 후 외부 호스트에서
IP/zboard/install.php 경로로 접속을 하면 아래와 같이 나온다.



(접속 모습)



여기서 한글이 깨지는 것을 발견할 수 있는데
웹브라우저가 인코딩을 안해주기 때문이다.
인코딩 해주는 프로그램을 추가해준다.



(인코딩 프로그램 추가)



추가해 준 후 해당 페이지에서 오른쪽 클릭을 해서
Korea 로 인코딩 눌러준다.



(Korea 클릭)



그렇게 되면 아래와 같은 화면으로 잘 나오게 된다.!





+ Recent posts