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 )