Pages

12/23/2013

My Note About Git

Git Config

  • ดู configuration ปัจจุบันของ git ได้ด้วย : git config -l
  • เซ็ตค่าสำหรับเฉพาะ git repo นั้น : git config --local  .........
  • เซ็ตค่าสำหรับทุกๆ git repo : git config --global  ........

Git Remote

  • ดู remote repo ทั้งหมด : git remote -v
  • เพิ่ม remote : git remote add origin username@server_ip:path_name.git
  • ลบ remote : git remote remove origin
  • แก้ URL ของ git remote : git remote set-url origin username@server_ip:path_name.git
  • แก้ URL ของ git remote #2 : git remote set-url origin ssh://username@server_ip/path_name.git

Git Bare & Git Non-Bare

Git repository สามารถสร้างได้ 2 แบบคือ แบบ bare กับ แบบ non-bare
  1. bare repository คือ repository ที่ข้างใน folder นั้นมีแค่ folder ".git" อย่างเดียว
    1. สร้างโดย 
      1. mkdir repo_name; cd repo_name; git init --bare 
      2. หรือ git clone --bare repo_name repo_path
    2. สามารถ config ให้ repo ใดๆที่มีอยู่แล้ว เป็น bare หรือไม่ได้ 
      1. โดยเข้าไปแก้ไฟล์ repo_path/.git/config ให้มีบรรทัด bare=true 
      2. หรือ git config --bool core.bare true
    3. ข้อดี: 
      1. ไม่ต้องเก็บโค้ดอยู่ในตัว folder ที่เก็บ repository
      2. ไม่ต้องคอยสั่ง git reset --hard HEAD บน repo directory เหมือนกับแบบ non-bare
      3. เวลา client จะ push ก็จะขึ้นมาได้เลย เนื่องจากว่าบน server ไม่ได้ checkout โค้ดอะไรไว้เลย
      4. เหมาะกับการใช้บน server
    4. ข้อเสีย
      1. เนื่องจากไม่มีโค้ดของตัวเอง ทำให้ไม่เห็นโค้ดได้ง่ายๆ ต้อง clone/checkout ออกมาก่อน
      2. การใช้ git status และ คำสั่ง git ที่ใช้ในการจัดการไฟล์ จะใช้ไม่ได้ใน directory นี้
  2. non-bare repository คือ repository ปกติ ที่ข้างในจะมีทั้ง ".git" และ ไฟล์อื่นๆที่ commit ขึ้นมา
    1. สร้างโดยคำสั่งแบบเดียวกับ bare แต่ต้องไม่มี "--bare"
    2. ถ้าอยากจะปรับให้ repo ที่เป็น bare ให้เป็น non-bare ต้องปรับค่า bare=false
    3. ข้อดี: บน server จะสามารถเห็นไฟล์และแก้ไขไฟล์ได้  ก็เหมือน checkout ออกมาดูตลอดเวลา
    4. ข้อเสีย: 
      1. เวลาที่ client สั่ง git push ขึ้นมา จะไม่สามารถเอาขึ้นมาได้ โดยจะขึ้นว่า 
        remote: error: refusing to update checked out branch: refs/heads/master
        remote: error: By default, updating the current branch in a non-bare repository
        remote: error: is denied, because it will make the index and work tree inconsistent
        remote: error: with what you pushed, and will require 'git reset --hard' to match
        remote: error: the work tree to HEAD.
        remote: error: 
        remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
        remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
        remote: error: its current branch; however, this is not recommended unless you
        remote: error: arranged to update its work tree to match what you pushed in some
        remote: error: other way.
        remote: error: 
        remote: error: To squelch this message and still keep the default behaviour, set
        remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'
        

        โดยจะต้องไปตั้งค่า receive.denyCurrentBranch ก่อน ถึงจะ push ขึ้นมาได้
      2. เวลาจะ update โค้ดบนฝั่ง server ( directory นี้ ) จะใช้ git pull ไม่ได้ เพราะมันบนเครื่องตัวเอง  ให้ใช้ git reset --hard HEAD แทน

Git Post-Receive Hook

ในการ deploy บน git server เองนั้น  สามารถใช้ hook ได้ ซึ่งหมายถึงว่า เราสามารถตั้งให้ เมื่อใดก็ตามที่ developer สั่ง git push ขึ้นมาบน server ใน branch "master"  เหตุการณ์นี้ก็จะสั่ง hook ที่ชื่อ post-receive เพื่อทำการรัน shell script ที่อยู่ข้างในได้

วิธีทำ
  1. เข้าไปใน ".git" directory ของ directory ที่เป็น repository หลัก ( repository ที่ตั้งไว้ตอน ssh หรือ git clone)
  2. สร้างไฟล์ชื่อ post-receive ภายใน path "hook/"
  3. ข้างในเขียนเป็น shell script โดยมีตัวแปรให้ตั้งสองตัวคือ
    1. GIT_DIR  : ตัวแปรที่ต้องตั้งเพื่อบอกว่า ".git" ที่จะใช้ อยู่ path อะไร
    2. GIT_WORKING_TREE : ตัวแปรที่บอกว่า path ที่จะดึงโค้ดออกมา อยู่ที่ path ไหน
  4. ตัวอย่าง: เมื่อมี push ขึ้นมา ให้เอาโค้ดล่าสุด(HEAD)จาก master ไปลงใน /var/www/myproject
    #!/bin/bash
    export GIT_DIR=~/myproject/.git
    export GIT_WORKING_TREE=/var/www/myproject
    git checkout -f master
    git reset --hard HEAD
    
  5. chmod u+x post_receive

12/20/2013

แอป Money Lover สำหรับจัดการการเงินส่วนตัว

วันนี้จะขอมาแนะนำ Android App สำหรับจดบันทึกรายการค่าใช้จ่ายประจำวัน

App นี้มีชื่อว่า "Money Lover"



ความสามารถหลักต่างๆ เช่น

  • จดบันทึกรายจ่าย (แน่นอนอยู่แล้ว)
  • จดบันทึกรายรับ (บาง app ถึงจะมี)
  • รายจ่ายสามารถแยกเป็นกลุ่มการใช้จ่ายได้ พร้อมทั้งเลือก icon สำหรับกลุ่มนั้นๆได้ด้วย  ปล. สามารถ download icons เพิ่มได้แต่ต้องเสียเงิน
  • ตั้งรายรับ/รายจ่าย แบบเป็นรอบอัตโนมัติได้
  • มีภาษาไทย!
  • มีเครื่องคิดเลขให้ตอนบันทึกรายรับ/รายจ่าย เพื่อจะใช้คำนวนต่างๆเช่นหารต่อหัว, รวมรายการ, ฯลฯ มีประโยชน์มาก
  • มีสรุปประจำเดือนได้  โดยแยกการใช้จ่ายเป็นกลุ่มต่างๆ ได้อย่างชัดเจน
  • มีการจดบันทึกและคำนวนการใช้หนี้ได้
  • มีการตั้งแพลน/งบประมาณ สำหรับการใช้จ่ายได้
  • มีโหมด travel สำหรับ รวบรวมการใช้จ่ายในช่วงเวลาท่องเที่ยวนั้นอยู่ในกลุ่มเดียวกันได้
  • มีการคำนวนอัตราแลกเปลี่ยนโดยดึงอัตราแรกเปลี่ยน ณ เวลาปัจจุบันมาได้
  • มีการ backup/restore ลงไฟล์ได้ และ ลง Dropbox ได้
  • สามารถตั้ง auto-backup ได้ พร้อมทั้งช่วงเวลาการ auto-backup ได้
  • กำลังจะมีเมนู sync ขึ้นมา (ใน version หน้า)
  • และสุดท้ายนี้...  แอปนี้ สวยมาก :)
หลังจากได้ทดลองใช้ app "Expense Manager" ของ Bishinews, และ "Expense Manager" ของ Markus Hintersteiner มา คิดว่า app นี้ดีกว่าสองตัวนี้ที่เคยใช้มามาก ทั้งด้าน features และ user experience. และที่สำคัญคือ เคยมีประสบการณ์ข้อมูลหายมาหลายรอบแล้ว ดังนั้นเลยเห็นความสำคัญของ auto-backup มากๆ 


ต่อไปนี้เป็นภาพตัวอย่าง จากการใช้งานจริง :)

เปิดมามีให้เลือกภาษา และ สกุลเงิน ซึ่งก็มี ไทย บาท ด้วย

หน้ายินดีต้อนรับ

หน้าหลักการจดบันทึกรายการใช้จ่าย

ในหน้าการกรอกตัวเงิน สามารถใช้เครื่องคิดเลขได้ด้วย

หน้าหมวดหมู่ มีรายการหมวดหมู่ พร้อมไอคอนมาให้สังเกตได้ง่าย 
ทั้งฝั่งรายรับและรายจ่ายด้วย

พอจดบันทึกแล้ว ก็จะมีสรุปเป็นรายวัน เรียงลงไปข้างล่าง

พอดูรายงานประจำเดือน ก็จะเห็นสรุปรายรับ และ รายจ่าย
รวมถึงแสดงยอดรายจ่ายที่แพงสุดประจำเดือนด้วย

พอเลื่อนรายงานประจำเดือนลงนิดนึง 
จะเห็นว่ารายจ่ายแยกตามหมวดหมู่ชัดเจน

สำหรับถ้าใครอยากใช้งานแบบ ไม่มีโฆษณา สามารถเลือกจ่ายประมาณ 64 บาท โดยเลือกจากในเมนูในโปรแกรมได้เลย
แต่ถ้าจ่าย License ก็จะได้ app แบบไม่มีโฆษณา และสามารถใช้ได้หลายบัญชี(หลายประเป๋าตังค์)พร้อมกันได้ ราคาเพียง 161 บาทเท่านั้น













12/19/2013

Flashing My Nexus 5

My previous phone was Nexus S, which I installed Cyanogen Mod 10 in it, and it's very fun to play with, except the fact that now it's very slow dues to the growing size of applications.

Then I bought my Google Nexus 5 phone for almost a month ago. What I have experienced is a very fast response from my phone (of course, it's newer), but I am not satisfied at all with the stock ROM that came with it. I don't really have any high hope on it, but it does poorer than what I expected. For example, I can't add a new home screen to the left (why?), I can't customize menus on my quick panel. Just few little things that I can't do that frustrates me.

I was thinking about using Cyanogen Mod for awhile but I didn't, because I thought it wasn't released for Nexus 5 yet.

Today, my friend just informed me that it was out. The CM11 M1!

And he suggested me to use the new recovery image from Team Win, instead of Clockwork Mod, because it provides touch capability. I don't care such a minor detail, but I try anyway.

Flashing recovery image (Team Win Recovery Project 2: TWRP2)
    - Download the newest recovery image from
        - http://techerrata.com/browse/twrp2/hammerhead
    - Boot the device into bootloader mode by either
        - turn on the device while holding lower volume button
        - using command "adb reboot bootloader" (usb cable must be connected)
    - Make sure that USB cable is connected and fastboot command sees the device by using
        - fastboot devices
        - *sometimes need to use sudo to do it
        - if the result shows something like "0313a8b9508b7cf0   fastboot" then it's ready
    - Install recovery image using command
        - fastboot flash recovery <filename>
        - * change <filename> to the file downloaded, e.g. openrecovery-twrp-2.6.3.4-hammerhead.img
    - wait until the writing is done, then reboot

Flashing ROM image (Cyanogen Mod 11.0 M1: CM11.0 M1)
    - Download the latest rom image from the link below, onto the device (in under /sdcard)
        - http://download.cyanogenmod.org/?device=hammerhead
    - Reboot in recovery mode using command
        - adb reboot recovery
    - (Optional) Wipe System & Dalvik Cache
        - Wipe
        - select Advance wipe (DONOT SELECT FORMAT DATA)
        - select System & Dalvik Cache
        - Swipe to wipe
    - Select "install"
    - Browse to the downloaded ROM image (its name should be something like cm-11-20131210-NIGHTLY-hammerhead.zip)
    - Swipe to flash
    - Reboot system

Flashing Google Apps (gapps)
    - CM doesn't come with Google Apps, even the play store, so we need to install it.
    - Download the latest for Kitkat at the link below into /sdcard
        - http://www.androidfilehost.com/?a=show&w=files&flid=10238
    - Reboot into recovery mode
    - select Install
    - browse for this downloaded file
    - swipe to install

To revert everything back to the original
http://www.androidbeat.com/2013/11/flash-factory-image-nexus-device/

12/18/2013

Upgrading to Sublime Text 3 (Beta)

As of today (Dec 17, 2013), Sublime Text 3 is still in beta-testing, not a fully-functioning official released yet.

I have been using Sublime Text 2 for several months now, and I find nothing wrong with this version.
But this morning, I found that it just released another build-release (build-3059) and it seems to fix a lot of things. I am kinda excited to try out, so I remove my Sublime Text 2 and install a new one.

I know that Sublime usually gives us a downloadable binary to download and install it on our computer manually, but that isn't a way to on Linux. Any linux user would want to have a way to install it with APT for sure. Therefore, I went to search for an apt repository to be able to incorporate it in my machine. And I found a PPA from webupd8team that does just that.

Here is how to add this PPA and install Sublime 3 with this method:
sudo add-apt-repository ppa:webupd8team/sublime-text-3
sudo apt-get update
sudo apt-get install sublime-text-installer

Pretty easy, huh?

Well, I've done this, and found myself with Sublime Text 3 with an older release than 3059.

I know that this is not an official Sublime repository and the team might have some other things to do rather keeping up with every release of Sublime Text, but I just want only the latest update, so I uninstall it :p

Good thing is I don't have to keep updating Sublime Text with only apt (like in Sublime Text 2). In Sublime Text 3, there is a built-in update notification.

Great! So I can just download and install the binary from the Sublime website, and that's it.

Finally,...


In Additions:
  • I found this website (http://www.caniswitchtosublimetext3.com/) before I did the upgrade. It provides a check on whether your Sublime plugins are still good on Sublime Text 3 or not.
  • I immediately install "Package Control" for Sublime plugin manager, by pressing Ctrl+` (backtick, located under ESC), then paste this in the box
import urllib.request,os; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); open(os.path.join(ipp, pf), 'wb').write(urllib.request.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ','%20')).read())
  • To use Package Control, press Ctrl+Shift+P, then select "Package Control: ......"

12/16/2013

14 โปรเจ็คเด่นของ Kickstarter ในปี 2014

Mashable.com รวบรวมลิสต์ของ 14 โปรเจ็คที่น่าสนใจ และส่วนใหญ่จะเริ่มผลิตออกมาในปี 2014 นี้
ดูรายการทั้งหมดที่ http://mashable.com/2013/12/16/kickstarter-projects-2014/

ข้างล่างต่อไปนี้ เป็นแค่ตัวอย่างบางส่วน

FlyKly Smart Wheel

   FlyKly เป็นล้อของจักรยานที่มีมอเตอร์อยู่ในตัว  ช่วยให้ลดแรงที่ต้องใช้ปั่นลงได้เช่นในกรณีปั่นระยะทางไกลๆ หรือปั่นขึ้นเนิน  แถมยังรีชาร์ตแบตเตอรี่ตัวเองได้ด้วยเมื่อปั่นลงเนิน หรือจะเสียบสายชาร์ตก็ได้

   FlyKly สามารถควบคุมผ่านระบบมือถือได้  รองรับทั้ง i-phone, android, และ pebble watch

   ข้อดีอีกอย่างนึงของ FlyKly คือ เมื่อเวลาจอดรถแล้ว สั่งจากมือถือให้ล็อครถจักรยานได้เลย โดยมอเตอร์ในตัวก็จะล็อคไม่ให้ขยับไปไหน  และถึงแม้ว่าจะมีขโมยมายกรถไปทั้งคัน  ในตัว FlyKly ยังมีระบบ GPS เอาไว้ติดตามหาตัวรถได้ด้วย


Ninja Sphere

   Ninja Sphere เป็นอุปกรณ์ที่อยู่ในบ้าน และคอยตรวจสอบว่า อุปกรณ์ไร้สายของเราต่างๆ อยู่ส่วนไหนของบ้านบ้าง มีใครเคลื่อนย้ายไปไหนรึเปล่า และอีกทั้งควบคุมอุปกรณ์เหล่านั้นผ่านทาง Ninja Sphere ได้หมดเลย  สามารถควบคุมด้วยการใช้มือได้(เหมือน Kinect, Leap Motion)



Infoactive

   เป็นโปรเจ็คที่สร้าง web application ออกมาเพื่อที่จะจัดทำข้อมูลดิบออกมาเป็น infographic ซึ่งพอเสร็จแล้วจะสามารถคลิ๊กที่ infographic นั้นได้ เพื่อเลือกข้อมูลต่างๆ แถมยังเอาออกมาแปะกับ website ในรูปแบบ embed เพื่อแสดงผลข้างนอกได้อีกด้วย



Touch Board

   โปรเจ็คที่ทำให้ electronic เข้าถึงทุกคนได้ โดยการใช้ควบคู่กับ electronic paint ซึ่งเป็นสีที่ใช้วาดภาพและนำไฟฟ้าได้ในตัว  เมื่อวาดภาพด้วย electronic paint และต่อกับ Touch Board แล้ว ก็จะสามารถสั่งงานให้ Touch Board ทำงานได้ เพียงแค่แตะ หรือ นำมือไปใกล้ๆกับรูปที่วาดไว้เท่านั้นเอง

PHP flaw in stripos and eregi

เมื่อวันก่อน Longcat เอาปัญหาจาก CTF อันนึงมาให้ดู
ในโจทย์คือ จะต้อง SQL injection เพื่อเอาชื่อตารางออกมาให้ได้
ซึ่งแน่นอนว่าจะต้องเอามาจาก information_schema.tables

แต่ปัญหาคือ โค้ด PHP ตัวนี้มีการป้องกันการโจมตีแบบต่างๆไว้ คร่าวๆ ดังนี้

if(stripos($_GET['val'],'schema')) exit();
if(eregi("union",$_GET['val'])) exit();
if(eregi("select",$_GET['val'])) exit();
if(eregi("from",$_GET['val'])) exit();
if(eregi("/",$_GET['val'])) exit();
if(eregi("\*",$_GET['val'])) exit();
if(eregi("#",$_GET['val'])) exit();
if(eregi("-",$_GET['val'])) exit();
if(eregi(",",$_GET['val'])) exit();
if(eregi("=",$_GET['val'])) exit();
if(eregi("!",$_GET['val'])) exit();
if(eregi("\|",$_GET['val'])) exit();
if(eregi("by",$_GET['val'])) exit();

ซึ่งเอาแค่สรุปหลักๆ จากการป้องกันก็คือ  ป้องกันไม่ให้ใช้คำว่า schema, select, from, union, และเครื่องหมาย comment ต่างๆได้เลย   และถ้าหลอกล่อด้วยการใช้ ตัวใหญ่ตัวเล็ก ก็ไม่ได้

แล้วจะทำยังไงดี?

จนเมื่อ CTF นี้ จบแล้ว  ได้ Xellos มาเฉลยว่า โค้ดชุดนี้ มีช่องโหว่อยู่

ช่องโหว่ของ if + stripos()

ถ้าไปค้นหาคำสั่ง strpos() หรือ stripos() ดูจาก PHP documentation ในเว็บ php.net (http://www.php.net/manual/en/function.stripos.php) ก็จะรู้ว่า

  • stripos จะค้นหาคำจากซ้ายไปขวา
  • ถ้า พบคำที่ค้นหา จะส่งคืนเป็นตำแหน่งของตัวอักษรตัวแรกที่เจอออกมา  โดย เริ่มต้นที่ 0
  • ถ้า ไม่พบ จะคืนค่าออกมาเป็นบูลลีน FALSE
และมีคำเตือนสีแดงชัดเจนว่า...


นั่นหมายความว่า stripos สามารถคืนค่าเป็น 0 ได้  ซึ่งมันจะถูกตีความเป็น FALSE ได้  *0*

นั่นคือ ถ้าเราส่ง $_GET['val'] ให้มีคำว่า "schema" เป็นคำเริ่มต้น
stripos($_GET['val'], 'schema') ก็จะให้ค่าออกมาเป็น 0
ซึ่งถ้าเราเอาไปตรวจสอบด้วย if ( 0 )  มันก็จะได้ค่าเท่ากับ if ( FALSE ) นั่นเอง
แล้วก็เลยทำให้ bypass filter ตัวนี้ไปได้

วิธีป้องกัน
ควรเขียน "===" ใน if ด้วย เพื่อป้องกันการ casting ชนิดตัวแปรจาก integer( 0 ) ไปเป็น boolean(FALSE) แบบที่เราไม่ได้ตั้งใจ ซึ่งโค้ดข้างบน ควรจะเขียนเป็น

if(stripos($_GET['val'],'schema') === TRUE) exit();

ช่องโหว่ของ eregi()

เนื่องจากโค้ดของ ereg() หรือ eregi() ใน PHP ยังใช้การทำงานของภาษา C อยู่ข้างใน

คำถามคือ: เมื่อไหร่ที่โค้ดภาษา C จะหยุดการทำงานกับ String?

ตอบ: เมื่อมันเจอ null byte (0x00, \0, หรือ chr(0) ) ซึ่งปกติจะมีอยู่ตัวเดียวที่อยู่ท้ายสุดของ string นั้น

แต่ถ้าเกิดเราใส่ null byte ให้ตั้งแต่ตัวอักษรแรกเลยล่ะ? แล้วเอาไปค้นหาด้วย ereg
ereg พอวิ่งมาถึงตัวแรก ก็เจอ null byte ซึ่งบอกว่า นี่มันปลายสุดของ string แล้ว ไม่ต้องทำอะไรต่อแล้ว
และมันก็จะถือว่า วิ่งมาไม่พบอะไร และ return FALSE กลับไป

นั่นทำให้ หลัง null byte นี้ เราสามารถใส่อะไรที่ filter ข้างบนห้ามไว้ลงไปได้หมดเลย ถือเป็นการ bypass filter แบบที่ใช้ ereg* ได้

วิธีป้องกัน
ควรย้ายไปใช้ฟังก์ชั่นตระกูล PCRE preg_* จะป้องกันปัญหาของการใช้ null byte กับฟังก์ชั่นตระกูล ereg* ได้
( แต่อาจจะเจอปัญหาอื่นเพิ่มใน preg_* เช่น \n, /e )




10/03/2013

Unlock Protected Excel File

For .XLS 


1. For protected excel file that has VBA disabled.
open any hex editor tool
search for "DPB", then change it to "DPx"
save and open the file normally.
Excel will say the file is a little corrupted, but it is fine. Just need to save and re-open it again.

2. After the enable VBA on the file, if the sheet or workbook is protected.
open the file
press ALT + F11 to open VBA
right click on module folder to create a new module (not class module)
copy the code from http://www.zorvek.com/excel/unlocking-workbooks-and-sheets.htm and paste in the module.

2.1 To unlock the sheet
switch to excel window
open the protected sheet
then switch back to VBA window
click mouse to have the cursor inside "UnlockSheet()" sub-module
click F5 to run
the popup will appear, just close it, and you'll have the unlocked sheet

2.2 To unlock the workbook
do the same as 2.2, but have the cursor inside "UnlockWorkbook" sub-module instead.

3. Unlock Macro/VBA Source Code
Even the VBA window can be displayed with ALT+F11, you can't really go to see the existing code in each macro.
It will pop-up error as "Unexpected error (40230)"
The way to fix it is right click at any macro file in VBA window
select "VBAProject Properties..."
go to "protection" tab
check at "Lock project for viewing"
set the password as you will remember
then OK, and save, and close the file
re-open the file, go to VBA window again,
unlock it with your password
Now you'll be able to read all the source code.
And you probably need to go to "VBAProject Properties..." again to uncheck "Lock project for viewing".

For .XLSX


rename the file extension from .xlsx to .zip
go inside to xl\worksheet subfolder
there will be sheets in their separated XML files
open the protected one with a text editor (e.g. notepad)
search and find the line that says "<sheetProtection password=......../>" and delete this whole tag.
save the file
zip it back, then rename it back to .xlsx


For .XLSM


found this way to go inside .XLSM zip file then replace the password hash with the password "macro"
http://lbeliarl.blogspot.com/2012/12/for-excel-20072010.html

9/08/2013

Keyboard Layout To Colemak

Lately, I got a chance to work with people that came from different nations: Germany, Italy, France.
When I go to their machine to type something in, they all use different layouts and that makes me quite frustrated.

At that point, I learned that there are more than just one layout, even for English.

I later found that there are some research that on improving efficiency on typing, some says ...

The disadvantages of QWERTY are:

  • The QWERTY layout was designed in the 19th century to allow typewriter salesmen to easily type the word "typewriter" and to prevent typebars from sticking. We've been stuck with QWERTY ever since.
  • Many common letter combinations require awkward finger motions.
  • Many common letter combinations require a finger to jump over the home row.
  • Many common letter combinations are typed with one hand. (e.g. was, were)
  • Most typing is done with the left hand, which for most people is not the dominant hand.
  • About 16% of typing is done on the lower row, 52% on the top row and only 32% on the home row.

Therefore, several keyboard layouts have been invented to resolve these. Some of them are Dvorak, Programmer Dvorak, Colemak.

Dvorak:




Claim to improve the disadvantages on QWERTY.
My opinion on this is it changes too much from QWERTY which will need much more time on erase the old habit from QWERTY, and with the number positions that does not make sense to me. I decided to not use it.

Programmer Dvorak:




Claim to improve speed on programming C, C#, Java, Pascal, Lisp, CSS, XML and alikes.
My opinion is, it quite strange on the symbol positions, and numbers positions.

Colemak:




With Colemak, on change are 17 characters from QWERTY, it will be using less time on adapt the habit, and with Z,X,C,V are still in the same position, so I can still using Cut, Copy & Paste, Undo while I'm adapting to the new layout.

In the end, I chose to try on using Colemak. Hope I can be fluent in this in no time.

References:


6/25/2013

สร้าง SSH Key สำหรับติดต่อกับเครื่อง EC2 แบบไม่ต้องพิมพ์รหัสผ่าน

สร้าง SSH Key สำหรับติดต่อกับเครื่อง EC2 แบบไม่ต้องพิมพ์พาสเวิร์ด


หมายเหตุ: ในที่นี้ใช้ EC2 ที่มี OS แบบที่เป็น Ubuntu-based นะครับ

ก่อนอื่น แก้ไขไฟล์ /etc/ssh/sshd_config เพื่อเปิดใช้งาน AuthorizedKeysFile ก่อน  เพื่อระบุว่า path ของไฟล์ที่เก็บ public key จะให้อ่านจากตรงไหน  โดยค่าปกติ จะเป็น

#AuthorizedKeysFile %h/.ssh/authorized_keys

ก็แค่เอา # ออก หรือจะเพิ่มต่อท้ายไฟล์ก็ได้ ด้วยคำสั่ง

sudo sh -c 'echo "AuthorizedKeysFile %h/.ssh/authorized_keys" >> /etc/ssh/sshd_config'

จริงๆจะต้องเช็คค่า สองตัวนี้ด้วยว่าเป็น yes รึเปล่า

RSAAuthentication yes
PubkeyAuthentication yes

ต่อจากนั้นก็สร้าง user
ในที่นี้ใช้ชื่อ anidear โดยจะสร้างให้มี group หลักเป็นชื่อของตัวเอง และเพิ่ม Group เสริมเป็น admin เพื่อที่จะสามารถใช้สิทธิ์ sudo ได้

sudo useradd -m -s /bin/bash anidear
sudo usermod -G admin anidear
sudo passwd anidear

แล้วใส่ รหัสผ่าน สำหรับ user นี้

ต่อมาก็เข้าไปใช้งาน user นี้ และสร้าง ssh key
su - anidear
ssh-keygen -t rsa -b 1024 

จะขึ้นว่า

Enter file in which to save the key (/home/anidear/.ssh/id_rsa): 

กรอกตำแหน่งที่จะเอาไฟล์ไว้ โดยมาตรฐานจะเป็น ~/.ssh/id_rsa  ถ้าโอเคอยู่แล้วก็กด enter ผ่านได้เลย

ต่อมาจะขึ้นว่า

Enter passphrase (empty for no passphrase):

ตรงนี้จะให้กรอกว่า รหัสผ่านสำหรับเปิดใช้ไฟล์ key นี้ คืออะไร ซึ่งจะเป็นคนละตัวกับรหัสผ่านของ user ที่กรอกไว้ตอนใช้คำสั่ง passwd

แล้วก็เริ่มทำ ให้ ssh key ที่เพิ่งสร้างนี้ใช้งานได้

cd .ssh
cat id_rsa.pub >> authorized_keys
chmod 600 *
cat id_rsa

คัดลอกโค้ดรหัสผ่านตัวนี้ไว้(private key) เก็บลงในไฟล์ในเครื่องที่จะเป็น client (เช่นเก็บไว้ที่ ~/.ssh ของ client) หรือจะใช้ ftp,http,sftp ดึงไว้นี้เก็บไว้ก่อนก็ได้

เสร็จแล้วก็เคลียร์ไฟล์ทิ้ง
rm id_rsa{,pub}
exit

แล้วก็สั่ง service ssh reload ก็ เป็นอันเสร็จพิธี

ส่วนเวลาใช้งาน ก็คือ

สมมุติว่าเก็บ private key ไว้ที่ ~/keys/ec2_private_key
และ public hostname ของเครื่องเป็น ec2-1-1-1-1.ap-southeast-1.compute.amazonaws.com

ใช้ไฟล์ตรงๆเลย ก็จะเป็น
ssh -i  ~/keys/ec2_private_key anidear@ec2-1-1-1-1.ap-southeast-1.compute.amazonaws.com

แต่ถ้าเก็บ key เอาไว้ในระบบ(เครื่องตัวเอง) ก็ ใช้คำสั่ง ssh-add

ssh-add ~/keys/ec2_private_key

จะเป็นการเก็บ private key นี้ไว้ในระบบ ssh ของเครื่อง
ทำให้เวลาต่อไปหา server จะไม่ต้องระบุ path ของไฟล์ private key แล้ว

ssh  anidear@ec2-1-1-1-1.ap-southeast-1.compute.amazonaws.com

แต่เพื่อความสะดวก ยิ่งขึ้น
สามารถ แก้ไฟล์ ~/.ssh/config โดยเพิ่ม

Host anidear_at_ec2
 HostName ec2-1-1-1-1.ap-southeast-1.compute.amazonaws.com
 User anidear
 IdentityFile ~/keys/ec2_private_key

เมื่อทำเสร็จแล้ว ก็ login ตรงๆได้เลย โดยไม่ต้องระบุ username

ssh ec2-1-1-1-1.ap-southeast-1.compute.amazonaws.com

[Optional] 
เนื่องจากการตั้งให้ user ที่เพิ่งสร้างอยู่ในกลุ่ม admin
เวลาเรียกใช้งาน sudo ยังคงจะต้องใช้รหัสผ่านของ user อยู่
ถ้าต้องการให้ไม่ต้องใช้รหัสผ่านเลย ให้ไปสร้างไฟล์เพิ่ม

sudo sh -c 'echo "anidear ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/91-anidear'

[Optional2]
ssh-add จะใช้ private key ในการเพิ่ม key เข้าระบบ แต่จะใช้ public key ในการถอดออก
ดังนั้น ถ้าตอนเพิ่มใช้คำสั่ง

ssh-add ~/keys/ec2_private_key

ตอนถอนออก จะต้องไปดาวน์โหลด public key ที่คู่กับ private key ตัวนั้นออกมา
ในที่นี้ก็คือ ไปคัดลอกมาจาก ภายในไฟล์ ~/.ssh/authorized_keys ของ server
และสมมุติว่า เอามาแปะ และสร้างเป็นไฟล์ชื่อ ec2.pub
เวลาจะถอดออกจะใช้คำสั่ง

ssh-add -d ~/keys/ec2.pub



6/09/2013

อธิบายการทำงานของ Reaver สำหรับ Crack Wifi ที่ใช้ระบบ WPS

วันนี้มีคนถามว่า
"iteasy": ใครลอง reaver wps แล้วมั้ง
"iteasy": สงสัยว่ามัน brute ยังไง
"iteasy": ทำไมเลขไม่เรียงหว่า
"iteasy": 0000001
"iteasy": 0000002
"iteasy": 0000001 0000002 0000003
"iteasy": แบบนี้ไปเรื่อย ๆ
"iteasy": แต่กลับข้าม
"iteasy": 00555678 00565677 00575676
เลยขออ้างอิง บล็อคของ Xelenonz [2.] มาตอบ และ บรรยายเพิ่มเติม ละกัน

โดยในนั้นจะมีคำอธิบายคร่าวๆ ถึงว่า ระบบ WPS (Wi-Fi Protected Setup) คืออะไร, มีช่องโหว่อย่างไร, และวิธีการใช้งานของ Reaver  ซึ่งจะไม่ขอกล่าวซ้ำ ณ ที่นี้

เนื่องจาก ระบบการตรวจสอบรหัสผ่านของ WPS นั้น มีช่องโหว่ในการตรวจสอบรหัสผ่าน (เลข 8 หลัก) ที่ใช้ในการอนุญาตให้เข้าใช้งาน Wi-Fi

โดยช่องโหว่นั้นก็คือ 

แทนที่การตรวจสอบรหัสผ่านจะใช้ตรวจสอบทีเดียวทั้ง 8 หลัก
แต่ระบบ WPS จะทำการแบ่งตัวเลข 8 หลักนั้นเป็น 3 ส่วน คือ PIN1 (4หลักแรก) , PIN2 (3หลักต่อมา) , Checksum (หลักสุดท้าย) และทำการตรวจสอบส่วน PIN1 ก่อน ถ้าถูกแล้วจึงทำการตรวจสอบ PIN2 แต่ถ้าผิดก็จะมีการบอกว่าผิดตั้งแต่การตรวจสอบ PIN1 เลย
นั่นเลยทำให้  จึงทำให้การโยนเลขเข้าไปทดสอบสามารถทำแยกเป็นส่วนๆได้ คือ รันเลข PIN1 ไปจนกว่าจะถูก แล้วจึงค่อยรันเลข PIN2 ก็ได้

ส่วน ค่า Checksum ที่จะต้องเปลี่ยนตามเมื่อมี PIN1 หรือ PIN2 เปลี่ยนไป ดังนั้น จะเปลี่ยนแปลงตลอดอยู่แล้ว และสามารถสร้างขึ้นได้จากการใช้ตัวเลข 7 ตัว (PIN1 และ PIN2) มาสร้าง ดังนั้นจึงไม่มีความจำเป็นที่จะต้องรันเลขหลักนี้

จึงทำให้ในกรณีตัวอย่าง ที่ว่า โปรแกรม Reaver จะทดลองรันค่าที่เอาไปใช้เพื่อในระบบ WPS จะเรียงเลขเป็น

00555678, 00565677, 00575676, ...


จะเห็นว่า ค่า PIN1 (4 ตัวแรก) จะมีการรันเลขเป็น
0055, 0056, 0057, ...

แต่ PIN2 (3 ตัวถัดมา) จะยังคงค่าเดิม เพราะส่วนนี้ยังไม่ได้ถูกใช้งาน ซึ่งจะเห็นว่าเป็น
567, 567, 567, ...

และ Checksum (หลักสุดท้าย) จะมีการเปลี่ยนแปลง เนื่องจากมีการเปลี่ยนตัวเลขใน PIN1 หรือ PIN2 ขึ้น จึงจะเห็นว่า เลข checksum นี้ก็จะเปลี่ยนไปด้วย
8, 7, 6, ...

ผลจากช่องโหว่นี้ก็คือ


จากเดิม ถ้าเราไม่รู้หลักการทำงานลึกๆของการยืนยันตัวเองในระบบ WPS , พอเราเห็นเลข 8 หลัก เราก็จะคิดว่าเราจะต้องทดลองแทนค่าตั้งแต่
00000000 ... 99999999 : คิดเป็นจำนวนมากสุด 100,000,000 ครั้ง
แต่พอเรารู้ช่องโหว่นี้ ทำให้เรารู้ว่า
เราต้องทดลองแทนค่าของ PIN1 ก่อน ซึ่งมี 4 หลัก ก็จะทดลองแทนค่า
0000 ... 9999 : คิดเป็นจำนวนมากสุด 10,000 ครั้ง

แล้วเราค่อยทดลองแทนค่า PIN2 ต่อ ซึ่งมีทั้งหมดแค่ 3 หลัก ซึ่งก็จะแทนค่า
000 ... 999 : คิดเป็นจำนวนมากสุด 1,000 ครั้ง

ส่วนเลขหลักสุดท้ายที่เป็น Check-sum นั้น ไม่ต้องนับเพราะมันจะถูกคำนวนจากตัวเลข 7 หลักก่อนหน้าอยู่แล้วได้โดยอัตโนมัติ

ทำให้การใช้งานช่องโหว่นี้ของโปรแกรม Reaver
จะทำให้มีการทดลองแทนค่าเพียง 10000 + 1000 = 11,000 ครั้งเท่านั้น
แทนที่จะเป็น 100,000,000 ครั้ง อย่างวิธีดิบๆอย่างแรก

ผลก็คือ การ bruteforce เพื่อหารหัสของ WPS จะทำได้เร็วขึ้นจากเดิมถึง 909,090 เปอร์เซนต์ !!!


และถ้า การทดลองแทนค่าแต่ละครั้ง ใช้เวลา 3 วินาที (อ้างอิง [2.]) การแทนค่า 11,000 ครั้งจะเสียเวลามากที่สุดอยู่ที่ราวๆ 9 ชม. เท่านั้น! ซึ่งเป็นเวลาที่ไม่ถึงกับรอไม่ได้ และในสถานการณ์จริงอาจจะใช้เวลาน้อยกว่า 9 ชม.มาก (อาจจะอยู่ที่หลักไม่กี่ชม.)

ซึ่งนี่ต่างกับวิธีคิดแบบแทนที่ตรงๆ มาก ซึ่งวิธีนั้นถ้าคำนวนแล้ว อาจจะต้องใช้เวลาถึง 9.5 ปี

หรือต่อให้ถ้าแทนค่าแค่ 7 หลัก แล้วหลักสุดท้ายคำนวนหาค่า checksum แยกเองต่างหาก ยังต้องใช้เวลาเกือบ 1 ปี

ซึ่งถ้าเป็นเช่นนั้น คงไม่มีใครแน่ๆ ที่ยอมเสียเวลากับการพยายามเข้าไปใช้ Wi-Fi Access Point ตัวเดียว ถึงขนาดนั้น .... แต่นี่มันไม่ได้เป็นเช่นนั้น

กลับกัน การเจาะเข้าไปในระบบ WPS ใช้เวลาจริงเพียงไม่กี่ชั่วโมงเท่านั้น !!


ส่วนวิธีการป้องกันนั้น


เนื่องจาก ระบบ WPS นั้นผิดพลาดมาตั้งแต่การออกแบบ จึงไม่สามารถแก้ไขอะไรในกลไกของการตรวจสอบรหัสผ่านได้แล้ว จึงแนะนำให้ปิดการใช้งาน WPS ของ Wi-Fi Access Point ของท่าน และปรับให้ใช้ระบบการลงทะเบียนเข้าใช้งาน ใช้เป็นระบบการเข้ารหัสด้วย WPA2 - AES เพื่อความปลอดภัย ของระบบท่านเอง

อ้างอิง:


  1. Bruteforcing Wifi Protected Setup, by Stefan Viehböck : http://sviehb.files.wordpress.com/2011/12/viehboeck_wps.pdf
  2. Crack Wireless WPA แบบได้ผล 100% , by Xelenonzhttp://blog.ipwned.it/crack-wireless-wpa-แบบได้ผล-100/

5/02/2013

Ruby Threading Benchmark

I just heard that Ruby 2.0 was improved in threading speed. So I decided to test it out.

My test environment:
  • Intel i-7 CPU (4 physical cores)
  • Ruby versions are run under Rbenv environment
  • Testing versions: 
    • MRI 1.9.3-p0
    • MRI 2.0.0-p0
    • JRuby 1.7.3 (1.9.3p385)
Code:
if ARGV.size > 0
 num_thread = ARGV[0].to_i
else
 num_thread = 1
end

puts "num_threads = #{num_thread}"

MAX_INT = 100000000

threads = []
num_thread.times{|i|
 threads << Thread.new {
  puts "Thread #{i} started"
  work_load = (MAX_INT/num_thread)
  puts "Thread #{i}: work load = #{work_load}"
  a=0
  work_load.times{|i| a=i }
  puts "Thread #{i} stopped"
 }
}

threads.each { |thr| thr.join }

Run Command:
I use "time" command in Linux to measure the time, and bash for-loop to repeating 10 times for each version.
for i in {1..10}; do time ruby testcode.rb; done

Results:

In average:

  • MRI 1.9.3 ==>  14.3178
  • MRI 2.0.0 ==>  13.5061
  • JRuby 1.7.3 ==> 5.9025

Conclusion:

Ruby MRI 2.0.0 is actually improved in thread performance. Unfortunately, it still does not have an actual threading yet. Unlike in JRuby, which it ran each thread in different CPU cores and caused the time to be much lower than the other two.



4/18/2013

Fix OWASP Mantra's crash at start: Your firefox profile cannot be loaded. It may be missing or inaccessible.

Problem:

Cannot start Mantra after installation with error message:
"Your firefox profile cannot be loaded. It may be missing or inaccessible."


My Environment:

  • Xubuntu 12.10 x64
  • Install OWASP Mantra (Janus version) from www.getmantra.com with installer
  • set installation directory to /pentest/mantra


Solution:

Edit file "OWASP Mantra" and change the following lines

echo "${app}portable:Debug/Info: 0="$0""
dir=${0%/*}
to

#echo "${app}portable:Debug/Info: 0="$0""
#dir=${0%/*}
dir=/pentest/mantra

Summary: 

Change the start-up script to use a direct absolute path for "dir" variable



4/16/2013

Writing Trojan App For Android (By LiquidSecurityNet)

Writing Trojan App For Android (By LiquidSecurityNet)

In these vdos, shows how to create a simple android application that receives commands from SMS and doing covert opertions.

Part 1/3

Part 2/3

Part 3/3

4/08/2013

เพิ่ม Build System ของภาษา PHP ใน Sublime Text 2

เพิ่ม Build System ของภาษา PHP ใน Sublime Text 2

 สร้างไฟล์ PHP.sublime-build เก็บไว้ใน ~/.config/sublime-text-2/Packages/User 

โดยมีเนื้อหาข้างในเป็น

{
    "cmd": ["/usr/bin/php","$file"],
    "selector": "source.php",
    "file_regex": "php$"
}

แล้วก็จะใช้งานได้เลย ด้วยการกด Ctrl+B ในหน้าไฟล์ .php (ที่ save แล้วเท่านั้น)

 วิธีการปิดหน้าจอ console ให้กดปุ่ม ESC

3/20/2013

DNS Tunneling with Iodine

หลังจาก เล่าเรื่องวิธีการ by-pass wifi login ด้วยการใช้ tunneling ไปแล้วในบทความที่แล้ว http://blog.anidear.com/2013/03/use-tunneling-to-bypass-wifi.html

DNS Tunneling

คราวนี้มาลองดูว่าถ้าจะ setup ระบบที่เป็น DNS Tunneling จะต้องทำอะไรบ้าง

โดยในบทความนี้ จะใช้ Iodine ในการทำ
(ภาพจาก http://periodictabledesign.com/wp-content/uploads/s002/iodine.jpg)

Iodine เป็นโปรแกรม open source ที่เอาไว้สำหรับสร้าง tunnel ผ่าน DNS protocol (UDP port 53) โดยตัว iodine จะมีโปรแกรมทั้ง 2 ส่วน ทั้ง client และ server

ที่น่าสนใจอีกอย่างคือ คำว่า iodine (ไอโอดีน) เป็น ธาตุที่มีเลขอะตอมเท่ากับ 53 ซึ่งตรงกับเลข port  ที่ใช้ของ DNS protocol เลย

การติดตั้งฝั่ง Server

Iodine เป็น open source ที่มีการ compile ไว้เรียบร้อยแล้วสำหรับระบบต่างๆ ไม่ว่าจะเป็น Windows, Mac, Linux (FreeBSD,OpenBSD,Gentoo,Debian,Arch,Fedora,Ubuntu,Mandriva,Backtrack), ถึงขนาด Android ก็มี native binary file ให้เลยทีเดียว

เนื่องจาก server ที่ผมใช้เป็น RaspBian (บน Raspberry Pi) ซึ่งมาจากระบบ Debian ก็เลยสามารถใช้ APT เพื่อดึงโปรแกรมมาลงได้เลย ด้วยคำสั่ง
sudo apt-get install iodine
เมื่อลงเสร็จแล้ว iodine จะมีไฟล์ให้รันทั้งแบบ server (ชื่อไฟล์ iodined) และ แบบ client (ชื่อไฟล์ iodine) ทั้งคู่เลย

โดยถ้าจะทดลองรันในแบบ server ก็จะใช้คำสั่งว่า
sudo iodined -f -P test 10.0.0.1 anidear.com
โดย

  • -f  เป็น ตัวบอกให้ iodined รันในโหมดที่แสดงการทำงานของโปรแกรมออกมาทางหน้าจอ
  • -P test  เป็นการตั้ง password ให้กับ tunnel  ในที่นี้ใช้คำว่า test
  • 10.0.0.1  เป็น IP ของเครื่อง server นี้หลังจาก tunnel ได้ถูกสร้างขึ้นแล้ว
  • anidear.com  เป็น ชื่อต้นของ domain ที่จะใช้ในการแทรกข้อมูลในการทำ DNS tunneling เข้าไป

หน้าตาจะออกมาประมาณนี้



การติดตั้งฝั่ง Client

ส่วนฝั่ง client ถ้าจะทดลองในการติดต่อมาหา server ตัวนี้  ก็สามารถลงตัว iodine ด้วยวิธีเดียวกัน (ถ้าเป็น debian base linux) หรือใช้การดาวน์โหลดจาก http://code.kryo.se/iodine/ สำหรับ OS ตัวอื่นๆ

เมื่อติดตั้งฝั่ง client เสร็จแล้ว ก็จะทดลองติดต่อข้อมูลไปหา server ด้วยคำสั่ง
sudo iodine -fP test 192.168.1.33 anidear.com
โดย

  • -f  เป็น การรันในโหมดที่แสดงผลของโปรแกรมผ่านทางหน้าจอ 
  • -P test  เป็น การใส่ password ตอนติดต่อกับ iodined server
  • 192.168.1.33  เป็น หมายเลขไอพี ของ server ที่จะติดต่อไปหา (ซึ่งถ้าเป็นกรณีรันจริงๆ ตรงนี้จะต้องเป็น public IP address ของ server)
  • anidear.com  เป็น ชื่อต้นของ domain ที่จะใช้ในการทำ DNS tunneling

โดยหน้าตาเมื่อลองรันคำสั่งข้างต้น ผลจะออกมาแบบนี้

จะเห็นว่า เมื่อติดต่อสำเร็จ  ฝั่ง client จะเสมือนมีการ์ด network interface ที่ชื่อ "dns0" ขึ้นมา โดยจะถูกจ่าย IP หมายเลข 10.0.0.2 ให้

และ interface ตัวนี้นี่เอง ที่เป็น tunnel ที่เราจะเอาไว้ใช้เหมือนกับ VPN โดยจะให้ข้อมูลที่เราต้องการออก internet วิ่งผ่านช่องทางนี้

อันนี้เป็นการทดสอบเล็กๆน้อยๆกับ tunnel บน dns0 interface นี้


ทีนี้ลองมาดูว่า ข้อมูลที่วิ่งออกวิ่งเข้า โดยผ่าน DNS Tunnel นี่หน้าตาเป็นยังไง

ในรูปนี้ คือการใช้โปรแกรม Wireshark เพื่อทำการดักข้อมูลบน eth0 ซึ่งเป็นการ์ดตัวต้นที่เราใช้สร้าง DNS tunnel (dns0)


นี่เป็นการดักข้อมูล ในขณะที่ฝั่ง client ทำการเปิดหน้าเว็บเพจ ผ่านทาง DNS tunnel ของเรา

เนื่องจาก DNS Tunnel จะแก้ไข DNS packet ให้แตกต่างไปจากธรรมดา เพื่อที่จะยัดข้อมูลลงไปได้ ดังนั้น Wireshark จึงขึ้นแถบสีแดงขึ้นและบอกว่า DNS packet นี้อ่านไม่ออก เพราะมันไม่อยู่ในรูปแบบมาตรฐาน


พอเปิด follow UDP stream จะเห็นว่า ไม่มีส่วนไหนที่อ่านออกเลย
ทั้งๆ ที่ปกติจะใช้การติดต่อแบบ HTTP protocol จะเป็น plain text แปลว่า ข้อมูลควรจะไม่ได้มีการเข้ารหัส และ ควรจะสามารถ เห็นข้อมูลได้โดยตรง ... แต่นี่ไม่เห็นเลย เพราะ iodine ทำการเข้ารหัสข้อมูลไว้ให้ด้วย

ติดตั้งฝั่ง Server ต่อ ให้ใช้งานได้จริง

หลังจากเรารู้แล้วว่าระบบนี้มันใช้งานได้  ก็ถึงเวลาเอาขึ้นไปรันในระบบจริง

ขอสรุปคร่าวๆละกัน

โดย สิ่งที่จะต้องมีคือ

  • public IP address สำหรับ server (อาจจะใช้ เน็ตบ้านและตั้ง router ให้ forward port 53 ก็ได้)
  • domain name
  • เครื่อง server ที่จะเปิดตลอดเวลา
ถ้าลงระบบผ่าน apt-get install เมื่อติดตั้งแล้ว จะมี config ของระบบอยู่ที่ไฟล์ /etc/default/iodine

โดยค่ามาตรฐานเป็น
# Default settings for iodine. This file is sourced from
# /etc/init.d/iodined
START_IODINED="false"
IODINED_ARGS=""
IODINED_PASSWORD=""

เราสามารถ config ได้แบบง่ายๆ ด้วยการรันคำสั่ง
dpkg-reconfigure iodined
ซึ่งจะมีหน้าจอ wizard ให้กด Next ไปเรื่อยๆได้

หรืออาจจะเลือกแก้ไขด้วยตัวเอง  ก็คือแก้ไฟล์ /etc/default/iodine ให้มีค่าเป็นแบบนี้
# Default settings for iodine. This file is sourced from
# /etc/init.d/iodined
START_IODINED="true"
IODINED_ARGS="10.0.0.1 anidear.com"
IODINED_PASSWORD="test"


เมื่อ save ไฟล์แล้วก็เริ่มเปิดการใช้งาน service นี้ด้วยคำสั่ง
sudo service iodined start
และนี่ก็จะจบการติดตั้งฝั่ง Server

หลังจากนั้น ก็ต้องไปยุ่งกับ domain ต่อ โดยการไปตั้งให้ domain หรือ sub-domain ชี้ไปหาเครื่อง server ที่เราติดตั้ง iodined ไว้
โดยจะต้องตั้งค่า DNS ไว้แบบนี้
dns A 202.xxx.xxx.xxx
tunnel NS dns.anidear.com 
โดยบรรทัดแรกจะระบุว่า  sub-domain ที่ชื่อ "dns.anidear.com" จะชี้ไปหา IP หมายเลข 202.xxx.xxx.xxx
และบรรทัดที่สองจะบอกว่า ถ้า sub-domain ชื่อ "tunnel.anidear.com" รองรับการติดต่อด้วย DNS protocol โดยใช้ที่อยู่ IP เดียวกับ "dns.anidear.com"

เมื่อตั้งค่าเสร็จแล้ว  อาจจะทดลองระบบโดยการใช้ตัวเช็ค DNS Tunnel ของผู้สร้าง Iodine ก็ได้
โดยนำ domain ที่ได้ไปเช็คที่ http://code.kryo.se/iodine/check-it/


ถ้าผลลัพธ์ออกมาเป็น
Well done, your iodine setup seems fine!
ก็หมายถึงว่า การติดตั้งสำเร็จ และพร้อมใช้งาน ^_^

ทดสอบการใช้งานผ่าน domain จริง

ทดสอบ connect ผ่านเครือข่าย 3G

$ sudo iodine -fP test 202.xxx.xxx.xxx tunnel.anidear.com
Opened dns0
Opened UDP socket
Sending DNS queries for tunnel.anidear.com to 202.xxx.xxx.xxx
Autodetecting DNS query type (use -T to override).
Using DNS type NULL queries
Version ok, both using protocol v 0x00000502. You are user #0
Setting IP of dns0 to 10.1.1.2
Setting MTU of dns0 to 1130
Server tunnel IP is 10.1.1.1
Testing raw UDP data to the server (skip with -r)
Server is at 192.168.1.33, trying raw login: ....failed
Using EDNS0 extension
Switching upstream to codec Base128
Server switched upstream to codec Base128
No alternative downstream codec available, using default (Raw)
Switching to lazy mode for low-latency
Server switched to lazy mode
Autoprobing max downstream fragment size... (skip with -m fragsize)
768 ok.. 1152 ok.. ...1344 not ok.. ...1248 not ok.. ...1200 not ok.. 1176 ok.. ...1188 not ok.. will use 1176-2=1174
Setting downstream fragment size to max 1174...
Connection setup complete, transmitting data.

แปลว่าต่อติดเรียบร้อย และลองเปิดเว็บแล้วก็ใช้งานได้จริงๆ

Reference


3/19/2013

Use Tunneling To Bypass Wifi Authentication

(ภาพจาก http://wallpaperwise.com/Blue_Binary_Matrix_Tunnel-3361.html)

เมื่อหลายวันก่อน  มีคนพูดถึงวิธีการใช้ UDP Tunneling ในการ bypass Wireless Authentication ที่เปิดให้เข้าแบบไม่มีรหัสผ่านตอน connect (Open System) แต่พอเข้าไปได้แล้วจะเข้าเว็บ จะเด้งเข้าหน้าให้ล็อคอิน

ถ้าพูดเป็นภาษาง่ายๆ ก็คือ เวลาเราไปต่อ wifi ที่ไหน แล้วมันให้เข้าไปได้แต่จะมีหน้าให้กรอก username และ password

โดยปกติ ถ้าไปถึงหน้านี้แล้ว แต่ไม่มี username และ password ก็จะไม่สามารถใช้อินเตอร์เน็ตได้

แต่ว่า  สำหรับ Wifi บางระบบ ที่ไม่ได้ตั้งค่ามาดีๆ เราจะสามารถออกเน็ตได้ โดยไม่จำเป็นต้องรู้ username และ password เลย

คือโดยส่วนมาก ทางผู้ติดตั้งระบบ จะป้องกันไม่ให้เราเข้าเว็บอะไรอย่างอื่นได้  ถ้าอยากเข้าเว็บจะต้องมาทำการล็อคอินก่อน

ซึ่งวิธีตรวจสอบว่าเรากำลังจะเข้าเว็บอะไรหรือเปล่า  ระบบจะตรวจสอบโดยการเช็คว่า เรากำลังจะติดต่อ server บน internet ที่ port 80 หรือเปล่า?

* port 80 คือ ช่องทางมาตรฐานที่ใช้ในการติดต่อแบบ HTTP
** การที่เราเข้าเว็บด้วยการใช้ http:// นำหน้า โดยทั่วไปจะหมายถึง การติดต่อด้วย HTTP protocol โดยใช้ port มาตรฐานคือ port หมายเลข 80

ดังนั้น ถ้าเราติดต่อ server ที่ port อื่นล่ะ ??

1. HTTPS


จริงๆ แล้ว เราสามารถเข้าเว็บด้วยอีกช่องทางนึงคือ การเปลี่ยนไปติดต่อกับ server ด้วยมาตรฐาน HTTPS ซึ่งทำงานบน TCP port 443  ผลลัพธ์ที่ได้คือ นอกจากจะเปิดเว็บได้ตามปกติอย่างที่ HTTP ทำแล้ว เรายังไม่ต้องติดตั้งอะไรเพิ่มไปจากเดิมด้วยเพราะ web browser แทบทุกตัว (Internet Explorer, Chrome, Firefox, Safari, ...) รองรับการเปิดเว็บแบบ HTTPS อยู่แล้ว  แถมการใช้ HTTPS ยังเพิ่มระบบความปลอดภัยเข้าไปอีกด้วย (HTTPS มาจากคำว่า HTTP Secure)

และอีกเหตุผลที่สำคัญคือ การย้ายไปใช้ HTTPS ที่ port 443 เป็นการใช้ port หมายเลขอื่นที่ไม่ใช่หมายเลข 80 ซึ่งส่วนใหญ่ถูกบล็อคเอาไว้ ก็จะทำให้เราติดต่อไปหา server ได้  โดยไม่ต้องกรอก username และ password เลย

การใช้ HTTPS ดูเหมือนจะมีข้อจำกัดอย่างนึงว่า เครื่อง server ที่รอรับปลายทางจะต้องเปิดรองรับการติดต่อด้วย HTTPS (ผ่าน port 443) ด้วย  ยกตัวอย่างระบบที่ใช้ได้ เช่น https://www.facebook.com , https://www.google.com , https://www.twitter.com เป็นต้น

ส่วนเครื่อง server ไหนไม่รองรับ  ถ้าเราติดต่อเข้าไป ก็จะพบว่า หน้าตาจะเป็นเช่นนี้


จะเห็นว่า ถ้าต่อด้วย http:// ปกติ (ติดต่อ server ที่ port 80)  server มีการตอบสนองได้ปกติ แต่ว่า ถ้าใช้ https:// (ติดต่อ server ที่ port 443) จะไม่สามารถเปิดได้  แสดงว่า  เว็บนี้รองรับแค่ HTTP อย่างเดียวเท่านั้น

(ป.ล. อาจจะแก้ได้ด้วยการใช้ "HTTPS Everywhere" อันนี้ไม่แน่ใจ เพราะยังไม่ได้ลอง)

2. UDP


Wifi บางระบบ อาจจะตั้งให้บล็อคการติดต่อออกไปหา server ข้างนอกที่ใช้ TCP ทั้งหมด  ซึ่งมันเป็นวิธีที่ค่อนข้างมีเหตุผล เนื่องจากการติดต่อส่วนใหญ่ระหว่าง client กับ server มักจะเลือกใช้ TCP protocol เกือบทั้งหมด เช่น การเปิดหน้าเว็บ (HTTP, HTTPS) , การเช็ค email (POP3, SMTP, IMAP), การแช็ต(MSN, Line, Whatsapp) และอีก ฯลฯ  ล้วนแต่ใช้ TCP ทั้งสิ้น

แต่ว่า  ก็อย่าลืมว่า เรายังมีอีกหลายระบบที่ใช้ UDP เช่น ระบบตั้งเวลา(NTP,SNTP), การดูข้อมูลสถานะของอุปกรณ์ต่างๆในระบบ(SNMP), การส่งไฟล์ (TFTP), การแปลงชื่อโดเมนเป็นหมายเลขไอพี (DNS), และอีก ฯลฯ เช่นกัน

ดังนั้น ถ้าเกิดระบบมีการป้องกันเฉพาะการใช้งาน TCP ทั้งหมด ซึ่งจะทำให้เข้าเว็บแบบปกติ (HTTP) และเข้าแบบ HTTPS ไม่ได้แล้ว  ก็หันมาใช้เข้าเว็บแบบ UDP ก็จะได้อยู่นะ ^_^

แต่ปัญหาหลักก็คือ... เว็บหรือบริการส่วนใหญ่ เขาจะเปิด server ที่รองรับไว้แต่ TCP นี่สิ  ให้เรายิงข้อมูล UDP ไปเท่าไหร่ ต่อให้มันทะลุผ่านการป้องกันไปหา server ได้โดยตรง แต่ server ไม่ได้รอรับข้อมูลที่ port นั้น ก็จะไม่ได้หยิบข้อมูลนั้นเอาไปประมวลผล มันก็ไร้ประโยชน์

ด้วยการนี้  เลยทำให้เราจำเป็นจะต้องมี proxy server ตัวกลางของเรา (อาจจะตั้งไว้ที่บ้าน หรือที่ทำงาน หรือที่อื่นๆ ที่สามารถต่อเน็ตได้ และได้ IP จริง) เพื่อทำการรอรับข้อมูลแบบ UDP จากเรา (ที่กำลังอยู่ใน wifi ที่ไม่มีล็อคอิน) แปลงข้อมูล แล้วนำไปทำการติดต่อกับ server ปลายทางด้วย TCP แบบที่ต้องการ  และเมื่อได้ข้อมูลจาก server ปลายทางแล้ว ตัวกลางตัวนี้ จะต้องทำหน้าที่แปลงข้อมูลนั้น ให้อยู่ในรูปแบบ UDP แล้วส่งกลับมาหาเราได้ด้วย

 .... ซึ่ง .... เริ่มยุ่งยากละ


จากรูป เวลาส่งข้อมูลไปหา server ปลายทางตามแนวคิดนี้จะส่งข้อมูลแบบนี้ ซึ่งจำเป็นอย่างมากที่เราจะต้องมี proxy server เป็นตัวกลางที่จะทำการแปลง UDP ไปเป็น TCP เพื่อติดต่อกับ server ปลายทาง และจะขากลับ ก็จะต้องแปลง TCP ไปเป็น UDP และส่งกลับไปเส้นทางเดิม

(หมายเหตุ วิธีนี้เรียกว่า "Tunneling" ซึ่งเปรียบได้กับการที่เราขุดอุโมงค์ต่อตรงไปหา proxy server ของเราเลย  โดยคนที่อยู่ระหว่างทางจะไม่สามารถดูข้อมูล หรือ แก้ไขข้อมูล ที่เราส่งไปหา proxy server ได้  แล้วเมื่อข้อมูลโผล่ออกจากอุโมงค์ที่ proxy server ก็จะวิ่งไปหา server ปลายทางได้ตามปกติ  ส่วนพอขากลับ ข้อมูลจาก serverปลายทาง ก็จะมุดลงอุโมงค์เดิม ย้อนกลับไปหาผู้ใช้งานได้)

ถ้าเราเลือกแล้วว่าเราจะอยากจะใช้ระบบแบบนี้  จะต้องทำยังไงบ้าง?

...ขอแนะนำ ให้ใช้การส่งข้อมูลแบบ DNS (UDP port 53)

เพราะว่า DNS ซึ่งเป็นระบบที่ใช้ในการแปลงชื่อโดเมน(เช่น google.com) ให้กลายเป็นหมายเลขไอพี(เช่น 113.21.241.24) เรียกได้ว่า เป็นระบบพื้นฐานสำหรับเน็ตเวิร์คที่ติดต่อไปหาอินเตอร์เน็ตได้จำเป็นต้องมี

ไม่เช่นนั้น คนที่เข้าเล่นอินเตอร์เน็ตจาก Wifi วงนั้นจะไม่สามารถเปิดเว็บต่างๆด้วยชื่อได้เลย  จำเป็นจะต้องกรอกด้วยไอพีอย่างเดียว ยกตัวอย่าง เช่น ถ้าต้องการเข้า Google.com แต่ว่าเราไม่มีระบบแปลง IP ให้ เลยจำเป็นต้องจำว่า google.com มี IP (ค่านึงจากหลายๆค่า) เป็น 113.21.241.24  และเวลาที่จะเข้า Google ก็จะต้องกรอก http://113.21.241.24 แต่ละครั้ง มันจะทรมาณแค่ไหน

ความน่าจะเป็นไปได้อีกอย่างคือ ในระบบการล็อคอินเข้าใช้เน็ตของ Wifi นั้น  บางทีหน้าที่ใช้ในการล็อคอิน  ก็ยังใช้ชื่อโดเมนที่จะต้องเอาไปแปลงเป็นไอพีก่อนถึงจะเปิดหน้านั้นได้

สรุปแล้ว จึงมีโอกาสสูง ที่ระบบ Wifi  จะ ไม่มีการบล็อคการใช้งาน DNS ในระบบ

ส่วนจะมีเครื่องมืออะไรบ้าง ขออ้างอิงจาก https://groups.google.com/forum/?fromgroups=#!topic/wimax-hacking/JYCdbsz7X0U ละกัน

โดยหลักๆ จะมี

ไม่ลงรายละเอียดละกันเดี๋ยวจะยาว  (จริงๆแค่นี้ก็ยาวมากละ)

3. ICMP


ICMP ย่อมาจาก Internet Control Message Protocol ซึ่งเป็น Protocol ที่แตกต่างกับ TCP และ UDP โดยที่มันอยู่คนละชั้นกันเลยกับ TCP และ UDP เมื่อเทียบกับ OSI model  โดยหน้าที่หลักของ ICMP คือเอาไว้ใช้ตรวจสอบการติดต่อกันของระบบเน็ตเวิร์ค  โดย ตัวอย่างที่เห็นกันบ่อยก็คือ การใช้คำสั่ง ping ที่เอาไว้เช็คว่าเครื่องปลายทางตอบสนองกลับมาช้าเร็วเท่าไหร่  ซึ่ง ping ก็ใช้ ICMP ในการทำงานด้วย

ดังนั้น ถ้าเราจะทำแบบเดิมที่ทำบน UDP แต่มาใช้ ICMP แทน ก็ทำได้เหมือนกัน  อาจจะดีกว่าด้วยตรงที่ว่า ICMP มีโอกาสที่ผู้ดูแลระบบจะไม่ได้บล็อคมากกว่า DNS (เนื่องจากผู้ดูแลระบบก็อาจจะใช้ ICMP เองด้วย เลยบล็อคไม่ได้)


ส่วนลิสต์ของโปรแกรมที่ใช้ทำ ICMP Tunnel (นำมาจาก http://en.wikipedia.org/wiki/ICMP_tunnel) ก็จะมี

สรุป

ในระบบอินเตอร์เน็ตไร้สาย ที่มีการตั้งค่าไว้ไม่ดีพอ อาจจะสามารถทำการ by-pass ออกไปสู่อินเตอร์เน็ตได้ในหลายช่องทาง  โดยสรุปคือ

  1. ติดต่อออกทาง TCP port เช่น ใช้ HTTPS ในการเปิดเข้าเว็บต่างๆ ที่ให้บริการแบบ HTTPS อยู่แล้ว
    • ข้อดี: ใช้งานง่าย, ไม่ต้องติดตั้งโปรแกรมเพิ่มเติม, เว็บไซต์ดังๆมักจะรองรับการใช้งานแบบ HTTPS อยู่แล้ว
    • ข้อเสีย: ไม่ใช่ทุกเว็บไซต์จะรองรับการเข้าแบบ HTTPS, ระบบ wifi มักจะป้องกันไ่ม่ให้เข้าถึงอินเตอร์เน็ตทาง TCP ทุก port
  2. ติดต่อออกทาง UDP port เช่น การใช้ DNS Tunneling เพื่อไปออกที่ proxy server ก่อน แล้วจึงให้ proxy server ทำการติดต่อแบบ TCP ไปหาเว็บปลายทางให้แทน
    • ข้อดี: ทะลุการป้องกันในระบบที่ห้ามใช้ TCP ทั้งหมดได้, DNS ค่อนข้างที่จะเป็นช่องทางที่มักเปิดไว้อยู่แล้วในระบบที่ออกเน็ตได้
    • ข้อเสีย: จำเป็นจะต้องมี proxy server ที่จะทำการแปลงไปกลับระหว่าง UDP และ TCP ให้ (ซึ่งส่วนใหญ่ proxy server ทั่วไปไม่เป็นแบบนี้), จะต้องมี public IP และ domain name ของ proxy server เครื่องนั้น, จะต้องทำการตั้งค่าหลายอย่างซึ่งทำให้ยุ่งยาก, ไม่สามารถใช้บนเครื่องผู้ใช้ได้ทันที จะต้องทำการติดตั้งโปรแกรมเพิ่มเติมก่อน
  3. ติดต่อออกทาง ICMP port
    • ข้อดี: ต่อให้ป้องกันทั้ง TCP และ UDP แต่มักจะไม่ป้องกันการใช้ ICMP เนื่องจากว่าผู้ดูแลระบบยังจำเป็นที่จะต้องใช้ ICMP ในเครื่องมือที่ใช้ดูแลระบบอยู่
    • ข้อเสีย: (เหมือนข้อเสียของ UDP ทุกอย่าง)


3/14/2013

MD5 กับ Hash Collision


วันนี้มีคนมาถามเรื่องว่า MD5 มีโอกาสเกิด Hash Collision เท่าไหร่

ขอเกริ่นย่อๆ สำหรับคนไม่รู้ว่าแต่ละตัวคืออะไรก่อนนะ

  • hash = วิธีการการย่อยข้อมูลเพื่อสร้างรหัสเฉพาะแต่ละข้อมูลออกมา เช่น file ไฟล์ๆนึงขนาดใหญ่มาก อาจจะคำนวนค่า hash ได้เหลือแค่ไม่กี่ bytes
  • MD5 = เป็นวิธีการคำนวนค่า hash วิธีหนึ่ง โดยผลลัพธ์ของ MD5 จะมีขนาด 128 bits หรือ 16 bytes
  • ส่วน Hash Collision (หรือเรียกอีกอย่างว่าปัญหา Birthday Attack) = รหัสเฉพาะข้อมูลที่สร้างขึ้นมา(hash)เนี่ย มันมีโอกาสที่จะซ้ำกันได้ 

ซึ่งความน่าจะเป็นนั้นเท่าไหร่มาดูกัน

เริ่มจาก..

สมมุติว่าตอนนี้มี Hash อยู่ในมือ k ตัว (k มีไม่กี่ตัว ซึ่ง k < N มากๆ)
ถ้าเราเอาแต่ละตัวมาจับเทียบกัน จะสามารถจับคู่ได้ทั้งหมด k*(k-1)/2 คู่
โดยมาจาก
  เราเลือกตัวซ้ายได้ k ตัว แต่พอจะเลือกตัวขวาที่จะมาจับคู่ด้วยจะเหลือเลือกได้แค่ k-1 ตัว(เพราะว่าตัวซ้ายโดนเลือกไปแล้วตัวนึง)
  และในการจับคู่กัน อาจจะเกิดการสลับที่กันได้ แบบ A-B, B-A ดังนั้นเพื่อลดปัญหาคู่เหมือนกันแต่สลับที่กัน เลยต้องหาร 2 ออก

จากจำนวนคู่ตรงนี้พักไว้ก่อน

ต่อมาลองมาคิดในภาพใหญ่ว่า...

ถ้าเกิด Hash จะชนกันได้ โอกาสมันจะเป็นเท่าไหร่
เนื่องจากถ้าเป็น MD5 ซึ่งมีผลลัพธ์ของ MD5 ออกมาขนาด 128 bits (16 bytes)
ดังนั้นจะสามารถสร้างค่า Hash ได้ไม่ซ้ำกันทั้งหมด
N = 2^128 = 340282366920938463463374607431768211456 = 3.4*10^38 ตัว
ดังนั้นถ้าเราเลือก Hash ออกมาซักคู่นึง โดยล๊อคค่าทางฝั่งซ้ายมือไว้ แล้วหวังว่าคู่ของมันจะมีโอกาสซ้ำเนี่ย
เนื่องจาก hash อีกตัวจะเป็นอะไรก็ได้ใน hash ทั้งหมดที่สามารถสร้างได้
ดังนั้น
ความน่าจะเป็นที่มันจะซ้ำกัน ก็คือ หยิบออกมา 1 ใน hash ทั้งหมดที่สร้างได้ ซึ่งก็คือ 1/N หรือ 1/2^128 = 2^-128
พอได้ความน่าจะเป็นที่มันจะซ้ำใน 1 คู่ใดๆแล้ว เราก็สามารถเอามาคำนวนความน่าจะเป็นเฉลี่ยได้ว่า

ในจำนวน hash k ตัวที่เรามีเนี่ย จะมีกี่ตัวที่ซ้ำ ด้วยการเอาไปคูณกับจำนวนคู่ที่เราคำนวนไว้ตอนแรก

ความน่าจะเป็นเฉลี่ยที่จะมี hash ชนกันในกลุ่ม hash จำนวน k ตัว จะมีค่า = จำนวนคู่ทั้งหมด * ความน่าจะเป็นที่จะเกิดการชนกันในแต่ละคู่
   λ = ( k(k-1)/2 ) * ( 1/N )
      = k(k-1)/2N

ณ จุดนี้ ถ้าหากใช้ Poisson Distribution เพื่อคำนวนหาความน่าจะเป็นที่จะเกิดการชนกัน
และเนื่องจากค่าเฉลี่ยของการเกิดเหตุการณ์ใดๆใน Poisson Distribution จะมีความน่าจะเป็น = E(X) = λ
เราสามารถย้อนกลับไปใช้ สูตรความน่าจะเป็นใดๆของ Poisson ได้ด้วยสูตร
 P(X=x) = (x^k * e^-λ)/x!
โดย x คือ จำนวนคู่ที่ hash เกิดการชนกัน
ถ้าต้องการความน่าจะเป็นที่ไม่เกิดการชนกันขึ้นเลย(x=0) จะได้ค่าเท่ากับ
 P(X=0) = (0^k * e^-λ)/0!
      = e^-λ
      = e^-(k(k-1)/2N)
และความน่าจะเป็นที่จะเกิดการชนกันขึ้นอย่างน้อย 1 ตัวขึ้นไป (x=1,2,3,..) จะมีค่าเท่ากับ
P(X=1,2,3...) = 1 - P(X=0) = 1 - e^-(k(k-1)/2N)
ซึ่งเมื่อแทนค่า N ซึ่งเป็นขนาด Hash ทั้งหมดที่สามารถสร้างได้ของ MD5 แล้ว (N=2^128) ก็จะได้สมการเป็น
P(X=1,2,3...) = 1 - e^-(k(k-1)/2^129)
ซึ่งจะสามารถ plot เป็นกราฟได้ดังรูป

http://www.wolframalpha.com/input/?i=1+-+e%5E-%28k%28k-1%29%2F2%5E129%29

ซึ่งจะเห็นได้ว่า  เมื่อเริ่มต้นที่เรามีจำนวนhash น้อยๆ (k ต่ำ)
โอกาสการชนกันของ hash ในมือจะต่ำมาก
และโอกาสการชนกันของ hash จะเริ่มเพิ่มขึ้นเรื่อยๆ เมื่อ k มีค่าสูงเพิ่มขึ้น

หรือหมายถึงว่า ยิ่งเรามี hash มากเท่าไหร่ ยิ่งได้เปอร์เซนต์ในการชนกันที่สูงขึ้น

ซึ่งโดยปกติแล้ว เขามักจะคิดว่าการเกิด hash collision จะอาการหนักมากๆ เมื่อมีความน่าจะเป็นในการเกิด collision > 50%

ถ้าเรานำค่านั้นมาแทนในสมการ เพื่อทำการหาค่า k จะได้ว่า
 P(ในการชน) = 50% = 0.5 = 1 - e^-(k(k-1)/2^129)
       e^-(k(k-1)/2^129) = 1-0.5 = 0.5
       -(k(k-1)/2^129) = ln(0.5)
       k(k-1)/2^129 = ln(0.5^-1) = ln(2)
       k(k-1) = 2^129 * ln(2)
ณ จุดนี้เพื่อความง่าย ขอประมาณค่า k(k-1)==>k^2 เมื่อ k มีค่ามากๆ
จะได้เป็น
       k^2 = 2^129(ln(2))
       k = sqrt(2^129(ln(2))) = sqrt(2)*2^64*sqrt(ln(2))
       k = 21,719,381,355,163,560,000 = 2.1719 * 10^19
ตามรูป
http://www.wolframalpha.com/input/?i=1+-+e%5E-%28k%28k-1%29%2F2%5E129%29+%3D+0.5



สรุป

MD5 ซึ่งมีผลลัพธ์ออกมาเป็นค่า 128 bits จะมีโอกาสเกิด Hash Collision มากๆ (50% ขึ้นไป) เมื่อมีจำนวน hash มากกว่า 2.1719 * 10^19 ตัวขึ้นไป หรือประมาณ 2^64.2 ตัวขึ้นไป

References:


ป.ล. 
ปัจจุบันมีคนหาวิธีทำให้เกิด MD5 Hash Collision ที่เร็วๆได้แล้ว ในระดับที่สร้างค่า hash ประมาณ 2^24.1 ตัวเท่านั้น ซึ่งสามารถทำเสร็จได้ภายในเวลาประมาณ 6 วินาที(ด้วย CPU 2.6 GHz)
อ้างอิงเพิ่ม



2/27/2013

Hack Fight - CTF at CDIC 2013 Write Up

Yesterday (Feb 27, 2013), I had a chance to participate in a hacking, capture-the-flag(CTF) style, competition called Hack Fight in Cyber Defense Initiative Conference (CDIC) 2013 at Centara Grand Hotel, Bangkok, along with other two team mates - Mayaseven and Xelenonz. And we won the 2nd place :)

It was a great experience. I want to thank my team mates. Although we were struggling in teamwork and communication, we pulled through :)  And also, I want to give my thanks to ACIS's red-team for setting up this CTF for us to play with. It was really fun.

Now, about the CTF, here are the rules:
  1. 3 hours
  2. no exploitation
  3. no disrupting to the other teams
  4. internet is allowed
And here are very brief explanation of the flags:
  1. hack wireless access-point
  2. compromise the web server
  3. find another host in the internal network, get into it, and retrieve key.txt and secret.rar
  4. find the password inside secret.rar (may involve rar-cracking)
My team can only captured 2 flags and it ran out of time :(

1. Hack The Wifi

We had been assigned to take on a wifi AP named "HackFight3". It was configured with WEP encryption, with no client on it. 

It should be an easy job and done in minutes, but it were few problems. One of them is, we-three tried to crack the same wifi at the same time. The packets were running wild, and we cannot tell whether it was the right one that should capture and work-on, or not. A small disaster.

2. Compromise The Server

After getting into the wireless LAN, there is no DHCP server inside. The organizer told us to use static IP addresses range from 10.10.10.100 - 10.10.10.199 for this network. So, we did as what we were told.

After ping scanning the whole C class, we found a server located at 10.10.10.200 and default port scanning said it was opening a port 80. It's a web server with Wordpress on it.

On a first glance, it was a wordpress website, with many video posts. The videos can be played (even though we were in internal network), so there must be a player and the video files inside this server.

Use wpscan revealed that this wordpress using twentyone theme and webplayer plugin. It was confirmed when I captured the HTTP requests when I browsed to the pages.

Then, searching through exploit-db (I had a local copy) found that "webplayer" plugin has a flaw that allows to use SQL-injection on the URL path like this:

http://site.com/wp-content/plugins/hd-webplayer/config.php?id=[INJECT HERE]
It works. We then quickly dumped the admin's hash from wp_users table, and then tried to crack the hash.

It should not take long to crack the wordpress hash without salt on the internet, but at the beginning, our internet connection is very poor (unusable). We switched to CPU+GPU cracking. We tried several wordlist sets but no one seemed to work. We lost considerable amount of time. Then P'Tum lent us his 3G internet, so we could crack that hash online. The admin's password was: 
H@ckFigHT4dic 
When we tried to use this password, another problem arose. 

The login page ( /wp-admin ) was blocked by HTTP authentication, and it used a different set of password.

We turned back to the SQL injection bug, to find the password for this HTTP authentication. This server also allowed to read files via SQL, so we did it to read C:/Documents and Settings/tester/Desktop/UsbWebserver-CWH/Root/.htaccess file. 

It stored password for HTTP authentication at C:/Documents and Settings/tester/Desktop/password.txt and we read that file too, then we found the hash like this:
$apr1$XXXXXXXX$XXXXXXXXXXXXXXXXXXXXXX
(Since, we didn't break this out, I want to censor the hash for safety)

It is APR1-MD5 hash that used for .htaccess file. 

We back to hash cracking again, this time with a salted-hash. And again, it took a lot of time, tried several sets of wordlist ( ~1GB in total) and still it doesn't crack.

After awhile, Xelenonz found a way to by-pass this HTTP authentication on this server. He used Netcat connecting to the server and tried "GETS /wp-admin HTTP/1.0" instead of "GET /wp-admin HTTP/1.0". And it works, even it looks painful to read the page in HTML in console.

Later in few minutes, the organizer decided to reveal an easier way to do that. By using Burp Suite to replace every GET header with other word (such as LOL). Our team were in disarray again, because I was using BackBox linux and it does not have Burp installed, and the alternative tool installed is OWASP ZAP Proxy which I am not familiar with. (I had experience with Burp Suite and OWASP WebScarap before, which are very alike in their user interface, but ZAP is totally different.) My team mates had problems in using this filter in Burp Suite as well. 

Anyway, my team mates did this, and be able to gain access to the Wordpress' admin page, and upload a php shellcode as a plugin. Then we can use the shellcode at the location like:
http://10.10.10.200/wp-content/uploads/2013/02/shell.php
At this point, we captured the 2nd flag, but we only have 20 minutes left to do the other two. 

We spent the rest of the minutes in trying to upload a meterpreter shell (3 times for 3 machines) and trying to route to internal network through the sessions and doing ping scan on the network. It turned out that ICMP was blocked to disable ping scan, we were thinking that we could not route through.

3. Retrieve key.txt And secret.rar From An Internal Server

We did not pass this step, so the followings are the solution given by the organizer.

After getting a shell on the web server, a simple command "ipconfig" can reveal that the server has 2 network interfaces: 10.10.10.0/24 and 192.168.72.0/24

The server containing file "key.txt" and "secret.rar" was located inside the network 192.168.72.0, so we need to gain access to that network using this web server as a pivot point. (web server's IP addresses are 10.10.10.200, 192.168.72.131)

First upload, a meterpreter packed in .EXE format onto the server using the PHP shell from the previous flag. Then run the meterpreter file on the server to get a session back to metasploit.

In metasploit, after getting the session, put the session into the background first, then create a route to that session ID (in this case, session ID = 1) using this command:
msf> route 192.168.72.0 255.255.255.0 1
Using a command, "route print", to confirm the routing to opening session #1
Subnet            Netmask           Gateway
------               -------                 -------
192.168.72.0  255.255.255.0  Session 1
At this point, using Metasploit's auxiliary tool, named "arp_scanner" (post/windows/gather/arp_scanner), with options of 
RHOST=192.168.72.0/24
SESSIONS=1
to scan the internal network.

The internal hosts will be displayed as following:
192.168.72.1
192.168.72.2
192.168.72.128
192.168.72.131
192.168.72.254
The reason to use ARP scan because the organizer setup a firewall to block ICMP in the internal network. It is a sure way to do the scan.

Then, you can also use auxiliary/scanner/portscan to scan the ports of these hosts to find a way to break in. 

It seems to be a 445-port opened on the server 192.168.72.128, the other hosts were decoys.

Port 445 is a port that Windows use for file sharing, duped "SMB protocol" in linux. We need to use smbclient tool to get access to it. But there are two problems:
  1. smbclient is an external tool, outside Metasploit. It will not see the routing.
  2. what is the credential to use when connecting to the server?
The first problem can be solved by using a meterpreter command portfwd. To use it:
msf> sessions -i 1
meterpreter> portfwd add -l 9999 -r 192.168.72.128 -p 445
This will create a tunnel on our machine port 9999 <-----> 192.168.72.128:445

Then we can list all shares using smbclient command as:
$ smbclient -p 9999 -L 127.0.0.1
It has /share to access, but it needs a credential.

Now the 2nd problem, how to get a credential to access the remote SMB share.

There is a tool named Windows Credentials Editor (WCE) that can collect the credentials on the windows machine. And since we have one, the web server, we can upload this tool using PHP shell and run it to get the result.

Or we can use some Metasploit's post exploitation module (post/windows/gather/credentials/credential_collector, or post/windows/gather/cachedump) to collect the credentials.

The result from this would be something like (I cannot recall it exactly) :
tester\T8 : 5plus4==10!@#$%^&*()
NETWORK SERVICE\WORKGROUP : 5plus4==10!@#$%^&*()
So, we can use smbclient to connect to the remote share with username "tester" and password "5plus4==10!@#%^&*()"
smbclient -p 9999 //127.0.0.1/C$/ -U tester
After connected, the available commands are very similar to FTP : dir, get, mget, cd, lcd, rm, del

There will be 2 files inside "\Users\Administrator\Desktop\Shared" folder: key.txt and secret.rar 

Download those files using "get" command and this flag is done.

4. Unpack The Rar

As told earlier, the rar file contains the final answer, and it has to be unpack with password from key.txt

Unfortunately, key.txt is no ordinary file. (obviously?)

This file contains some kind of base64 encryption of some thing. 

After decrypt using base64 decryption, it comes out a hex string like it is from a hex dump, which is something like:
ab a1 78 a6 d8 9f  ...  
        (this is not the real ones in the challenge, but just for you to get the picture)

Trying to put this string back to its binary value, it still incomprehensible. Then it might be a binary file.

Save that as a file, then using some hex editor tool to look at its file header (first few characters). 

It appears that the file header of this binary is "Rar" (this exact word was shown), so we now know that this binary is a rar archive file. Then save it to .rar then unpack it.

After unpack this rar file (from key.txt), there is only one file inside, called "key.pdf"

Again, this file is not normal either, because it will not be displayed if you double-click it.

And yet again, we need to read the header of this file, and this time, it is "PNG" in the file's header.

Then, rename the file from "key.pdf" to "key.png" and open it with any image viewer. The password key is displayed in the image. The password is: 
CDICCONFERENCE
To confirm it, use that password to unpack the secret.rar file. It has only one image file, which when opened with a image viewer displayed
"the final flag captured"
And that is the end of the challenge.


Thank you for reading.

----------------------------------------------------------------------------------
Update on March 2, 2013: update contents on Challenge #3 to be more accurate.

2/25/2013

Install CUDA on Ubuntu

This is another short-note from my struggle in installing Nvidia's CUDA. 
My main purpose was to run Pyrit on graphic card using CUDA, but installing CUDA just happened to be uneasy task.

Brief explanation of the steps in installing CUDA is,
1. install pre-requisite packages
2. download CUDA.run
3. symlink libglut.so
4. symlink gcc-4.6
5. start CUDA.run
6. post-installation

1. Install the pre-requisites
It needs: freeglut3, freeglut3-dev, python-dev, build-essential, gcc-4.6 
put them all together: 

sudo apt-get install freeglut3 freeglut3-dev python-dev build-essential gcc-4.6

remark: I don't know why it really need gcc-4.6. In my machine, gcc-4.7.2 was already installed, but it gave an error, "unsupported gcc 4.7.2", while compiling CUDA.

2. download CUDA toolkit
Download the install file from https://developer.nvidia.com/cuda-downloads
I chose Ubuntu 11.10 x64, and the file name is cuda_5.0.35_linux_64_ubuntu11.10-1.run

remark: although it's for 11.10, but it works as well on 12.10

3. create symbolic link for libglut.so
After installing freeglut3 package, the library, named "libglut.so.3", has been installed in /usr/lib/x86_64-linux-gnu/libglut.so.3. However, the CUDA installation file only looks in /usr/lib, so it will never found the library. I needed to make a symbolic link for it there:

sudo ln -s /usr/lib/x86_64-linux-gnu/libglut.so.3 /usr/lib/libglut.so

4. create symbolic link for gcc-4.6
As mentioned above, I don't understand why it only needs gcc-4.6. So, I changed it anyway.
In /usr/bin, there is a link for gcc --> gcc-4.7 already. If I want to use gcc-4.6 for that instant, I can change it to point to gcc-4.6 instead.

sudo rm /usr/bin/gcc
sudo ln -s /usr/bin/gcc-4.6 gcc

remark: to undo this, execute these two lines again, but change from 4.6 to 4.7

5. start CUDA.run

chmod +x cuda_5.0.35_linux_64_ubuntu11.10-1.run
sudo ./cuda_5.0.35_linux_64_ubuntu11.10-1.run

It will display a license agreement document. You can press 'q' to quit the screen after read it.
It then asks whether you accept this agreement or not, type "agree" if you agree.
After that it'll ask you 4 questions:
 - install a new proprietary version of nvidia driver?
 - install CUDA toolkit?
 - where to install it?
 - install CUDA samples?

I input: n, y, (enter), n   << means no, yes, default value, no
Installation will run. Wait for it to finish.

6. Post-installation
It is now installed in the location given in step5, (default is at /usr/local/cuda-5.0)
What to do next is:

6.1 Link gcc for CUDA 
I'm not sure that it is neccessary, but I saw a post from http://gunnicom.wordpress.com/2012/09/23/blenderto-render-with-cycles-and-cuda-on-nvidia-gpu-in-ubuntu-12-10-2/ that made me do the same :)

sudo ln -s /usr/bin/gcc-4.6 /usr/local/cuda-5.0/bin/gcc

remark: so gcc at /usr/bin is now free from cuda, you can change it back

6.2 set path for the binary files
There are many binary file inside /usr/local/cuda-5.0/bin, you can add PATH environment to point to that location.

echo "export PATH=$PATH:/usr/local/cuda-5.0/bin" >> ~/.bash.rc

6.3 set path for the library files
There are 2 directories inside CUDA - lib and lib64. You can add LD_PATH to point to these locations too.

echo "export LD_PATH=$LD_PATH:/usr/local/cuda-5.0/lib64:/usr/local/cuda-5.0/lib" >> ~/.bash.rc



More Readings: