2020-2021-2 网络对抗技术 20181318 Exp5 信息搜集与漏洞扫描

一、实验目标

  • 掌握信息搜集的最基础技能与常用工具的使用方法。

二、实验内容概述

  • 各种搜索技巧的应用

  • DNS IP注册信息的查询

  • 基本的扫描技术:主机发现、端口扫描、OS及服务版本探测、具体服务的查点(以自己主机为目标)

  • 漏洞扫描:会扫,会看报告,会查漏洞说明,会修补漏洞(以自己主机为目标)

三、基础知识

1. 信息搜集

  • 信息搜集是渗透测试前期要做的重要事项之一。我们需要尽可能多的查找关于目标的信息。

    • 只有我们掌握了目标网站或目标主机足够多的信息之后,渗透测试才更有可能成功。
  • 任务:搜集关于目标机器的一切信息。比如IP地址,开放的服务,开放的端口......

  • 信息收集的方式可以分为两种:主动和被动。

  • 主动信息收集:建立逻辑连接并获取信息,对目标的安全性设置进一步理解。

    • 方法:直接访问、主动扫描技术等,探测目标开放的端口和服务。
    • 优点:能获取更多的信息
    • 缺点:这种流量将流经网站,目标主机可能会记录你的操作记录
  • 被动信息收集:不接触目标,无物理连接。

    • 方法:利用第三方的服务对目标进行访问了解

      • 查询whois信息
        • 假设我们的目标是一个在线的Web服务,那么通过whois查询可以获得它的ip地址,域名信息,子域信息,服务器位置信息等。
      • 数据窃听与分析
      • Google搜索、Shodan搜索等
    • 其他用途:调查取证

    • 优点:行动并不会被目标主机发现

    • 缺点:收集的信息会相对较少

  • 社会工程学:主要是针对人为错误,比如信息以打印输出、电话交谈、电子邮件等形式泄露,进而获取信息。

2.nmap

  • Nmap,最早是Linux下的网络扫描和嗅探工具包。
  • nmap是一个网络连接端扫描软件
    • 主机发现(Host Discovery);
    • 端口扫描(Port Scanning);
    • 版本侦测(Version Detection);
    • 操作系统侦测(Operating System Detection)。

2.1 主机发现

  • 原理:默认情况下,Nmap会发送四种不同类型的数据包来探测目标主机是否在线。

    • ICMP echo request
    • a TCP SYN packet to port 443
    • a TCP ACK packet to port 80
    • an ICMP timestamp request
  • 依次发送四个报文探测目标机是否开启。只要收到其中一个包的回复,那就证明目标机开启。

    • 使用四种不同类型的数据包可以避免因防火墙或丢包造成的判断错误。
  • 通常主机发现并不单独使用,而只是作为端口扫描、版本侦测、OS侦测先行步骤。

  • 而在某些特殊应用(例如确定大型局域网内活动主机的数量),可能会单独专门适用主机发现功能来完成。

  • 主机发现的相关参数如下:

    -sL:简单列出扫描的目标,不进行主机发现。
    -sP/-sn:做ping扫描,只进行主机发现,不进行端口扫描。 
    -Pn/-P0:将所有指定的主机视作开启的,跳过主机发现的过程,直接扫描其他信息。
    -PS/-PA/-PU/-PY:分别是SYN扫描、ACK扫描、UDP扫描、SCTP扫描
    -PE/-PP/-PM:分别是ICMP回显、时间戳、网络掩码发现扫描
    -n/-R: -n表示不进行DNS解析;-R表示总是进行DNS解析。  
    --dns-servers <serv1[,serv2],...>: 指定DNS服务器。  
    --system-dns: 指定使用系统的DNS服务器     
    --traceroute: 追踪每个路由节点  
    
  • 实例:nmap –sn 192.168.1.100-120

    扫描局域网192.168.1.100-192.168.1.120范围内哪些IP的主机是活动的。

2.2端口扫描

  • 端口扫描是Nmap最基本最核心的功能,用于确定目标主机的TCP/UDP端口的开放情况。

  • 默认情况下,Nmap会扫描1000个最有可能开放的TCP端口。

  • Nmap通过探测将端口划分为6个状态:

  • 端口扫描方式选项如下:

    -sS/sT/sA/sW/sM:指定使用 TCP SYN/Connect()/ACK/Window/Maimon scans的方式来对目标主机进行扫描。  
    -sU: 指定使用UDP扫描方式确定目标主机的UDP端口状况。  
    -sN/sF/sX: 指定使用TCP Null, FIN, and Xmas scans秘密扫描方式来协助探测对方的TCP端口状态。  
    --scanflags <flags>: 定制TCP包的flags。  
    -sI <zombiehost[:probeport]>: 指定使用idle scan方式来扫描目标主机(前提需要找到合适的zombie host)  
    -sY/sZ: 使用SCTP INIT/COOKIE-ECHO来扫描SCTP协议端口的开放的情况。  
    -sO: 使用IP protocol 扫描确定目标机支持的协议类型。  
    -b <FTP relay host>: 使用FTP bounce scan扫描方式  
    
  • 端口参数与扫描顺序

    -p <port ranges>: 扫描指定的端口(T代表TCP协议、U代表UDP协议、S代表SCTP协议)
    -F: Fast mode – 快速模式,仅扫描TOP 100的端口  
    -r: 不进行端口随机打乱的操作(如无该参数,nmap会将要扫描的端口以随机顺序方式扫描,以让nmap的扫描不易被对方防火墙检测到)。  
    --top-ports <number>:扫描开放概率最高的number个端口。默认情况下,nmap会扫描最有可能的1000个TCP端口)  
    --port-ratio <ratio>: 扫描指定频率以上的端口。概率大于--port-ratio的端口才被扫描。
    
  • 实例:nmap –sS –sU –top-ports 300 192.168.1.100

    表示使用TCP SYN方式扫描主机192.168.1.100的TCP端口,也扫描其UDP端口,扫描最有可能开放的300个端口(TCP和UDP分别有300个端口)。

3.openvs

  • 简介:OpenVAS是开放式漏洞评估系统,也可以说它是一个包含着相关工具的网络扫描器。其核心部件是一个服务器,包括一套网络漏洞测试程序,可以检测远程系统和应用程序中的安全问题。

四、实验过程

(一)各种搜索技巧的应用

1.搜索网址目录结构

  • 原理:利用MSF下dir_scanner网页目录结构扫描辅助模块,暴力猜解,获取网站目录结构。参数设置如下:

    • THREADS:攻击使用的线程数。数值越大,力度越大;数值小不容易被发现
    • RHOSTS:目标网址或IP地址。
  • 方法:在kali机中,输入以下指令

    msfconsole
    use auxiliary/scanner/http/dir_scanner
    set THREADS 20
    set RHOSTS www.baidu.com
    exploit
    
  • 可以找到以下目录

    image

2.检测特定类型的文件

  • 原理:有些网站会链接通讯录,订单等敏感的文件,可以进行针对性的查找

  • 相关查询参数如下:

    • filetype:能对搜索结果的文件类型进行限定,格式为 检索词 filetype:文件类型
    • -:能在检索结果中获取检索词的补集,格式为 检索词 -词语
    • site:能限制检索结果的来源,格式为 检索词 site:限制域名
      • 不要在 :后的域名中输入“http:”和“www.”
    • inurl: 能在网址中进行搜索,格式为 检索词inurl:检索词
    • 空格:表示布尔逻辑中的交集(and)关系,使用格式为 关键词1 关键词2
    • |:表示布尔逻辑中的或者(or)关系,使用格式为 关键词1 | 关键词2
    • 高级搜索界面的入口在搜索引擎首页右上角“设置”->“高级搜索”
  • 方法:使用 site:edu.cn filetype:xls 关键词 来搜索与关键词有关的XLS文件,此处我们限定了结果的来源为edu.cn

  • 举例:我们使用site:edu.cn filetype:xls 学号

    image

  • 出现上图中满足要求的链接,我们任选其中一个,浏览器会自动下载该xls文件。

    image

    • 打开该文件,发现学生的信息毫无遮掩的显示在我们面前!

    使用 site:baidu.com filetype:xls 北京电子科技学院 ,结果如下:

    image

    image

3.使用traceroute命令进行路由侦查

  • 原理:traceroute 命令利用ICMP协议来检测发出数据包的主机到目标主机之间所经过的路由器。它通过设置探测包的 TTL(存活时间)值,跟踪数据包到达目标主机所经过的网关或路由器的数量,并监听来自网关 ICMP 的应答。

    • 每当数据包经过一个路由器,其TTL就会减1。当TTL=0时,主机便取消数据包,并发送一个ICMP 超时报文给原数据包的发出者。
    • 原数据包的发出者从超时报文中即可提取出数据包所经过的第一个网关地址。然后又发出一个 TTL=2 的 ICMP 数据包,可获得第二个网关地址。
    • 依次递增 TTL 便获取了沿途所有网关地址。
  • 我们以侦查百度为例。在cmd中输入tracert www.baidu.com

    image

  • 参数解释:从左到右的5条信息分别代表了:

    • TTL
    • 探测数据包向每个网关发送3个数据后,网关响应后的返回时间(单位:ms)
    • 途经路由器的IP地址,如果有主机名,还会包含主机名
    • 其中带有星号(*)的信息说明是此ICMP包返回时间超时。
      • 原因:可能是防火墙封掉了ICMP的返回信息

4.使用搜索引擎

Google Hacking

  • GHDB(Google Hacker DataBase,谷歌黑客数据库),是HTML / JavaScript的封装应用,使用的先进的JavaScript技术搜索黑客所需的信息,包含了大量使用Google从事渗透的搜索字符串,拥有很多常用的模块。

  • 进入谷歌黑客数据库,可以查看到最新的搜索方法目录,可以根据这些提示进行针对性搜索

    image

  • shellcode模块,包含了我们见到的大部分shellcode

    image

ZoomEye

  • 国内互联网安全厂商知道创宇开放了他们的海量数据库,对之前沉淀的数据进行了整合、整理,打造了一个名符其实的网络空间搜索引擎ZoomEye,该搜索引擎的后端数据计划包括两部分:

    • 网站组件指纹:包括操作系统,Web服务,服务端语言,Web开发框架,Web应用,前端库及第三方组件等等。
    • 主机设备指纹:结合NMAP大规模扫描结果进行整合。

    image

  • 利用ZoomEye查找中国的教育网站,结果如下:

    image

    image

(二)DNS IP注册信息的查询

1.whois查询

  • 功能:通过whois来实现对域名信息的查询。

    • whois就是一个用来查询域名是否已经被注册,以及注册域名的详细信息的数据库
  • 方法:在kali中进入root模式,在终端输入 whois qq.com 可查询到该域名的3R注册信息,包括注册人的姓名、组织和城市等信息。

  • 注意:进行whois查询时去掉www等前缀,因为注册域名时通常会注册一个上层域名,子域名由自身的域名服务器管理,在whois数据库中可能查询不到。

    image

2.nslookup,dig域名查询

nslookup

  • 功能:用于查询DNS解析服务器保存的Cache的结果(查询域名解析是否正常)

    • 结果并不一定是准确的
  • 方法:在终端输入nslookup qq.com

  • 注意:我们采用默认的DNS服务器进行查询,但是每个DNS服务器查询到的IP可能不相同,也可能会查询出来多个结果

    image

dig

  • 功能:从官方DNS服务器上查询精确的结果。

  • 方法:输入 dig qq.com ,结果如下:

    image

  • 查询选项:dig 提供查询选项号,它影响搜索方式和结果显示。每个查询选项被带前缀(+)的关键字标识。常用查询选项如下:

    • +[no]tcp :查询域名服务器时使用 [不使用] TCP。缺省行为是使用 UDP,除非是 AXFR 或 IXFR 请求,才使用 TCP 连接。
    • +[no]search :使用 [不使用] 搜索列表或 resolv.conf 中的域伪指令(如果有的话)定义的搜索列表。缺省情况不使用搜索列表。
    • +[no]trace :切换为待查询名称从根名称服务器开始的代理路径跟踪。缺省情况不使用跟踪。一旦启用跟踪,dig 使用迭代查询解析待查询名称。它将按照从根服务器的参照,显示来自每台使用解析查询的服务器的应答。
    • +[no]short :提供简要答复。缺省值是以冗长格式显示答复信息。
    • +[no]stats :该查询选项设定显示统计信息:查询进行时,应答的大小等等。缺省显示查询统计信息。

    image

    image

3.IP2Location 地理位置查询

www.maxmind.com

  • 该网站可以根据IP查询地理位置。

  • 方法:

    • 首先在cmd中使用ping命令获取所要查询网站的ip,ping qq.com

    image

    image

    • 点击go查看结果,我们发现qq.com服务器的所在地为:中国辽宁

    image

www.ip-adress.com

  • 这个网站可以查询到更详细的关于IP的信息

  • 方法:打开该网站,页面首先会显示本机的IP地址。在搜索框输入要查询的ip地址,点击搜索,即可得到更加详细的信息

    image

    image

4. IP2反域名查询

shodan搜索引擎

  • 该网站可以进行反域名查询,可以搜索到该IP的地理位置、服务占用端口号,以及提供的服务类型。

  • 方法:打开该网站,在搜索框输入要查询的ip地址,点击搜索,即可得到可以看到地理位置,端口号和提供的服务具体信息

    image

(三)基本的扫描技术

1.主机发现

(1)ping命令

  • ping命令可以发送ICMP数据包探测主机是否在线

  • 在cmd中输入 ping www.qq.com

    image

(2)metasploit中的arp_sweep模块和 udp_sweep 模块

  • Metasploit 中提供了一些辅助模块可用于活跃主机的发现,这些模块位于Metasploit 源
    码路径的modules/auxiliary/scanner/discovery/ 目录中

  • arp_sweep:使用ARP请求枚举本地局域网络中的所有活跃主机。

  • arp_sweep的步骤如下:

    sudo msfconsole
    use auxiliary/scanner/discovery/arp_sweep    //进入arp_sweep 模块
    set RHOSTS 192.168.43.0/24   //用set进行win10主机段设置
    set THREADS 50   //加快扫描速度
    show options   //查询模块参数
    run //执行run进行扫描
    

    image

由检测结果可以看出,该网段内有3台主机处于活跃状态。

  • udp_sweep:通过发送UDP数据包探查指定主机是否舌跃,发现主机上的UDP服务,还可以获得主机名称信息。

  • udp_sweep的步骤如下:

    sudo msfconsole
    use auxiliary/scanner/discovery/udp_sweep    //进入arp_sweep 模块
    set RHOSTS 192.168.43.110/24   //此处为win10主机地址
    set THREADS 50   //加快扫描速度
    show options   //查询模块参数
    run //执行run进行扫描
    

    image

由检测结果可以看出查询主机处于活跃状态,还可以得到主机名称、端口号等信息。

(3)nmap -sn

  • 原理:nmap -sn 可以用来探测某网段的活跃主机

  • 在root模式下,输入 nmap -sn 192.168.43.0/24(探测win10主机所在网段)

    image
    该检测结果显示该网段内有3台主机处于活跃状态

2.端口扫描

(1)nmap -p <port_range>

  • 输入命令 nmap -sS -p 1-1024 -v 192.168.43.110

    解释:以TCP SYN的方式扫描win10主机的TCP端口,-p是指定端口范围,-v是详细信息、

    image

  • 由图可以得到,有1018个端口处于关闭状态,135、139、443、445、902、912这六个端口是打开状态。

(2)nmap -sU

  • nmap -sU:对UDP端口进行探测

  • 输入命令 nmap -sU 192.168.43.110

    解释:扫描win10主机的UDP端口状态

    image

  • 由图可以得到,默认扫描的这1000个UDP端口均处于Closed|filtered状态

(3)MSF中的端口扫描模块

  • TCP 端口扫描

    • MSF模块:auxiliary/scanner/portscan/tcp
  • TCP SYN 扫描

    • MSF模块:auxiliary/scanner/portscan/syn
    • 不会完成TCP三次握手
      • SYN扫描速度更快
      • 躲避防火墙和入侵检测系统的检测。
  • 以TCP 端口扫描为例

    • 设置模块 use auxiliary/scanner/portscan/tcp
    • 设置扫描地址 set RHOSTS 192.168.43.110
    • 设置扫描端口范围set PORTS 0-1024
    • 进行扫描exploit

    image

    扫描结果和(1)中的一致,有6个端口处于打开状态。

3.操作系统版本检测

(1)nmap -O

  • 原理:使用Nmap对目标的操作系统进行识别,获取目标机的操作系统和服务版本等信息

  • 方法:在root模式下,输入命令 nmap -O 192.168.43.110

    image

    探测结果为Windows 10,结果正确!

(2)nmap -sV

  • 原理:查看目标主机的详细服务信息

  • 在root模式下,输入命令 nmap -sV 192.168.43.110

    image

  • NetBIOS,即网络基本输入/输出系统协议,是一种在局域网上的程序可以使用的应用程序编程接口(API),为程序提供了请求低级服务的统一的命令集,作用是为了给局域网提供网络以及其他特殊功能,几乎所有的局域网都是在NetBIOS协议的基础上工作的。

    • 从图中我们可以得到:netbios服务是开启的。

4.具体服务的查点(以自己主机为目标)

  • 每个具体服务的探测都对应一个msf模块,可以在modules/auxiliary/scanner中进行搜索

(1)telnet

  • telnet命令用于登录远程主机,对远程主机进行管理。

  • 步骤:

    - msfconsole    //登录msf控制台
    - use auxiliary/scanner/telnet/telnet_version    //进入telnet模块
    - set RHOSTS 192.168.43.110    //扫描win10主机
    - set THREADS 50    //提高查询速度
    - run
    

    image

    由图可以得出,对win10主机的远程登录被拒绝。

(2)SSH

  • SSH是标准的网络协议,可用于大多数UNIX操作系统,能够实现字符界面的远程登录管理,它默认使用22号端口,采用密文的形式在网络中传输数据,相对于通过明文传输的Telnet,具有更高的安全性。

  • SSH提供了口令和密钥两种用户验证方式,这两者都是通过密文传输数据的。

  • ssh版本探测步骤如下:

    - msfconsole    //登录msf控制台
    - use auxiliary/scanner/ssh/ssh_version    //进入ssh版本探测模块
    - set RHOSTS 192.168.43.110    //扫描win10主机
    - set THREADS 50    //提高查询速度
    - run
    

    image

(3)Oracle数据库服务

  • 步骤如下:

    - msfconsole    //登录msf控制台
    - use auxiliary/scanner/oracle/tnslsnr_version    //进入oracle数据库模块
    - set RHOSTS 192.168.43.110    //扫描win10主机
    - set THREADS 50    //提高查询速度
    - run
    

    image

(四)漏洞扫描:会扫,会看报告,会查漏洞说明,会修补漏洞(以自己主机为目标)

(1)安装gvm,步骤如下:

  • 更新系统:
    apt-get update
    apt-get upgrade
    apt-get dist-upgrade
    
    由于openvas在kali新版本下已被取代(执行openvas-start等命令都会报没有该命令),所以直接安装gvm
    
    apt-get install gvm
    gvm-setup   初始化,成功之后会有用户名和密码,可以截图记录!
    gvm-check-setup    检验初始化是否完全完成
    

    image
    (2)运行gvm

  • 由于前面初始化gvm的时候没有记住用户名和密码,所以在这里重新创建用户。

    sudo runuser -u _gvm -- gvmd --user=admin --new-password=admin

    image

  • 打开kali机的火狐浏览器,在终端中输入gvm-start,开启gvm

  • 输入网址或者直接点击链接https:127.0.0.1:9392。点击Advanced,然后接受风险并继续

    image

  • 点击scan->Tasks,找到一个类似仙女棒的东东,Task Wizard

    image

    image

  • 输入win10主机的ip地址,点击start scan

    image

(3)扫描结束,查看报告信息

  • 扫描结束后会显示Done,点击Full and Fast查看详细信息

    image

  • NVT Families是漏洞库,我们可以看到,扫描win10主机后,有57个漏洞,我们选择Buffer Overflow缓冲区溢出漏洞进行分析

    image

    image

    我们可以看到在这个漏洞族中有很多漏洞,且漏洞的危险等级不一样,我们选择一个危险等级比较高(红色)的看看漏洞说明

    image

  • Summary描述该漏洞:说明该漏洞位于该主机运行3CTftpSvc TFTP的服务器中,容易出现缓冲区溢出漏洞。

  • Impact是该漏洞可能造成的后果:成功利用此漏洞将允许攻击者导致应用程序崩溃,拒绝向合法用户提供进一步服务。

  • Solution给出解决方法:无法修复。自该漏洞被披露以来,至少一年内没有已知的解决方案可用。很可能不会再提供了。一般的解决方案是升级到一个较新的版本,禁用相应的功能,删除生产或用另一种产品替换产品。

  • 换一个中毒危险漏洞来看看

    image

  • Summary描述该漏洞:此主机安装有AbsoluteFTP,并且易于缓冲溢出漏洞。

  • Impact是该漏洞可能造成的后果:成功利用此漏洞可使远程攻击者执行应用程序上下文中的任意代码。失败的攻击可能导致拒绝服务情况。

  • Solution给出解决方法:无法修复。自该漏洞被披露以来,至少一年内没有已知的解决方案可用。很可能不会再提供了。一般的解决方案是升级到一个较新的版本,禁用相应的功能,删除生产或用另一种产品替换产品。

五、实验后问题回答

1.哪些组织负责DNS,IP的管理?

  • 全球根服务器均由美国政府授权的ICANN统一管理,负责全球的域名根服务器、DNS和IP地址管理

  • ICANN——互联网名称与数字地址分配机构,是一个非营利性的国际组织,负责在全球范围内对互联网唯一标识符系统及其安全稳定的运营进行协调,包括互联网协议(IP)地址的空间分配、协议标识符的指派、通用顶级域名(gTLD)以及国家和地区顶级域名(ccTLD)系统的管理、以及根服务器系统的管理。

    • 根据ICANN的章程规定,它设立三个支持组织,从三个不同方面对Internet政策和构造进行协助,检查,以及提出建议。这三个组织分别是:

      • 地址支持组织(ASO):负责IP地址系统的管理。

      • 域名支持组织(DNSO):负责互联网上的域名系统(DNS)的管理。

      • 协议支持组织(PSO):负责涉及Internet协议的唯一参数的分配。此协议是允许计算机在因特网上相互交换信息,管理通讯的技术标准。

  • 全球根域名服务器:绝大多数在欧洲和北美(全球13台,用A~M编号),中国仅拥有镜像服务器(备份)。

  • 全球一共有5个地区性注册机构:

    • ARIN:主要负责北美地区业务
    • RIPE:主要负责欧洲地区业务
    • APNIC:主要负责亚太地区业务
    • LACNIC:主要负责拉丁美洲美洲业务
    • AfriNIC:负责非洲地区业务

2.什么是3R信息?

  • 注册人(Registrant)、注册商(Registrar)、官方注册局(Registry)

3.评价下扫描结果的准确性。

做完整个实验,扫描的结果相对准确,可以为我们提供所需要的信息;但是不同的扫描方法对应的结果会有一些出入,可能是不同扫描器的侧重点不一样。详细记录请看实验内容。

六、实验中的问题与解答

1.在使用msf中的arp_sweep模块时,会有下图中的报错

image

解决方法:使用root权限登录msf控制台

2.在使用openvas(gvm)进行扫描时,当要查看扫描结果的详细信息时,会出现下图中的错误,提示需要SCAP 数据库

image

在讨论区中和同学们进行了讨论,参考了同学们的意见,最后还是没有解决,于是很无奈的拷了一台虚拟机。

3.在使用gvm-start开启gvm服务的时候,会出现端口占用的情况

image

原因:这是因为我们初始化完成后默认开启了gvm服务,所以当我们再次使用gvm-start时会出现端口占用

解决方法:用gvm-stop关闭默认开启的gvm,再输入gvm-start就可以成功开启服务。

七、实验心得

本次实验与前几次实验对比,难度不大,最难的地方就是openvas的安装。openvas在kali新版本下已被取代,执行openvas-start、openvas-feed-update命令会报错,显示没有该命令,所以在安装时直接安装gvm即可。在参考课题负责人和同学 的博客时,没有留意要记住用户名和密码,所以后续使用相关命令重新设置了用户名和密码。我的电脑最奇怪的是,在对win10主机扫描完成后,要查看详细信息时,会告诉我需要SCAP数据库,我表示一脸懵。在进行check时很顺利也没有报错,为什么会出现这种问题呢?操作了n天之后,还是没有成功,于是拷了一台虚拟机。

通过这次实验,让我清楚地认识到信息收集对于渗透测试的重要性,同时也让我对当前的信息泄露产生了恐惧,我们的个人信息、主机的操作系统、版本、网络服务、端口等信息竟然都可以被轻松的扫描出来,所以我们一定要注重网络环境中的信息保护!!

原文地址:https://www.cnblogs.com/jjy-666/p/14670849.html