Contents
Hello.rb
#!/usr/bin/ruby puts 'Hello World!"
Classes
Ruby knows the following classes:
- Integer
- Float
- String
Methods
A method is something you can do with a class.
- foo.to_i convert to integer
- foo.to_f convert to float
- foo.to_s convert to string
Variables
Warnung: Variablennamen dürfen nicht mit einem Großbuchstaben beginnen.
stadt = "Berlin"
Working with Numbers
Math
var = var + 2 var += 2 var = var - 3 var -= 3 var = var * 6 var *= 6 var = var / 2 var /= 2 var = var** 3 var **=3 var = var % 4 var %= 4
Working with Strings
String Manipulation
name = name.chomp
number = gets.chomp.to_i
Data Structures
Working with Arrays
Defining Arrays
item = Array.new @item = Array.new $a = `ls` => "bin\nDATA\nDesktop\nvmware\n" $a = `ls`.split => ["bin", "DATA", "Desktop", "vmware"] zahlen = [ "null", "eins", "zwei", "drei", "vier" ]
Accessing Arrays
zahlen = [ "null", "eins", "zwei", "drei", "vier" ] zahlen.lenght # Anzahl der Array-Elemente
freunde = ["Jim", "Jeff", "Tim", "Rob"] freunde.each do |freund| puts "Ich habe einen Freund, der " + freund + " heißt" end # same as 4.times do |i| puts "Ich habe einen Freund, der " + freunde[i] + " heißt" end # same as freunde.length.times do |i| # 'i' für 'index'. puts "Ich habe einen Freund, der " + freunde[i] + "heißt" end
Working with Hashes
Defining Hashes
data = Hash.new freund = { "vorname" => "Herbert", "nachname" => "Maier", "adresse" => "Auf Maien 69", "stadt" => "Neunkirchen", "bundesland" => "Saarland" }
Accessing Hashes
freund.each do |key, value| puts key + " => " + value end # same as freund.each_key do |key| puts freund[key] end
freund.each_key do |key| puts key end
h = { "a" => 100, "b" => 200 } h.each_pair {|key, value| puts "#{key} is #{value}" } => a is 100 => b is 200
Working with Hashes of Hashes
Creating HOH in Ruby is a bit quiet strange IMHO.
The “default_proc” Method
int = Hash.new{|h,k| h[k]=Hash.new &h.default_proc} int[:eth0][:ip] = "10.0.0.1" int[:eth0][:mask] = "255.255.255.0" int[:eth0][:cidr] = "24" int[:eth1][:ip] = "10.0.1.1" int[:eth1][:mask] = "255.255.255.0" int[:eth1][:cidr] = "24" puts "IP of eth0 is:"+int[:eth0][:ip]
The “ostruct” Method
require 'ostruct' int = Hash.new{|h,k| h[k]=OpenStruct.new} int[:eth0].ip = "10.0.0.1" int[:eth0].mask = "255.255.255.0" int[:eth0].cidr = "24" int[:eth1].ip = "10.0.1.1" int[:eth1].mask = "255.255.255.0" int[:eth1].cidr = "24" puts int[:eth1].cidr
Loops
Counted Loop
count = 0 5.times do count += 1 puts "count = " + count.to_s end
count = 1 count = 2 count = 3 count = 4 count = 5
count = sum = 0 11.times do count += 1 sum += count puts "Summe to " + count.to_s + " = "+ sum.to_s end
Summe to 1 = 1 Summe to 2 = 3 Summe to 3 = 6 Summe to 4 = 10 Summe to 5 = 15 Summe to 6 = 21 Summe to 7 = 28 Summe to 8 = 36 Summe to 9 = 45 Summe to 10 = 55 Summe to 11 = 66
count=10 count.times do count-=1 puts count.to_s end
9 8 7 6 5 4 3 2 1 0
Conditional Statements
IF THEN ELSE
stadt="zh" if stadt == "Berlin" drinking_age = 18 else drinking_age = 21 end
WHILE
count=0 while count < 10 puts "count = " + count.to_s count +=1 end
Methodes (functions)
Methodes are in Ruby what you would call a function in Bash or Perl.
A simple Methode looks like:
def showme(message) puts message end message="ruby says hello" showme(message)
Task specific solutions
Networking
Banner grabbing
# Lets try a simple banner grabber in ruby # require 'socket' socket = TCPSocket.new("www.heise.de", "80") socket.write("GET / HTTP/1.0\n\n") print socket.read + " - soso \n"
Get MAC and IP from network interface
require 'socket' # From bits/ioctls.h SIOCGIFHWADDR = 0x8927 # Get hardware address SIOCGIFADDR = 0x8915 # get PA address class String def to_ipaddr4 self.unpack("CCCC").join(".") end def to_etheraddr self.unpack("H2H2H2H2H2H2").join(":") end end class Interface def self.hw_address(iface) sock = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM,0) buf = [iface,""].pack('a16h16') sock.ioctl(SIOCGIFHWADDR, buf); sock.close return buf[18..24].to_etheraddr end def self.ip_address(iface) #sock = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM,0) sock = UDPSocket.new buf = [iface,""].pack('a16h16') sock.ioctl(SIOCGIFADDR, buf); sock.close # Another way # Socket::unpack_sockaddr_in(buf[16..256])[1] buf[20..24].to_ipaddr4 end end if $0 == __FILE__ puts Interface.hw_address('eth0') puts Interface.ip_address('eth0') end
Set NIC into promiscuous mode
You have to install the bit-struct library from: http://raa.ruby-lang.org/project/bit-struct/
Installation:
tar xvfz bit-struct-0.10.tgz cd bit-struct-0.10 ruby install.rb config ruby install.rb setup sudo ruby install.rb install
require 'socket' require 'bit-struct' AF_PACKET = 17 ETH_P_ALL = 3 # From bits/socket.h SOL_PACKET = 263 # From netpacket/packet.h PACKET_ADD_MEMBERSHIP = 1 PACKET_MR_PROMISC = 1 # Equivalent C htons function def htons(h) [h].pack("S").unpack("n")[0] end # Struct in linux/if_packet.h class MReq < BitStruct signed :mr_ifindex, 32, :endian => :native unsigned :mr_type, 16, :endian => :native unsigned :mr_alen, 16, :endian => :native char :mr_address, 64 end mreq = MReq.new do |m| m.mr_ifindex = 2 m.mr_type = PACKET_MR_PROMISC m.mr_alen = 0 m.mr_address = 0 end begin ssock = Socket.open(AF_PACKET, Socket::SOCK_RAW, htons(ETH_P_ALL)) ssock.setsockopt(SOL_PACKET, PACKET_ADD_MEMBERSHIP, mreq) rescue Errno::EPERM $stderr.puts "Must run #{$0} as root." exit! end