Pages

11/27/2011

รีวิวหนังสือ รู้ทัน!! ฅนโคตรโกง


Link: http://se-ed.com/eShop/Products/Detail.aspx?No=9786162530326
Details:
ชื่อ: รู้ทัน!! ฅนโคตรโกง
สำนักพิมพ์: I.S. (Pocket) Publishing
เดือนปีที่พิมพ์: สิงหาคม 2554
ชื่อผู้แต่ง: ?????
จำนวนหน้า: 160 หน้า
ราคา: 98 บาท

      ไปสะดุดตาหนังสือเล่มนี้เข้าที่ 7-11  พอดีเห็นว่าเกี่ยวกับเรื่องแฉกลโกงต่าง มันค่อนข้างจะเข้าทางกับที่อ่านอยู่พอดี  แล้วก็ยังมีเนื้อหาเกี่ยวกับเรื่อง work@home ที่ผมยังหาข้อมูลไม่ได้อยู่พอดี เลยตัดสินใจซื้อมา
      ก่อนอื่นเลยต้องบอกว่า หน้าปกอ่านยากมาก ดูไม่ออกว่ามันมีเรื่องอะไรอยู่บ้างในหนังสือเล่มนี้ ภาพมันสับสนวุ่นวายอยู่แล้ว พอเอาตัวหนังสือไปแอบเนียนไว้กับองค์ประกอบของภาพอีกก็ยิ่งอ่านไม่ออกใหญ่  มาอ่านออกก็ตรงปกหลังของหนังสือที่เขียนเป็นคำพูดชัดเจนว่ามีอะไรบ้าง  แต่ด้านหลังจะเขียนไว้แค่ 8 หัวข้อ แต่ในความจริงในหนังสือมีเรื่องราวเยอะกว่านั้น
      ต้องใช้คำว่าเรื่องราวเพราะว่า หนังสือเล่มนี้ เป็นการรวบรวมเรื่องจริงๆ ที่เกิดขึ้นกับชาวบ้านทั่วไป และถูกเขียนส่งมาหาบ.ก. ของหนังสือเล่มนี้ เพื่อรวบรวมและจัดทำเป็นเล่ม  ตอนแรกก็แปลกใจอยู่ที่ว่าหนังสือเล่มนี้ไม่มีชื่อผู้แต่งชัดเจน  แต่ก็อ่านแล้วก็เข้าใจว่า เนื้อหาของแต่ละเรื่องเป็นทางบ้านส่งมาและเขาต้องการปิดชื่อเป็นความลับ  ดังนั้นก็จะไม่มีชื่อผู้แต่งหนังสือเล่มนี้
     สรุปแล้วหนังสือเล่มนี้ รวมสาระพัดกลโกง(Scam) อาทิ แก๊งคอลล์เซ็นเตอร์ แก๊งขโมยบัตรเครดิต การขายตรง(แต่กินส่วนแบ่งแบบพิรามิด) การเล่นแชร์ลูกโซ่ และอื่นๆ อีกมากมาย ในรูปแบบของจดหมายบรรยายเรื่องราวที่ส่งมาจากทางบ้าน และมีการเขียนสรุปคำเตือนและวิธีป้องกันไว้ท้ายเรื่องของแต่ละเรื่องด้วย  แถมภาษายังอ่านง่ายเป็นภาษาพูดบรรยายแบบเล่าเรื่อง ดังนั้นเลยอ่านง่าย เข้าใจง่ายอีกด้วย
 

11/22/2011

Luhn Algorithm Implementation in Ruby

Luhn Algorithm (a.k.a. Mod10, Modulus10): 
    used for creating checksum digit for credit cards, IMEI number, SSN in US and Canada.
(for more see http://en.wikipedia.org/wiki/Luhn_algorithm and http://en.wikipedia.org/wiki/Bank_card_number)


Algorithm:
using "7992739871" as an example here.

  1. break string into digits:
    "7992739871" ==> [7,9,9,2,7,3,9,8,7,1]
  2. double every other digit, starting at 2nd digit:
     [7,9,9,2,7,3,9,8,7,1]  ==> [7,18,9,4,7,6,9,16,7,2]
  3. sum 2-digit number into single-digit number: ex. 18=>1+8=9
    trick is: using either 1+val%10 , or just simply val - 9 if value is over 9
    [7,18,9,4,7,6,9,16,7,2] ==> [7,9,9,4,7,6,9,7,4,2]
  4. sum all numbers:
     [7,9,9,4,7,6,9,7,4,2] ==> 67
  5. modulo with 10:
    67%10 ==> 7
  6. use the reminder to subtract from 10:
    10-7 ==> 3
  7. it is the check digit:
    so the final number will be "79927398713"
Implementation in Ruby:

1st implementation: 
   create 'b' as 1,2,1,2... alternative array and use .zip method to make it parallel array, thne using map to do multiplication (dot-product-like). 'k' variable will be digit-summed, and finally the whole array is summed by .inject(&:+)

input = '7992739871'
b = (1..input.length).map{|i| i%2==0?2:1}
output = 10 - input.split('').map(&:to_i).zip(b).map{|i,j| k=i*j; k<10?k:1+k%10}.inject(&:+)%10

2nd implementation:
   This one uses a benefit of .each_with_index method, so we can omit array 'b'. But the loop does not return changed values, we need another variable (sum) to hold the value.

input = '7992739871'
sum = 0
input.split('').map(&:to_i).each_with_index{|v,i| k=(i%2==0)?v:(v*2<10)?v*2:1+(v*2)%10; sum= sum+k}
output = 10 - sum%10

3rd implementation: 
    based on idea of using Hash to reduce computation on sum of 2-digit, we can use this hash ('b' variable) to directly map the doubled digit into sum of 2-digit value. In 'b' variable (summation of 2-digit of doubled value), we'll get
    b => {5=>1, 0=>0, 6=>3, 1=>2, 7=>5, 2=>4, 8=>7, 3=>6, 9=>9, 4=>8}  
   *** 5=>1 means 5*2 => 10 => 1+0 => 1

input = '7992739871'
b=Hash[(0..9).collect{|i| [i,i*2<10?i*2:1+(i*2%10)]}]
sum = 0
input.split(//).collect(&:to_i).each_with_index{|v,i| sum=sum+(i%2==0?v:b[v])}
output = 10 - sum%10
4th implementation:     If combine all the implementation, would it be easier?
(also change to use val-9 in computation for sum of digits)

input = '7992739871'
b=Hash[(0..9).collect{|i| [i,i*2<10?i*2:i*2-9]}]
output = 10 - input.split(//).collect(&:to_i).zip((1..input.length).to_a).map{|v,i| i%2==0?b[v]:v}.inject(&:+)%10

Or into one-liner as:

input = '7992739871'
output = 10 - input.split(//).collect(&:to_i).zip((1..input.length).to_a).map{|v,i| i%2==0?(v*2<10?v*2:v*2-9):v}.inject(&:+)%10

Additionally useful snippets:
   Found these 2 snippets for checking credit card company.

From: https://gist.github.com/1182499
def valid_association?(number)
  number = number.to_s.gsub(/\D/, "") 
  return :dinners  if number.length == 14 && number =~ /^3(0[0-5]|[68])/   # 300xxx-305xxx, 36xxxx, 38xxxx
  return :amex     if number.length == 15 && number =~ /^3[47]/            # 34xxxx, 37xxxx
  return :visa     if [13,16].include?(number.length) && number =~ /^4/    # 4xxxxx
  return :master   if number.length == 16 && number =~ /^5[1-5]/           # 51xxxx-55xxxx
  return :discover if number.length == 16 && number =~ /^6011/             # 6011xx
  return nil
end

From: http://www.missiondata.com/blog/web-development/25/credit-card-type-and-luhn-check-in-ruby/
def ccTypeCheck(ccNumber)
  ccNumber = ccNumber.gsub(/\D/, '')
  case ccNumber
    when /^3[47]\d{13}$/ then return "AMEX"
    when /^4\d{12}(\d{3})?$/ then return "VISA"
    when /^5\d{15}|36\d{14}$/ then return "MC"
    when /^6011\d{12}|650\d{13}$/ then return "DISC"
    when /^3(0[0-5]|8[0-1])\d{11}$/ then return "DINERS"
    when /^(39\d{12})|(389\d{11})$/ then return "CB"
    when /^3\d{15}|1800\d{11}|2131\d{11}$/ then return "JCB"
    else return "NA"
  end
end

11/21/2011

In-place Replace by Ruby

The following code will replace "searchword" from all *.txt files with word "newword".
The original files will be changed, and backup file will have .bak extension.
ruby -pi.bak -e "gsub(/searchword/,"newword")" *.txt
sed command:
sed -i "s/searchword/newword" filename
sed for multiple-file (using find command)
find /path -n "*.txt" -type f -exec sed -i "s/searchword/newword" {} \;

11/15/2011

Attempt to use Siri on Ubuntu

First off, according to this post from Applidium http://applidium.com/en/news/cracking_siri/
It is about what they learn while trying to figure out how Siri works.
They also provide tools that they used during the process here https://github.com/applidium/Cracking-Siri
and they were written in Ruby.

So, I thought,... Well, it's a good time to try it out. Since I am not an Apple fan boy, I have never use Siri before and I don't have iPhone. All the things matches up with my situation, I then started to try it out.

Unfortunately, after awhile of trying to make it works, I can't.
It seems this tool works by creating a proxy server to capture the authenticated session, use "an actual iphone" to communicate to Siri server to get a session, then you can use that session with the client tools they provides....

So... it  needs an iPhone, and I don't have one....
This tool is not working for me (yet),
but I hope it will work with others.
(or until I can find an iPhone to test it)



Here is the steps I tried:


1. Install all the requirements
It needs ruby, rubygems, openssl, libssl-dev, ffmpeg, speex, eventmachine, uuidtools, CFPropertyList
to install

sudo apt-get install ruby rubygems openssl libssl-dev ffmpeg speex
sudo gem install eventmachine uuidtools CFPropertyList

Possibly also need Audacity or other recording tool to create a sound file

2. Download the tools and extract them
p.s. you can read README.md and Siri.txt inside the first file, but I think it is more like a summary (doesn't give much detail).

3. Generate a certificate and such
(for more information about .cer, .crt, .key, PEM, DER read this http://www.gtopia.org/blog/2010/02/der-vs-crt-vs-cer-vs-pem-certificates/)
I found this command below from http://shib.kuleuven.be/docs/ssl_commands.shtml and only one line it can create both .crt and .key for the certification. I should work (remind that I don't have an iPhone to test)

openssl req -x509 -new -out MYCERT.crt -keyout MYKEY.key -days 365

It will prompt several questions for you to answer. Answer them whatever, but you need to
  • type in the passphrase, it can't be blank
  • "Common Name" (CN) answer as "guzzoni.apple.com" (without quote)

After the prompting questions stop, you will get file MYCERT.crt (for certification, signed) and MYKEY.key (for key)

4. Put the certificate to iPhone 
Well, I don't have one, so I'll skip it.

5. Configure Siri local server
File "siriServer.rb" contains code to work as a Siri proxy between your client (iPhone or Ruby) and Apple's Siri server.
It needs to be configured to use the certificate and key that we created.
First, find the lines below 
Default file names from the tool are "server.passless.crt" and "server.passless.key". 
They need to be changed to the files we just created (or vise-versa).
If you choose to edit the server file, it would be...

6. Start the server
This server will act as Siri server, which is using HTTPS connection. Therefore, this Ruby server will bind to port 433 (default HTTPS) and it also needs super-user permission (sudo needed). 

sudo ./siriServer.rb

If it shows nothing but the waiting prompt, that means it is running correctly. It is waiting for a connection from a client.

7. Use iPhone to connect to Siri via our local server
I haven't done this, but I have some ideas on it.
In order for iPhone to use Siri, it will need to connect to "guzzoni.apple.com". We don't want it to connect directly to the Apple's server, but we need to route the traffic to go through our Ruby server first, so we can capture and view the data inside the traffic.
According to this http://stackoverflow.com/questions/2028544/does-hosts-file-exist-on-the-iphone-how-to-change-it , there are ways to run Siri via our server

  • Router configuration: if you have access to router admin page, and the router support DNS modifying.
  • Using another proxy server: if you can setup another proxy server (Fiddler for example. see http://conceptdev.blogspot.com/2009/01/monitoring-iphone-web-traffic-with.html) and set iPhone to use proxy server and set hosts file on that machine to our server. This will redirect the traffic through the proxy server and finally to our Ruby server. 
  • Edit /etc/hosts (for rooted iPhone): install "iFile" app from Cydia, then navigate to /etc and open "hosts" file to edit. (more about hosts file http://en.wikipedia.org/wiki/Hosts_(file))
  • Setting up a new DNS server: possible but it'd be a hassle.
After the connection setting is working, try using Siri with an app such as Notes.app , server will dump some data out (including session data) that we can use later
- Make Siri dictation request, for example from the Notes.app application. On the server, this will dump all the "interesting" bits (X-Ace-Host identifier, sessionData and such).

8. Configure Ruby client (for speech-to-text)
In the downloaded files, there is a file called "Siri.old.inline.rb", used for speech-to-text conversion.
This file takes

  • Input audio file name: In the file, "input.sif" is fixed as the input. Change it if you need it.
  • Session data: needs several values captured from Ruby server step 7. to replace the word "COMMENTED_OUT"
  • Siri server address: By default, it connect directly to guzzoni.apple.com, but you can comment out/change address to localhost, or other host.


If the session data values are captured, "theoretically" you do not need Ruby server and iPhone anymore. In this step you can put the captured data in this file, and connect directly to guzzoni.apple.com.

9. Prepare Speech file
  • First, prepare a sound file for any format. You can use the original speech file from Step 2. (recording.m4a) or you can use a software to record your own voice (I use Audacity to do it). 
  • Then convert it into raw format by using ffmpeg. Because the Speex tool has default input format as "raw PCM input is 16-bit, little-endian, mono", ffmpeg will have "-acodec pcm_s16le". Command use:

    ffmpeg -i recording.m4a -acodec pcm_s16le -f rawvideo recording.raw

  • Convert raw sound file into .sif:

    speexenc testsound.raw input.sif
10. Run Ruby client 
Simply use command
./Siri.old.inline.rb

It will load the input speech file (default=input.sif) and connect to Siri server, get data back and then dump the data on the screen.



Some More Screenshots

Server dumps data that client sending through it


Got this "Not authenticated" appears on client-side because I do not have session data


Errors I Found
  • "what(): Encryption not available on this event-machine"
    • Ruby's library "eventmachine" is required SSL library to connect to HTTPS. 
    • To fix it, install "libssl-dev" (Ubuntu package)
  • "eventmachine.rb:572:in `start_tcp_server': no acceptor (RuntimeError)"
    • Ruby's library "eventmachine" cannot bind to a port while creating a server, dues to permission
    • Use super-user (sudo) to run the program, e.g. sudo ./siriServer.rb

Test Environment:

  • Ubuntu 11.10 x64
  • Ruby 1.8



Hope I can complete this tutorial soon.
(if I can find an iPhone to test)



UPDATE (related links):



11/10/2011

Convert String to Binary in Ruby

As for the sake of today 11/11/11,
Everything is in binary mode.
Why not do a conversion between String and binary :)

Conversion from String to binary
Easiest way, using unpack and tell Ruby that it is binary
"Hello".unpack("B*")
=> ["0100100001100101011011000110110001101111"]

You can specify length of each binary by replace * with total length of the word (default binary has 8 bit per character)
"Hello".unpack("B40")
=> ["0100100001100101011011000110110001101111"]

The output is in array format, removing an array can be done by adding [0] to select the first element from array.
"Hello".unpack("B*")[0]
=> "0100100001100101011011000110110001101111"

Other method is to break down the string into characters first and get ASCII number of each character, then convert them to binary.
Here is a way for breaking a String into ASCII character code.
‎"Hello".unpack("C*")
=> [72, 101, 108, 108, 111]

Then using print formatting with %b to convert each ASCII code (int) to binary
"Hello".unpack("C*").each{|c| print "%08b" % c}

Another way to do using split('')
"Hello".split('').each{|c| print "%08b" % c[0] }
=> 0100100001100101011011000110110001101111

Or you could use scan(/./)
"Hello".scan(/./).each{|c| print "%08b" % c[0] }
=> 0100100001100101011011000110110001101111

Actually there is another method for converting number into binary, it is using ".to_str(2)" but this method doesn't put leading-zeros in the result, as you can see:
"Hello".scan(/./).each{|c| print "%08s " % c[0].to_s(2) }
=> 1001000 1100101 1101100 1101100 1101111

Conversion from binary back to String
Same as above, we can use the same method to convert binary back to String
a="0100100001100101011011000110110001101111"
[a].pack("B*")
=> "Hello"

Or split it by 8 digit each, then convert each 8 digit to int , then to character
a="0100100001100101011011000110110001101111"
(0..a.length).step(8).each {|i| print a[i,8].to_i(2).chr}
=> Hello



P.S.
After reading .pack and .unpack function API, I found that Ruby has a built-in Base64 encoder/decoder.
To use it just use pack() or unpack() with "m" directive
Base64 Encoding
["Hello"].pack("m*").chomp
=> "SGVsbG8="
Base64 Decoding
"SGVsbG8=".unpack("m*")[0]
=> "Hello"

11/04/2011

Enable USB Devices on Virtualbox on Ubuntu Host

My test environment:
- Ubuntu 11.10
- Virtualbox 4.1.2 + extension pack

To enable USB devices in Virtualbox after installed it, is only add your username into vboxusers group (created by Virtualbox)

step by step (ordinary method):

 1. sudo vi /etc/group
 2. add your username in the line that says
vboxusers:x:125:
, so it would be
vboxusers:x:125:anidear
(where as "anidear" is the username)
 3. save and restart Ubuntu for it to take effect.

short way:
  sudo usermod -G vboxusers -a anidear
(where as "anidear" is the username)