해당 문제는 동일한 소스코드에 버전 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}