在SQLite中实现命令执行
Posted MottoIN
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在SQLite中实现命令执行相关的知识,希望对你有一定的参考价值。
前言
在一次家庭智能设备的安全性研究中,我们发现了一中利用SQL注入漏洞在SQLite数据库任意命令执行的新技术。这篇文档我们如何能够创建一个SQLite数据库,从shell脚本执行SQL查询。这种技术更适用于透测试和漏洞研究。
背景
SQLite注入漏洞执行任意代码最明显的方法是使用load_extension()在共享库中执行函数。但是,libsqlite3.so库默认情况下禁用此功能,因为它是一个明显的安全漏洞。在一些SQLite注入备忘表中发现的另一种技术是使用ATTACH DATABASE查询在Web服务器的根目录中创建一个SQLite文件,并用php代码填充它,当该文件被请求时,PHP解析器会执行该文件。
ATTACH DATABASE首先查看在指定位置是否存在文件。如果存在,那么它会尝试将其作为SQLite数据库打开。如果没有,那么它将创建文件并将其打开以便作为SQLite数据库进行读取和写入。在上面的示例中,在/var/www/中创建lol.php文件,并通过数据库名称lol访问。然后,在该数据库中创建一个名为pwn的表,并将一个字符串插入到该表中。当通过web服务器请求文件时,php文件扩展名将导致web服务器调用PHP解释器。解释器通过文件搜索标签<?,并试图解释<?之后的内容,直到?>标签终止。在这种情况下,代码将执行cmd GET请求变量中的任何内容作为系统上的命令。这是一个从SQL注入到任意命令执行的非常方便的方式。但是,对于使用SQLite数据库但没有PHP解释器的系统,如许多嵌入式系统,此技术将无法工作。
SQLite作为一个ash脚本
许多基于Linux的嵌入式系统使用BusyBox工具套件来实现基本的Linux命令。默认情况下,BusyBox使用ash shell来实现/bin/sh。 因此,我们可以看看是否可以创建一个SQLite数据库文件,该文件可以只使用SQL查询作为ash shell脚本执行。 这比PHP的情况更复杂,因为ash的命令解析器比PHP更复杂。 然而,它比在更复杂的命令解释器尝试这中技术简单得多,比如bash。
第一步是理解ash解析器主要关心换行符(即’\ n’)和括号(即’(’和’)’)。这是因为当用户在命令行上输入命令时,插入一个换行符,并且括号中的命令表示它应该在子shell中执行。 因此,如果我们能找出一种策略性的方法来将这些字符插入到SQLite数据库文件中,那么我们可以使用它们来控制文件如何被ash解释。
图1:在SQLite数据库文件中插入和保留换行符
插入换行字符的诀窍在于SQLite将保留用于构建数据库模式的查询。 在图1顶部的CREATE语句中显示了一个示例。虽然整个语句可以放在一行中,但是列定义放在下一行,因为结果数据库文件将在其模式定义中包含换行符 。
图1的下半部分显示了当数据库文件作为ash shell脚本运行时发生的情况。 第一个ash错误报告是它找不到名为“SQLite”的命令。这是因为它将文件的第一个字解释为命令,并且将直到CREATE语句换行符之前的一切作为其参数。现在我们只需要弄清楚如何修复第二个错误“unterminated quoted string.”。
图2:执行echo命令
解决第二个错误的方法是插入另一个换行符。图2显示了我们如何在新行上为CREATE语句添加“without rowid;”语法。 在列定义之后插入的换行符意味着列定义现在由换行符字符包围,并且当文件被解析为脚本时,将被视为它自己的文本行。实际上,图2的底部显示当文件作为脚本执行时,echo列名称被解释为echo命令,并且“none primary key”被回送到屏幕。 这在技术上意味着我们已经实现了命令执行,因为我们可以使列名(即命令)变成其他内容,而不仅仅是echo。但是,它不是任意命令执行,因为我们不能为命令设置任意参数。 为了具有有效的列定义,列名后面的第一个字必须是设置数量的类型之一。
图3:使用SQLite文件执行任意命令
为了获得任意命令执行,我们参考PHP示例,其中所需的命令以表值形式输入。 在图3中,我们利用相同的技术,注意字符串的第一个和最后一个字符必须是换行符。请注意,来自列定义的echo命令仍然执行,但作为表的唯一值插入的ls命令也是如此。
结论
现在你知道如何创建一个SQLite文件并将其作为ash shell脚本执行的方法。这个方法应该在所有自带BusyBox的ash版本。
以上是关于在SQLite中实现命令执行的主要内容,如果未能解决你的问题,请参考以下文章