페이지에 접속해보면 Login 버튼이 존재한다. 우리의 목표는 TheMaster 계정으로 로그인 하는것이다.



Login 버튼을 눌러보면 Monkey 계정으로 로그인 된 것을 확인 할 수 있다.


        <b>Welcome to Level 10</b><br><br>
        Target: Bypass the login. Login as TheMaster<br>
        <br><br><br>
        <form method="post">
            <input type="hidden" name="login" value="YToyOntzOjg6InVzZXJuYW1lIjtzOjY6Ik1vbmtleSI7czo4OiJwYXNzd29yZCI7czoxMjoiMDgxNXBhc3N3b3JkIjt9">
            <input type="submit" value="Login" name="dologin">
        </form>
        <br><br><br>
    Welcome Monkey. You are just a normal user!



소스를 확인해보면 Login 버튼을 눌렀을 때 login 파라미터로 YToyOntzOjg6InVzZXJuYW1lIjtzOjY6Ik1vbmtleSI7czo4OiJwYXNzd29yZCI7czoxMjoiMDgxNXBhc3N3b3JkIjt9가 전달되는 것을 알 수 있다. 이를 base64 디코딩하면 a:2:{s:8:"username";s:6:"Monkey";s:8:"password";s:12:"0815password";}가 나온다. PHP Serialize 함수의 결과이기 때문에 이를 수정하여 base64로 인코딩 후 login 파라미터에 태워 보내주면 로그인 할 수 있을 것이다.



boolean 타입으로 password 변수를 지정해준 후 1을 넘겨주어 true를 반환시키면 TheMaster 계정으로 로그인 할 수 있다.

'Wargame > RedTiger:OverTheWire' 카테고리의 다른 글

[RedTiger] Level 10  (2) 2017.11.07
[RedTiger] Level 9  (0) 2017.11.06
[RedTiger] Level8  (0) 2017.11.01
[RedTiger] Level7  (0) 2017.11.01
[RedTiger] Level6  (0) 2017.11.01
  1. horensic 2017.11.11 00:09

    항상 블로그 잘 보고 있습니다. ^^

    • Choiys 2017.11.12 18:51 신고

      고려대학교 정보보호대학원 석사과정(진)님 아니십니까?


문제에 접속하면 Name과 Title, Content로 보이는 부분을 입력하는 폼이 존재한다.

SQLi가 바탕인 RedTiger 문제이기 때문에 왠지 insert 구문을 이용하여 데이터를 추가 할 것 같다.



이는 Name에 1, Title에 2, Content에 3을 입력하여 제출 했을 때의 결과이다.

mysql의 insert 구문에서는 parentheses를 필터링 하지 않을 경우 사용자의 입력값에 따라 데이터의 중복 삽입을 유발할 수 있다.

이 문제의 경우 모든 입력값에 대해 single quotation으로 묶여있는 형태인데, Name과 Title의 경우에는 single quotation을 \'로 치환하여 특수문자가 아닌 단일문자로 사용하는 반면 Content 부분에서는 이를 필터링하지 않아 string의 끝을 의미하는 quotation으로 적용된다.

mysql에서는 insert 구문 사용 시 insert into table_name values(val1,val2,val3),(val4,val5,val6),... 등으로 데이터를 중복 삽입 할 수 있다.



이를 이용하여 Content 부분에 single quotation을 포함하여 데이터를 중복 삽입하고, 데이터를 삽입하는 위치에 select 구문을 이용하여 level9_users 테이블의 username과 password를 추출해낼 수 있다.


이를 이용해 얻어낸 username과 password를 하단의 입력 폼에 넣어 요청하면 플래그를 얻을 수 있다.



'Wargame > RedTiger:OverTheWire' 카테고리의 다른 글

[RedTiger] Level 10  (2) 2017.11.07
[RedTiger] Level 9  (0) 2017.11.06
[RedTiger] Level8  (0) 2017.11.01
[RedTiger] Level7  (0) 2017.11.01
[RedTiger] Level6  (0) 2017.11.01


Level8은 admin 계정의 패스워드를 알아내라고 합니다.


Edit 버튼을 누르면 정보가 갱신되며, 이는 곧 update 구문을 이용한 것이라고 생각 할 수 있습니다.


따라서 update [table명] set [attribute1=value1, attribute2=value2, ...]의 형태이기 때문에 single quotation을 추가하여 다른 속성의 값을 중복 변경 할 수 있습니다.


single quotation만을 입력했을 때 나타나는 오류로 보아 update 구문에 적용되는 속성의 순서는 다음과 같습니다.



name, username, email, icq, age 의 순서로 update 되기 때문에 가장 먼저 나타나는 name의 속성의 값을 password로 변경한다면 Admin 계정의 패스워드를 알아낼 수 있습니다.




'Wargame > RedTiger:OverTheWire' 카테고리의 다른 글

[RedTiger] Level 10  (2) 2017.11.07
[RedTiger] Level 9  (0) 2017.11.06
[RedTiger] Level8  (0) 2017.11.01
[RedTiger] Level7  (0) 2017.11.01
[RedTiger] Level6  (0) 2017.11.01


textbox에 있는 내용은 search 파라미터를 통해 post로 전송되며, single quotation과 함께 전송하면 SQLi를 유발시킬 수 있다.


이 때 에러 메시지를 통해 쿼리문 전체를 알아낼 수 있다.


SELECT news.*,text.text,text.title FROM level7_news news, level7_texts text WHERE text.id = news.id AND (text.text LIKE '%a'%' OR text.title LIKE '%a'%')


like문에서 SQLi가 발생하며, parentheses를 열고 닫음으로 구문을 마무리 후 union을 통해 원하는 컬럼을 추출해낼 수 있다.



이 중 TestUserforg00gle이 username이 되며, 이를 입력하면 플래그를 얻을 수 있다.

'Wargame > RedTiger:OverTheWire' 카테고리의 다른 글

[RedTiger] Level 10  (2) 2017.11.07
[RedTiger] Level 9  (0) 2017.11.06
[RedTiger] Level8  (0) 2017.11.01
[RedTiger] Level7  (0) 2017.11.01
[RedTiger] Level6  (0) 2017.11.01



user 파라미터(integer)를 입력받아 Username과 Email을 출력해준다.


?user[]=1과 같이 입력해주면 mysql_real_escape_string() 함수를 사용하는 것을 확인 할 수 있다. 따라서 single quotation과 같은 특수문자는 사용이 불가하다.


하지만 integer 기반 쿼리이기 때문에 single quotation 없이 SQLi가 가능하며, union select 구문을 사용할 수 있다.


또한 like와 parentheses 등 주요 기능이 필터링 되어 있다.


union을 사용하다 보면 2번째 컬럼에서 username의 이름을 넣어주면 쿼리가 정상 동작하는 것을 알 수 있다.


여기서 username 컬럼에 deddlef를 hex encoding 하여 보내줘도 동일한 결과가 출력되는 것을 알 수 있으며, deddlef'는 에러가, deddlef'#는 에러가 발생하지 않는 것을 확인 할 수 있었다.


여기서 출력되는 쿼리의 결과에서 username 부분을 새로운 쿼리에 넣어 실행, 결과를 출력하는 것이라 예상 할 수 있으며 exploit code를 hex encoding 하여 보내주면 패스워드를 얻어낼 수 있다.

'Wargame > RedTiger:OverTheWire' 카테고리의 다른 글

[RedTiger] Level 10  (2) 2017.11.07
[RedTiger] Level 9  (0) 2017.11.06
[RedTiger] Level8  (0) 2017.11.01
[RedTiger] Level7  (0) 2017.11.01
[RedTiger] Level6  (0) 2017.11.01


이전 레벨과 소스코드는 거의 비슷하다고 합니다.

대신 쿠키를 확인해보면

num-id 형식을  hex로 인코딩 한 값이 들어갑니다.




스크립트 돌려줍시다.



'Wargame > Natas:OverTheWire' 카테고리의 다른 글

[Natas] Level19  (0) 2016.10.24
[Natas] Level18  (0) 2016.10.24
[Natas] Level17  (0) 2016.10.23
[Natas] Level16  (0) 2016.10.23
[Natas] Level15  (0) 2016.10.23
[Natas] Level14  (0) 2016.10.23


<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": "natas18", "pass": "<censored>" };</script></head> <body> <h1>natas18</h1> <div id="content"> <? $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) { ?> <p> Please login with your admin account to retrieve credentials for natas19. </p> <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>

소스를 보면 admin 세션의 값이 1이 되어야만 패스워드를 뱉어낸다는 것을 알 수 있습니다.

하지만 일반적인 로그인으로는 return 값이 없기 때문에 1이 될 수 없겠죠.

여기서 admin이 로그인 되어 있어 세션 값이 1인 세션이 존재할 경우, 그 세션만 탈취하여 적용시킨다면 패스워드를 알아낼 수 있습니다.



간단하게 스크립트를 짜서 돌려줍시다. Key 부분은 파싱을 잘못 해서 출력이 안됐네요.






'Wargame > Natas:OverTheWire' 카테고리의 다른 글

[Natas] Level19  (0) 2016.10.24
[Natas] Level18  (0) 2016.10.24
[Natas] Level17  (0) 2016.10.23
[Natas] Level16  (0) 2016.10.23
[Natas] Level15  (0) 2016.10.23
[Natas] Level14  (0) 2016.10.23


<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": "natas17", "pass": "<censored>" };</script></head> 
<body> 
<h1>natas17</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', 'natas17', '<censored>'); 
    mysql_select_db('natas17', $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> 

이번 소스를 보니 이전에 풀었던 Blind SQLi네요.

그런데 다른 점이 하나 있다면 참/거짓을 판별해주는 echo문이 주석 처리 됬다는 점입니다.

따라서 response 값의 차이로는 판별하기 힘들 것 같으니 time based blind SQLi로 풀면 될 것 같습니다.



중간에 타임 꼬여서 한번 더돌림..



'Wargame > Natas:OverTheWire' 카테고리의 다른 글

[Natas] Level19  (0) 2016.10.24
[Natas] Level18  (0) 2016.10.24
[Natas] Level17  (0) 2016.10.23
[Natas] Level16  (0) 2016.10.23
[Natas] Level15  (0) 2016.10.23
[Natas] Level14  (0) 2016.10.23


<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>

소스를 보니 이전에 했던 정규표현식 문제와 비슷합니다.

그러나 이번에는 key 부분에 double quotation으로 묶여있다는 점과 필터링이 강화되었다는 차이가 있네요.

여기서 생각 할 수 있는 것은 dictionary.txt를 무조건 참조할수밖에 없다는 것인데, 정규표현식에서는 if와 같이 조건을 걸어 줄 수 있습니다.

따라서 이를 이용하여 blind SQLi와 비스무리한 기법으로 패스워드를 찾아낼 수 있습니다.






'Wargame > Natas:OverTheWire' 카테고리의 다른 글

[Natas] Level18  (0) 2016.10.24
[Natas] Level17  (0) 2016.10.23
[Natas] Level16  (0) 2016.10.23
[Natas] Level15  (0) 2016.10.23
[Natas] Level14  (0) 2016.10.23
[Natas] Level13  (0) 2016.10.23


<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> 


Blind SQLi인것 같습니다.


그래서 돌렸습니다.



'Wargame > Natas:OverTheWire' 카테고리의 다른 글

[Natas] Level17  (0) 2016.10.23
[Natas] Level16  (0) 2016.10.23
[Natas] Level15  (0) 2016.10.23
[Natas] Level14  (0) 2016.10.23
[Natas] Level13  (0) 2016.10.23
[Natas] Level12  (0) 2016.10.23

+ Recent posts