深入浅出sql注入之sqlite

之前的文章写的太长了,感觉打开看的时候加载很慢,所以打算分章节去写了

sqlite基础知识

基础知识参考:菜鸟教程

什么是sqlite?

SQLite 是一个轻量级的关系型数据库管理系统(RDBMS),它以 C 语言编写,SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。

关于sqlite的命令,还是跟其他数据库一样,有DDL,DML,DQL三种命令

image-20250210093129451

和mysql一样,我们先学习一些基础语句

Sqlite服务搭建

这次测试我就放Windows里面测了,这样方便些

先去SQLite下载Windows版本的二进制文件,需要下载一个sqlite-tools-win-x64-3500400.zipsqlite-dll-win-x64-3500400.zip

  • sqlite-tools-win-x64-*.zip —— 包含 sqlite3.exe 命令行工具(推荐用于日常管理数据库)。
  • 可选:sqlite-dll-win-x64-*.zip —— 包含 DLL,用于程序中调用 SQLite。

然后我们解压两个二进制文件,并将当前文件夹添加到PATH中

并在命令行中进行验证

1
2
3
4
5
6
C:\Users\23232>sqlite3
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>

出现版本号以及命令行界面,就代表安装成功了

sqlite命令

介绍几个sqlite比较重要的命令

首先就是.help命令,该命令可以获取所有的点命令及其介绍

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
sqlite> .help
.archive ... Manage SQL archives
.auth ON|OFF Show authorizer callbacks
.backup ?DB? FILE Backup DB (default "main") to FILE
.bail on|off Stop after hitting an error. Default OFF
.cd DIRECTORY Change the working directory to DIRECTORY
.changes on|off Show number of rows changed by SQL
.check GLOB Fail if output since .testcase does not match
.clone NEWDB Clone data into NEWDB from the existing database
.connection [close] [#] Open or close an auxiliary database connection
.crlf ?on|off? Whether or not to use \r\n line endings
.databases List names and files of attached databases
.dbconfig ?op? ?val? List or change sqlite3_db_config() options
.dbinfo ?DB? Show status information about the database
.dbtotxt Hex dump of the database file
.dump ?OBJECTS? Render database content as SQL
.echo on|off Turn command echo on or off
.eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN
.excel Display the output of next command in spreadsheet
.exit ?CODE? Exit this program with return-code CODE
.expert EXPERIMENTAL. Suggest indexes for queries
.explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto
.filectrl CMD ... Run various sqlite3_file_control() operations
.fullschema ?--indent? Show schema and the content of sqlite_stat tables
.headers on|off Turn display of headers on or off
.help ?-all? ?PATTERN? Show help text for PATTERN
.import FILE TABLE Import data from FILE into TABLE
.indexes ?TABLE? Show names of indexes
.intck ?STEPS_PER_UNLOCK? Run an incremental integrity check on the db
.limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT
.lint OPTIONS Report potential schema issues.
.load FILE ?ENTRY? Load an extension library
.log FILE|on|off Turn logging on or off. FILE can be stderr/stdout
.mode ?MODE? ?OPTIONS? Set output mode
.nonce STRING Suspend safe mode for one command if nonce matches
.nullvalue STRING Use STRING in place of NULL values
.once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE
.open ?OPTIONS? ?FILE? Close existing database and reopen FILE
.output ?FILE? Send output to FILE or stdout if FILE is omitted
.parameter CMD ... Manage SQL parameter bindings
.print STRING... Print literal STRING
.progress N Invoke progress handler after every N opcodes
.prompt MAIN CONTINUE Replace the standard prompts
.quit Stop interpreting input stream, exit if primary.
.read FILE Read input from FILE or command output
.recover Recover as much data as possible from corrupt db.
.restore ?DB? FILE Restore content of DB (default "main") from FILE
.save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)
.scanstats on|off|est Turn sqlite3_stmt_scanstatus() metrics on or off
.schema ?PATTERN? Show the CREATE statements matching PATTERN
.separator COL ?ROW? Change the column and row separators
.session ?NAME? CMD ... Create or control sessions
.sha3sum ... Compute a SHA3 hash of database content
.shell CMD ARGS... Run CMD ARGS... in a system shell
.show Show the current values for various settings
.stats ?ARG? Show stats or turn stats on or off
.system CMD ARGS... Run CMD ARGS... in a system shell
.tables ?TABLE? List names of tables matching LIKE pattern TABLE
.timeout MS Try opening locked tables for MS milliseconds
.timer on|off Turn SQL timer on or off
.trace ?OPTIONS? Output each SQL statement as it is run
.version Show source, library and compiler versions
.vfsinfo ?AUX? Information about the top-level VFS
.vfslist List all available VFSes
.vfsname ?AUX? Print the name of the VFS stack
.width NUM1 NUM2 ... Set minimum column widths for columnar output
.www Display output of the next command in web browser

我们关注几个比较重要的命令

1
2
3
4
5
.help   获取可用的点命令的清单
.show 显示各种设置的当前值
.quite 退出SQLite 提示符
.databases 列出数据库的名称及其所依附的文件
.schema ?TABLE? 显示 CREATE 语句,例如.schema sqlite_master

sqlite语法

sqlite注释

SQL 注释以两个连续的 - 字符(ASCII 0x2d)开始,并扩展至下一个换行符(ASCII 0x0a)或直到输入结束,以先到者为准。

也可以使用 C 风格的注释,以 "/*" 开始,并扩展至下一个 "*/" 字符对或直到输入结束,以先到者为准。SQLite的注释可以跨越多行。

语句的开始和结束

所有的 SQLite 语句可以以任何关键字开始,如 SELECT、INSERT、UPDATE、DELETE、ALTER、DROP 等,所有的语句以分号 ; 结束。

1、创建数据库

在sqlite中,每个数据库都是以文件的形式存在的

所以我们要创建数据库的语法就是:

1
sqlite3 test.db

然后我们在当前目录下可以看到创建的数据库文件

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
E:\SQLite>sqlite3 test.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> .databases;
Error: unknown command or invalid arguments: "databases;". Enter ".help" for help
sqlite> .databases
main: E:\SQLite\test.db r/w
sqlite> .quit

E:\SQLite>dir
驱动器 E 中的卷是 web
卷的序列号是 3492-78F9

E:\SQLite 的目录

2025/08/29 15:17 <DIR> .
2025/07/31 03:48 3,176,960 sqldiff.exe
2025/08/29 14:59 1,344,617 sqlite-dll-win-x64-3500400.zip
2025/08/29 14:59 6,430,656 sqlite-tools-win-x64-3500400.zip
2025/07/31 03:49 8,280 sqlite3.def
2025/07/31 03:49 3,232,256 sqlite3.dll
2025/07/31 03:48 3,885,056 sqlite3.exe
2025/07/31 03:48 4,439,040 sqlite3_analyzer.exe
2025/07/31 03:49 3,122,688 sqlite3_rsync.exe
2025/08/29 15:17 0 test.db
9 个文件 25,639,553 字节
1 个目录 58,361,475,072 可用字节

此时生成的test.db数据库文件将被sqlite引擎用作数据库,并且可以发现在创建了数据库文件后会自动进入sqlite提示符

.open命令

另外我们也可以在sqlite的命令行中用.open去打开数据库文件,如果数据库存在则打开他,不存在则创建

1
.open test.db

这里的话会直接进入该数据库文件

.databases命令

.databases 是一个命令,用于显示当前已连接数据库的列表及其相关信息。

1
2
3
sqlite> .open test.db
sqlite> .databases
main: E:\SQLite\test.db r/w

.quit命令

该命令会退出sqlite提示符

.dump命令

.dump 命令用于导出数据库或特定表的内容

image-20250829152535383

上面结果说明当前数据库没有表或数据

2、 附加(选择)数据库

如果我们有多个数据库文件可以操作使用,而我们想要使用其中一个的时候,我们就可以用SQLite 的 ATTACH DATABASE 语句来选择一个特定的数据库,使用该命令后,所有的 SQLite 语句将在附加的数据库下执行。

其作用是什么呢?前面我们可以知道,sqlite中每个数据库就代表一个文件,那我们一次也只能打开一个数据库文件,此时如果我们希望用到其他数据库的内容该怎么办呢?这时候就可以用到附加数据库去进行处理了

举个例子,假如我们需要对两个数据库 user.dbnew.db,我们需要将user的表复制到new.db中

1
2
ATTACH DATABASE 'new.db' AS newdb;
CREATE TABLE newdb.users AS SELECT * FROM main.users;

newdb 数据库里创建一张新表 users,并把 main.users 表里的所有数据完整复制过去。

ATTACH DATABASE命令

基础语法

1
ATTACH DATABASE file_name AS database_name;

我们测试一下

1
2
3
4
sqlite> attach database 'test.db' as 'TEST';
sqlite> .databases
main: E:\SQLite\test.db r/w
TEST: E:\SQLite\test.db r/w

为什么这里有两个呢?其实是因为当我们用open命令去打开一个数据库文件的时候,sqlite会自动将该数据库文件挂载到main中,而后面我们自己附加的数据库设置为TEST没问题

.database命令

该命令会显示当前 SQLite 连接中所有已附加的数据库

1
2
3
4
5
6
7
sqlite> attach database 'test.db' as 'TEST';
sqlite> .databases
main: E:\SQLite\test.db r/w
TEST: E:\SQLite\test.db r/w
sqlite> .database
main: E:\SQLite\test.db r/w
TEST: E:\SQLite\test.db r/w

其实区别不大

[!IMPORTANT]

数据库名称 maintemp 被保留用于主数据库和存储临时表及其他临时数据对象的数据库。这两个数据库名称可用于每个数据库连接,且不应该被用于附加,否则将得到一个警告消息

1
2
3
4
sqlite> attach database 'test.db' as 'main';
Runtime error: database main is already in use
sqlite> attach database 'test.db' as 'temp';
Runtime error: database temp is already in use

可以看到这两个名称都是被占用了的

3、分离数据库

和上面的附加数据库相反,分离数据库主要是将我们附加的数据库从当前会话中删除

DETACH DATABASE命令

SQLite 的 DETACH DATABASE 语句是用来把命名数据库从一个数据库连接分离和游离出来,连接是之前使用 ATTACH 语句附加的。但是我们无法分离main或temp数据库

基础语法

1
DETACH DATABASE 别名;

举个例子

我们先附加两个数据库TESTTEST2

1
2
3
4
5
6
sqlite> attach database 'test.db' as 'TEST2'
...> ;
sqlite> .database
main: E:\SQLite\test.db r/w
TEST: E:\SQLite\test.db r/w
TEST2: E:\SQLite\test.db r/w

然后我们尝试将TEST2给分离出去

1
2
3
4
sqlite> detach database 'TEST2';
sqlite> .database
main: E:\SQLite\test.db r/w
TEST: E:\SQLite\test.db r/w

此时不难看到,之前的TEST是不会受影响的,仍然和main保持连接

4、创建数据表

CREATE TABLE命令

SQLite 的 CREATE TABLE 语句用于在任何给定的数据库创建一个新表。创建基本表,涉及到命名表、定义列及每一列的数据类型。其实和mysql的创建表是一样的

语法

1
2
3
4
5
6
7
8
CREATE TABLE database_name.table_name(
column1 datatype PRIMARY KEY(one or more columns),
column2 datatype,
column3 datatype,
.....
columnN datatype,
);

好了,又该了解一下数据类型了

sqlite数据类型

https://www.runoob.com/sqlite/sqlite-data-types.html

常用的数据类型主要有五大类

数据类型 描述
NULL 值是一个 NULL 值。
INTEGER 值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。
REAL 值是一个浮点值,存储为 8 字节的 IEEE 浮点数字。
TEXT 值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。
BLOB 值是一个 blob 数据,完全根据它的输入存储。

往细分的话就是很多小类了,可以直接看菜鸟教程中的亲和类型

然后还要sqlite的约束

sqlite约束

https://www.runoob.com/sqlite/sqlite-constraints.html

约束其实就是用来限制插入到表中的数据类型

常用的约束

  • NOT NULL 约束:确保某列不能有 NULL 值。
  • DEFAULT 约束:当某列没有指定值时,为该列提供默认值。
  • UNIQUE 约束:确保某列中的所有值是不同的。
  • PRIMARY Key 约束:唯一标识数据库表中的各行/记录。
  • CHECK 约束:CHECK 约束确保某列中的所有值满足一定条件。

介绍完了,我们回到创建数据表中

尝试创建一个数据表

1
2
3
4
5
sqlite> create table helloworld(
(x1...> id integer primary key not null,
(x1...> username text not null,
(x1...> password text not null
(x1...> );

.tables 命令

.tables 命令可以用于 显示当前数据库里所有表的列表

我们看看刚刚创建的数据表是否存在

1
2
3
4
5
6
7
sqlite> create table helloworld(
(x1...> id integer primary key not null,
(x1...> username text not null,
(x1...> password text not null
(x1...> );
sqlite> .tables
TEST.helloworld helloworld
  1. 主数据库表helloworld 是您在当前数据库中创建的表,属于主数据库(通常是 main 数据库)。
  2. 附加数据库表TEST.helloworld 表示在一个名为 TEST 的附加数据库中的 helloworld 表。

.schema 命令

.schema 命令可以用于查看数据库对象的 所有表、索引、触发器等对象的创建 SQL创建 SQL(通常指 CREATE 语句)是用来 创建数据库对象 的 SQL 命令。

1
2
3
4
5
6
7
8
9
10
11
sqlite> .schema
CREATE TABLE helloworld(
id integer primary key not null,
username text not null,
password text not null
);
CREATE TABLE TEST.helloworld(
id integer primary key not null,
username text not null,
password text not null
);

5、删除数据表