2017. 1. 1. 18:43 :: 문제풀이/WebHacking,kr

안녕하세요. Message 입니다.

Webhacking.kr Lv10 문제풀이입니다.

 

 

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

0x00 문제분석

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

 

10번 문제로 접속합니다.

"buy lotto" 라는 문구가 보이며, 별다른 특징은 없어보입니다.

 

소스코드를 살펴봅니다.

"hackme" 라는 id값을 가진 a태그 외에는 주목할만한 점이 보이지 않습니다.

 

<a> 태그에 몇몇가지 이벤트가 존재합니다.

onmouseover, onmouseout 이벤트로 인해 O라고 되어 있는 문자에 마우스를 가져가면 모양이 변하며,

onclick 이벤트 안에 하드코딩 되어 있는 this.style.posLeft+=1; 스크립트로 인해 글자를 클릭시 오른쪽으로 이동합니다.

 

 

 

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

0x01 문제풀이

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

 

<a> 태그에 있는 onclick 이벤트를 좀더 자세히 살펴보겠습니다.

아무래도 아래의 스크립트가 이번 문제를 해결하는 열쇠인듯 합니다.

if(this.style.posLeft=800) this.href='?go='+this.style.posLeft

 

posLeft 속성이 800이 되면 특정 go 변수에 800을 할당하고, 해당 URL로 이동합니다.

그럼 go 속성에 800을 할당해서 새로고침을 누르면 되는구나 싶어 시도해보았더니

아래쪽에 "nohack" 이라는 문구가 생깁니다. 단순히 숫자만 바꿔서는 해결이 안되는 케이스인듯 합니다.

 

그래서 일단 go 변수에 799 까지 할당한 다음 직접 클릭하여 어떤 패킷이 들어가는지 확인해보기로 했습니다.

이때 hackme.style.posLeft에 799를 할당하는 방법은 여러가지가 있는데,

제가 주로 사용하는 방법은 IE의 개발자 - 콘솔모드 입니다만,

DOM탐색기 - 스타일에서 속성을 변경하면 정확한 타겟에 오타없이 지정할 수도 있습니다.

이후에 문구를 한번 클릭해주면 클리어입니다.

 

자..그렇다면 직접 800을 URL로 입력했을 경우와 799까지 입력해주고 클릭했을 경우

어떤 차이가 있길래 클리어가 갈리는지 알고싶어집니다.

일단 패킷을 떠서 비교해보니 직접 URL을 만들어서 접속한 경우 Referer 속성이 누락되는군요.

 ← 직접클릭

 ← URL작성

 

확실히 그 차이인지 확인해보기 위해서, 직접 URL을 작성한 상황에서 Referer 속성을 추가하여 보내봅니다.

 

이에 대한 응답은 Congratulation 입니다.

특정 페이지에서만 접근할 수 있도록 접근제어 옵션이 설정되어 있다고 보면 될 것 같습니다.

 

 

posted By Message.

Commit your way to the LORD, trust in him and he will do this. [PSALms 37:5]

 

posted by Red_Message
2016. 11. 9. 21:00 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv9 문제풀이입니다. 

 

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

1. 문제분석

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

 

1) 살펴보기

9번 문제에 접속합니다. 점수는 무려 900점...

숫자 1, 2, 3 과 password 쿼리전송 버튼이 존재하는 페이지가 나옵니다.

다른분들의 풀이를 보니, ID/PW 입력 인증창이 별도로 뜨면서 Method를 이용하여 우회해야 볼 수 있는 화면인데

바로 뜨는거 보니...수정되었나봅니다.

 

각 번호를 클릭하면 각 아래의 화면이 나타납니다.

페이지 넘버 3에서 "Secret" 이라는 문구와 함께 hint가 주어졌습니다.

length = 11, 그리고 column명 2개(id, no) 입니다.

  

 

또한 이것저것 특수문자도 넣어보고, 각종 쿼리문을 날려보았더니

아래와 같은 "Access Denied" 문구가 뜹니다. 특정 문자가 필터링되고 있음을 알 수 있습니다.

 

2) 문제 의도파악

처음에는 "Apple", "Banana"가 ID값이라는 표시가 없어서 페이지들의 목적이나 의미에 대해서 헷갈렸습니다.

결국 다른 풀이들을 찾아본 후에야 저 과일이름들이 ID값이라는걸 알게되었죠..

예를들어 no=1 일때의 ID값은 "Apple", no=2 일때의 ID값은 "Banana",

no=3 일때의 ID값은 알려주지 않으므로 우리가 알아내야할 값은 no=3일대의 ID값인듯 합니다.

 

 

 

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

2. 문제풀이

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

 

0) 아파치 웹인증 우회

아파치 웹인증이 나오진 않았지만, 공부하는데 초점이 맞춰져 있으므로 간략하게 짚고 넘어갑니다.

만약 정상적으로 인증창이 나왔다면 아래와 비슷한 창이 나타났을겁니다.

 

이러한 인증은 아파치 서버에서 .htaccess 파일을 이용한 인증을 사용할 경우 나타나는 창으로서,

.htaccess 파일을 이용한 인증을 이용하기 위해서는 httpd.conf 파일에 AllowOverride 설정을 해줘야 합니다.

 <Directory "/var/www/html">

...

AllowOverride AuthConfig

...

 </Directory>

 

설정이 완료되면 .htaccess 파일 내부에 Limit 옵션으로 인증에 적용될 메소드를 기재하게 됩니다.

아래와 같이 설정을 하게 된다면, GET과 POST로 요청이 들어올 경우 아파치 웹인증이 동작합니다.

 AuthName  "~~~"

 AuthType   Basic

 AuthUserFile "~~~~/.htpasswd"

 <Limit GET POST>

requre valid-user

 </Limit>

 

하지만, 만약 관리자가 옵션을 적는 방법을 헷갈리거나, 단순히 GET과 POST 등 일부 메소드만 설정한다면

다른 메소드로 접근하여 인증이 우회되는 상황이 발생합니다.

테스트는 못해봤지만, 아래와 같이 OPTIONS 등의 메소드로 패킷을 보내면 해당 인증창은 무시되고 다음 단계로 넘어갑니다.

 

 

1) 이용할것

일단 주어진 힌트를 살펴봅니다. 만약 ID를 구하는것이 맞다면,

힌트가 의미하는바는 ID의 길이가 11자리이며, 테이블의 컬럼은 id, no 이라는 뜻일겁니다.

 

힌트와 쿼리문을 입력하는 칸을 보니 느낌적으로 Blind SQL 공격을 시도하는게 맞는것 같습니다.

그래서 예전 Blind SQL을 사용했던 2번 문제를 살펴보니 

2번 문제는 Time 주석문을 이용하여 Blind SQL의 결과를 알아내는 케이스였습니다. (아래와 같이요)

하지만 이번 문제는 no, pw 변수에 이것저것 넣어봐도 True/False를 체크할만한 수단이 없어보입니다.

2번문제 링크 : http://redscreen.tistory.com/87

 

어떤식으로 Blind SQL의 성공여부를 알 수 있는지 검색해보니 

MYSQL 쿼리문에서 SELECT문에 IF문을 결합하여 사용하는 방법이 있더군요.

아래는 APMSETUP에서 테스트용으로 IF문과 SUBSTR 함수를 결합하여 사용한 예시입니다.

그렇다면 IF문은 이번 문제에서 어떻게 사용해야 하는걸까요?

 

현재 문제를 풀이하고 있는 페이지는 index.php 입니다.

그리고 no 값에 따라서 보여지는 글자가 달라집니다. 즉, 다른 페이지에 넘어가는게 아니라

입력해주는 no에 따라서 DB에서 ID값을 가져오는 메커니즘으로 추측됩니다.

그렇다면 "SELECT id FROM no = OO" 정도가 되지 않을까요?

여기에 IF문을 아래와 같은 방식으로 적용한다면 우리가 원하는 값을 불러올 수 있습니다.

 SELECT id FROM 테이블명 WHERE no = IF(substr(id, 1, 1) = 0x41, 3, 0)

 

이를 검증하기 위해 테이블에 세가지 튜플을 넣고 테스트합니다.

① (1, Apple)  ② (2, Banana)  ③ (3, aaaaaaaaaaa) / 11자리

 

이후에 위와 같은 쿼리를 날리면 아래와 같은 결과를 얻을 수 있습니다.

 ①번 튜플 : (1, apple )

    - 첫번째 문자 'A' 와 0x41 일치 → no=3 반환 

    - 완성쿼리 : SELECT id FROM lv9 WHERE no=3 : ①번 튜플은 no=1 이므로 출력 NO

 ②번 튜플 : (2, Banana)

    - 첫번째 문자 'B' 와 0x41 불일치 → no=0 반환

    - 완성쿼리 : SELECT id FROM lv9 WHERE no=0 : 번 튜플은 no=2 이므로 출력 NO

 ③번 튜플 : (3, AAAAAAAAAAA)

    - 첫번째 문자 'A' 와 0x41 일치 → no=3 반환 

    - 완성쿼리 : SELECT id FROM lv9 WHERE no=3 : ③번 튜플은 no=3 이므로 출력 YES

 

 

2) 필터링 문자 파악

버프슈트의 Intruder 기능을 이용하여 특수문자 필터링을 파악합니다.

엑셀등에서 복사하여 Paste 버튼을 누르면 편리하게 페이로드 추가가 가능합니다.

Length 448 결과값이 "Access Denied" 응답입니다.

위의 쿼리에서 작성한 쿼리에서 "=", "if", "%20" 등이 필터링되고 있습니다.

 

 

 

3) 공격시도

위에서 작성한 쿼리는 아래와 같습니다.

필터링 되는 문자를 파악했으니 뜯어고쳐야 합니다.

 SELECT id FROM 테이블명 WHERE no = IF(substr(id, 1, 1) = 0x41, 3, 0)

 

문자 "=" 을 사용하지 못하므로 strcmp 함수로 대체합니다.

다른분의 풀이를 보니 LIKE로 대체하신분도 계십니다. 저의 경우 strcmp가 더 손에 익어서 선택했습니다.

strcmp 함수는 문자열이 동일한 경우 0을 반환하므로, IF문의 True/False 순서도 바뀌어야 합니다.

 SELECT id FROM 테이블명 WHERE no = IF(strcmp(substr(id, 1, 1), 0x41), 0, 3)

 

또한 %20 이 필터링 되므로, 공백을 제거해야합니다.

 SELECT id FROM 테이블명 WHERE no = IF(strcmp(substr(id,1,1),0x41),0,3)

 

문제에 테스트해봅니다. 결과는 Secret 입니다.

URL : (생략)../web-09/?no=IF(strcmp(substr(id,1,1),0x41),0,3)

 

테스트 완료된 쿼리를 이용한 파이썬 스크립트로 공격을 시도하면 성공입니다.

0x41 부터 시작할 경우 ID값이 대문자로 출력되는데, 아마 8번 문제처럼 자동으로 소문자화 시켜주는 코드가 있을듯 합니다.

하지만 패스워드에 입력할 시에는 소문자로 입력해야합니다.

 

 

 

By Red_Message.

 

posted by Red_Message
2016. 11. 6. 23:24 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv8 문제풀이입니다. 

 

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

1. 문제분석

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

 

문제 메인에 접속하면 아래와 같은 문구가 뜹니다.

새로고침을 누르니 카운트가 늘어납니다.

최대치인 70번까지가 시도할 수 있는 횟수인걸까요?

 

 

소스코드를 살펴보니 "<!-- index.phps -->" 힌트가 있습니다.

 

해당 페이지에 접속하면 아래와 같은 소스코드가 나타납니다.

 

 

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

2. 문제풀이

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

 

1) 문제 의도파악

소스코드를 살펴보면 아래부분에

"select id from lv0 where agent='$_SERVEr[HTTP_USER_AGENT]'" 쿼리문의 결과로

"admin" 값이 얻어지면 $solve() 함수가 호출됨을 알 수 있습니다.

 

 

2) 장애물

우리가 원하는 "admin" 값이 나오려면 여러가지 방법이 있습니다.

가장 빨리 생각난건 지난 문제의 해결방법이었던 union을 이용하는 방법입니다.

하지만 이번 문제에서는 preg_match() 함수를 이용하여

"union"을 비롯한 "char, ascii" 등의 문자는 물론, 여러가지 특수문자를 모두 필터링하고 있습니다.

 

3) 이용할것

처음에는 DB를 검색하는 Select 문을 조작해서 어딘가에 있을 "admin" 값을 찾아와야 하나? 싶었습니다.

하지만 그런 방법은 맨땅에 헤딩하는 느낌이 들더군요. "admin"값이 없을수도 있죠.

결국 직접 "admin" 값을 입력해야 한다는 생각이 들었고 union, char 등을 이용한 공격을 시도해보았지만,

시도하면 할수록 필터링이 잘되있다는 깨달음만 얻었지요.

이런 방법이 아닌가 싶다가 PHP 소스 아랫부분을 살펴보니, INSERT문이 보입니다.

위의 쿼리문에 대한 결과가 "admin"이 아닐경우, guest의 접속 여부를 기록하기 위한 쿼리로 보입니다.

 

$ip 변수를 조작하기 보다는, 버프를 이용하여 $agent 값을 변경해야겠다는 생각이 듭니다.

또한 결정적으로 따옴표가 치환되는 부분은 $agent 변수가 아니라 $_SERVER[HTTP_USER_AGENT] 기 때문에

$agent를 변경해도 문제를 클리어할 수 있습니다.

 

4) 공격시도

지난 문제에서 연습한대로 APMSETUP에서 테스트를 수행합니다.

수행하기에 앞서 아래와 같은 절차대로 간단히 필드2개 짜리 테이블을 생성하고 쿼리문을 날려봅니다.

 ① DB

      - DB선택 :  use db이름;

     - 테이블생성 :  create table test(name varchar(20) NOT NULL, passwd varchar(20) NOT NULL);

     - 래코드삽입 :  insert into table이름(필드명1, 필드명2) values(data1, data2); 

 ② PHP

     - DB연결 :  $conn = mysql_connect('localhost', 'root', 'apmsetup');

     - DB선택 :  $db_id = mysql_select_db("mysql", $conn);

     - 질의 :  $query = @mysql_query("insert into test2(name, passwd) values('message', 'admin')";#','guest')");

     - 실행 :  mysql_query($q, $conn);

 

처음에는 PHP 소스코드 형식에 맞추기 위해 다음과 같이 쿼리문을 날렸습니다 message', 'admin')";#

나름대로 아래의 PHP소스상에서 주석처리와 쌍따옴표까지 고려를 한것이죠.

 

하지만 아래와 같이 쿼리문 에러와 함께 DB에서도 오류가 나더군요. 형식이 맞지 않습니다.

쌍따옴표는 PHP소스코드 상에서 문자열을 표시하기 위해 사용된 부분이군요.

이래서 직접 DB에 테스트 하지 않으면, 어떤 오류가 나는지도 모르고 헤메는 경우가 많은듯 합니다.

 

따라서 다음과 같이 수정하여 쿼리문을 날립니다(쌍따옴표 제거) → message', 'admin');#

APM 환경에서는 성공적으로 질의문이 수행됩니다.

 

실제 문제풀이 사이트에 접속합니다.

버프슈트를 이용하여 User-Agent에 테스트 완료된 문자열을 입력해줍니다.

인자수를 맞추어 줘야 하기 때문에, 의미없는 루프백 주소를 추가해서 총 3개의 인자를 넣어줍니다.

message','127.0.0.1','admin');#

이후에 User-Agent를 message 로 조정해서 쿼리를 날리면

"admin" 값을 가져오면서 성공입니다!

 

 

By Red_Message.

posted by Red_Message
2016. 11. 4. 23:50 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv7 문제풀이 달립니다!

! 빠른 문제풀이 보다는 풀이과정 속에서 이것 저것 배우는것을 목표로 합니다.

 

 

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

1. 문제분석

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

 

7번 문제에 접속합니다.

auth 버튼을 누르면 "Access_Denied!" 창이 뜹니다.

 

개발자도구로 소스코드를 살펴보면,

"<!-- admin mode : val=2 -->" 이라는 주석과 "index.phps" 주석을 볼 수 있습니다.

 

해당 주석에 적힌 내용을 바탕으로 val=2 페이지와 index.phps 페이지에 접속하면 아래와 같습니다.

 

 

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

2. 문제풀이

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

 

소스코드를 쭉 살펴보면

 

우리의 최종 목표는 소스코드의 맨 아래에 있는 "$data[0]==2" 조건을 가진 IF문을 충족시켜서

숨겨진 button을 얻어야 한다는 것을 알 수 있습니다.

 

변수 $data에 값을 할당하려면 DB에서 값을 얻어오는 mysql_fetch_array 함수에

인자로 들어가는 변수 $result에 어떤 값이 들어가는지 살펴봐야 합니다.

변수 $result에 들어가는 값은 아래 소스코드에서 알 수 있듯이

웹페이지 방문자가 입력하는 $go 변수에 어떤 값이 들어가느냐에 따라 달라집니다.

 

또한 특수문자 * / 를 사용할 수 없으며, "--" "2150" "\+" 등의 문자를 사용할 수 없는 제약과

rand() 함수로 인해서, 우리가 제대로 입력을 해도 4/5 확률로 die() 함수가 실행될 수 있습니다.

 

주어진 힌트는 아래와 같이 val=2는 존재하지 않는다와 union을 이용하라는 내용입니다.

 

1) 1차시도

일반적인 union select 공격 쿼리를 날려보았습니다.

"select lv from lv1 where lv=( 1) union select lv ...(생략).. )"

하지만 공백 "%20" 테이블명 "lv" 등에서 필터링되어 접근거부되었습니다.

 

2) 2차시도

가장 시급한것은 스페이스 구문을 사용하지 않고 UNION 쿼리를 날리는것입니다.

구글링을 해보니 스페이스를 사용하지 않는 UNION 구문 예시가 있더군요 ex)  union(select("필드")from("테이블명") 

그래서 2번 문제와 동일하게 MYSQL에서 미리 테스트를 해보고 시도 해보기로 했습니다.

 

일단 평범한 SELECT 문에 UNION 쿼리를 날려 차이점을 살펴보았습니다.

기존에 검색되던 내용에서 추가로 2개의 쿼리가 검색되더군요.

 

그리고 제가 원했던 스페이스가 아닌 괄호로 표현된 UNION 쿼리문을 날려보았습니다.

동일한 결과가 나오는것을 확인합니다.

 select user from user user union(select(password)from(user));

 

그리고 이어지는 테스트는 우리가 푸는 문제에서 주어진대로 WHERE 조건이 추가된 부분에서

공백없이 UNION 쿼리를 입력하였을 경우입니다.

 select user from user where user=('root')union(select(password)from(user));

 

하지만 UNION SELECT의 결과는 앞에 있는 SELECT문의 뒤에 이어진다는 단점이 있습니다.

우리가 원하는건 data[0]에 값2가 들어가는것입니다.

따라서 앞에있는 SELECT의 WHERE에 적절한 값을 넣어주면 검색되는 쿼리가 없을것이고

우리가 넣은 UNION SELECT의 값만 나올것입니다.

 

이제 다음 목표는 결과값에 우리가 얻어야할 숫자 2가 나오는것입니다.

여기저기 구글링을 해보니 UNION SELECT에서 필드명에 숫자를 넣는 예제가 보여서

테스트도 할겸 필드명에 숫자를 넣어보았더니, 아래처럼 제가 넣어준 숫자가 나오더군요.

그리고 임의로 여러가지의 숫자를 넣어봤더니, 넣어준 숫자가 그대로 나옴을 알 수 있었습니다.

 

마지막으로 해결해야할 문제는 테이블명입니다. 우리가 넣어야 하는 테이블명 "lv"는 필터링되는

문자이므로, 동일하게 숫자를 넣어 우회해보려 했지만 오류가 나더군요.

그래서 혹시나? 하고 FROM을 아예 지워서 테스트해보았습니다.

OLLEH! 쿼리가 검색이 되네요

 

해당 내용을 바탕으로 아래와 같이 URL을 작성하여 날려보았습니다.

하지만 여지없는 "Access Denied!"

http://webha...(중략)...web-07/index.php?val=999)union(select(2))

 

이유는 숫자 또한 필터링 되어 있기 때문입니다.

2라는 숫자를 못쓰기 대문에 "1+1", "4/2" 등을 시도해보았지만 역시 실패입니다.

하지만 "-" 가 필터링 되어 있지 않은 부분을 발견하여 아래와 같이 마이너스로 넣어보았습니다.

http://webha...(중략)...web-07/index.php?val=999)union(select(3-1)

 

"nice try" 는 rand 함수에 의해 5/4 확률로 발생하는 문구입니다.

일단 필터링 단계는 지나쳤다는 의미죠.

내부 소스코드에서 아래와 같이 적용될때(rand 결과가 1)까지 F5를 눌러줍니다.

계속 URL 쿼리를 날리면 1/5 확률로 원하는 값을 얻어낼 수 있습니다.

 select lv from lv1 where lv=(999)union(select(2))

 

By Red_Message.

 

posted by Red_Message
2016. 8. 13. 20:23 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv6 문제풀이 달립니다!

! 빠른 문제풀이 보다는 풀이과정 속에서 이것 저것 배우는것을 목표로 합니다.

 

 

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

1. 문제분석

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

 

6번 문제에 접속합니다.

Hint로 base64가 주어졌고, ID와 PW가 써져있군요....?!

 

소스코드를 살펴보면 초기 Cookie 값을 설정하기 위해

20번의 base64 인코딩과 특수문자 치환을 하고 있음을 알 수 있습니다.

 

이후 동일하게 base64로 디코딩 과정을 거치고 있군요!

 

디코딩 결과값이 "admin" 인 경우에 solve 함수를 호출합니다.

 

 

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

2. 문제풀이

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

 

우리가 문제를 풀이하기 위해서는

20번의 디코딩 + 특수문자 치환 => "admin" 이라는 결과값을 만들어 내야 합니다.

즉, 반대로 "admin" 값을 20번 인코딩 한후 특수문자 치환을 하고나서

아래의 Cookie 값에 설정하면 됩니다.

 

전 이번 문제를 해결하기 위해 룰루랄라 하면서

파이썬으로 간단히 20번의 for문을 작성했습니다.

아래와같이 말이죠! 심지어 이번 문제는 삽질 없이 빨리 끝내겠네~ 라는 생각과 함께요

 id = base64.encodestring(id

 

그런데...안되더군요

인코딩 방법을 바꾸어 보았습니다.

 id = id.encode("base64") 

 

안됩니다. 뭐가 문제지 싶었습니다.

삽질끝에 알고 왔더니 encodestring과 encode("base64")에 포함된 개행문자 "\n" 때문입니다.

encodestring의 경우는 print로 찍어보면 print 메소드 자체의 개행문자까지 총 2번의 개행이 됨을 볼 수 있습니다.

이를 해결하기 위해 rstrip 함수를 사용한다고 해도 아래 그림처럼

8번째 줄부터는 자동으로 개행 문자가 삽입되어 우리가 원하는 값을 얻을 수 없습니다.

물론, 개행문자가 들어갔다 하더라도 동일 함수로 디코딩 하면 최초 문자열인 "admin"이 나옵니다.

 

결과적으로 제가 원했던 "파이썬 코딩을 이용한 해결"은 b64encode 함수를 써야합니다.

그러면 아래와 같이 개행문자가 삽입되지 않고 결과값이 나옴을 볼 수 있습니다.

WebHacking 홈페이지에서 제공하는 base64 인코딩 기능을 사용하는 방법도 있습니다.

 

특수문자를 치환하는 부분은 딱히 치환되는 부분이 없기 때문에

단순히 디코딩만 20번 해준뒤에 Coockie 값을 변경해주면

문제를 해결할 수 있습니다.

 

그냥 삽질만 하면 아쉬운것 같아서, Tab이 허전한 RDT에 BASE64 탭을 추가했습니다.

이번 케이스를 통해서 BASE64 인코딩이나 디코딩이 여러번 중첩되는 경우

놓치는 부분을 최소화 하기 위해 , XOR 연산처럼 횟수를 지정할 수 있도록 구현했습니다.

그래도 삽질 끝에 뭔가 하나라도 얻었으니 다행이네요.

posted by Red_Message
2016. 8. 12. 18:27 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv5 문제풀이 달립니다!

! 빠른 문제풀이 보다는 풀이과정 속에서 이것 저것 배우는것을 목표로 합니다.

 

 

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

1. 문제분석

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

 

5번 문제에 접속하면 아래와 같은 화면이 우리를 반겨줍니다.

 

소스를 살펴보아도 별다른건 보이지 않습니다.

Join 버튼을 눌러보아도, 역시 소스코드대로 "Access_Denied" 경고창이 뜨는군요.

 

Login 버튼을 눌러 다음으로 넘어가면 이러한 화면이 나옵니다.

지난번 문제에서 처럼, Burp를 이용하여 간단히 SQl Injection을 수행해 보았으나,

별다른 취약점은 발견하지 못했습니다.

 

이제 다른 루트를 모색해봐야 할 것 같군요!

 

 

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

2. 문제풀이

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

 

1) 디렉토리 리스팅

Join 버튼을 괜히 넣어놓지는 않았을겁니다.

그렇다면 join을 할 수 있는 다른 페이지가 존재하는가? 라는 의문이 들었드랬죠.

소스코드에서는 발견할 수 없었으니, 다른 페이지가 존재하는지 여부를 살펴봐야합니다.

join 페이지를 추측해서 일단 넣어보는 방법도 있겠지만,

디렉토리 리스팅이 통한다면 가장 편한 방법이겠죠! 한번 시도해봅니다.

 

join.php 의 존재를 확인하였으니, 접속해봅니다.

그러면 검은색 화면이 우리를 반겨줍니다.

소스코드를 확인하면 아래와 같이 난독화된 소스를 볼 수 있습니다.

 

 

2) 난독화 & 지핑 해제

난독화된 소스를 한눈에 알아보기 쉽지 않습니다.

다른분들의 풀이도 살펴보고, 나름대로의 검색을 통해서

난독화되거나 정렬되어 있지 않은 JScript를 분석하는 방법은 대체로 아래와 같더군요.

Malzilla / Format Code 기능

Notepad++ / JSFormat(JSTool Plugin) 기능

 IE 개발자도구 / Console 기능

 온라인 Unpack & Deobfuscator 이용

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

- Malzilla : https://sourceforge.net/projects/malzilla/?source=typ_redirect

- Notepad++ : https://notepad-plus-plus.org

- Online Javascript Deobfuscator : http://jsbeautifier.org

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

 

 

방법1 : Malzilla / Format code

정리된 소스코드의 윗부분은 주로 선언부인것 같네요.

 

아랫부분에 주요 소스코드가 나옵니다.

주요 골자는 2개의 if 조건과, else 조건으로 보입니다.

그중에서도 else 문이 핵심인듯 하여, 좀더 세밀하게 정리해봅니다.

 

document.write() 메소드를 이용하여 붉은색의 html 소스를 추가로 입력하는 것으로 보입니다.

특정 변수가 있다면, alert() 메소드로 난독화가 해제된 소스코드를 보겠지만

일일이 wirte() 를 이용했기 때문에 손으로 어느정도 정리해 줘야 겠군요!

 

 

방법2 : Notepad++ / JSFormat

정렬 기능을 사용하기 위해 JSTool 플러그인을 설치해줍니다.

 

이후에 JSTool의 JSFormat 기능을 선택하여 정렬해줍니다.

 

Malzilla보다 조금더 안정감 있게 정리된 느낌이네요.

 

Notepad++의 장점은, 윈도우에 기본적으로 설치되어 있는 Notepad 보다

우수한 성능의 replace(바꾸기, Ctrl+H) 기능을 제공해줍니다.

특히 바꾸고 싶은 문자열을 더블클릭해서 단축키를 누를경우, 좀더 편리하게 바꿀 수 있으며,

Notepad에서는 할 수 없는 개행문자도 변경가능합니다.

 

파이썬으로 변경하신분도 있으시던데, 저의 경우 그냥 바꾸기 기능을 이용하여 아래와 같이 정렬했습니다.

대소문자 구분과 단어 완전일치를 체크해주지 않으면, 엉뚱한 문자들이 교체될 수 있습니다.

대략 살펴보면 아래와 같습니다.

- document.cookie 에서 "oldzombie" 문자열이 없으면 --> bye

- document.url 에서 mode 값이 1이 아니면 "access.denied"

- 모두 충족되면 document.write

 

그래서 cooxie 툴바를 이용하여 cookie값에 "oldzombie" 문자열을 넣어주고

URL에는 mode=1 값을 넣어주면 됩니다. (http://webhacking.kr/challenge/web/web-05/mem/join.php?mode=1)

그럼 정상적인 회원가입 폼을 만날 수 있습니다.

 

 

방법3 : IE 개발자도구 / Console

난독화되거나, 지핑된 코드는 정렬 기능을 가진 도구를 이용해도

난독화가 쉽게 풀리지 않는 경우가 많습니다.

IE 개발자도구의 콘솔기능을 이용하면, 현재 웹페이지의 소스코드를 고치지 않고도

변수등을 alert로 찍어볼 수 있습니다. 

 

특히 저희가 풀고 있는 문제에서는 document.write 부분만 따로 복사하여

콘솔부분에 붙여 넣으면, 조건문을 거치지 않고도 회원가입 스크립트를 볼 수 있습니다.

해당 폼에 회원가입을 해도 정상적인 쿼리값이 전송됩니다.

 

 

3) 회원가입

우리는 admin ID값으로 로그인 해야하므로,

admin으로 회원가입을 해보면 아래와 같은 이미 존재한다는 창이 뜹니다.

 

그렇다면, admin으로 로그인은 하되

글자는 admin이 아닌 경우를 생각해야하는데,

만약 서버가 사용자 입력값을 trim() 한다면 space 값을 이용하여 우회할 수 있는 여지가 생깁니다.

하지만 글자 길이가 5자리로 제한되어 있으므로, 프록시툴로 우회해줍니다.

 

회원가입이 완료되었습니다.

 

로그인을 시도해볼까요?

 

 

 Tip. JScript - indexOf

 문자열 중에서 특정 문자나 문자열의 위치를 말해주는 메소드로,

 특정 문자가 있는지 없는지를 판단하는 메소드.

 시작위치를 지정해주지 않으면, 전체 문자열에서 처음부터 검사합니다.

 ex) alert("redscreen".indexOf("r")) 의 결과값은 0 입니다.

 

 Tip. Javascript의 세미콜론

 자바스크립트는 문장 끝에 세미콜론을 입력하지 않아도 프로그램을 실행하는데 문제가 없습니다.

 하지만 대부분의 프로그래밍 언어가 문장 끝에 세미콜론을 입력하므로 자바스크립트도 관례상 입력합니다.

 

posted by Red_Message
2016. 8. 6. 13:25 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv4 문제풀이 달립니다!

 

 

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

1. 문제분석

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

 

4번 문제에 접속하면 아래와 같은 문자열이 나옵니다.

아마 해당 문자열을 복호화 하거나 디코딩하라는 의미겠죠?

 

단순히 즐겨찾기 해두면 맨날 없어지고, PC 바뀌면 못찾고...

이러한 문자열을 디코딩하거나 레인보우 테이블이 필요할때 유용한 사이트입니다.

암복호/디코딩 : http://tools.web-max.ca/encode_decode.php

 

레인보우테이블 : http://hashtoolkit.com

 

 

 

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

2. 문제풀이

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

 

일단 주어진 문자열의 끝부분이 "==" 으로 끝나므로 BASE64 로 디코딩해주면 아래와 같은 문자열이 나옵니다.

 c4033bff94b567a190e33faa551f411caef444f2

 

해당 문자열을 패스워드에 입력하면 아무 반응이 나타나지 않습니다.

아마 어떠한 방법으로 디코딩을 더 해야되는것 같네요.

해당 문제를 풀기위해 공부한 결과로는, 16진수 X 40개 = 160bit 값을 통해 SHA1 으로 유추하는 방법이 있다고 하는데,

저는 직관적으로 해당 방법을 몰랐으므로, 위에 URL에 남긴 레인보우테이블 사이트를 이용했습니다.

bit값을 알아서 계산해서 결과를 알려주는 듯 합니다. SHA1 Decrypt 결과값이 나왔습니다.

 

하지만 결과값 역시 160bit 이므로, 한번더 동일한 작업을 수행합니다.

그러면 아래와 같은 의미있는 문자열을 발견할 수 있습니다.

사실 윗단계에서 의미 없다고 다른 방법을 찾아보았다면 낭패를 보았겠죠..

 

해당값을 입력하면 클리어입니다.

 

 Tip. 해쉬함수

 보통 웹사이트에서 패스워드를 저장할 때 SHA1, SHA256 등을 이용한 해쉬값을 많이 사용합니다.

 하지만 해당 방법들을 사용하면, 위 사이트에서 제공하는 레인보우테이블을 이용할 경우 패스워드 추축이 가능하게 됩니다.

 그래서 쉽게 추측하는 부분을 방지하기 위해 대형 사이트에서는 아래와 같이

 무의미한 쓰레기값과 salt 값을 이용한다고 합니다.

  "쓰레기값" + SHA1(salt + password) = 유추하기 어려운 값 

 

posted by Red_Message
2016. 8. 5. 16:53 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv3 문제풀이 달립니다!

중간 과정과 삽질을 생략하지 않아 다소 길 수 있습니다.

 

 

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

1. 문제분석

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

 

문제에 접속하면 퍼즐이 나옵니다.

뭔가 있을줄 알았으나...그냥 풀어주고 넘어가면 됩니다.

 

 

다음 화면으로 넘어가면 아래와 같은 페이지가 나옵니다.

왠지 SQL Injection를 하라고 대놓고 만든 페이지처럼 느껴집니다...

해야될것만 같습니다. 느낌이 그렇습니다 그냥...

 

프록시 툴로 어떤 인자 값이 전달되는지 확인합니다.

answer와 id값이 동시에 전달됨을 확인합니다.

 

유저가 입력한 answer값과 name 값이 서버에 저장되는것 같습니다.

이런 부분을 체크하고 문제풀이에 돌입합니다.

 

 

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

2. 문제풀이

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

 

다른 분들의 풀이를 보면, 특수문자 샥샥 해서 한페이지 만에 답을 도출하시던데...

저는 그게 안되는데 어떻게 되는거죠? 오늘도 삽질을 시작합니다.

그래도 삽질을 하면 배우는게 있어요...

 

남들이 하는것처럼 일단 특수문자를 넣어보기로 했습니다.

예전에 손가락으로 일일이 넣다가 포기했던 아름다운 추억이 있으므로

Burp의 Intruder 기능을 이용하기로 했습니다. 공격할 포지션으로 answer를 지정합니다.

 

1) 특수문자

PayloadSimple List로 지정해줍니다.

일단 산뜻하게 특수문자로 시작합니다. (복사 + Paste버튼) 

 

공격 결과는 아래와 같습니다.

첫 패킷은 페이로드가 포함되지 않아서 그냥 엔터를 친 결과와 같습니다.

우리가 주목해야 할 부분은 돌아온 Response 값의 Length입니다.

 

Length 값이 458인 경우는 no hack 이라는 말과 함께 차단되는 것으로 보입니다.

여기서 제가 주목하지 않아 삽질을 하게 만든 특수문자는 % 입니다.

특수문자 테스트에서 % 문자가 차단되는 부분을 고려하여 Injection 코드를 구성했어야 했는데

스페이스가 URL 인코딩이 되면서 %20 으로 치환되는 부분을 간과해버려서

스페이스가 들어간 모든 Injection 공격문이 차단되었기 때문입니다.

차단되는 특수문자 : ! # % * ' /

 

Length 값이 458인 경우는, query error! 라는 말로 보아 차단되는 특수문자는 아닌것으로 판단됩니다.

여기서도 제가 신경 쓰지 못한 특수문자가 있는데, 바로 || 입니다.

평소 MySQL Injection에 익숙해져 있는데다가, 대부분 or 를 쓰다보니 관심이 없었더랬죠..

 

Length 값이 451인 경우는 아무런 값이 리턴되지 않아 알수가 없습니다. ex) @

 

2) 1차시도

기존에 SQL Injection의 존재 여부를 간단히 체크할 수 있는 리스트를 검색해서

복붙 해놓은게 생각나서 버프슈트의 payload에 입력해 보았습니다.

결과 : 실패

 or 1
 or 1=1
 or 1=1--
 or 1=1#
 or 1=1/*
 admin' --
 admin' #
 admin or 1
 admin or 1=1
 admin or 1=1--
 admin or 1=1#
 admin or 1=1/*
 admin" or "1"="1"--
 admin" or "1"="1"#
 admin" or "1"="1"/*
 admin" or 1=1 or ""="
 admin" or 1=1
 admin' /*
 admin' or '1'='1
 admin' or '1'='1'--
 admin' or '1'='1'#
 admin' or '1'='1'/*
 admin' or 1=1 or ''='
 admin' or 1=1
 admin' or 1=1#
 admin') or ('1'='1
 admin') or ('1'='1'--
 admin') or ('1'='1'#
 admin') or ('1'='1'/*
 admin') or '1'='1
 admin') or '1'='1'--
 admin') or '1'='1'#
 admin') or '1'='1'/*
 admin" --
 admin" #
 admin" /*
 admin" or 1=1--
 admin" or 1=1#
 admin" or 1=1/*
 admin") or ("1"="1
 admin") or ("1"="1"--
 admin") or ("1"="1"#
 admin") or ("1"="1"/*
 admin") or "1"="1
 admin") or "1"="1"--
 admin") or "1"="1"#
 admin") or "1"="1"/*

 

3) 2차시도 : 공백제거

특수문자 %가 막혀있는 부분을 생각하여, 공백(space)를 제거하여 시도합니다.

결과 : 실패

 

4) 3차시도 : 문자열 "or" → "||" 교체

검색을 하여 or 문자를 특수문자 || 로 교체하여야 된다는 사실을 알게되었습니다.

하지만 Length를 보아도 별다른 소득이 없습니다.

결과 : 실패

 

5) 4차시도 : 공백 다시 제거

스페이스가 포함되어 있는걸 까먹었습니다. 머리가 안돌아가면 몸이 고생...

다시 공백을 제거하여 시도합니다.

결과 : 8번째 라인에서 성공

 

 

성공한 8번째 라인의 리턴된 값을 보면 아래와 같습니다.

이거 하나 보기가 까다롭네요.

 

 

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

2. 마무리

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

 

답을 모른다고 생각하고, 풀이를 진행해 보았습니다.

시간은 오래걸렸지만, 삽질을 하면서 얻은 교훈이 있네요 ㅎㅎ

1. 인젝션을 수행할 때 "or" 만이 능사는 아니다.

2. 프록시 툴로 파악한 파라미터에 인젝션을 시도할 경우, 기존의 데이터를 유지하고 뒤에 추가하는 부분도 고려해야 한다.

 

posted by Red_Message
2016. 7. 30. 10:46 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv2 문제풀이입니다.

 

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

1. 문제분석

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

 

해당 문제는 홍길동 문제라는 아주 유명한 문제더군요

단서들간의 연관성을 짓기가 매우 어려웠고,

예전에는 힌트가 주어졌다고 했는데, 힌트도 없이 풀면 난이도가 더 상승하겠죠.

 

2번 문제에 접속합니다.

 

1) 첫번째 단서

문제풀이용으로 홈페이지가 구축되어 있습니다.

소스를 살펴보면 첫번째 단서를 얻을 수 있습니다.

아래 하이라이트 처리된 부분을 보면 admin 페이지가 노출되어 있다는 사실입니다.

 

접속해보면 아래와 같은 페이지가 나옵니다. 패스워드를 어떻게 알아낼 수 있을까요?

 

2) 두번째 단서

두번째 단서는 주석처리 되어 있는 시간 값입니다.

 

3) 세번째 단서

세번째는 패스워드가 설정되어 있는 게시글입니다.

 

 

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

2. 문제풀이

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

 

이번문제의 핵심은 admin 페이지에 설정되어 있는 time 인자값과

메인 페이지의 주석처리 되어 있는 부분의 연관성입니다.

바로 아래의 time 부분에 Injection 시도가 가능한가? 라는 발상이 문제풀이의 핵심입니다.

 

아마 문제풀이가 아니고 실제 모의해킹을 수행하는 과정이었다면

Burp Suite로 time 인자값에 Injection을 한번쯤 수행해봤겠지만,

인젝션 수행 후에 어떤 값이 바뀌는지 인지하는것 또한 어려웠을겁니다.

 

아래와 같은 간단한 인젝션을 테스트해봅니다.

1) 결과값이 False인 경우 : <!--2070-01-01 09:00:00-->

  

 

2) 결과값이 True인 경우 : <!--2070-01-01 09:00:01-->

  

 

위와 같은 결과값을 이용하여 우리는 Blind SQL Injeciton 공격을 이용할 수 있습니다.

예전에는 테이블명을 Hint로 주었다고 하는데,

힌트없이 진행하려고 시도해봤지만

MySQL 버전이 낮아서 information.schema 를 활용할 수 없는 관계로...

힌트를 참고하여 테이블명 FreeB0aRd, admin 값을 이용하여 인젝션을 시도합니다.

 

주요 쿼리문은 아래와 같이 구성합니다.

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

MySQL Version : time=1469864699 and substr(version(),1,1) > '5'; PHPSESSID=%s

DB Length : time=1469864699 and substr(length(database()),1,1) = %d; PHPSESSID=%s

DB Name : time=1469864699 and substr(database(),%d,1) = char(%d); PHPSESSID=%s

PW Length : time=1469864699 and (select ascii(substr(password,%d,1)) from FreeB0aRd) = %d; PHPSESSID=%s

PW : time=1469864699 and (select length(password) from FreeB0aRd) = %d; PHPSESSID=%s

첨부파일 >blind.py

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

 

패스워드를 알아냈다면 암호가 걸려있던 admin 페이지로 갑니다.

매뉴얼 패스워드를 알려줍니다.

 

매뉴얼은 패스워드가 걸려있던 게시글에 첨부되어 있습니다.

압축파일에 암호가 걸려있으며, 매뉴얼 패스워드를 입력합니다.

 

압축을 풀고 열어보면 문제 2번을 클리어할 수 있는 패스워드를 알아낼 수 있습니다.

 

 Tip. Accept-Encoding

 서버로부터의 응답이 인코딩된 문자열로 들어와서 삽질을 했습니다.

 처음에는 이클립스의 인코딩 설정인줄 알고 건드리다가

 응답값에 URL, BASE64 등등의 디코딩을 해봐도 안되더군요...

 

 

 근데 다른분들의 코딩을 살펴봐도 디코딩을 하신분은 없길래 약간 의아했습니다.

 문제는 헤더값을 모두 설정해주겠다고 제가 입력한 Accept-Encoding 입니다.

 

 

 Accept-Encoding은 클라이언트가 웹 서버에게 보내는 HTTP Request 헤더에 들어있는 값으로서

 클라이언트가 해당 인코딩 또는 디코딩할 수 있음을 서버에 알려주는 역할입니다.  

 

 그래서 제가 받은 html문서의 body 부분은 Content-Encoding 에 명시된 gzip으로 인코딩 되었습니다.

 FIddler가 인코딩 되어 있음을 알려주고 있으며, 클릭하면 디코딩할 수 있습니다.

 Tip. MySQL Query (APMSETUP)

 Blind SQL Injection에 사용되는 문법을 보는데 이해가 잘 안되더군요

 확실히 숙지 하지 못하고, 머리속으로 상상하면서 코딩을 했습니다.

 당연히 시간이 지연되고 오류도 많이....하아

 사용되는 문법에 대한 흐름을 간략히 APM Setup에서 테스트해보았습니다.

 APMSETUP 설치경로(C:\APM_Setup\Server\MySQL5\bin)에서 아래와 같이 실행합니다.

 

제가 테스트 해보고 싶었던 부분은 select 뒤에 오는

 

 ascii(substr(password, 1,1)) 부분입니다. (이해가 잘 안되더군요)

 정확한 컬럼명을 입력해야 하는거 아닌가 싶어서요..

 하지만 password 컬럼을 검색한 결과값에서 필터가 적용되는것으로 보입니다.

 

 

 사용한 MYSQL 주요 명령어는 아래와 같습니다.

 - DB생성 : CREATE DATABASE dbname;

 - DB검색 : SHOW DATABASES;

 - DB선택 : USE dbanme;

 - TB검색 : SHOW TABLES;

 

posted by Red_Message
2016. 7. 30. 10:23 :: 문제풀이/WebHacking,kr

안녕하세요. Message입니다.

Webhacking.kr Lv1 문제풀이입니다.

 

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

1. 문제분석

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

1번 문제로 접속합니다.

아래와 같은 문구 외에는 별다른게 없습니다.

적혀 있는 index.phps 가 힌트인 것 같습니다.

 

 

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

2. 문제풀이

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

소스보기를 해봅니다.

index.phps에 onclike 이벤트가 걸려있는것을 확인하고, 클릭합니다. 

 

그럼 아래와 같은 소스를 볼 수 있습니다.

 

간단한 소스코드 해석을 합니다.

 

1) 첫번째 PHP 문단 : 쿠키세팅

$_COOKIE라는 PHP의 슈퍼전역변수를 이용하여 user_lv 변수의 쿠키값을 확인합니다.

처음접속했다면 당연히 없을테니 Cookie값이 1 로 세팅될겁니다.

 

쿠키가 세팅되는 매커니즘을 간단히 메모장으로 테스트해보면 아래와 같습니다.

SetCookie 함수는 다른 함수가 실행되기 이전에 처음에 세팅되어야 하기 때문에

가장 상단에 존재해야 합니다.

 

 

2) 두번째 PHP 문단 : COOKIE값 확인

다시한번 $_COOKIE 변수와 정규표현식 [^0-9,.] 을 비교합니다.

대괄호 안에 있는 ^ 문자의 의미는 "해당 문자열을 제외한 나머지가 있으면 True값입니다."

즉, 저희는 저 대괄호 범위 안에 있는 문자열만 입력 가능하다는 뜻이죠.

이후에는 5 < Clear조건 <=6 을 만족하면 @solve() 함수가 실행되는 내용입니다.

 Tip. ereg 와 eregi

 두개의 함수는 동일 문자열을 검색하는 함수입니다.

 int ereg(string $pattern , string $string [, array &$regs ]) : 대,소문자 구별

 int eregi(string $pattern , string $string [, array &$regs ]) : 대소문자 구별없음

 첫번째 인자인 $pattern은 찾을 문자열이 들어가며,

 두번째 인자인 $string은 대상 문자열이 들어갑니다.

 

이제 문제를 클리어해봅시다.

일단 우리는 접속하자마자 SetCookie() 함수로 인하여 Cookie 값이 1 로 세팅됩니다.

이제 소스코드가 파악이 되었으니 Cooxie 툴바로 Cookie 값만 변경해주면 됩니다.

 

 

다음 레벨로 넘어갑니다!

 

 

posted by Red_Message