学 web 安全也有段时间了,但我一直都只是在打靶场,实战直接猿形毕露,连个后台都找不到,呜呜。所以,我打算稍微改变下学习方式,目前思路是酱紫的:针对某一课题(最近在看 race conditions)–> 尽可能多、尽可能详细地分析实战案例、CVE –> 挑一些典型的尝试复现 –> 看到新的 vector 及时实践 –> 抽象出通用规律,探索自动化的可能。
不知道这思路好不好使,不过,干就完了!!
在分析过程中碰到好多 Ruby 代码,就简单过了下 Ruby 的基础语法,本文更多的是我学习过程中的记录,方便后续查阅。根据老马的第一性原理,我在学了 Ruby 基础语法之后,rails 应该也没啥问题了,devise 也是手到擒来,漏洞赏金绝对能拿到手软,如果没有,那就是老马有问题! (不是)
话不多说,hacking for fun!
啥时候能挖到我的处女洞啊!!!
参考资料:
输出字符串 括号可加可不加。
1 2 3 4 5 6 7 8 9 10 print "Hello, World" puts "Hello, World" p "Hello, World" p 'hello world' p %Q (hello world) p %q (hello world)
字符串中嵌入变量:
1 2 3 4 5 6 name = "Sean" age = 18 puts "I'm #{name} , and I am #{age} years old" puts %Q(I'm #{name} , and I am #{age} years old) puts %q(I'm #{name} , and I am #{age} years old)
1 2 3 4 5 6 say_hi = "hello world" puts say_hi[0 ] puts say_hi[5 ] say_hi[0 ..5 ] = "Hi!" puts say_hi
注释
函数 有时候 ()
可加可不加
1 2 3 def hello puts "hi, 你好啊!" end
?
和 !
可作为函数命名的一部分,不过只能放在最后面
1 2 3 4 def double_num? (num ) return num * 2 end p double_num?(5 )
方法后的 !
会改变对象原本的值。
1 2 3 4 5 list = [1 ,4 ,3 ,2 ] p list.sort p list p list.sort! p list
列表/数组 array 1 2 list = ["apple" ,"bird" ,"哈樓" , 1 , 2 ] list = %w(apple bird 哈樓 1 2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 pokemon = ["皮卡丘" ,"傑尼龜" ,"妙蛙種子" ,"小火龍" ] puts pokemon[0 ] puts pokemon[1 ] puts pokemon[-1 ] puts pokemon[-2 ] puts pokemon.first puts pokemon.last puts pokemon.length pokemon << '小智' puts pokemon.length pokemon.push('小霞' ) puts pokemon.length puts pokemon
话说台湾同胞都喜欢神奇宝贝嘛?!看见好几个了。
map 方法 |x|
代表传递给某个代码块的局部变量。
1 2 3 a = [1 ,2 ,3 ] p a.map { |x | x*2 }
select 方法 1 2 3 a = [1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ] p a.select { |x | x < 5 }
reduce 方法 1 2 3 a = [1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ] p a.reduce { |sum, n | sum + n }
范围 Range ..
少一点多一点,...
多一点少一点。 emmmm,6,同胞真是太幽默了。
1 2 3 4 5 6 7 8 9 puts (1 ..10 ).to_a puts (1 ...10 ).to_a p *1 ..10 p [*1 ..10 ]
1 2 3 4 5 6 p [*1 ..10 ].map { |x | x+1 } p (1 ..10 ).to_a.map { |x | x+1 } p ("a" .."g" ).to_a.select { |chars | chars < "c" }
哈希 hash 字典?
1 2 profile = { :name => 'caishao' , :age => 20 } profile = { name: 'caishao' , age: 20 }
1 2 3 4 5 6 7 profile = { name: 'caishao' , age: 20 } puts profile["name" ] puts profile[:name ] profile.keys profile.values character[:power ] = 100 p character
1 2 3 profile = {name: "Sean" , age: 25 , power: 100 , ability: "Ruby" } p profile.length p profile.size
分支 1 2 3 4 5 6 7 8 age = 10 if age >= 0 && age<=10 puts "小学生" elsif age >= 11 && age<=17 puts "青少年" else puts "成年" end
unless = if not
1 2 3 unless age >=18 puts "未成年" end
三目运算
1 status = (age>=18 )? "成年" :"未成年"
case when,可使用范围。
1 2 3 4 5 6 7 8 9 age = 20 case agewhen 0 ..10 puts "小学生" when 11 ..17 puts "青少年" else puts "成年" end
迭代 Loop and Iteration for 循环:
1 2 3 4 5 6 names = ["Sean" , "Ken" , "John" , "Tom" ] for name in names puts name end
while 循环:
1 2 3 4 5 6 x = 0 while x < 10 puts x x += 1 end
until 循环,until = while not:
1 2 3 4 5 6 x = 0 until x >= 10 puts x x += 1 end
loop 循环:
1 2 3 4 5 6 7 i = 0 loop do puts i i += 1 break if i > 10 end
ruby 中 do-end
或 {}
均可以表示代码块,二者可相互替换。loop 循环可理解为:loop
+ 代码块
1 2 3 4 5 6 7 i = 0 loop { puts i i += 1 break if i > 10 }
ruby 中数字也是对象,可对其使用方法,.times{}
.upto()
.downto()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 5 .times{puts "hello" }5 .times do puts "hello" end 1 .upto(10 ) do |i | puts "hello, ruby #{i} " end 10 .downto(1 ) do |i | puts "hello, ruby #{i} " end
迭代:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 names = ["Sean" , "Ken" , "John" , "Tom" ] x = 0 names.each do |name | puts "#{x} #{name} " x += 1 end names = ["Sean" , "Ken" , "John" , "Tom" ] x = 0 names.each_with_index do |name, x | puts "#{x} #{name} " x += 1 end
代码块 block block 可以传递参数,|n|
代表传递给某个代码块的局部变量。
1 2 3 4 5 6 7 8 9 10 11 def test_two if yield (2 ) puts "yes, it is 2" else puts "no, it is not 2" end end test_two {|n | n == 2 }
执行到 yield(2)
时,会先执行代码块 {|n| n == 2 }
的内容,并将参数 2 传递过去。感觉 yield
其实就是个可传参的代码占位符 ?
do-end
和 {}
的区别:
优先级不同
没啥区别了,多行建议用 do-end
单行用 {}
1 2 3 4 5 6 p [*1 ..10 ].map { |i | i * 2 } p [*1 ..10 ].map do |i | i * 2 end
类 & 对象 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 #!/usr/bin/env ruby class MegaGreeter attr_accessor :names def initialize (names = "World" ) @names = names end def say_hi if @names .nil ? puts "..." elsif @names .respond_to?("each" ) @names .each do |name | puts "Hello #{name} !" end else puts "Hello #{@names } !" end end def say_bye if @names .nil ? puts "..." elsif @names .respond_to?("join" ) puts "Goodbye #{@names .join(", " )} . Come back soon!" else puts "Goodbye #{@names } . Come back soon!" end end end if __FILE__ == $0 mg = MegaGreeter .new mg.say_hi mg.say_bye mg.names = "Zeke" mg.say_hi mg.say_bye mg.names = ["Albert" , "Brenda" , "Charles" , "Dave" , "Engelbert" ] mg.say_hi mg.say_bye mg.names = nil mg.say_hi mg.say_bye end
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 Hello World! Goodbye World. Come back soon! Hello Zeke! Goodbye Zeke. Come back soon! Hello Albert! Hello Brenda! Hello Charles! Hello Dave! Hello Engelbert! Goodbye Albert, Brenda, Charles, Dave, Engelbert. Come back soon! ... ...
实例方法和类别方法:
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 class Human def initialize (name ) @name = name end def my_name puts "I'm #{@name } ." end def self .say_hi puts "hi 我是類別方法" end end Sean = Human .new('Sean' )麥克 = Human .new('麥克' ) #實體方法 instance method Sean .my_name 麥克.my_name Human .my_name #類別方法 class method Human .say_hi Sean .say_hi
继承:
1 2 3 4 5 6 7 8 9 10 11 class Animal def eat (food ) puts "#{food} 也太好吃了吧!!" end end class Human < Animal end class Dog < Animal end
模块 module 模组? 代码占位符?相当于把代码块导入类中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 module spinning def spin puts "我會吐絲啦!" end end class Human include spinning end Sean = Human .newSean .spinning
Class 与 Module 的区别:
1 2 3.1.2 :002 > Class .instance_methods - Module .instance_methods => [:allocate , :superclass , :subclasses , :new ]
PS: Ruby 确实蛮灵活的,这都能减!!
类 Class 比模块 Module 多了以上四个方法,所以 Module:
无法创建实例
无法继承其他 Module