CTF学习之0基础入门笔记

Posted Autumn_Hibiscus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CTF学习之0基础入门笔记相关的知识,希望对你有一定的参考价值。

ctf基本入门,从基本知识开始,本文是作者的学习计划和笔记,欢迎参考和交流

文章目录


前言

随着一系列新型的互联网产品的产生,基于Web环境的互联网应用越来越广泛

Web业务的迅速发展也引起黑客们的强烈关注,接踵而至的就是Web安全威胁的凸显。

黑客利用网站操作系统的漏洞和Web服务程序的SQL注入漏洞等得到Web服务器的控制权限,轻则篡改网页内容,重则窃取重要内部数据,更为严重的则是在网页中植入恶意代码,使得网站访问者受到侵害。这也使得越来越多的用户关注应用层的安全问题,对Web应用安全的关注度也逐渐升温。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Web应用程序的发展历程

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

1、静态内容阶段

在这个时候,Web 由大量的静态 html 文档组成,其中大多是一些学术论文。Web 服务器可以被看作是支持超文本的共享文件服务器

2、CGI 程序阶段

Web 服务器增加了一些编程 API。通过这些 API 编写的应用程序,可以向客户端提供一些动态变化的内容。这里相当于客户不仅可以看,还可以调用其中的程序

也就是放置在服务器上的一段可执行程序。作为HTTP服务器的时候,客户端可以通过GET或者POST请求来调用这可执行程序。

3、脚本语言阶段

服务器端出现了 ASP、php、JSP、ColdFusion 等支持 session 的脚本语言技术,浏览器端出现了 Java Applet、javascript 等技术。使用这些技术,可以提供更加丰富的动态内容。

允许客户端的JavaScript脚本为局部页面提供请求服务,然后可以在无需回到服务器情况下动态刷新部分页面

4、瘦客户端应用阶段

在服务器端出现了独立于 Web 服务器的应用服务器

同时出现了 Web MVC 开发模式,各种 Web MVC 开发框架逐渐流行,并且占据了统治地位。基于这些框架开发的 Web 应用,通常都是瘦客户端应用,因为它们是在服务器端生成全部的动态内容。

5、RIA 应用阶段

出现了多种 RIA(Rich Internet Application)技术(丰富互联网程序,具有高度互动性、丰富用户体验以及功能强大的客户端),大幅改善了 Web 应用的用户体验。

其具有丰富的数据模型,丰富的界面元素。

应用最为广泛的 RIA 技术是 DHTML+Ajax。Ajax 技术支持在不刷新页面的情况下动态更新页面中的局部内容。同时诞生了大量的 Web 前端 DHTML 开发库。

6、移动 Web 应用阶段

在这个阶段,出现了大量面向移动设备的 Web 应用开发技术。除了 androidios、Windows Phone 等操作系统平台原生的开发技术之外,基于 HTML5 的开发技术也变得非常流行。

从以上可以看出,Web 从最初其设计者所构思的主要支持静态文档的阶段,逐渐变得越来越动态化。Web 应用的交互模式,变得越来越复杂,web开发是大势所趋。

二、常见安全隐患说明

首先我们都知道,黑客分为两种,一种是社工类黑客,一种是技术类黑客,其中社工类黑客最常见也最防不胜防。

并且,大多数web应用程序并不安全,还是要特别注意以下漏洞,这也是我们需要特别防范的,这里只是进行一个介绍,后期会针对这些漏洞进行讲解。

1、不完善的身份验证信息

这类漏洞主要包括应用程序登录机制中的各种缺陷,可能会使攻击者破解保密性不强的密码、发动蛮力攻击或者完美避开登录。

2、不完善的访问控制措施

这类漏洞涉及的情况包括:应用程序无法为数据和功能提供全面保护,攻击者可以查看其他用户保存在服务器里面的敏感信息,或者执行一些特权操作。

3、SQL注入

通过这个漏洞,攻击者提交专门设计的输入,干扰应用程序与后端数据库的交互活动。攻击者能够从应用程序里提取任何数据、破坏其逻辑结构,或者在数据库服务器上执行命令。

4、跨站点脚本

攻击者可以利用这一漏洞攻击应用程序的其他用户、访问其信息、代表他们执行未授权的工作,或者向其发动攻击。

5、信息泄露

攻击者利用应用程序泄露的敏感信息,通过有缺陷的错误处理或者其他攻击行为攻击应用程序。
比如可以通过访问的网页,爬取网站信息。

6、跨站点请求伪造

攻击者可以利用这类漏洞,诱使用户无意中是用自己的用户权限地应用程序执行操作。恶意Web站点可以利用该漏洞,通过受害用户与应用程序进行交互,执行用户并不打算执行的操作。
web 服务器(特卡--CPU资源被占用)-->用户量访问量大-->web服务代码中有病毒代码信息(可能外部植入)

7、弱口令

攻击者可以利用弱口令(系统登录口令的设置强度不高,容易被攻击者猜到或破解)漏洞,获取合法用户的权限,从而能够查看用户的敏感信息,还有可以进行钓鱼等操作,甚至可以破解管理员的密码从而能够拿到管理员的权限,通过查找网站是否还有其它危害较大的漏洞,进而控制整个站点。

8、任意文件上传

攻击者的主要是把一些恶意代码上传到要攻击的系统中。然后,攻击者只需要找到一种方法来让代码被执行即可完成攻击,极大可能造成主机系统失陷、文件系统或数据库过载、被作为攻击后端系统的跳板机等。

9、远程代码执行漏洞

攻击者直接向后台服务器远程注入操作系统命令或代码,从而控制后台系统,盗取各种信息。

其实,我们的网页出现问题,被攻击,很大一部分的原因是:

1、不成熟的安全意识
2、独立开发(应用程序和第三方组件自定义或拼接在一起,很可能包含独有的缺陷)
欺骗性的简化(编写功能性代码与编写安全代码存在巨大的差异
4、逐渐发展起来的威胁(随着网络安全的发展,黑客攻击也在提升)
5、资源与时间的限制(把功能放在主要位置忽视掉不明显的安全问题)
6、技术上强其所难(开发人员沿用之前的技术来满足新的需求,没有什么大的变化)
7、对功能的需求不断增强(添加一些不在能力范围之内或者不必要的功能,实际上增大了该站点的受攻击可能性)
……

总结

最后,这里提供各种提交漏洞,学习的网站:

1、腾讯:http://security.tencent.com
2、网易: http://aq.163.com
3、京东: http://security.jd.com
4、百度: http://sec.baidu.com
5、Sebug: http://sebug.net/
6、补天:https://www.butian.com
漏洞银行:https://www.bugbank.cn
7、freebuf:http://www.freebuf.com/
8、wooyun 镜像: http://www.anquan.us/
9、全球黑客攻防学习站点: https://link-base.org/
10、安全圈:https://www.anquanquan.info/

小伙伴们可以学习,看一看。

Netty笔记2-Netty学习之NIO基础

Netty学习之NIO基础

本博客是根据黑马程序员Netty实战学习时所做的笔记

可先参考博客 [Java NIO](https://nyimac.gitee.io/2020/11/30/Java NIO/)

non-blocking io:非阻塞IO

一、三大组件简介

Channel与Buffer

Java NIO系统的核心在于:通道(Channel)和缓冲区(Buffer)

通道表示打开到 IO 设备(例如:文件、套接字)的连接。若需要使用 NIO 系统,需要获取用于连接 IO 设备的通道以及用于容纳数据的缓冲区。然后操作缓冲区,对数据进行处理

简而言之,通道负责传输,缓冲区负责存储

常见的Channel有以下四种,其中FileChannel主要用于文件传输,其余三种用于网络通信

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

Buffer有以下几种,其中使用较多的是ByteBuffer

  • ByteBuffer
    • MappedByteBuffer
    • DirectByteBuffer
    • HeapByteBuffer
  • ShortBuffer
  • IntBuffer
  • LongBuffer
  • FloatBuffer
  • DoubleBuffer
  • CharBuffer

1.1 Selector

在使用Selector之前,处理socket连接还有以下两种方法

多线程版设计

为每个连接分别开辟一个线程,分别去处理对应的socket连接

⚠️这种方法存在以下几个问题【餐馆,服务员&客人】

  • 内存占用高
    • 每个线程都需要占用一定的内存,当连接较多时,会开辟大量线程,导致占用大量内存
  • 线程上下文切换成本高
  • 只适合连接数少的场景
    • 连接数过多,会导致创建很多线程,从而出现问题

线程池版设计

使用线程池,让线程池中的线程去处理连接

⚠️线程池版缺点

  • 阻塞模式下,线程仅能处理一个连接

    • 线程池中的线程获取任务(task)后,只有当其执行完任务之后(断开连接后),才会去获取并执行下一个任务
    • 若socke连接一直未断开,则其对应的线程无法处理其他socke连接
  • 仅适合短连接场景

    • 短连接即建立连接发送请求并响应后就立即断开,使得线程池中的线程可以快速处理其他连接

Selector版设计

selector 的作用就是配合一个线程来管理多个 channel(fileChannel因为是阻塞式的,所以无法使用selector),获取这些 channel 上发生的事件,这些 channel 工作在非阻塞模式下,当一个channel中没有执行任务时,可以去执行其他channel中的任务。适合连接数多,但流量较少的场景

若事件未就绪,调用 selector 的 select() 方法会阻塞线程,直到 channel 发生了就绪事件。这些事件就绪后,select 方法就会返回这些事件交给 thread 来处理

1.2 ByteBuffer

使用案例

使用方式

  • 向 buffer 写入数据,例如调用 channel.read(buffer)

  • 调用 flip() 切换至模式

    • flip会使得buffer中的limit变为position,position变为0
  • 从 buffer 读取数据,例如调用 buffer.get()

  • 调用 clear() 或者compact()切换至模式

    • 调用clear()方法时position=0,limit变为capacity
    • 调用compact()方法时,会将缓冲区中的未读数据压缩到缓冲区前面
  • 重复以上步骤

使用ByteBuffer读取文件中的内容

public class TestByteBuffer 
    public static void main(String[] args) 
        // 获得FileChannel
        try (FileChannel channel = new FileInputStream("stu.txt").getChannel()) 
            // 获得缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(10);
            //从channel读取数据,向buffer写
            int hasNext = 0;
            StringBuilder builder = new StringBuilder();
            while((hasNext = channel.read(buffer)) > 0) //【“多次”从缓冲区读取】
                // 切换【读】模式 limit=position, position=0
                buffer.flip();
                // 当buffer中还有数据时,获取其中的数据
                while(buffer.hasRemaining()) 
                    builder.append((char)buffer.get());
                
                // 切换【写】模式 position=0, limit=capacity
                buffer.clear();
            
            System.out.println(builder.toString());
         catch (IOException e) 
        
    

打印结果

0123456789abcdef

核心属性

字节缓冲区的父类Buffer中有几个核心属性,如下

// Invariants: mark <= position <= limit <= capacity
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;   //读写指针
  • capacity:缓冲区的容量。通过构造函数赋予,一旦设置,无法更改
  • limit:缓冲区的界限。位于limit 后的数据不可读写。缓冲区的限制不能为负,并且不能大于其容量
  • position下一个读写位置的索引(类似PC)。缓冲区的位置不能为负,并且不能大于limit
  • mark:记录当前position的值。position被改变后,可以通过调用reset() 方法恢复到mark的位置。

一开始

写模式下,position 是写入位置,limit 等于容量,下图表示写入了 4 个字节后的状态

flip 动作发生后,position 切换为读取位置,limit 切换为读取限制

读取 4 个字节后,状态

clear 动作发生后,状态

compact 方法,是把未读完的部分向前压缩,然后切换至写模式。d后面可以写

核心方法

rewind()方法

  • 该方法只能在读模式下使用
  • rewind()方法后,会恢复position、limit和capacity的值,变为进行get()前的值

clean()方法

  • clean()方法会将缓冲区中的各个属性恢复为最初的状态,position = 0, capacity = limit
  • 此时缓冲区的数据依然存在,处于“被遗忘”状态,下次进行写操作时会覆盖这些数据

mark()和reset()方法

mark 是在读取时,做一个标记,即使 position 改变,只要调用 reset 就能回到 mark 的位置

注意:rewind 和 flip 都会清除 mark 位置

compact()方法

  • compact会把未读完的数据向前压缩,然后切换到写模式
  • 数据前移后,原位置的值并未清零,写时会覆盖之前的值

clear() VS compact()

clear只是对position、limit、mark进行重置,而compact在对position进行设置,以及limit、mark进行重置的同时,还涉及到数据在内存中拷贝(会调用array)。**所以compact比clear更耗性能。**但compact能保存你未读取的数据,将新数据追加到为读取的数据之后;而clear则不行,若你调用了clear,则未读取的数据就无法再读取到了

所以需要根据情况来判断使用哪种方法进行模式切换

方法调用及演示

调用ByteBuffer的方法

public class TestByteBuffer 
    public static void main(String[] args) 
        ByteBuffer buffer = ByteBuffer.allocate(10);
        // 向buffer中写入1个字节的数据
        buffer.put((byte)97);
        // 使用工具类,查看buffer状态
        ByteBufferUtil.debugAll(buffer);

        // 向buffer中写入4个字节的数据
        buffer.put(new byte[]98, 99, 100, 101);
        ByteBufferUtil.debugAll(buffer);

        // 获取数据
        buffer.flip();
        ByteBufferUtil.debugAll(buffer);
        System.out.println(buffer.get());
        System.out.println(buffer.get());
        ByteBufferUtil.debugAll(buffer);

        // 使用compact切换模式
        buffer.compact();
        ByteBufferUtil.debugAll(buffer);

        // 再次写入
        buffer.put((byte)102);
        buffer.put((byte)103);
        ByteBufferUtil.debugAll(buffer);
    

运行结果

// 向缓冲区写入了一个字节的数据,此时postition为1
+--------+-------------------- all ------------------------+----------------+
position: [1], limit: [10]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 61 00 00 00 00 00 00 00 00 00                   |a.........      |
+--------+-------------------------------------------------+----------------+

// 向缓冲区写入四个字节的数据,此时position为5
+--------+-------------------- all ------------------------+----------------+
position: [5], limit: [10]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 61 62 63 64 65 00 00 00 00 00                   |abcde.....      |
+--------+-------------------------------------------------+----------------+

// 调用flip切换模式,此时position为0,表示从第0个数据开始读取
+--------+-------------------- all ------------------------+----------------+
position: [0], limit: [5]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 61 62 63 64 65 00 00 00 00 00                   |abcde.....      |
+--------+-------------------------------------------------+----------------+
// 读取两个字节的数据             
97
98
            
// position变为2             
+--------+-------------------- all ------------------------+----------------+
position: [2], limit: [5]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 61 62 63 64 65 00 00 00 00 00                   |abcde.....      |
+--------+-------------------------------------------------+----------------+
             
// 调用compact切换模式,此时position及其后面的数据被压缩到ByteBuffer前面去了
// 此时position为3,会覆盖之前的数据             
+--------+-------------------- all ------------------------+----------------+
position: [3], limit: [10]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 63 64 65 64 65 00 00 00 00 00                   |cdede.....      |
+--------+-------------------------------------------------+----------------+
             
// 再次写入两个字节的数据,之前的 0x64 0x65 被覆盖         
+--------+-------------------- all ------------------------+----------------+
position: [5], limit: [10]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 以上是关于CTF学习之0基础入门笔记的主要内容,如果未能解决你的问题,请参考以下文章

Scala入门学习之包类与对象

ctf入门怎么弄啊?

WorkerMan 入门学习之基础教程-Timer类的使用

机器学习之概率统计基础,机器学习学习笔记----07

机器学习之概率统计基础,机器学习学习笔记----08

python学习之网络编程基础