前言
最近实在是忙都没时间写博客,难得周四院休赶紧把之前挖的sqlite的坑给填了。
sqlite与mysql的不同
- Sqlite数据库的特点是它每一个数据库都是一个文件,当你查询表的完整信息时会得到创建表的语句。所以mysql盲注还是比较花时间的,因为会查出完整语句。
- sqlite数据库有一张sqlite_master表,里面有type/name/tbl_name/rootpage/sql记录着用户创建表时的相关信息,查询的利用核心便是这个表了。
- sqlite数据库的注释符是
--
,而并非是mysql的#
或者--+
,sqlite中的空格会自动用加号表示。
sqlite的增删查改
新建表:
1 | create table test01(id int,name varchar(255)); |
插入数据:
1 | insert into test01 (id,name) values (1,'mrl64'); |
插入字段:
1 | alter table test01 add column passwd varchar(255); |
查询数据:
1 | select name from test01 where id=1; |
更改数据:
1 | Update teat01 set name=’strl’ where id=1; |
删库跑路(bushi:
1 | drop table test01; |
要注意,sqlite不能直接更改字段类型,如果要更改只能重新创建表格并进行数据迁移。
sqlite注入
sqlite和mysql虽然存在的一些细微差别,不过在注入方法上还是大体相近的。
联合注入
由于sqlite的性质决定了我们不需要查库想,联合查询同样也是order by
配合union select
一套组合拳下来,下面就放一下大概的流程吧:
1 | ?id=1 order by 3 //order by确定字段数 |
布尔盲注
这里和mysql最大的差别在于sqlite没有ascii()函数,因此只能使用字典爆破的方式进行盲注,不过sqlite是区分大小写的,因此可以避免mysql盲注时不确定大小写的尴尬。
没有很强的waf的话直接用sqlmap也是可以跑的,这里贴一个之前做题的脚本:
1 | import requests |
时间盲注
sqlite没有sleep()函数,我们就用下位替代randomblob()函数来代替,这个函数可以生成一个N字节的blob,我们可以通过这个函数来达到延迟的效果。
randomblob():
The randomblob(N) function return an N-byte blob containing pseudo-random bytes. If N is less than 1 then a 1-byte random blob is returned. Hint: applications can generate globally unique identifiers using this function together with hex() and/or lower() like this:hex(randomblob(16))
我们的查询语句构造方法:
1 | and 1=(case when(substr(sqlite_version(),1,1)='3') then randomblob(1000000000) else 0 end) |
case when()的用法就相当于三目运算符那样,注入的时候适当更改payload就可以了。
构造webshell
用sqlite构建webshell这个姿势还是比较有意思的,用到了sqlite的附加数据库——ATTACH语句来进行构造。
ATTACH:
1 | ATTACH DATABASE file_name AS database_name; |
我们通过去建立一个文件,再插入payload的方式构建webshell。
构造过程:
1 | ATTACH DATABASE '/home/shell.php' AS shell; //创建文件 |
总结
sqlite还是很有意思的一块内容,除了SQLite voting那题以外暂时还没有看到难度较高的sqlite题,这块的知识感觉在之后也是一个趋势吧。