Loading... <p><span style="font-family: Arial"><strong><span style="font-size: 18px">1. 安全模式</span></strong></span></p> <p><span style="font-family: Arial"> 一直没有用过php的safe_mode安全模式,以此说明作为日后参考。<br /></span></p> <p><span style="font-family: Arial"> PHP 的安全模式是为了试图解决共享服务器(shared-server)安全问题而设立的。在结构上,试图在 PHP 层上解决这个问题是不合理的,但修改 web 服务器层和操作系统层显得非常不现实。因此许多人,特别是 ISP,目前使用安全模式。</span></p> <p><span style="font-family: Arial"> safe_mode是唯一PHP_INI_SYSTEM属性,必须通过php.ini或httpd.conf来设置。要启用safe_mode,只需修改php.ini: safe_mode = On 或者修改httpd.conf,定义目录:Options FollowSymLinks php_admin_value safe_mode 1,重启apache后safe_mode就生效了。</span></p> <p><span style="font-family: Arial"> 启动safe_mode,会对许多PHP函数进行限制,特别是和系统相关的文件打开、命令执行等函数。 所有操作文件的函数将只能操作与脚本UID相同的文件。(脚本的uid并不一定是运行wen服务器用户的uid)</span></p> <p><span style="font-family: Arial"> 虽然safe_mode不是万能的(低版本的PHP可以绕过),但还是强烈建议打 开安全模式,在一定程度上能够避免一些未知的攻击。不过启用 safe_mode会有很多限制,可能对应用带来影响,所以还需要调整代码和配置才能和谐。</span></p> <p><span style="font-family: Arial"><strong>安全模式配置指令:</strong><br /></span></p> <table class="CALSTABLE"> <colgroup> <col /> <col /> <col /> <col /></colgroup> <thead> <tr class="firstRow"> <th><span style="font-family: Arial">名称</span></th> <th><span style="font-family: Arial">默认值</span></th> <th><span style="font-family: Arial">可修改范围</span></th> <th><span style="font-family: Arial">更新记录</span></th> </tr> </thead> <tbody> <tr> <td><span style="font-family: Arial">safe_mode</span></td> <td><span style="font-family: Arial">"0"</span></td> <td><span style="font-family: Arial">PHP_INI_SYSTEM</span></td> <td></td> </tr> <tr> <td><span style="font-family: Arial">safe_mode_gid</span></td> <td><span style="font-family: Arial">"0"</span></td> <td><span style="font-family: Arial">PHP_INI_SYSTEM</span></td> <td><span style="font-family: Arial">自 PHP 4.1.0 起可用</span></td> </tr> <tr> <td><span style="font-family: Arial">safe_mode_include_dir</span></td> <td><span style="font-family: Arial">NULL</span></td> <td><span style="font-family: Arial">PHP_INI_SYSTEM</span></td> <td><span style="font-family: Arial">自 PHP 4.1.0 起可用</span></td> </tr> <tr> <td><span style="font-family: Arial">safe_mode_exec_dir</span></td> <td><span style="font-family: Arial">""</span></td> <td><span style="font-family: Arial">PHP_INI_SYSTEM</span></td> <td></td> </tr> <tr> <td><span style="font-family: Arial">safe_mode_allowed_env_vars</span></td> <td><span style="font-family: Arial">"PHP_"</span></td> <td><span style="font-family: Arial">PHP_INI_SYSTEM</span></td> <td></td> </tr> <tr> <td><span style="font-family: Arial">safe_mode_protected_env_vars</span></td> <td><span style="font-family: Arial">"LD_LIBRARY_PATH"</span></td> <td><span style="font-family: Arial">PHP_INI_SYSTEM</span></td> <td></td> </tr> <tr> <td><span style="font-family: Arial">open_basedir</span></td> <td><span style="font-family: Arial">NULL</span></td> <td><span style="font-family: Arial">PHP_INI_SYSTEM</span></td> <td></td> </tr> <tr> <td><span style="font-family: Arial">disable_functions</span></td> <td><span style="font-family: Arial">""</span></td> <td><span style="font-family: Arial">仅 <tt class="filename">php.ini</tt></span></td> <td><span style="font-family: Arial">自 PHP 4.0.1 起可用</span></td> </tr> <tr> <td><span style="font-family: Arial">disable_classes</span></td> <td><span style="font-family: Arial">""</span></td> <td><span style="font-family: Arial">仅 <tt class="filename">php.ini</tt></span></td> <td><span style="font-family: Arial">自 PHP 4.3.2 起可用</span></td> </tr> </tbody> </table> <p><span style="font-family: Arial"><br /></span></p> <p><span style="font-family: Arial"><span style="font-size: 18px"><strong>2. 配置选项的简要解释</strong></span></span></p> </p> <ul class=" list-paddingleft-2"> <li> <p><span style="font-family: Arial"><var class="parameter">safe_mode</var><span class="type" style="font-weight: bold">boolean</span></span></p> </li> <li> <p><span style="font-family: Arial">是否启用 PHP 的安全模式。php的安全模式是个非常重要的内嵌的安全机制,能够控制一些php中的函数,比如system(),<br />同时把很多文件操作函数进行了权限控制,也不允许对某些关键文件的文件,比如/etc/passwd,<br />但是默认的php.ini是没有打开安全模式的,我们把它打开:<br />safe_mode = on 或者</span></p> </li> <li> <pre class="brush:python;toolbar:false">ini_set("safe_mode",true);</pre> <p><span style="font-family: Arial"><var class="parameter">safe_mode_gid</var><span class="type" style="font-weight: bold">boolean</span></span></p> </li> <li> <p><span style="font-family: Arial">默认情况下,安全模式在打开文件时会做 UID 比较检查。如果想将其放宽到 GID 比较,则打开 safe_mode_gid。是否在文件访问时使用<var class="literal">UID</var>(<tt class="constant"><strong>FALSE</strong></tt>)或者<var class="literal">GID</var>(<tt class="constant"><strong>TRUE</strong></tt>)来做检查。</span></p> <p><span style="font-family: Arial"><var class="parameter">safe_mode_include_dir</var><span class="type" style="font-weight: bold">string</span></span></p> </li> <li> <p><span style="font-family: Arial">当从此目录及其子目录(目录必须在 include_path 中或者用完整路径来包含)包含文件时越过<var class="literal">UID</var>/<var class="literal">GID</var> 检查。</span></p> <p><span style="font-family: Arial">从 PHP 4.2.0 开始,本指令可以接受和 include_path 指令类似的风格用冒号(Windows 中是分号)隔开的路径,而不只是一个目录。</span></p> <p><span style="font-family: Arial">指定的限制实际上是一个前缀,而非一个目录名。这也就是说“safe_mode_include_dir = /dir/incl”将允许访问“/dir/include”和“/dir/incls”,如果它们存在的话。如果希望将访问控制在一个指定的目录,那么请在结尾加上一个斜线,例如:“safe_mode_include_dir = /dir/incl/”。</span></p> <p><span style="font-family: Arial">如果本指令的值为空,在 PHP 4.2.3 中以及 PHP 4.3.3 起具有不同 <var class="literal">UID</var>/<var class="literal">GID</var> 的文件将不能被包含。在较早版本中,所有文件都能被包含。</span></p> <p><span style="font-family: Arial"><var class="parameter">safe_mode_exec_dir</var><span class="type" style="font-weight: bold">string</span></span></p> </li> <li> <p><span style="font-family: Arial">如果 PHP 使用了安全模式,<span class="function" style="font-weight: bold">system()</span> 和其它程序执行函数将拒绝启动不在此目录中的程序。必须使用<var class="literal">/</var> 作为目录分隔符,包括 Windows 中。</span></p> <p><span style="font-family: Arial"><var class="parameter">safe_mode_allowed_env_vars</var><span class="type" style="font-weight: bold">string</span></span></p> </li> <li> <p><span style="font-family: Arial">设置某些环境变量可能是潜在的安全缺口。本指令包含有一个逗号分隔的前缀列表。在安全模式下,用户只能改变那些名字具有在这里提供的前缀的环境变量。默认情况下,用户只能设置以 PHP_ 开头的环境变量(例如 PHP_FOO = BAR)。</span></p> <blockquote class="note"><p><span style="font-family: Arial"><strong>注: </strong>如果本指令为空,PHP 将使用户可以修改任何环境变量!</span></p> </blockquote> <p><span style="font-family: Arial"><var class="parameter">safe_mode_protected_env_vars</var><span class="type" style="font-weight: bold">string</span></span></p> </li> <li> <p><span style="font-family: Arial">本指令包含有一个逗号分隔的环境变量的列表,最终用户不能用 <span class="function" style="font-weight: bold">putenv()</span> 来改变这些环境变量。甚至在 safe_mode_allowed_env_vars 中设置了允许修改时也不能改变这些变量。</span></p> <p><span style="font-family: Arial"><var class="parameter">open_basedir</var><span class="type" style="font-weight: bold">string</span></span></p> </li> <li> <p><span style="font-family: Arial">将 PHP 所能打开的文件限制在指定的目录树,包括文件本身。本指令<span class="emphasis"><span class="emphasis" style="font-style: italic">不受</span></span>安全模式打开或者关闭的影响。</span></p> <p><span style="font-family: Arial">当一个脚本试图用例如 <span class="function" style="font-weight: bold">fopen()</span> 或者<span class="function" style="font-weight: bold">gzopen()</span> 打开一个文件时,该文件的位置将被检查。当文件在指定的目录树之外时 PHP 将拒绝打开它。所有的符号连接都会被解析,所以不可能通过符号连接来避开此限制。</span></p> <p><span style="font-family: Arial">特殊值 <span class="systemitem">.</span> 指明脚本的工作目录将被作为基准目录。但这有些危险,因为脚本的工作目录可以轻易被<span class="function" style="font-weight: bold">chdir()</span> 而改变。</span></p> <p><span style="font-family: Arial">在 <tt class="filename">httpd.conf</tt> 文件中中,open_basedir 可以像其它任何配置选项一样用“php_admin_value open_basedir none”的方法关闭,例如某些虚拟主机中:</span></p> <p><span style="font-family: Arial"></span></p> <p></p> <p><span style="font-family: Arial">在 Windows 中,用分号分隔目录。在任何其它系统中用冒号分隔目录。作为 Apache 模块时,父目录中的 open_basedir 路径自动被继承。</span></p> <p><span style="font-family: Arial">用 open_basedir 指定的限制实际上是前缀,不是目录名。也就是说“open_basedir = /dir/incl”也会允许访问“/dir/include”和“/dir/incls”,如果它们存在的话。如果要将访问限制在仅为指定的目录,用斜线结束路径名。例如:“open_basedir = /dir/incl/”。</span></p> <blockquote class="note"><p><span style="font-family: Arial"><strong>注: </strong>支持多个目录是 3.0.7 加入的。</span></p> </blockquote> <p><span style="font-family: Arial">默认是允许打开所有文件。</span></p> </li> <li> <p></p> </li> <li> <pre class="brush:python;toolbar:false"><Directory /serverroot/test> php_admin_value open_basedir /docroot </Directory></pre> </li> <li> <p><span style="font-family: Arial"><var class="parameter">disable_functions</var><span class="type" style="font-weight: bold">string</span></span></p> </li> <li> <p><span style="font-family: Arial">本指令允许你基于安全原因禁止某些函数。接受逗号分隔的函数名列表作为参数。 disable_functions 不受安全模式的影响。</span></p> <p><span style="font-family: Arial">本指令只能设置在 <tt class="filename">php.ini</tt> 中。例如不能将其设置在<tt class="filename">httpd.conf</tt>。</span></p> </li> <li> <p><span style="font-family: Arial"><var class="parameter">disable_classes</var><span class="type" style="font-weight: bold">string</span></span></p> </li> <li> <p><span style="font-family: Arial">本指令可以使你出于安全的理由禁用某些类。用逗号分隔类名。disable_classes 不受安全模式的影响。</span></p> <p><span style="font-family: Arial">本指令只能设置在<tt class="filename">php.ini</tt> 中。例如不能将其设置在<tt class="filename">httpd.conf</tt>。</span></p> </li> <li> <p><span style="font-family: Arial">本指令只能设置在 <tt class="filename">php.ini</tt> 中。例如不能将其设置在 <tt class="filename">httpd.conf</tt>。</span></p> </li> <li> <p><span style="font-family: Arial"><var class="parameter">expose_php = On/Off</var><span class="type" style="font-weight: bold">string</span></span></p> </li> </ul> <blockquote style="border: medium none;padding: 0px;margin: 0px 0px 0px 40px"><ul class=" list-paddingleft-2"> <li> <p><span style="font-family: Arial"> 利用整个设置,你能够阻碍一些来自自动脚本针对web服务器的攻击。通常情况下,http的响应头信息里面包含了如下信 息:</span></p> </li> </ul> </blockquote> <ul class=" list-paddingleft-2"> <li> <p>fiebug查看:</p> </li> <li> <p><img src="//cto.wang/usr/uploads/2016/07/20160703165924-51.jpg" title="1428568497540727.jpg" alt="1.jpg" /></p> </li> <li> <p><strong>3. 实战演示</strong></p> <p>当 safe_mode 设置为 on,PHP 将通过文件函数或其目录检查当前脚本的拥有者是否和将被操作的文件的拥有者相匹配。例如:</p> </li> <li> <p><span style="margin: 0px;padding: 0px;border: none;color: black"></span></p> </li> <li> <pre class="brush:python;toolbar:false">4 -rw-r--r-- 1 httpd root 72 2012-04-16 00:51 test.php 4 -rw-r--r-- 1 root root 1853 2012-03-28 16:20 /etc/passwd</pre> </li> </ul> <p>运行 test.php</p> <pre class="brush:python;toolbar:false"><?php fopen('/etc/passwd','r'); readfile('/etc/passwd'); mkdir('test');</pre> <p>如果安全模式被激活,则将会导致以下错误:</p> </p> <pre class="brush:python;toolbar:false">Warning: fopen() [function.fopen]: SAFE MODE Restriction in effect. The script whose uid is 1003 is not allowed to access /etc/passwd owned by uid 0 in /usr/local/httpd/htdocs/test.php on line 2 Warning: fopen(/etc/passwd) [function.fopen]: failed to open stream: Inappropriate ioctl for device in /usr/local/httpd/htdocs/test.php on line 2 Warning: readfile() [function.readfile]: SAFE MODE Restriction in effect. The script whose uid is 1003 is not allowed to access /etc/passwd owned by uid 0 in /usr/local/httpd/htdocs/test.php on line 3 Warning: readfile(/etc/passwd) [function.readfile]: failed to open stream: Inappropriate ioctl for device in /usr/local/httpd/htdocs/test.php on line 3</pre> <p>也可以单独地屏蔽某些函数。请注意disable_functions 选项不能在<tt class="filename">php.ini</tt> 文件外部使用,也就是说无法在<tt class="filename">httpd.conf</tt> 文件的按不同虚拟主机或不同目录的方式来屏蔽函数。如果将如下内容加入到<tt class="filename">php.ini</tt> 文件: </p> <pre class="brush:python;toolbar:false">disable_functions readfile,system</pre> <p>则会得到如下的输出:</p> <pre class="brush:python;toolbar:false">Warning: readfile() has been disabled for security reasons in /usr/local/httpd/htdocs/test.php on line 3</pre> <p><span style="line-height: 20px"><strong><span style="font-size: 18px">4. 安全模式限制函数</span></strong></span></p> <p><span style="line-height: 20px"><span style="font-size: 18px"></span></span></p> <table class="CALSTABLE"> <thead> <tr class="firstRow"> <th>函数名</th> <th>限制</th> </tr> </thead> <tbody> <tr> <td><span class="function" style="font-weight: bold">dbmopen()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">dbase_open()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">filepro()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">filepro_rowcount()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">filepro_retrieve()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td>ifx_*</td> <td>sql_safe_mode 限制, (!= safe mode)</td> </tr> <tr> <td>ingres_*</td> <td>sql_safe_mode 限制, (!= safe mode)</td> </tr> <tr> <td>mysql_*</td> <td>sql_safe_mode 限制, (!= safe mode)</td> </tr> <tr> <td><span class="function" style="font-weight: bold">pg_loimport()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">posix_mkfifo()</span></td> <td>检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">putenv()</span></td> <td>遵循 ini 设置的 safe_mode_protected_env_vars 和 safe_mode_allowed_env_vars 选项。请参考 <span class="function" style="font-weight: bold">putenv()</span> 函数的有关文档。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">move_uploaded_file()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">chdir()</span></td> <td>检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">dl()</span></td> <td>本函数在安全模式下被禁用。</td> </tr> <tr> <td>backtick operator</td> <td>本函数在安全模式下被禁用。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">shell_exec()</span>(在功能上和 backticks 函数相同)</td> <td>本函数在安全模式下被禁用。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">exec()</span></td> <td>只能在 safe_mode_exec_dir 设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 <tt class="literal">..</tt>。<span class="function" style="font-weight: bold">escapeshellcmd()</span> 将被作用于此函数的参数上。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">system()</span></td> <td>只能在 safe_mode_exec_dir 设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 <tt class="literal">..</tt>。<span class="function" style="font-weight: bold">escapeshellcmd()</span> 将被作用于此函数的参数上。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">passthru()</span></td> <td>只能在 safe_mode_exec_dir 设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 <tt class="literal">..</tt>。<span class="function" style="font-weight: bold">escapeshellcmd()</span> 将被作用于此函数的参数上。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">popen()</span></td> <td>只能在 safe_mode_exec_dir 设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 <tt class="literal">..</tt>。<span class="function" style="font-weight: bold">escapeshellcmd()</span> 将被作用于此函数的参数上。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">fopen()</span></td> <td>检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">mkdir()</span></td> <td>检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">rmdir()</span></td> <td>检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">rename()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">unlink()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">copy()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。 (on <code class="parameter">source</code> and <code class="parameter">target</code>)</td> </tr> <tr> <td><span class="function" style="font-weight: bold">chgrp()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">chown()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">chmod()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 另外,不能设置 SUID、SGID 和 sticky bits</td> </tr> <tr> <td><span class="function" style="font-weight: bold">touch()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">symlink()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。 (注意:仅测试 target)</td> </tr> <tr> <td><span class="function" style="font-weight: bold">link()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。 (注意:仅测试 target)</td> </tr> <tr> <td><span class="function" style="font-weight: bold">apache_request_headers()</span></td> <td>在安全模式下,以“authorization”(区分大小写)开头的标头将不会被返回。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">header()</span></td> <td>在安全模式下,如果设置了 <tt class="literal">WWW-Authenticate</tt>,当前脚本的 uid 将被添加到该标头的 <tt class="literal">realm</tt> 部分。</td> </tr> <tr> <td>PHP_AUTH 变量</td> <td>在安全模式下,变量 <code class="varname">PHP_AUTH_USER</code>、<code class="varname">PHP_AUTH_PW</code> 和 <code class="varname">PHP_AUTH_TYPE</code> 在 <code class="varname">$_SERVER</code> 中不可用。但无论如何,您仍然可以使用 <code class="varname">REMOTE_USER</code> 来获取用户名称(USER)。(注意:仅 PHP 4.3.0 以后有效)</td> </tr> <tr> <td><span class="function" style="font-weight: bold">highlight_file()</span>, <span class="function" style="font-weight: bold">show_source()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。 (注意,仅在 4.2.1 版本后有效)</td> </tr> <tr> <td><span class="function" style="font-weight: bold">parse_ini_file()</span></td> <td>检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。 (注意,仅在 4.2.1 版本后有效)</td> </tr> <tr> <td><span class="function" style="font-weight: bold">set_time_limit()</span></td> <td>在安全模式下不起作用。</td> </tr> <tr> <td>max_execution_time</td> <td>在安全模式下不起作用。</td> </tr> <tr> <td><span class="function" style="font-weight: bold">mail()</span></td> <td>在安全模式下,第五个参数被屏蔽。(注意,仅自 PHP 4.2.3 起受影响)</td> </tr> <tr> <td></td> <td></td> </tr> </tbody> </table> 最后修改:2021 年 12 月 10 日 10 : 53 AM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 赞赏作者 支付宝微信