3번째로 풀이할 문제이다.

Solve me 의 Winter Sleep 문제이다.
이 문제를 풀면서 느낀것이 문제이름 잘지었네~ 라는 생각이 들었다. :)



(Winter Sleep)



아래는 문제 페이지이다.



(문제 페이지)



코드를 보면 단순하다. time이라는 변수에 값을 넣어 get방식으로 전달하면 된다.

그 값이 특정값 이상 이하이어야하고
그 값동안 sleep 한 후 flag를 보여준다.
음 그렇군! 초를 계산해볼까?

php online interpreter를 이용하여 계산하였다.



(sleep 할 시간 계산)



오? 간단한데? 저 값을 보내주었다.





(7776000 값 전달)




...






...


...


음? 기네?
초단위니까 몇분기다려야되는거지?






(시간 단위)



시간단위로 2160...
2160 시간.. 날짜로는 90일..
뭔가 잘못되어가는 기분이 들었다.

그럼 최소 시간으로 잡아보자! 라는 생각으로 계산해보았지만...



(최소)





(최소 시간)




(최소 60일)




이쯤 되니 아! 60일 정도 자고 일어나면 되겠다 라는 생각이 들었다.

말도 안되는 소리같고..
이쯤되서 별것들에 눈길을 주었다.
is_numeric 함수
error_reporting 함수

게다가 왜 sleep 앞에 int로 형변환을 해주었을까?
구지? is_numeric으로 숫자인지 검사해놓고서는..




(의심 대상)



오류 리포팅을 하지 않겠다? 라는 의미로 저 구문이 있었다.

sleep 에서 에러를 유발시켜서 sleep을 패스시키고 flag를 확인하는 건가?

그렇기 위해서는 우선 is_numeric을 우회할 수 있어야 했다.

그래서 php.net 공식 홈페이지에서 is_numeric을 찾아보았다.



(is_numeric)




여기서 눈에 딱 들어온건 바로
e
지수표현도 is_numeric에서 true로 판단한다는 것이었다.

이때 아하!
하고 모든것이 퍼즐처럼 맞춰졌다.

바로 그렇기 때문에 sleep 앞에 int로 형변환해주었고
e 지수표현으로 소수로 넘겨주어 int로 바뀌면 소수점들은 날라가니까 
기다릴만한 시간이 되는 거였다.

그리하야
time에 5.184e6  을 넘겨주고 flag를 얻을 수 있었다.




(문제 해결)



(문제 해결)


'WarGame > 500 Project' 카테고리의 다른 글

(6/500) Wargame.kr - flee button  (0) 2017.04.11
(5/500) Wargame.kr - QR Code Puzzle  (0) 2017.04.11
(4/500) CodeShell.kr - dummy 64  (0) 2017.04.10
(2/500) Solve Me - Bad Compare  (0) 2017.04.06
(1/500) Solve Me - Warm up  (0) 2017.04.06


오랜 만에 간단한 웹 문제를 풀어볼것이다.

오늘 푼 문제는 xcz.kr 의 18번문제 웹 문제이다.
아주 아주 아주 기본적인 문제라고 Title에 적혀있다..!

문제 화면이다.



(문제 화면)



설명에 소스보기를 클릭한다!
소스가 나와있다.
보니 php 코드로 이루어져있고
난독화가 되어있다.
변수 이름을 요상하게 지어놓은 것이다.



(소스 코드)



보기 힘드니
Notepad++ 를 받아서 여기서 코드를 확인하였다. (눈이 아프니까)

난독화 또한 풀어주었다.
아래는 난독화 풀은 코드이다.
난독화를 풀었다는 이야기는 내가 보기 쉽게 어려운 변수들을 쉬운 변수이름으로 바꾸어 놓았다는 뜻이다.



(문제 코드)



먼저 눈에 띄는 것은 아래 빨간 박스



(폼 체크?)



여기서 보면 쿠키값 c와 GET방식으로 전달받은 변수 g, 그리고 POST방식으로 전달받은 변수 p가 선언되어있고
이 값들이 비어있으면 Wrong T.T 가 나오게 되어있다.

우선 내가 이 3개의 값을 채워서 넘겨줘야한다는 것을 파악하였다.

쭉 소스코드를 이어서 보면
test function이 있다. 만약 아래에서 이 함수를 쓰지 않으면 무시했겠지만
아래 이 함수를 사용하니까 분석해보았다.



(test function)



이 함수는 변수를 받아서 특정 형태로 변형하는 것이다.
ord 함수는 문자를 아스키 코드로 변환하는 것이다.

ord 함수가 없다면 원래
test 변수가 들어가면
- t - e - s - t 이렇게 출력되는 함수이다.
즉 여기서 t의 아스키 값, e의 아스키값 ... 등으로 변환하여
 - t - e - s - t 값을 출력하는 함수이다.

아래 코드는 확대해서 봐야한다.
conn 이라고 내가 이름지어준 변수인데
위에서 보면
conn 변수는 $g . $cookieval; 으로
GET방식 변수와 쿠키값이 연결된 값이다.
또 twinp 변수는 $twinp = $p;  값으로 p와 같은 값이다.



(소스 코드)



이 코드를 분석하면
conn의 값이 test 함수에 들어가서 출력한 값이 위에 표시된 값인지 또는
twinp의 값이 위에 적혀있는 값인지 체크하여 맞으면 key를 보여준다.

GET 혹은 POST 둘 중 하나의 변수만 맞게 써줘도 되지만
뭐하러!
그냥 두개 다 정답을 보내겠다!

정리하면
conn에는 givemepassword  
twinp에는 keyplz!
의 값이 들어가면 된다.
conn은 g와 cookieval의 값을 연결한 것이므로 작전을 짜면

나는
cookie 값 c = passowrd 를
GET 변수 g = giveme 를
POST변수 p = keyplz! 를
넣어서 보내겠다.

먼저 쿠키 값을 설정할 것이다.
F12에서
아래와 같이 쿠키를 입력한다.



(쿠키 입력)





(입력된 모습)




그리고 POST 방식으로 보내려면
form 태그를 사용해야하므로
form 태그를 만들어준다.



(Form 태그 작성)



그리고 action 변수 url에 g의 값을 GET방식으로 동시에 전달하기 위하여
?g=giveme 를 적었다.
여기서 go 버튼을 누르면 이 값들이 전송되게 Form태그를 만들었다.

이제 이 태그를 한줄로 이어서 아래와 같이 입력해준다. (F12 콘솔에서)



(만들어진 코드)




(코드 입력)



입력하면 아래와 같이 go 버튼이 하나 나온다.



(go 버튼 클릭)



클릭을 하면 우리가 설정해주었던 값들이 전부 전달되고
아래와 같이 Key가 나오게 된다.


(정답 화면)


'WarGame > xcz.kr' 카테고리의 다른 글

xcz.kr - prob21(Web)  (0) 2017.02.24
xcz.kr - porb13 (network)  (0) 2017.02.03
xcz.kr - porb17 (network)  (0) 2017.02.03



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

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

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



(세션인증값 설정)



로그인 해보겠다.



(로그인)





(세션 확인)



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

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



(세션값 확인)



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

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



(인증 코드)




(인증 성공)




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

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



(session_destroy() 사용)




사용 후 확인해보니..



(세션 파일 존재)




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

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

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



(세션파일 삭제)




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




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")





(실행 결과)



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



+ Recent posts