常见减肥用公式

基础代谢率公式

BMR(男)=(13.7×体重(公斤))+(5.0×身高(公分))-(6.8×年龄)+66
BMR(女)=(9.6×体重(公斤))+(1.8×身高(公分))-(4.7×年龄)+655

脂肪和千卡换算

1KG脂肪 ≈ 7700KCal

跑步消耗能量计算

(1)已知体重、时间和速度

跑步热量(kcal)=体重(kg)×运动时间(小时)×指数K 
指数K=30÷速度(分钟400米) 

例如:某人体重60公斤,长跑1小时,速度是3分钟400米或8公里小时,那么他跑步过程中消耗的热量=60×1×303=600kcal(千卡) 
此种计算含盖了运动后由于基础代谢率提高所消耗的一部分热量,也就是运动后体温升高所产生的一部分热量。 

(2)已知体重、距离

跑步热量(kcal)=体重(kg)×距离(公里)×1.036 
例如:体重60公斤的人,长跑8公里,那么消耗的热量=60×8×1.036=497.28 kcal(千卡) 

(3)已知体重、速度和时间

跑步热量(kcal)=体重(kg)×运动时间(分钟)×指数K 
一小时8公里 K=0.1355 
一小时12公里 K=0.1797 
一小时15公里 K=0.1875 
体重60公斤的人,长跑1小时,速度为8公里小时,那么消耗的热量=60×60×0.1355=487.8kcal(千卡)

初探机器学习检测 PHP Webshell

简介

最近刷完了吴恩达(Andrew Ng)的Machine Learning课程,恰巧实验室有相关的需求,看了几个前辈的机器学习检测PHP Webshell 的文章,便打算自己也抄起袖子,在实战中求真知。

本文会详细的介绍实现机器学习检测PHP Webshell的思路和过程,一步一步和大家一起完成这个检测的工具,文章末尾会放出已经写好的下载链接。

可能需要的背景知识

php基础知识(PHP opcode)

php Webshell

Python(scikit-learn)

背景知识简单介绍

PHP:世界上最好的编程语言,这个不多说了。

PHP opcode:PHP opcode 是脚本编译后的中间语言,就如同Java 的Bytecode、.NET 的MSL。

PHP Webshell:可以简单的理解为 网页后门。

Python scikit-learn:

2018102918259-初探机器学习检测-PHP-Webshell-1

(翻译:用起来美滋滋的Python 机器学习包)

可行性分析

PHP Webshell本质上也是一段PHP的代码,在没有深入研究前,也知道PHP Webshell 必然有一些规律,比如执行了某些操作(执行获取到的命令、列出目录文件、上传文件、查看文件等等)。如果直接用PHP 的源代码分析,会出现很多的噪音,比如注释内容、花操作等等。如果我们将PHP Webshell 的源代码转化成仅含执行语句操作的内容,就会一定程度上,过滤掉这些噪音。所以,我们使用PHP opcode 进行分析。

针对opcode这种类型的数据内容,我们可以采用词袋,词频等方法来进行提取关键特征。最后使用分类的算法来进行训练。

根据上面的简单“分析”,知道咱们在大体思路上,是可以行得通的。

实战

第一步:准备环境

要获取到PHP opcode,需要添加一个PHP 的插件 VLD,我们拿Windows环境来进行举例。

插件下载地址:传送门

选择对应版本进行下载

20181029182520-初探机器学习检测-PHP-Webshell-2

下载好后,放入到PHP 安装目录下的ext文件夹内,我使用的是PHPstudy环境,

20181029182527-初探机器学习检测-PHP-Webshell-3

然后编辑php.ini文件,添加一行内容

20181029182540-初探机器学习检测-PHP-Webshell-4

extension=php_vld.dll

测试是否安装成功:

测试文件1.php

20181029182550-初探机器学习检测-PHP-Webshell-6

执行命令:

php -dvld.active=1 -dvld.execute=0 1.php

20181029182558-初探机器学习检测-PHP-Webshell-7

如果显示内容是差不多一样的,那我们的环境配置就成功了。

我们需要的就是这段输出中的

2018102918266-初探机器学习检测-PHP-Webshell-8

ECHO 、RETURN

这样的opcode。

到这里,我们的PHP环境配置基本完成了。

第二步:准备数据

进行机器学习前,我们很关键的一步是要准备数据,样本的数量和质量直接影响到了我们最后的成果。

下载数据

这里需要准备的数据分为两类,【白名单数据】、【黑名单数据】。

白名单数据指我们正常的PHP程序,黑名单数据指的是PHP Webshell程序。数据源还是我们的老朋友 github.com

在github上搜索PHP,可以得到很多的PHP的项目,咱们筛选几个比较知名和常用的。

白名单列表(一小部分):

再继续搜索一下 Webshell 关键字,也有很多收集 Webshell 的项目。

黑名单列表(一小部分):

创建工程文件夹

创建工程文件夹【MLCheckWebshell】,并在目录下创建【black-list】【white-list】文件夹。用于存放黑名单文件和白名单文件。

提取opcode

我们创建一个utils.py 文件,用来编写提取opcode的工具函数。

工具函数1:

20181029182628-初探机器学习检测-PHP-Webshell-9

方法load_php_opcode 解读:

用Python 的subprocess 模块来进行执行系统操作,获取其所有输出,并用正则提取opcode,再用空格来连接起来

工具函数2;

20181029182636-初探机器学习检测-PHP-Webshell-11

工具方法2 recursion_load_php_file_opcode 的作用是遍历目标文件夹内的所有的PHP文件并生成opcode,最后生成一个列表,并返回。

然后我们在工程目录下,创建train.py文件。

编写prepare_data() 函数

20181029182641-初探机器学习检测-PHP-Webshell-12

prepare_data 做了以下几个事:

  1. 把黑名单和白名单中的PHP opcode 统一生成并分别写入到两个不同的文件中。
  2. 如果这两个文件已经存在,那就不再次生成了
  3. 把白名单中的PHP opcode 贴上 【0】的标签
  4. 把黑名单中的PHP opcode 贴上 【1】的标签
  5. 最后返回所有PHP opcode 的集合数据 X(有序)
  6. 返回所有PHP opcode 的标签 y(有序)

第三步:编写训练函数

终于到了我们的重点节目了,编写训练函数。

在这里先简单的介绍一下scikit-learn中我们需要的一些使用起来很简单的对象和方法。

  1. CountVectorizer
  2. TfidfTransformer
  3. train_test_split
  4. GaussianNB

CountVectorizer 的作用是把一些列文档的集合转化成数值矩阵。

TfidfTransformer 的作用是把数值矩阵规范化为 tf 或 tf-idf 。

train_test_split的作用是“随机”分配训练集和测试集。这里的随机不是每次都随机,在参数确定的时候,每次随机的结果都是相同的。有时,为了增加训练结果的有效性,我们会用到交叉验证(cross validations)。

GaussianNB :Scikit-learn 对朴素贝叶斯算法的实现。朴素贝叶斯算法是常用的监督型算法。

先上写好的代码:

20181029182650-初探机器学习检测-PHP-Webshell-15

代码介绍:

首先,我们用了刚才写的prepare_data()函数来获取我们的数据集。然后,创建了一个CountVectorizer 对象,初始化的过程中,我们告诉CountVectorizer对象,ngram的上下限为(3,3) 【ngram_range=(3,3)】,当出现解码错误的时候,直接忽略【decode_error=”ignore”】,匹配token的方式是【r”\b\w+\b”】,这样匹配我们之前用空格来隔离每个opcode 的值。

然后我们用 cv.fit_transform(X).toarray() 来“格式化”我们的结果,最终是一个矩阵。

接着创建一个TfidfTransformer对象,用同样的方式处理一次我们刚才得到的总数据值。

然后使用train_test_split函数来获取打乱的随机的测试集和训练集。这时候,黑名单中的文件和白名单中的文件排列顺序就被随机打乱了,但是X[i] 和 y[i] 的对应关系没有改变,训练集和测试集在总数聚集中分别占比60%和40%。

接下来,创建一个GaussianNB 对象,在Scikit-learn中,已经内置好的算法对象可以直接进行训练,输入内容为训练集的数据(X_train) 和 训练集的标签(y_train)。

gnb.fit(X_train, y_train)

执行完上面这个语句以后,我们就会得到一个已经训练完成的gnb训练对象,我们用测试集(X_test) 去预测得到我们的y_pred 值(预测出来的类型)。

然后我们对比原本的 y_test 和 用训练算法得到的结果 y_pred。

metrics.accuracy_score(y_test, y_pred)

结果即为在此训练集和测试集下的准确率。

2018102918272-初探机器学习检测-PHP-Webshell-17

约为97.42%

还需要计算混淆矩阵来评估分类的准确性。

metrics.confusion_matrix(y_test, y_pred)

输出结果见上图。

编写训练函数到这里已经初具雏形。并可以拿来简单的使用了。

第四步:持久化&应用

编写完训练函数,现在我们可以拿新的Webshell来挑战一下我们刚才已经训练好的gnb。

但是,如果每次检测之前,都要重新训练一次,那速度就非常的慢了,我们需要持久化我们的训练结果。

在Scikit-learn 中,我们用joblib.dump() 方法来持久化我们的训练结果,细心的读者应该发现,在method1() 中有个被注释掉的语句

joblib.dump(gnb, ‘save/gnb.pkl’)

这个操作就是把我们训练好的gnb保存到save文件夹内的gnb.pkl文件中。

方面下次使用。

创建check.py

理一下思路:先实例化我们之前保存的内容,然后将新的检测内容放到gnb中进行检测,判断类型并输出。

核心代码:

20181029182713-初探机器学习检测-PHP-Webshell-18

最后根据标签来判断结果,0 为 正常程序, 1 为 Webshell。

我们来进行一个简单的测试。

20181029182720-初探机器学习检测-PHP-Webshell-usage

20181029182728-初探机器学习检测-PHP-Webshell-usage-1

那么,一个简单的通过朴素贝叶斯训练算法判断Webshell的小程序就完成了。

下一步?

这个小程序只是一个简单的应用,还有很多的地方可以根据需求去改进

如:

在准备数据时:

  1. 生成 opcode过程中,数据量太大无法全部放入内存中时,更换写入文件中的方式。

在编写训练方法时:

  1. 更换CountVectorizer的ngram参数,提高准确性。
  2. 增加cross validation 来增加可靠性
  3. 更换朴素贝叶斯算法为其他的算法,比如MLP、CNN(深度学习算法)等。

在训练后,得到数据与预期不符合时:

  1. 重复增量型训练,优化训练结果。
  2. 增大训练数据量
  3. 如果对PHP opcode 有深入研究的同学可以采用其他的提取特征的方法来进行训练。
  4. 选择多种训练方法,看看哪一种的效果最好,而且不会过度拟合(over fitting)。

#

结语

最后咱们总结一下机器学习在Webshell 检测过程中的思路和操作。

  1. 提取特征,准备数据
  2. 找到合适的算法,进行训练
  3. 检查是否符合心中预期,会不会出现过度拟合等常见的问题。
  4. 提供更多更精准的数据,或更换算法。
  5. 重复1~4

本人也是小菜鸡,在此分享一下简单的思路和方法。希望能抛砖引玉。

项目下载地址:

https://github.com/hi-WenR0/MLCheckWebshell

参考链接:

基于机器学习的 Webshell 发现技术探索

PHP反序列化漏洞详细教程及实例(下) Typecho 反序列化漏洞分析

大家好,结合上一篇PHP反序列化的文章,炒一下冷饭,给大家分析一下10月份出的 Typecho 反序列化漏洞。

本文的目的是把反序列化漏洞讲清楚,奶妈级讲解方式,让你看明白。

回顾

PHP反序列化漏洞详细教程及实例(上)

示例漏洞利用的过程:

  1. 需要有一个漏洞触发点 :pets.php 内的 $pet = unserialize($_GET[‘pet_serialized’]);
  2. 需要有一个相关联的,有魔术方法(会被自动调用)的类。log.php (WTFLog 内的__destruct函数)。
  3. 漏洞的效果取决于__destruct 这个魔术函数内的操作,这里的是可以操控的可以删除的log 的 filename。
  4. 构建poc.php ,利用程序,先序列化后,从可控输入$_GET[‘pet_serialized’]输入进去。
  5. 完成。

代码回溯

在本文编写时,Typecho早已发布了很多新版本,让我们从git logs 中,找到存在漏洞的版本。

根据漏洞发生时间:10月左右,commit message : 漏洞 来确定具体的commit是哪一个

2018102918145-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-3-1

可以看到e277141 是已经修复后的commit,那么242fc1a就是我们需要回溯到的版本。

通过git 方式下载仓库以后。切换到目标版本。

20181029181418-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-4-1

漏洞分析

Typecho 反序列化漏洞存在于install.php 文件中,让我们按照之前的思路来分析一下。

1. 寻找可控的反序列化输入点。

在install.php中,通过搜索 unserialize 关键词,发现两个相关点。

20181029181431-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-5-1

看下代码:

install.php

20181029181442-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-6

232行是漏洞关键输入点。那么Typecho_Cookie::get()是啥?

看下代码:

Cookie.php

20181029181452-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-7

A: “获取指定的COOKIE值”

那么,232 行的意思是:反序列化了用base64解码后的key为__typecho_config 的 cookie 内容。

cookie 可控,还有一个关键点是如何进入这段代码。

一起来看一下

2018102918150-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-8-1

执行到232行漏洞触发点的前提:

  1. 设置finish参数
  2. 设置refer,来源于漏洞站就ok

第一步已经搞定。下面来分析第二步。

2. 需要有一个相关联的,有魔术方法(会被自动调用)的类。

我们重新来看下232行开始的代码。

20181029181515-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-6

序列化后的内容赋值给了$config

234行把$config[‘adapter’] , $config[‘prefix’]作为参数传入了Typecho_Db类。

复习一下之前说过的magic method。

  1. __construst()
  2. __destruct()
  3. __toString()

__construst() 方法在每次创建新对象时会被自动调用

__destruct() 方法在使用 exit() 终止脚本运行时也会被自动调用

_toString() 方法在一个类被当成字符串时应怎样回应。例如 _echo $obj; 应该显示些什么。

查看Typecho_Db类查看下源代码。

Db.php

2018102918160-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-db-php-构造函数

 

114 行,$adapterName 作为参数被传进来以后,在120行进行了字符串拼接操作,字符串拼接操作会触发实例化类的toString()方法, 那我们的目标就可以放在toString()这个magic method 的方向上了。

搜索__toString(),

20181029181611-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-feed-php-toString

当我们找到一个符合条件的类的时候,就要确定这个类的magic method 中执行了什么东西。在Typecho_Feed这个类的__toString()中,没有跟上个文章中举例的一样的方法,这里就要另辟蹊径。

3. 寻找能利用的利用点

20181029181622-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-typecho-feed-screenName

在290行,我们可控的$item[‘auther’]调用了一个screenName 这个属性。

在PHP中,如果该实例化的对象访问了一个‘不可访问’的属性的时候,就会调用__get()方法。

这时候我们需要再次寻找 包含 __get() 的类。

20181029181649-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-search-get

20181029181714-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php__get

这里的__get()调用了get()

继续看get()

20181029181723-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php-get

298行到310行都是一些赋值操作。

追踪一下_applyFilter()

20181029181730-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php-_applyFilter

终于见到了我们想要的可以执行操作的函数call_user_func,

把第一个参数作为回调函数调用

通过这个函数,可以执行函数。

回溯一下参数传递。从后到前。

[Request.php] call_user_func() 的参数 $filter 可控,来自

20181029181942-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php-property-filter
$value 参数可控,来自_applyFilter() 的参数 $value。
_appleyFilter() 参数来自get()方法的$key。

20181029181959-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php-property-params

20181029182011-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php-get

_get($key) 直接调用get($key)

看下Feed.php。

[Feed.php] $item[‘author’]->screenName 调用了 _get()方法。

$item[‘auther’]->screenName 的$item 来自 $this->_item

20181029182023-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-feed-php-additem

4. 构建Poc.

通过第三点的分析,来构建Poc。

再顺过来整理一遍。

install.php – > Db.php -> Feed.php -> Request.php

  1. install.php 漏洞触发点,存在unserialize()函数,序列化后的结果传给了Typecho_DB()
  2. Db.php 中 120行

$adapterName = ‘Typecho_Db_Adapter_’ . $adapterName;触发了__toString()方法。

  1. 找到存在__toString()并有可以利用的Feed.php,在其中调用了

$item[‘author’]->screenName,调用__get()方法。

  1. 找到__get()方法的Request.php ,调用了get()->调用了_appleyFilter()->call_user_func()
  2. 结束、

Poc:test.php

20181029182040-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-poc

先访问:

20181029182049-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-poc-show

设置cookie __typecho_config 为test的输出值

2018102918211-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-cookie

设置refer & url

20181029182119-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-url

成功写入shell

20181029182128-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-shell2

20181029182146-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-shell1

结语

PHP反序列化漏洞详细教程及实例(下)的分析到这里,就告一段落了。

如果还有疑问,欢迎来讨论。

同时,非常感谢下面的小伙伴的分析。在编写这篇文章的过程中,起到了参考和启发的作用。

Refer

1
2
3
4
5
> http://p0sec.net/index.php/archives/114/
>
> https://paper.seebug.org/424/
>
> https://paper.tuisec.win/detail/c1ecf917be22318.jsp

PHP反序列化漏洞详细教程及实例(上)

PHP反序列化漏洞是一种常见的漏洞,在本篇文章中,希望能深入简出的让各位即使没有安全背景的读者明白什么是PHP反序列化漏洞,以及如何利用。

如有错误不足之处,请不吝指教。

你需要的前置知识

  1. PHP类与对象
  2. PHP魔术方法
  3. PHP反序列化方法

PHP类与对象

先从最简单的开始。

在PHP中,定义一个类,和定义一个类的方法。

一个简单的例子:

PHP魔术方法

在PHP官方网站中的定义:

__construct()__destruct()__call()__callStatic()__get()__set()__isset()__unset()__sleep()__wakeup()__toString()__invoke()__set_state()__clone()__debugInfo() 等方法在 PHP 中被称为”魔术方法”(Magic methods)。在命名自己的类方法时不能使用这些方法名,除非是想使用其魔术功能。

咱们来简单讲解几个魔术方法

  1. __construst()
  2. __destruct()
  3. __toString()

__construst() 方法在每次创建新对象时会被自动调用

__destruct() 方法在使用 exit() 终止脚本运行时也会被自动调用

_toString() 方法在一个类被当成字符串时应怎样回应。例如 _echo $obj; 应该显示些什么。

代码:


输出结果:

2018102917599-PHP反序列化漏洞详细教程及实例(上)-4

PHP对象序列化

在PHP网站中的定义:

所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。unserialize()函数能够重新把字符串变回php原来的值。 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。

简单的理解序列化:就是把一个类的实例变成一个字符串。

简单的理解反序列化:把一个特殊的字符串转换成一个实例。

代码:

输出结果:

高亮部分即为序列化后的对象。

反序列化的操作:

2018102918019-PHP反序列化漏洞详细教程及实例(上)-7

代码执行效果:

2018102918026-PHP反序列化漏洞详细教程及实例(上)-8

想要深入了解序列化后的字符的具体意义,请参考这个链接:

1
http://php.net/manual/zh/function.serialize.php

小试牛刀

通过上面的前置知识,相信大家已经对PHP序列化相关的内容有一个初步的认识。下面来开始分析一个简单的例子。

201810291810-PHP反序列化漏洞详细教程及实例(上)-9

这是一个WTFLog 类,调用 loginfo 方法会记录一条记录到access.log文件中,WTF的地方是,当这个类完成它的使命的时候(exit),会删除掉它所记录的文件。

201810291819-PHP反序列化漏洞详细教程及实例(上)-11

这里有一个“正常”的业务,pets.php :

2018102918115-PHP反序列化漏洞详细教程及实例(上)-10

该代码的业务目标是从用户处收集序列化后的数据,并进行一些操作。

该代码段的特点是:直接使用客户端可以控制的输入点($_GET[‘pet_serialized]),在不进行验证的情况下,直接实例化了这段代码!!

看我们如何利用这个危险的输入点:

还记得刚才的WTFLog吧!

先新创建一个新的poc.php,把 log.php 内的WTFLog类引入进来。

2018102918146-PHP反序列化漏洞详细教程及实例(上)-12

index.php 是一个很有用的文件,会输出一句话。

2018102918153-PHP反序列化漏洞详细教程及实例(上)-13

运行 poc.php ,得到我们想要的序列化后的WTFLog 字符串。

201810291822-PHP反序列化漏洞详细教程及实例(上)-15

1
O:6:'WTFLog':1:{s:8:'filename';s:9:'index.php';}

这里利用这个字符串,去调用pets.php

2018102918225-PHP反序列化漏洞详细教程及实例(上)-17

本来要删除掉access.log这个文件,却删除了我们的重要文件index.php。

验证一下:

2018102918229-PHP反序列化漏洞详细教程及实例(上)-18

到了这一步,漏洞已经利用完成。

回顾一下整个漏洞利用的过程:

  1. 需要有一个漏洞触发点 pets.php 内的 $pet = unserialize($_GET[‘pet_serialized’]);
  2. 需要有一个相关联的,有魔术方法(会被自动调用)的类。log.php (WTFLog 内的__destruct函数)
  3. 漏洞的效果取决于__destruct 这个魔术函数内的操作,这里的是可以操控的可以删除的log 的 filename。
  4. 构建poc.php ,利用程序,先序列化后,从可控输入$_GET[‘pet_serialized’]输入进去。
  5. 完成。

结语

大家从上面的过程中对PHP反序列化的方式及危害有了一个比较直观的理解了。那如何利用PHP反序列化这个漏洞来做更多的事情呢,这里需要看更多的魔术方法的自动触发的情景,根据不同的使用情景(代码实现方式),来定制我们的Poc,如果可控代码中,存在call_user_func() 这个函数,可以实现通过PHP反序列化漏洞来进行任意代码执行。

结语的下一步

下一篇文章将会分析一下Typecho 这个很受欢迎的Blog程序的反序列化漏洞的利用。

Thanks for watching.

《绝地求生:大逃杀》 死亡总结

玩一个游戏,就要好好的玩,总结自己的不足,这样才会进步,吃到!🐔

下面是我死亡时候的总结。前车之鉴,后车之师。

  1. 在无掩体的情况下被打死(应对:冲圈先找掩体
  2. 站着不动刚枪被打死(应对:蛇皮走位
  3. 有房子的时候,没有躲进房子,被打死(应对:进房子
  4. 在楼房楼梯正上面。被人爆头打死(应对:进房间,找掩体,能看到楼梯的方向来阴死对方。
  5. 在局势不明朗的时候,不要先开枪,除非有把握一枪爆头。
  6. 下车一定要看速度!
  7. 对枪,有掩体的时候才要移动来打,不然不要动,因为可能对方就是少打了一枪就死了。
  8. 及时掌握自己手里枪的发射状态,是单点,连发,还是自动。很关键。