반응형

첫번째 문제는 php로 되어있었다.

 

두번째 문제는 DB 그림이 존재하는것으로 보아.

 

 

SQLi 공격을 이용해야할듯하다. (이것 또한 힌트일 수 있다.)

 

2번째 문제를 클릭해서 들어가보면 다음과 같은 문구를 볼 수 있다.

 

 

근데 이게 전부???

 

아무런 기능이 없다...

 

따라서 할 수 있는거는 페이지 소스라도 봐야한다.

 

페이지 소스를 보니 주석으로 admin.php라는 페이지가 있다고 친절하게 알려준다.

 

따라서 https://webhacking.kr/challenge/web-02/admin.php에 에 접속해보자. 

 

접속하면 다음과 같이 볼 수 있을것이다.

 

 

패스워드를 입력하라고한다.

 

여기서도 마찬가지로 페이지 소스를 보았다.

 

위의 페이지 소스를 보아하니 여기서는 딱히 얻을 힌트는 없어 보인다.

 

따라서 처음 문제에서 힌트(DB)를 얻었던것을 생각해 SQLi를 수행보았다.

 

하지만 아무런 반응을 볼 수 없었다.....

 

따라서 다시 처음으로...

 

아무리 생각해도 패스워드를 입력하는곳에서 SQLi를 수행하는것이 맞는거같은데... 하면서

 

혹시 몰라서 쿠키값을 보았다.

 

 

쿠키값을 보니 현재 timestamp가 적혀있다.

 

timestamp값을 알아보니 처음 페이지 소스보기에서 주석처리로 되었던 시간과 똑같이 적혀있었다.

 

따라서 쿠키값을 임의의 숫자인 123456789를 입력하고 다시 페이지 소스보기를 눌러보았다.

 

 

그러니 다음과 같이 페이지 소스에 시간이 반영이 되었다.

 

따라서 여기서 힌트를 얻었다. (Attack Vector)

 

힌트를 조금 알기쉽게 풀어 설명하면,

 

time이라는 쿠키값에 시간이나 어떤 값을 입력하면

 

페이지 소스보기의 시간을 출력(서버의 반응)을 볼 수 있다는 것이다.

 

여기까지의 내용으로 정리하고 가정을 세워보면 다음과 같다.

  1. 해당 문제의 그림에서 DB가 나왔기 때문에 해당 문제는 SQLi를 이용해야한다.
  2. 하지만 어디에서 SQLi가 발생하는지는 알 수 없다.
  3. 패스워드를 입력하는곳에 SQLi 공격을 수행해보았지만 딱히 별다른것이 없다.
  4. time이라는 쿠키값에 사용자가 입력한 timestamp가 반응을 보인다.
  5. time이라는 쿠키값을 가지고 SQLi를 수행해본다.

먼저 true, false 반응이 나오는지 보기 위해서

 

원래의 timestamp 뒤에 and 1and 0을 삽입하여 페이지 소스 보기 살펴보자.

 

예를들어 현재 기준으로 1634532456라는 time이 나와있을때는 참이다.

 

왜냐? 서버에서 미리 쿠키값을 설정했기때문이다.

 

따라서 1634532456 and 1을 넣었을때 이면 페이즈 소스 보기에서의 시간이 나오는 주석에는

 

2021-10-18 01:47:36가 보일것이고 1634532456 and 0,

 

false일때는 2021-10-18 01:47:36가 아닌 다른 값이 나와야한다.

 

만약 1634532456 and 0가 false인데도 2021-10-18 01:47:36가 나온다면

 

true/false를 알 수 없기 때문에 다른 방법으로 찾아봐야할것이고

 

SQLi 공격으로 푸는 문제가 아닐 수 있다.

 

그럼 time이라는 쿠키에 1634532456 and 1를 넣어보자.

 

 

예상했던거와 달리 1634532456 and 1(true)를 입력하니 2021-10-18 01:47:36가 나오지 않고

 

2070-01-01 09:00:01가 나왔다.

 

????

 

그럼 1634532456 and 0(false)인 경우일 때는 어떤지 보자.

 

 

이번에는 2070-01-01 09:00:01이 아니라 2070-01-01 09:00:00가 나왔다.

 

그럼 여기까지 정리를 해보면 true(참)일 경우에는 2070-01-01 09:00:01이 나오고 

 

false(거짓)일 경우에는 2070-01-01 09:00:00이 나온다.

 

그렇다면 time이라는 곳에 timestamp 값 말고 1=1, 1=0 true, false를 입력해도 값을까?

 

넣어보니 같았다. (Point 1)

 

따라서 이것을 기준으로 삼아 SQLi를 수행해보자. 

 

먼저 패스워드를 알려면 DB명도 알아야하고 table 명도 알아야하고 column명도 알아야 하고

 

각각의 이름을 알려면 길이 또한 알아야한다.

 

따라서 갈길이 먼것같다. 그리고 이렇게 푸는게 아직 맞는지도 모르겠다.

 

DB명을 알아내는것으로 해당 문제가 쿠키값에서 SQLi를 진행하는지

 

또한 2번 문제가 SQLi로 푸는건지 판단할 수 있을것 같다. 

 

일단 해보자.

 

일단 DB 길이를 알아내기 위해서 length(database())=DB 길이를 이용할 것이다.

 

EditThisCookie에 하나 하나 대입하는것보다 그냥 코드로 짜서 돌리는게 편할것같아 코드로 돌려버렸다.

 

코드로 DB의 길이를 알아보니 6자리임을 알 수 있었다.

 

자리수를 알아냈으니 DB명을 알아보자.

 

코드를 작성해서 알아본 결과 DB명은 다음과 같이 chall2라는것을 알 수 있다.

 

DB명을 알아냈으니 이제 테이블 구조를 살펴보자.

 

먼저 chall2이라는 DB에 몇개의 테이블이 있는지 테이블의 길이를 구해보자.

 

테이블 길이와 테이블 명, column 길이와 명을 알아내는 방법은 여기(클릭)에 가서 참고하자!

코드를 작성한 결과 0번째 테이블의 길이 즉, 첫번째 테이블은 13자리, 2번째 테이블 길이는 3개이다.

 

나머지는 1로 보아 1번째, 2번째 테이블에 우리가 원하는 패스워드 값이 있을것이라고 추측해본다.

 

따라서 먼저 첫번째 13자리의 테이블명을 알아보자.

 

13자리의 테이블명은 admin_area_pw이다.

 

여기에 우리가 원하는 패스워드가 있을것같다.

 

테이블 명을 알았으니 이제 admin_area_pw의 존재하는 column갯수길이이름을 알아야한다.

 

먼저 column의 갯수는 1개이다.

 

길이는 2자리이다. (뭔가 느낌상 column명이 pw인것 같다.)

 


역시 코드를 작성해서 실행해본 결과 컬럼명이 pw로 나왔다.

 

이제 해당 pw를 알아내면 끝이다!!

 

pw를 알아내기 위해서는 길이를 먼저 알아야한다.

 

이렇게 총 길이는 17자리이다.

 

이제 pw의 값을 알아보자!

 

코드를 작성해서 돌려본 결과 다음고 같이 pw값이 나왔다.

 

위의 pw값을 https://webhacking.kr/challenge/web-02/admin.php에 입력해보자. 

 

 

반응형

'웹 해킹 > Webhacking.kr' 카테고리의 다른 글

6. old-06  (0) 2021.11.03
5. old-05  (0) 2021.11.01
4. old-04  (0) 2021.11.01
3. old-03  (0) 2021.10.19
1. old-01  (0) 2021.10.18
반응형

먼저 old-01 문제를 클릭해서 들어가 본다면 다음과 같은 화면을 볼 수 있다.

 

딱히 다른 기능이 없어 보이므로 view-source를 클릭해보자.

 

 

view-source를 클릭하면 다음과 같은 php 소스 코드를 볼 수 있다.

 

위의 php 소스 코드 중 핵심 코드는 다음과 같다.

 

바로 solve(1); 함수를 실행시켜야지 이번 old-01 문제를 해결 할 수 있을것 같다.

 

solve(1); 함수를 해결 하기 위해서는 3개의 if문을 잘 봐야한다.

 

3개의 if문의 조건절에 COOKIE값이 들어가있다.

 

따라서 이번 문제는 COOKIE 값을 이용해야한다는것을 알 수 있다.

 

editthiscookie를 이용하여 COOKIE값을 보게되면 user_lv이라는 이름을 가진 쿠키의 값이 1이라고 셋팅되어 있다.

 

다시 3개의 if문으로 돌아와 첫번째 if문은 숫자인지 아닌지를 판단하는것 같다.

 

여기서 쿠키값은 문자가 아닌 숫자임을 알 수 있다. (Point 1)

 

2번째 if문에서는 user_Iv값이 4이상이면 다시 user_Iv값이 1로 셋팅된다. (Point 2)

 

마지막 if문에서는 user_Iv값이 3보다 크면 solve(1)를 실행 시킨다. (Point 3)

 

3개의 힌트를 조합해보면 user_Iv값은 숫자이며 3보다는 크고 4보다는 작아야 한다.

 

따라서 3.1~3.9로 user_Iv값을 설정해주면 solve(1) 함수가 실행되며 문제를 clear 할 수 있다.

 

반응형

'웹 해킹 > Webhacking.kr' 카테고리의 다른 글

6. old-06  (0) 2021.11.03
5. old-05  (0) 2021.11.01
4. old-04  (0) 2021.11.01
3. old-03  (0) 2021.10.19
2. old-02  (0) 2021.10.18
반응형

문제를 보자.

 

 

Password를 맞추는 문제인것 같다.

 

index.phps가 아닌 해당 페이지의 소스코드를 보자.

 

 

소스코드를 보면 입력하는 pw의 최대 길이가 3이다.

 

따라서 패스워드의 총 길이는 3자리라는것이다.

 

이제 index.phps 소스 코드를 보자.

 

 

우리가 중요하게 봐야할것은 역시 php 코드이다.

 

<?php
if($_POST[pw])
{
        $password="????";

    if(!$_COOKIE[check]) exit("access denied");

    if(eregi("[^0-9]",$_POST[pw])) exit();
    if($_POST[pw]>1000) exit();

    if($_POST[pw]==???)
    {
        echo("Password is $password");
        exit();
    }

    else echo("Wrong");
}
?>

 

일단 if문에 들어가기 위해서는 pw가 무조건 어떤 값이 들어가야 한다는것이다.

 

그런 다음 if(!$_COOKIE[check]) exit("access denied");라는 코드가 있다.

 

이 코드는 뭘까? 생각을 해보았는데

 

"check"라는 쿠기값이 만약 존재하지 않는다면 exit("access denied"); 가 출력되며 프로그램이 종료된다.

 

일단 123를 입력해보자.

 

123를 입력하면 "access denied"가 뜨면서 종료된다.

 

즉,  if(!$_COOKIE[check]) exit("access denied"); 여기에 코드가 걸려 종료된다는 의미이다.

 

따라서 "check"라는 쿠키 이름을 가진 0이 아닌 값이 존재하고 값이 있어야지만  

 

if(!$_COOKIE[check]) exit("access denied");를 넘어가 프로그램이 종료되지 않는다.

 

만약 if(!$_COOKIE[check]) exit("access denied");를 통과 했다고 가정하면

 

다음 코드를 보자.

 

다음 코드는 if(eregi("[^0-9]",$_POST[pw])) exit(); 이것이다.

 

eregi()를 SQL Injection에서 설명을 따로 자세히했다.

 

eregi() 함수는 문자열을 필터링하는 함수이다.

 

[0-9]는 숫자를 의미하지만 앞에 ^가 있다.

 

^를 의미하는것은 숫자가 아닌 경우 프로그램을 종료시키겠다는것이다.

 

이것으로 보아 우리가 원하는 패스워드는 3자리 숫자이다.

 

이것을 이제 코드로 나타내보자.

 

import requests

for i in range(1,1000):
    print("시도: " + str(i))

    datas = {"pw": str(i)}
    cookie = {'check': '1'}

    get_pw = ("문제 URL")
    html = requests.post(get_pw, data=datas, cookies=cookie).text

    if "Wrong" in html:
        continue
    else:
        print(i)
        print(html)
        break

 

만약 응답 페이지에서 "Wrong"이 발견되지 않는다면 패스워드를 찾았다는 의미이므로

 

시도한 숫자 3자리가 패스워드를 의미한다.

 

프로그램에서 출력되는 패스워드를 입력하면 우리가 원하는 flag 값을 볼 수 있다.

 

반응형

'웹 해킹 > Coding' 카테고리의 다른 글

Coding 2번.  (0) 2020.12.13
Coding 1번.  (0) 2020.12.12
반응형

문제를 보면 다음과 같다.

 

 

처음에 Start라는 버튼이 있다.

 

눌러보면 다음과 같이 페이지가 변한다.

 

 

먼저 자신의 ip가 나오며 패스워드를 입력하는 폼이 있다.

 

여기서 "?"라는 버튼이 있는데 눌러보면 alert되는데 alert된 값을 보면 "1234"가 있다.

 

1234를 입력해보자.

 

 

당연히 1234가 패스워드가 아니다.

 

여기서 봐야할것은 처음에는 1/100이 였다가 1234를 입력한 후에는 2/100이 됬다.

 

위의 결과를 보고 다음과 같은 가정을 세워보면

 

2는 시도한 횟수를 의미하는것이고 100은 100번안에 우리가 원하는 패스워드가 있다는 가정이다.

 

다시한번 "?"를 클릭하여 나오는 값을 입력해보자.

 

 

위의 alert된 값을 입력하니 역시 시도횟수가 1이 증가한 3/100이 되었다.

 

이렇게 수동으로 하면 언젠가는 우리가 원하는 패스워드가 나올것이다.

 

하지만 출제자의 의도는 수동이 아닌 코드를 작성하여 위의 행위를 코드로 하고자 문제를 출제하였으니

 

코드를 작성해보자.

 

import requests

for i in range(1,시도 횟수):
    print("시도 횟수: "+str(i))
    get_pw = ("...../index.php")
    html = requests.get(get_pw).text
    if "onclick" in html:
        cur_pw = (html[html.find("onclick=alert('")+15:html.find("')>")])
        send_pw = ("...../index.php?pw="+cur_pw)
        requests.get(send_pw)
    else:
        break

 

코드 설명은 따로 하지 않겠다.

 

 

반응형

'웹 해킹 > Coding' 카테고리의 다른 글

Coding 3번.  (0) 2020.12.13
Coding 1번.  (0) 2020.12.12
반응형

이번에는 Coding 문제이다.

 

문제를 보자.

 

패스워드를 입력하는 곳이있다.

 

아무값이나 값을 입력해보자

 

당연히 password가 아니기 때문에 "Wrong password"라는 문구를 볼 수 있다.

 

소스 코드를보자.

 

 

뭐 특별한 것이없다.

 

하지만 하나 눈에 보이는것이 있다.

 

바로 "brute_force_me"라는 문구를 볼 수 있다.

 

그 뒤로 바로 sizemaxlength가 나와있다.

 

최대 길이는 4이며 사이즈는 4라는 의미이다.

 

따라서 0001에서부터 9999까지 대입을 해봐야하는것이다.

 

이것이 바로 brute force 공격기법이다.

 

brute force 공격 기법은 조합 가능한 모든 문자열을 순차적으로 하나씩 모두 대입해 보는 것이다.

 

그 야말로 무식하게 암호가 일치할때 까지 모든 경우의 수를 조합해 대입을 시도한다.

 

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

 

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

 

따라서 이것을 손으로 0001~9999까지 대입하면된다.

 

하지만 문제 카테고리가 Coding이기 때문에 code로 brute force을 할것이다.

 

코드는 다음과 같다.

 

import requests

for i in range(1,10000):
    url=(".....?brute_force_me=" + str("{0:04d}".format(i)))
    res = requests.get(url)
    if "Wrong password" in res.text:
        pass
    else:
        print("Password: "+str("{0:04d}".format(i)))
        break

 

코드 설명은 따로 하지 않는다.

 

이렇게하면 우리가 원하는 패스워드를 얻을 수 있다.

 

 

반응형

'웹 해킹 > Coding' 카테고리의 다른 글

Coding 3번.  (0) 2020.12.13
Coding 2번.  (0) 2020.12.13

+ Recent posts