storedxss(storedxss漏洞)
本文目录一览:
- 1、存储过程sql语句拼合有错,但不知道怎么改,希望帮忙改一下。代码如下:
- 2、请教laravel view 怎么显示 controller 中传递的对象值
- 3、怎么在 Phalcon 框架里管理使用cookie
- 4、nmap使用求助
存储过程sql语句拼合有错,但不知道怎么改,希望帮忙改一下。代码如下:
请把@sql改成nvarchar(4000);
你原来的nvarchar(200)太短,所以在sub处截断了。
另外还要照楼上那样把类型都改过来。
建议以后把拼接后的sql语句打印出来看一看,很容易发现问题在哪儿。
请教laravel view 怎么显示 controller 中传递的对象值
你应该学习下 blade模板
Blade 模板引擎
简介
Blade 是 laravel 提供的一个简单强大的模板引擎。它不像其他流行的 PHP 模板引擎那样限制你在视图中使用原生的 PHP 代码,事实上它就是把 Blade 视图编译成原生的 PHP 代码并缓存起来。缓存会在 Blade 视图改变时而改变,这意味着 Blade 并没有给你的应用添加编译的负担。Blade 视图文件使用 .blade.php 后缀,一般情况下都被存储在 resources/views 目录。
模板继承
定义布局
Blade 带来的两个主要的福利就是模板继承和挂件。为了方便开始,我们来看一个简单的例子。首先,我们建立一个主页面布局。因为多数 web 应用是在不同的页面中使用相同的总体布局,我们可以方便的定义这个布局为单独的 Blade 视图:
!-- Stored in resources/views/layouts/master.blade.php--
html
head
titleApp Name - @yield('title')/title
/head
body
@section('sidebar')
This is the master sidebar.
@show
div class="4187-1e6f-fac2-69f9 container"
@yield('content')
/div
/body
/html
从上面的例子你可以看到,Blade 模板文件包含了典型的 HTML 标记。你肯定注意到了 @section 和 @yield 指令。@section 指令就如它的名字所暗示的那样定义了一个内容区块,而 @yield 指令是用来显示所提供的挂件区块所包含的内容。
现在我们已经定义好了一个基本的布局,接下来我们来构建一个子页面去继承这个布局。
扩展布局
我们可以使用 Blade 的 @extends 指令来明确的指定继承某个布局。然后使用 @section 指令将挂件中的内容挂载到布局中,在上面的例子中,挂件的内容将被挂载到布局中的 @yield 部分:
!-- Stored in resoures/views/child.blade.php --
@extends('layouts.master')
@section('title', 'Page Title')
@section('sidebar')
@parent
pThis is appended to the master sidebar./p
@endsection
@section('content')
pThis is my body content./p
@endsection
在上面的例子作用 sidebar 挂件利用 @parent 指令来追加布局中的 sidebar 部分的内容,如果不使用则会覆盖掉布局中的这部分。@parent 指令会在视图被渲染时替换为布局中的内容。
Blade 视图可以像原生 PHP 视图一样使用全局帮助函数 view 来返回渲染后的内容:
Route::get('blade', function () {
return view('child');
});
显示数据
你可以使用花括号 { 来在视图中显示传递到视图中的变量,例如,你定义了下面的路由:
Route::get('greeting', function () {
return view('welcome', ['name' = 'Samantha']);
})
你可以在视图中这样来输出 name 变量的内容:
Hello, {{ $name }}
当然,你并没有被限制只允许显示传递到视图中的变量的内容。你也可以从原生 PHP 方法中返回内容。事实上,你可以在 Blade echo 声明中使用任意的 PHP 代码:
The current UNIX timestamp is {{ time() }}
注意:Blade {{}} 声明中的内容是自动通过 PHP 的 htmlentities 方法过滤的,用来防止 XSS 攻击。
Blade JavaScript Frameworks
由于很多 JavaScript 框架都使用花括号来表明所提供的表达式应该被显示在浏览器中。所以你可以使用 @ 符号来告诉 Blade 渲染引擎你需要这个表达式原样保留:
h1Laravel/h1
Hello, @{{ name }}
上面的例子中,@ 符号会在 Blade 渲染时被移除,并且 {{ name }} 表达式会被原样保留下来。
输出数据假如它存在
有时候你可能希望输出一个变量,但是你并不确定它是否已经被设置,你可以使用这个表达式:
{{ isset($name) ? $name : 'Default' }}
Blade 提供了一个便捷的方式来替换这个三元声明:
{{ $name or 'Default' }}
上面的例子中,如果变量 $name 存在,它将被输入,如果不存在,Default 会被输出。
显示未转义的数据
默认的,Blade {{}} 声明会自动的使用 PHP 的 htmlentities 方法来避免 XSS 攻击。如果你不想你的数据被转义,你可以使用下面的语法:
Hello, {!! $name !!}
注意:当你在应用中输出用户输入的数据时应该非常的谨慎,你应该总是使用 {{}} 来转义内容中任意的 HTML 实体。
控制结构
除了模板继承和数据显示,Blade 为通用的 PHP 控制结构提供了便利的简写方式,比如条件声明和循环。这些简写提供了一个干净简洁的方式来处理 PHP 的控制结构,而且还保持与 PHP 语句的相似性。
if 声明
你可以通过 @if,@elseif,@else和 @endif 指令来使用 if 控制结构,这些指令和 PHP 方法保持一致:
@if (count($records) === 1)
I have one record!
@elseif (count($records) 1)
I have multiple records!
@else
I don't have any records!
@endif
为了方便,Blade 也提供了 @unless 指令:
@unless (Auth::check())
You are not signed in.
@endunless
你也可以使用 @hasSection 指令来判断提供给布局的挂件是否包含了内容:
title
@hasSection('title')
@yield('title') - App Name
@else
App Name
@endif
/title
循环
除了条件声明,Blade 也提供了一些简单指令来支持 PHP 的循环结构。这些指令方法和 PHP 语法相同:
@for ($i = 0; $i 10; $i++)
The current value is {{ $i }}
@endfor
@foreach ($users as $user)
pThis is user {{ $user-id }}/p
@endforeach
@forelse ($users as $user)
li{{ $user-name }}/li
@empty
pNo users/p
@endforelse
@while (true)
pI'm looping forever./p
@endwhile
Blade 也提供了终止迭代或取消当前迭代的指令:
@foreach ($users as $user)
@if($user-type == 1)
@continue
@endif
li{{ $user-name }}/li
@if($user-number == 5)
@break
@endif
@endforeach
你也可以使用指令声明包含条件的方式来达到中断:
@foreach ($users as $user)
@continue($user-type == 1)
li{{ $user-name }}/li
@break($user-number == 5)
@endforeach
包含子视图
你可以使用 @include 指令来包含一个视图的内容,当前视图中的变量也会被共享给子视图:
div
@include('shared.errors')
form
!-- Form Contents --
/form
/div
尽管子视图会自动继承父视图中的所有数据变量,你也可以直接传递一个数组变量来添加额外的变量到子视图:
@include('view.name', ['some' = 'data'])
主要:你应该在 Blade 视图中避免使用 __DIR__ 和 __FILE__ 常量,因为它们会解析为视图缓存所在的位置。
为集合渲染视图
你可以使用 Blade 的 @each 指令来在一行中合并引入多个视图:
@each('view.name', $jobs, 'job')
第一个参数是数组或集合中每个元素需要被渲染的视图名称。第二个参数是一个数组或集合,被用来提供迭代。而第三个参数是要分配给当前视图的变量名。举个例子,如果你需要遍历一个数组 jobs,通常你想要在局部渲染的视图中使用 job 作为变量来访问 job 信息。
你也可以传递第四个参数到 @each 指令。如果所提供的数组是空数组的话,该参数所提供的视图将会被引入。
@each('view.name', $jobs, 'job', 'view.empty')
注释
Blade 也允许你在视图中定义注释,但是它不会在渲染时生成 HTML 注释:
{{-- This comment will not be present in the rendered HTML --}}
堆
Blade 允许你在已命名的堆中压入内容:
@push('scripts')
script src="/example.js"/script
@endpush
你可以在你需要的时候压入相同的堆任意的次数,你需要在布局中使用 @stack 来渲染堆:
head
!-- Head Contents --
@stack('scripts')
/head
服务注入
你可以使用 @inject 指令来从服务容器中取回服务,该指令的第一个参数将作为所取回服务存放的变量名,而第二个参数是你想要在服务容器中取回的类或接口名称:
@inject('metrics', 'App\Services\MetricsService')
div
Monthly Revenue: {{ $metrice-monthlyRevenue() }}
/div
扩展 Blade
Blade 允许你自定义一些指令,你可以使用 directvie 方法来注册指令。当 Blade 编译器遇到该指令时,它会自动的调用该指令注册时提供的回调函数并传递它的参数。
下面的例子创建了 @datetime($val) 指令来格式化 $val:
?php
namespace App\Providers;
use Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
Blade::directive('datetime', function ($expression) {
return "?php echo with{$express}-format('m/d/Y H:i'); ?";
});
}
/**
* Register bindings in the container
*
* @return void
*/
public function register()
{
//
}
}
上面的例子中使用了 Laravel 的 with 帮助方法,它只是简单的返回一个所提供的对象或值,并提供方便的链式调用。最终该指令生成的 PHP 代码如下:
?php echo with($var)-format('m/d/Y H:i'); ?
在你更新 Blade 指令的逻辑之后,你应该删除所有已缓存的 Blade 视图,你可以使用 view:clear Artisan 命令来清除。
作者:Dearmadman
链接:
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
怎么在 Phalcon 框架里管理使用cookie
Phalcon\Http\Response\Cookies(不是Phalcon\Http\Cookie)是一个为响应设置cookie的容器,类似于PHP中的setcookie()函数。
这个容器中设置的每个cookie都是一个Phalcon\Http\Cookie类实例,容器的send()方法实际是添加响应头Set-Cookie指令。
在Phalcon中,最终会调用:
Phalcon\Http\Response-sendHeaders()
Phalcon\Http\Response-sendCookies()
这里的Phalcon\Http\Response-sendCookies()内部实际调用Phalcon\Http\Response\Cookies的send()方法。
如下例子:
//在控制器方法中添加如下代码:
$this-cookies-useEncryption(false);
$this-cookies-set("test-cookie","ffffffffffffffff");
$this-cookies-send();
return;
//响应头
Connection Keep-Alive
Content-Length 10
Content-Type text/html
Date Mon, 08 Sep 2014 04:20:17 GMT
Keep-Alive timeout=5, max=100
Server Apache/2.2.27 (Unix) PHP/5.5.15
Set-Cookie test-cookie=ffffffffffffffff; path=/; httponly test-cookie=ffffffffffffffff; path=/; httponly
代码中设置了一个cookie,然后调用容器的send()方法,在客户端查看响应头,发现Set-Cookie指令中test-cookie设置了两次,这个说明Phalcon在响应时也调用了一次send()方法,这个就可以证明Phalcon在响应时调用的sendCookies()方法内部就是调用cookie容器的send()方法。
Phalcon\Http\Response有三个和cookie有关的方法:
Phalcon\Http\Response::getCookies();
Phalcon\Http\Response::setCookies($cookies);
Phalcon\Http\Response::sendCookies();
分别获取和设置Response的Cookies容器(\Phalcon\Http\Response\CookiesInterface 实例),sendCookies()是调用容器的send()方法发送cookie。
还有一个问题是,如何获取来自请求的cookie?你可以发现,在Phalcon\Http\Request中并不存在类似getCookies()方法,难道要使用$_COOKIE全局数组?Phalcon文档对于这个并没有提及。使用如下例子:
//使用的请求头信息
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Cache-Control max-age=0
Connection keep-alive
Cookie test-cookie=only+for+test+cookie.
Host 192.168.1.168
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
//控制器代码
$this-cookies-set("hello-cookie","hello cccccc kie.");
if($this-cookies-has("test-cookie")){
echo $this-cookies-get("test-cookie")-getValue();
}
print_r($this-cookies);
$this-view-disable();
//输出
only for test cookie.
Phalcon\Http\Response\Cookies Object
(
[_dependencyInjector:protected] = Phalcon\DI\FactoryDefault Object
[_registered:protected] =
[_useEncryption:protected] =
[_cookies:protected] = Array
(
[hello-cookie] = Phalcon\Http\Cookie Object
(
[_readed:protected] = 1
[_restored:protected] =
[_useEncryption:protected] =
[_dependencyInjector:protected] = Phalcon\DI\FactoryDefault Object
[_filter:protected] =
[_name:protected] = hello-cookie
[_value:protected] = hello cccccc kie.
[_expire:protected] = 0
[_path:protected] = /
[_domain:protected] =
[_secure:protected] =
[_httpOnly:protected] = 1
)
)
)
请求中发送了cookie(test-cookie=only+for+test+cookie.)
$this-cookies-get("test-cookie")获取到了这个来自请求的cookie,但是从Phalcon\Http\Response\Cookies输出来看,这个cookie并不在它的_cookies数组中,观察到代码中设置了一个叫hello-cookie的cookie,而它在_cookies数组中,所以应该是只有设置了才进入_cookies数组,$this-cookies-get("test-cookie")先判断在不在_cookies数组中,否则再判断是不是来自请求的cookie。
注意,$this-cookies-get("test-cookie")返回的是一个来自请求的Phalcon\Http\Cookie的类实例,所以可以调用相关方法。
Phalcon对管理来自请求的cookie比较隐晦,它只能通过Phalcon\Http\Response\Cookies容器相关方法调用,从名字来看,不应该是它的一部分。
HTTP 请求环境(Request Environment)
每个HTTP请求(通常来源于浏览器)会包含请求的附加信息,比如头部数据,文件,变量等。一个基于Web的应用需要解析这些信息以提供正确的响应返回到请求者。Phalcon\Http\Request封装了这些请求的信息,允许你以一个面向对象的方式访问它。
?php
// Getting a request instance
$request = new \Phalcon\Http\Request();
// Check whether the request was made with method POST
if ($request-isPost() == true) {
// Check whether the request was made with Ajax
if ($request-isAjax() == true) {
echo "Request was made using POST and AJAX";
}
}
获取值(Getting Values)
PHP更加请求的类型自动地填充$_GET和$_POST超全局数组。这些数组保存了来自提交表单的值或者通过URL传递的参数值。在这些数组中的变量没有被清理兵器包含非法字符,甚至是可能导致SQL注入或跨站脚本(XSS)攻击的恶意代码。
Phalcon\Http\Request allows you to access the values stored in the $_REQUEST, $_GET and $_POST arrays and sanitize or filter them with the ‘filter’ service, (by default Phalcon\Filter). The following examples offer the same behavior:
Phalcon\Http\Request允许你访问这些存储在$_REQUEST, $_GET 和 $_POST数组中的值并且通过使用'filter'服务清理或过滤它们,(默认是Phalcon\Filter)。
以下例子提供了相同的行为:
?php
// Manually applying the filter
$filter = new Phalcon\Filter();
$email = $filter-sanitize($_POST["user_email"], "email");
// Manually applying the filter to the value
$filter = new Phalcon\Filter();
$email = $filter-sanitize($request-getPost("user_email"), "email");
// Automatically applying the filter
$email = $request-getPost("user_email", "email");
// Setting a default value if the param is null
$email = $request-getPost("user_email", "email", "some@example.com");
// Setting a default value if the param is null without filtering
$email = $request-getPost("user_email", null, "some@example.com");
(这写个用法基本要牢记了,要么直接使用filter清理,要么间接使用)
控制器中访问请求(Accessing the Request from Controllers)
最通用的方法请求环境的地方是在控制器的动作中。为了从访问控制器访问Phalcon\Http\Request对象你将需要使用$this-request控制器的公共属性:(注意,DI资源通过魔术方法映射到公共属性,并非真的是它的公共属性)
?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller {
public function indexAction() {
}
public function saveAction() {
// Check if request has made with POST
if ($this-request-isPost() == true) {
// Access POST data
$customerName = $this-request-getPost("name");
$customerBorn = $this-request-getPost("born");
}
}
}
文件上传(Uploading Files)
另一个常见的任务是文件上传。
Phalcon\Http\Request提供了一个面向对象的方法去完成这个任务:
?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller {
public function uploadAction() {
// Check if the user has uploaded files
if ($this-request-hasFiles() == true) {
// Print the real file names and sizes
foreach ($this-request-getUploadedFiles() as $file) {
//Print file details
echo $file-getName(), " ", $file-getSize(), "\n";
//Move the file into the application
$file-moveTo('files/' . $file-getName());
}
}
}
}
通过Phalcon\Http\Request::getUploadedFiles()返回的每个对象是一个Phalcon\Http\Request\File类的实例。
使用$_FILES超全局数组提供类似行为。Phalcon\Http\Request\File仅封装了请求的跟每个上传文件相关的信息。
使用头信息(Working with Headers)
跟上面提到的一样,请求头包含了允许我们去发送合适的响应到用户的有用的信息。以下例子展示这些信息的用法:
?php
// get the Http-X-Requested-With header
$requestedWith = $response-getHeader("HTTP_X_REQUESTED_WITH");
if ($requestedWith == "XMLHttpRequest") {
echo "The request was made with Ajax";
}
// Same as above
if ($request-isAjax()) {
echo "The request was made with Ajax";
}
// Check the request layer
if ($request-isSecureRequest() == true) {
echo "The request was made using a secure layer";
}
// Get the servers's ip address. ie. 192.168.0.100
$ipAddress = $request-getServerAddress();
// Get the client's ip address ie. 201.245.53.51
$ipAddress = $request-getClientAddress();
// Get the User Agent (HTTP_USER_AGENT)
$userAgent = $request-getUserAgent();
// Get the best acceptable content by the browser. ie text/xml
$contentType = $request-getAcceptableContent();
// Get the best charset accepted by the browser. ie. utf-8
$charset = $request-getBestCharset();
// Get the best language accepted configured in the browser. ie. en-us
$language = $request-getBestLanguage();
nmap使用求助
Nmap是一款网络扫描和主机检测的非常有用的工具。Nmap是不局限于仅仅收集信息和枚举,同时可以用来作为一个漏洞探测器或安全扫描器。它可以适用于winodws,linux,mac等操作系统
Nmap是一款非常强大的实用工具,可用于:检测活在网络上的主机(主机发现)检测主机上开放的端口(端口发现或枚举)检测到相应的端口(服务发现)的软件和版本检测操作系统,硬件地址,以及软件版本检测脆弱性的漏洞(Nmap的脚本)Nmap是一个非常普遍的工具,它有命令行界面和图形用户界面。本人包括以下方面的内容:介绍Nmap扫描中的重要参数操作系统检测Nmap使用教程Nmap使用不同的技术来执行扫描,包括:TCP的connect()扫描,TCP反向的ident扫描,FTP反弹扫描等。所有这些扫描的类型有自己的优点和缺点,我们接下来将讨论这些问题。 Nmap的使用取决于目标主机,因为有一个简单的(基本)扫描和预先扫描之间的差异。我们需要使用一些先进的技术来绕过防火墙和入侵检测/防御系统,以获得正确的结果。下面是一些基本的命令和它们的用法的例子:扫描单一的一个主机,命令如下:
代码如下:
#nmap nxadmin.com#nmap 192.168.1.2
扫描整个子网,命令如下:
代码如下:
#nmap 192.168.1.1/24
扫描多个目标,命令如下:
代码如下:
#nmap 192.168.1.2 192.168.1.5
扫描一个范围内的目标,如下:
代码如下:
#nmap 192.168.1.1-100 (扫描IP地址为192.168.1.1-192.168.1.100内的所有主机)
如果你有一个ip地址列表,将这个保存为一个txt文件,和namp在同一目录下,扫描这个txt内的所有主机,命令如下:
代码如下:
#nmap -iL target.txt
如果你想看到你扫描的所有主机的列表,用以下命令:
代码如下:
#nmap -sL 192.168.1.1/24
扫描除过某一个ip外的所有子网主机,命令:
代码如下:
#nmap192.168.1.1/24-exclude192.168.1.1
扫描除过某一个文件中的ip外的子网主机命令
代码如下:
#nmap192.168.1.1/24-excludefilexxx.txt(xxx.txt中的文件将会从扫描的主机中排除)
扫描特定主机上的80,21,23端口,命令如下
代码如下:
#nmap-p80,21,23192.168.1.1
从上面我们已经了解了Nmap的基础知识,下面我们深入的探讨一下Nmap的扫描技术
Tcp SYN Scan (sS) 这是一个基本的扫描方式,它被称为半开放扫描,因为这种技术使得Nmap不需要通过完整的握手,就能获得远程主机的信息。Nmap发送SYN包到远程主机,但是它不会产生任何会话.因此不会在目标主机上产生任何日志记录,因为没有形成会话。这个就是SYN扫描的优势.如果Nmap命令中没有指出扫描类型,默认的就是Tcp SYN.但是它需要root/administrator权限.
代码如下:
#nmap -sS 192.168.1.1
Tcp connect() scan(sT)如果不选择SYN扫描,TCP connect()扫描就是默认的扫描模式.不同于Tcp SYN扫描,Tcp connect()扫描需要完成三次握手,并且要求调用系统的connect().Tcp connect()扫描技术只适用于找出TCP和UDP端口.
代码如下:
#nmap -sT 192.168.1.1
Udp scan(sU)顾名思义,这种扫描技术用来寻找目标主机打开的UDP端口.它不需要发送任何的SYN包,因为这种技术是针对UDP端口的。UDP扫描发送UDP数据包到目标主机,并等待响应,如果返回ICMP不可达的错误消息,说明端口是关闭的,如果得到正确的适当的回应,说明端口是开放的.
代码如下:
#nmap -sU 192.168.1.1
FINscan(sF)
有时候TcpSYN扫描不是最佳的扫描模式,因为有防火墙的存在.目标主机有时候可能有IDS和IPS系统的存在,防火墙会阻止掉SYN数据包。发送一个设置了FIN标志的数据包并不需要完成TCP的握手.
代码如下:
a href="mailto:root@bt:~#nmap-sF192.168.1.8"root@bt:~#nmap-sF192.168.1.8/a/p pStartingNmap5.51at2012-07-0819:21PKTNmapscanreportfor192.168.1.8Hostisup(0.000026slatency).Notshown:999closedportsPORTSTATESERVICE111/tcpopen|filteredrpcbind
FIN扫描也不会在目标主机上创建日志(FIN扫描的优势之一).个类型的扫描都是具有差异性的,FIN扫描发送的包只包含FIN标识,NULL扫描不发送数据包上的任何字节,XMAS扫描发送FIN、PSH和URG标识的数据包.
PINGScan(sP)
PING扫描不同于其它的扫描方式,因为它只用于找出主机是否是存在在网络中的.它不是用来发现是否开放端口的.PING扫描需要ROOT权限,如果用户没有ROOT权限,PING扫描将会使用connect()调用.
代码如下:
#nmap-sP192.168.1.1
版本检测(sV)
版本检测是用来扫描目标主机和端口上运行的软件的版本.它不同于其它的扫描技术,它不是用来扫描目标主机上开放的端口,不过它需要从开放的端口获取信息来判断软件的版本.使用版本检测扫描之前需要先用TCPSYN扫描开放了哪些端口.
代码如下:
#nmap-sV192.168.1.1
Idlescan(sL)
Idlescan是一种先进的扫描技术,它不是用你真实的主机Ip发送数据包,而是使用另外一个目标网络的主机发送数据包.
代码如下:
#nmap-sL192.168.1.6192.168.1.1
Idlescan是一种理想的匿名扫描技术,通过目标网络中的192.168.1.6向主机192.168.1.1发送数据,来获取192.168.1.1开放的端口
有需要其它的扫描技术,如FTPbounce(FTP反弹),fragmentationscan(碎片扫描),IPprotocolscan(IP协议扫描),以上讨论的是几种最主要的扫描方式.
Nmap的OS检测(O)
Nmap最重要的特点之一是能够远程检测操作系统和软件,Nmap的OS检测技术在渗透测试中用来了解远程主机的操作系统和软件是非常有用的,通过获取的信息你可以知道已知的漏洞。Nmap有一个名为的nmap-OS-DB数据库,该数据库包含超过2600操作系统的信息。Nmap把TCP和UDP数据包发送到目标机器上,然后检查结果和数据库对照。
代码如下:
InitiatingSYNStealthScanat10:21Scanninglocalhost(127.0.0.1)[1000ports]Discoveredopenport111/tcpon127.0.0.1CompletedSYNStealthScanat10:21,0.08selapsed(1000totalports)InitiatingOSdetection(try#1)againstlocalhost(127.0.0.1)RetryingOSdetection(try#2)againstlocalhost(127.0.0.1)
上面的例子清楚地表明,Nmap的首次发现开放的端口,然后发送数据包发现远程操作系统。操作系统检测参数是O(大写O)
Nmap的操作系统指纹识别技术:
设备类型(路由器,工作组等)运行(运行的操作系统)操作系统的详细信息(操作系统的名称和版本)网络距离(目标和攻击者之间的距离跳)
如果远程主机有防火墙,IDS和IPS系统,你可以使用-PN命令来确保不ping远程主机,因为有时候防火墙会组织掉ping请求.-PN命令告诉Nmap不用ping远程主机。
代码如下:
#nmap-O-PN192.168.1.1/24
以上命令告诉发信主机远程主机是存活在网络上的,所以没有必要发送ping请求,使用-PN参数可以绕过PING命令,但是不影响主机的系统的发现.
Nmap的操作系统检测的基础是有开放和关闭的端口,如果OSscan无法检测到至少一个开放或者关闭的端口,会返回以下错误:
代码如下:
Warning:OSScanresultsmaybeunreliablebecausewecouldnotfindatleast1openand1closedport
OSScan的结果是不可靠的,因为没有发现至少一个开放或者关闭的端口
这种情况是非常不理想的,应该是远程主机做了针对操作系统检测的防范。如果Nmap不能检测到远程操作系统类型,那么就没有必要使用-osscan_limit检测。
想好通过Nmap准确的检测到远程操作系统是比较困难的,需要使用到Nmap的猜测功能选项,–osscan-guess猜测认为最接近目标的匹配操作系统类型。
代码如下:
#nmap-O--osscan-guess192.168.1.1
下面是扫描类型说明
-sTTCPconnect()扫描:这是最基本的TCP扫描方式。connect()是一种系统调用,由操作系统提供,用来打开一个连接。如果目标端口有程序监听,connect()就会成功返回,否则这个端口是不可达的。这项技术最大的优点是,你勿需root权限。任何UNIX用户都可以自由使用这个系统调用。这种扫描很容易被检测到,在目标主机的日志中会记录大批的连接请求以及错误信息。
-sSTCP同步扫描(TCPSYN):因为不必全部打开一个TCP连接,所以这项技术通常称为半开扫描(half-open)。你可以发出一个TCP同步包(SYN),然后等待回应。如果对方返回SYN|ACK(响应)包就表示目标端口正在监听;如果返回RST数据包,就表示目标端口没有监听程序;如果收到一个SYN|ACK包,源主机就会马上发出一个RST(复位)数据包断开和目标主机的连接,这实际上有我们的操作系统内核自动完成的。这项技术最大的好处是,很少有系统能够把这记入系统日志。不过,你需要root权限来定制SYN数据包。
-sF-sX-sN秘密FIN数据包扫描、圣诞树(XmasTree)、空(Null)扫描模式:即使SYN扫描都无法确定的情况下使用。一些防火墙和包过滤软件能够对发送到被限制端口的SYN数据包进行监视,而且有些程序比如synlogger和courtney能够检测那些扫描。这些高级的扫描方式可以逃过这些干扰。些扫描方式的理论依据是:关闭的端口需要对你的探测包回应RST包,而打开的端口必需忽略有问题的包(参考RFC793第64页)。FIN扫描使用暴露的FIN数据包来探测,而圣诞树扫描打开数据包的FIN、URG和PUSH标志。不幸的是,微软决定完全忽略这个标准,另起炉灶。所以这种扫描方式对Windows95/NT无效。不过,从另外的角度讲,可以使用这种方式来分别两种不同的平台。如果使用这种扫描方式可以发现打开的端口,你就可以确定目标注意运行的不是Windows系统。如果使用-sF、-sX或者-sN扫描显示所有的端口都是关闭的,而使用SYN扫描显示有打开的端口,你可以确定目标主机可能运行的是Windwos系统。现在这种方式没有什么太大的用处,因为nmap有内嵌的操作系统检测功能。还有其它几个系统使用和windows同样的处理方式,包括Cisco、BSDI、HP/UX、MYS、IRIX。在应该抛弃数据包时,以上这些系统都会从打开的端口发出复位数据包。
-sPping扫描:有时你只是想知道此时网络上哪些主机正在运行。通过向你指定的网络内的每个IP地址发送ICMPecho请求数据包,nmap就可以完成这项任务。如果主机正在运行就会作出响应。不幸的是,一些站点例如:microsoft.com阻塞ICMPecho请求数据包。然而,在默认的情况下nmap也能够向80端口发送TCPack包,如果你收到一个RST包,就表示主机正在运行。nmap使用的第三种技术是:发送一个SYN包,然后等待一个RST或者SYN/ACK包。对于非root用户,nmap使用connect()方法。在默认的情况下(root用户),nmap并行使用ICMP和ACK技术。注意,nmap在任何情况下都会进行ping扫描,只有目标主机处于运行状态,才会进行后续的扫描。如果你只是想知道目标主机是否运行,而不想进行其它扫描,才会用到这个选项。
-sUUDP扫描:如果你想知道在某台主机上提供哪些UDP(用户数据报协议,RFC768)服务,可以使用这种扫描方法。nmap首先向目标主机的每个端口发出一个0字节的UDP包,如果我们收到端口不可达的ICMP消息,端口就是关闭的,否则我们就假设它是打开的。有些人可能会想UDP扫描是没有什么意思的。但是,我经常会想到最近出现的solarisrpcbind缺陷。rpcbind隐藏在一个未公开的UDP端口上,这个端口号大于32770。所以即使端口111(portmap的众所周知端口号)被防火墙阻塞有关系。但是你能发现大于30000的哪个端口上有程序正在监听吗?使用UDP扫描就能!cDcBackOrifice的后门程序就隐藏在Windows主机的一个可配置的UDP端口中。不考虑一些通常的安全缺陷,一些服务例如:snmp、tftp、NFS使用UDP协议。不幸的是,UDP扫描有时非常缓慢,因为大多数主机限制ICMP错误信息的比例(在RFC1812中的建议)。例如,在Linux内核中(在net/ipv4/icmp.h文件中)限制每4秒钟只能出现80条目标豢纱锏肾CMP消息,如果超过这个比例,就会给1/4秒钟的处罚。solaris的限制更加严格,每秒钟只允许出现大约2条ICMP不可达消息,这样,使扫描更加缓慢。nmap会检测这个限制的比例,减缓发送速度,而不是发送大量的将被目标主机丢弃的无用数据包。不过Micro$oft忽略了RFC1812的这个建议,不对这个比例做任何的限制。所以我们可以能够快速扫描运行Win95/NT的主机上的所有65K个端口。
-sAACK扫描:这项高级的扫描方法通常用来穿过防火墙的规则集。通常情况下,这有助于确定一个防火墙是功能比较完善的或者是一个简单的包过滤程序,只是阻塞进入的SYN包。这种扫描是向特定的端口发送ACK包(使用随机的应答/序列号)。如果返回一个RST包,这个端口就标记为unfiltered状态。如果什么都没有返回,或者返回一个不可达ICMP消息,这个端口就归入filtered类。注意,nmap通常不输出unfiltered的端口,所以在输出中通常不显示所有被探测的端口。显然,这种扫描方式不能找出处于打开状态的端口。
-sW对滑动窗口的扫描:这项高级扫描技术非常类似于ACK扫描,除了它有时可以检测到处于打开状态的端口,因为滑动窗口的大小是不规则的,有些操作系统可以报告其大小。这些系统至少包括:某些版本的AIX、Amiga、BeOS、BSDI、Cray、Tru64UNIX、DG/UX、OpenVMS、DigitalUNIX、OpenBSD、OpenStep、QNX、Rhapsody、SunOS4.x、Ultrix、VAX、VXWORKS。从nmap-hackers邮件3列表的文档中可以得到完整的列表。
-sRRPC扫描。这种方法和nmap的其它不同的端口扫描方法结合使用。选择所有处于打开状态的端口向它们发出SunRPC程序的NULL命令,以确定它们是否是RPC端口,如果是,就确定是哪种软件及其版本号。因此你能够获得防火墙的一些信息。诱饵扫描现在还不能和RPC扫描结合使用。
-bFTP反弹攻击(bounceattack):FTP协议(RFC959)有一个很有意思的特征,它支持代理FTP连接。也就是说,我能够从evil.com连接到FTP服务器target.com,并且可以要求这台FTP服务器为自己发送Internet上任何地方的文件!1985年,RFC959完成时,这个特征就能很好地工作了。然而,在今天的Internet中,我们不能让人们劫持FTP服务器,让它向Internet上的任意节点发送数据。如同Hobbit在1995年写的文章中所说的,这个协议"能够用来做投递虚拟的不可达邮件和新闻,进入各种站点的服务器,填满硬盘,跳过防火墙,以及其它的骚扰活动,而且很难进行追踪"。我们可以使用这个特征,在一台代理FTP服务器扫描TCP端口。因此,你需要连接到防火墙后面的一台FTP服务器,接着进行端口扫描。如果在这台FTP服务器中有可读写的目录,你还可以向目标端口任意发送数据(不过nmap不能为你做这些)。传递给-b功能选项的参数是你要作为代理的FTP服务器。语法格式为:-busername:password@server:port。除了server以外,其余都是可选的。如果你想知道什么服务器有这种缺陷,可以参考我在Phrack51发表的文章。还可以在nmap的站点得到这篇文章的最新版本。
通用选项这些内容不是必需的,但是很有用。
-P0在扫描之前,不必ping主机。有些网络的防火墙不允许ICMPecho请求穿过,使用这个选项可以对这些网络进行扫描。microsoft.com就是一个例子,因此在扫描这个站点时,你应该一直使用-P0或者-PT80选项。
-PT扫描之前,使用TCPping确定哪些主机正在运行。nmap不是通过发送ICMPecho请求包然后等待响应来实现这种功能,而是向目标网络(或者单一主机)发出TCPACK包然后等待回应。如果主机正在运行就会返回RST包。只有在目标网络/主机阻塞了ping包,而仍旧允许你对其进行扫描时,这个选项才有效。对于非root用户,我们使用connect()系统调用来实现这项功能。使用-PT来设定目标端口。默认的端口号是80,因为这个端口通常不会被过滤。
-PS对于root用户,这个选项让nmap使用SYN包而不是ACK包来对目标主机进行扫描。如果主机正在运行就返回一个RST包(或者一个SYN/ACK包)。
-PI设置这个选项,让nmap使用真正的ping(ICMPecho请求)来扫描目标主机是否正在运行。使用这个选项让nmap发现正在运行的主机的同时,nmap也会对你的直接子网广播地址进行观察。直接子网广播地址一些外部可达的IP地址,把外部的包转换为一个内向的IP广播包,向一个计算机子网发送。这些IP广播包应该删除,因为会造成拒绝服务攻击(例如smurf)。