해당 문제는 동일한 소스코드에 버전 1,2로 두문제가 출제됬다.


두 문제모두 php 소스코드 오디팅을 통해 플래그가 나오는 조건을 맞춰주면 된다.


LinkedList - 1


index.php


<?php

@session_set_cookie_params(36000);

@session_start();


@require_once dirname(__FILE__)."/classes.php";

@require_once dirname(__FILE__)."/config.php";


if (@$_POST['name']) {

@$_SESSION['link'] = @array('name' => @htmlspecialchars(@$_POST['name']), 'time' => @time());

@die("<script type='text/javascript'>location.href='.';</script>");

}

if (!@$_SESSION['link']['name']) {

if (!@$_SESSION['link']['real_first?']) {

@$_SESSION['link']['real_first?'] = true;

@die("<script type='text/javascript'>location.href='.';</script>");

}

@die(@file_get_contents(@dirname(__FILE__).'/templates/set.html'));

}

if (!isset($_SESSION['link'][$_SESSION['link']['name']."_tail"])) {

@$_SESSION['link'][@$_SESSION['link']['name']."_tail"] = 0;

@die("<script type='text/javascript'>location.reload();</script>");

}

if (@$_SESSION['link']['name']) @$obj = new LinkList();

if (@$_GET['p'] == 'reset') {

unset($_SESSION['link']);

@die("<script type='text/javascript'>location.reload();</script>");

}

if (@$_SESSION['link'][@$_SESSION['link']['name']."_list"]) {

@$arr = @json_decode(@$_SESSION['link'][@$_SESSION['link']['name']."_list"]);

for(@$i=0;@$i<count(@$arr);@$i++){

@$obj->insert(@$arr[@$i], @$i);

}

}

if (@$_GET['p'] == 'raw') {

@header("Content-Type: text/plain");

@die(@$_SESSION['link'][@$_SESSION['link']['name']."_list"]);

}

if (@$_SESSION['link']['admin_only_list']) {

unset($_SESSION['link']);

die("<script type='text/javascript'>alert('GJ!!! The first flag is ".@addslashes(@$flag1)."');location.href='.';</script>");

admin:

if ($_POST['value'] && $_POST['key']) {

@$obj->insert(@$_GET['value'], @$_POST['key']);

@$arr[@$_POST['key']] = @$_GET['value'];

@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = @json_encode(@$arr);

}

}

if (@$_SESSION['link'][@$_SESSION['link']['name']."_tail"] > 0xff) {

unset($_SESSION['link']);

@die("<script type='text/javascript'>alert('Realrudaganya?!?!? The second flag is ".@addslashes(@$flag2)."');location.href='.';</script>");

}

if (!@$_GET['p'] || $_GET['p'] == '') {

@$content = @file_get_contents(@dirname(__FILE__).'/templates/login.html');

@$content = @str_replace('$name', @$_SESSION['link']['name'], @$content);

if (@$_SESSION['link'][@$_SESSION['link']['name']."_list"] || @$data='') {

@$r = @$obj->readList();

@$data = '<pre>linked list: '.PHP_EOL;

for(@$i=0;@$i<count(@$r);@$i++){

@$data .= "No.".(@$i+1).": ".@$r[@$i].PHP_EOL;

}

@$data .= '</pre>';

}

@$content = str_replace('$content', @$data, @$content);

die(@$content);

}

if (@$_GET['p'] == 'insert' && isset($_GET['value'])) {

if (@$arr[100]) die("<script type='text/javascript'>alert('Too many linked-list! Get out!');location.href='.';</script>");

if (@$_SESSION['link'][@$_SESSION['link']['name']."_tail"] == 0) @$obj->insertFirst(@htmlspecialchars(@$_GET['value']));

else @$obj->insert(@$_GET['value'], @$_SESSION['link'][@$_SESSION['link']['name']."_tail"]);

@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]++;

@$arr[@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]-1] = @htmlspecialchars(@$_GET['value']);

@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = @json_encode(@$arr);

die("<script type='text/javascript'>location.href='.';</script>");

}

if (@$_GET['p'] == 'insert_first' && isset($_GET['value'])) {

@$obj->insertFirst(@htmlspecialchars(@$_GET['value']));

@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]++;

@$arr[0] = @htmlspecialchars(@$_GET['value']);

@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = @json_encode(@$arr);

@die("<script type='text/javascript'>location.href='.';</script>");

}

if ($_GET['p'] == 'delete' && isset($_GET['key'])) {

if (!@$arr[0]) @$arr[0] = '';

@$obj->deleteNode(@$_GET['key']);

unset($arr[@$_GET['key']]);

#@$_SESSION['link'][@$_SESSION['link']['name']."_tail"] = (int)@$_GET['key'] & 0x7fffffff;

#@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]--;

@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = json_encode(@$arr);

@die("<script type='text/javascript'>location.href='.';</script>");

}



classes.php


<?php

class ListNode {

public $data;

public $next;


function __construct($data){

$this->data = $data;

$this->next = NULL;

}


function readNode(){

return $this->data;

}

}


class LinkList {

private $firstNode;

private $lastNode;

private $count;


function __construct(){

$this->firstNode = NULL;

$this->lastNode = NULL;

$this->count = 0;

}


public function insertFirst($data){

$link = new ListNode($data);

$link->next = $this->firstNode;

$this->firstNode = &$link;


if ($this->lastNode == NULL) $this->lastNode = &$link;

$this->count++;

}



public function readList(){

$listData = array();

$current = $this->firstNode;


while($current != NULL){

array_push($listData, $current->readNode());

$current = $current->next;

}

$i = 0;

$return = array();

foreach($listData as $v){

$return[$i++] = $v;

}

return $return;

}


public function reverseList(){

if ($this->firstNode != NULL) {

if ($this->firstNode->next != NULL) {

$current = $this->firstNode;

$new = NULL;


while($current != NULL){

$temp = $current->next;

$current->next = $new;

$new = $current;

$current = $temp;

}

$this->firstNode = $new;

}

}

}


public function deleteNode($key){

$current = $this->firstNode;

$previous = $this->firstNode;


while($current->data != $key){

if ($current->next == NULL) return NULL;

else{

$previous = $current;

$current = $current->next;

}

}


if ($current == $this->firstNode) {

if ($this->count == 1) $this->lastNode = $this->firstNode;

$this->firstNode = $this->firstNode->next;

}else{

if ($this->lastNode == $current) $this->lastNode = $previous;

$previous->next = $current->next;

}

$this->count--;  

}


public function emptyList(){

$this->firstNode == NULL;

}


public function insert($NewItem,$key){

if ($key == 0) $this->insertFirst($NewItem);

else{

$link = new ListNode($NewItem);

$current = $this->firstNode;

$previous = $this->firstNode;


for($i=0;$i<$key;$i++){       

$previous = $current;

$current = $current->next;

}


$previous->next = $link;

$link->next = $current; 

$this->count++;

}

}

}



index.php를 보면 첫번째 플래그가 나오는 조건은 아래와 같다.

if (@$_SESSION['link']['admin_only_list']) {
unset($_SESSION['link']);
die("<script type='text/javascript'>alert('GJ!!! The first flag is ".@addslashes(@$flag1)."');location.href='.';</script>");
admin:
if ($_POST['value'] && $_POST['key']) {
@$obj->insert(@$_GET['value'], @$_POST['key']);
@$arr[@$_POST['key']] = @$_GET['value'];
@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = @json_encode(@$arr);
}
}

@$_SESSION['link']['admin_only_list'] 요 값이 존재하면 플래그가 나오기 때문에 해당 값이 생성될 수 있는 조건을 확인해 보면 아래와 같다.

if (@$_GET['p'] == 'insert' && isset($_GET['value'])) {
if (@$arr[100]) die("<script type='text/javascript'>alert('Too many linked-list! Get out!');location.href='.';</script>");
if (@$_SESSION['link'][@$_SESSION['link']['name']."_tail"] == 0) @$obj->insertFirst(@htmlspecialchars(@$_GET['value']));
else @$obj->insert(@$_GET['value'], @$_SESSION['link'][@$_SESSION['link']['name']."_tail"]);
@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]++;
@$arr[@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]-1] = @htmlspecialchars(@$_GET['value']);
@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = @json_encode(@$arr);
die("<script type='text/javascript'>location.href='.';</script>");
}
if (@$_GET['p'] == 'insert_first' && isset($_GET['value'])) {
@$obj->insertFirst(@htmlspecialchars(@$_GET['value']));
@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]++;
@$arr[0] = @htmlspecialchars(@$_GET['value']);
@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = @json_encode(@$arr);
@die("<script type='text/javascript'>location.href='.';</script>");
}
if ($_GET['p'] == 'delete' && isset($_GET['key'])) {
if (!@$arr[0]) @$arr[0] = '';
@$obj->deleteNode(@$_GET['key']);
unset($arr[@$_GET['key']]);
#@$_SESSION['link'][@$_SESSION['link']['name']."_tail"] = (int)@$_GET['key'] & 0x7fffffff;
#@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]--;
@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = json_encode(@$arr);
@die("<script type='text/javascript'>location.href='.';</script>");
}

해당 코드는 리스트를 삽입,우선삽입,삭제할때인데 해당 기능 사용시 
@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = json_encode(@$arr);
요 코드들을 통해 @$_SESSION['link']['admin_only_list'] 요 값을 세팅할 수 있다.

그럼 이제 @$_SESSION['link']['name'] 요 값을 admin_only로 어떻게 입력할 수 있는지 보면 되는데 해당 방법은 아래 코드를 통해 볼 수 있다.

if (@$_POST['name']) {
@$_SESSION['link'] = @array('name' => @htmlspecialchars(@$_POST['name']), 'time' => @time());
@die("<script type='text/javascript'>location.href='.';</script>");
}

그럼 이제 아래와 같이 name란에 admin_only를 넣고 접속한 뒤 insert,insert(priority), delete 중 아무 기능이나 사용해보면 아래와 같이 플래그가 나온다.







Flag = TDCTF{easy_7o_solve123}

LinkedList - 2


해당 문제는 1버전과 동일한 소스코드이며 두번째 플래그가 나오는 조건은 아래와 같다.


if (@$_SESSION['link'][@$_SESSION['link']['name']."_tail"] > 0xff) {

unset($_SESSION['link']);

@die("<script type='text/javascript'>alert('Realrudaganya?!?!? The second flag is ".@addslashes(@$flag2)."');location.href='.';</script>");

}


@$_SESSION['link'][@$_SESSION['link']['name']."_tail"] 값이 255보다 크면되기 때문에 해당 값을 어떠한 방식으로 증가시킬 수 있는지 보면 된다.


아래 코드를 보면 @$_SESSION['link'][@$_SESSION['link']['name']."_tail"] 값은 insert 혹은 priority insert 기능 사용시 1씩 증가하는데 insert와 같은 경우 리스트 길이가 100이면 더이상 증가가 안되기 때문에 priority insert 기능을 255번이상 사용해주면 플래그가 나오게 된다.


if (@$_GET['p'] == 'insert' && isset($_GET['value'])) {

if (@$arr[100]) die("<script type='text/javascript'>alert('Too many linked-list! Get out!');location.href='.';</script>");

if (@$_SESSION['link'][@$_SESSION['link']['name']."_tail"] == 0) @$obj->insertFirst(@htmlspecialchars(@$_GET['value']));

else @$obj->insert(@$_GET['value'], @$_SESSION['link'][@$_SESSION['link']['name']."_tail"]);

@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]++;

@$arr[@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]-1] = @htmlspecialchars(@$_GET['value']);

@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = @json_encode(@$arr);

die("<script type='text/javascript'>location.href='.';</script>");

}

if (@$_GET['p'] == 'insert_first' && isset($_GET['value'])) {

@$obj->insertFirst(@htmlspecialchars(@$_GET['value']));

@$_SESSION['link'][@$_SESSION['link']['name']."_tail"]++;

@$arr[0] = @htmlspecialchars(@$_GET['value']);

@$_SESSION['link'][@$_SESSION['link']['name']."_list"] = @json_encode(@$arr);

@die("<script type='text/javascript'>location.href='.';</script>");

}



Flag = TDCTF{easy_t0_solve412}

'CTF > Writeup' 카테고리의 다른 글

TenDollar CTF 2018 Kou  (0) 2018.12.01
TenDollar CTF 2018 XSS  (0) 2018.12.01
TenDollar CTF 2018 Ninja  (0) 2018.12.01
TenDollar CTF 2018 I'm Blind Not Deaf  (0) 2018.12.01
RITSEC CTF 2018 Archivr  (0) 2018.11.19
블로그 이미지

JeonYoungSin

메모 기록용 공간

,