2015-03-30

Software Security course on Coursera

Course link: https://www.coursera.org/course/softwaresec

This course is really interesting, especially the course projects. I have accomplished two projects out of three.

Project 1: Exploiting Buffer Overflows in C
Project 2: Exploiting Web Application Vulnerabilities in BadStore.net

The challenging projects are practical exercises for me to find the vulnerabilities of a program or a web service. Meanwhile, to find the answer of assignments, I learn several techniques of attack. Although I spend much time on doing these projects, I still enjoy in these puzzles.

2015-03-15

Edit file remotely with Sublime Text

Sublime Text is a great editor for local files. But what if I want to edit files remotely on the other machine under ssh? Like edit my project files on Raspberry Pi using Sublime Text on local machine.

First, (on local machine)
install rsub by Package Control in Sublime Text.

Second, (on RPi)
$ sudo apt-get install ruby
$ sudo gem install rmate

Install rmate on RPi.

Third, (on local machine)
$ ssh -R 52698:localhost:52698 rpi_user@rpi_host
Connect to RPi and forward port rpi_host:52698 to localhost:52698

Fourth, (on RPi)
$ rmate to_be_edited_file
Then the file will open in Sublime Text in local machine.

[1] https://github.com/henrikpersson/rsub
[2] https://github.com/textmate/rmate

[Update]
For convenient use, add following to ~/.ssh/config
RemoteForward pi_host:52698 localhost:52698
Then no need to add -R while using ssh command

2015-03-07

ssh to RPi with hostname via wifi

Got problems while trying to ssh to your RPi with hostname via wireless network? Yes, me too.

I am a lazy guy to connect keyboard and display to RPi every time I develop and test my project on RPi. Also, I don't like too many wires so I use a wifi dongle. After setting up the wireless network environment and hostname of my RPi, I still cannot connect my RPi from my laptop with hostname. I connect the display and keyboard to RPi again to check the wifi settings. Guess what? The settings are fine. I could connect to internet from RPi. Then I try to connect to RPi with IP address instead of hostname and it works. So the problem is there is no mapping from RPi's hostname to RPi's IP address.

Finally, I find "libnss-mdns" could solve my issue. Here I summarize all setting steps to ssh to RPi with hostname via wifi.

1. Set hostname in /etc/hosts
2. Set hostname in /etc/hostname
3. Install libnss-mdns by sudo apt-get install libnss-mdns

Now I could connect my RPi from my laptop with hostname. But there is a little trick: the suffix ".local" must be added to the hostname.

Correct:
ssh pi@myrpi.local
Incorrect:
ssh pi@myrpi

There is one more thing annoying me on my Edimax wifi adapter. It is going to sleep very quickly and frequently. So I add one more step to prevent the dongle from suspending.

4. Edit /etc/modprobe.d/8192cu.conf by adding
options 8192cu rtw_power_mgnt=0
to disable power management

常用的設計原則 (SOLID)

最近在研究Design Pattern跟Refactoring,發現對SOLID這五個常用的設計原則一知半解,索性花了一些時間研究並筆記。

SRP (single responsibility principle)
SRP用來簡化類別的責任歸屬。最初看到這個原則,只知道是在設計類別時希望儘量簡化單一類別的能力,但是為什麼要這麼做卻說不出個所以然。"responsibility"的定義為"a reason for change",這是以類別有可能需要修改的觀點為出發點的考量。多種類的功能集中在同一類別會造成功能之間的耦合,當需要新增或修改某些功能,改變的結果可能會影響原本其他不變的功能,這將會增加日後維護的成本,因此利用SRP降低不同功能之間耦合程度。

OCP (open/closed principle)
OCP最大的特色就是"對擴充保持開放,對修改保持封閉"。這到底在說什麼?同樣的,以日後維護程式碼的觀點來看,最好不要為了增加新功能而修改已經完成並經過測試的類別,因為可能會改錯並且需要重新測試,維護成本較高。那要如何增加新功能?利用繼承或實作,來增加新的類別,這樣的做法就不會提高維護的成本。簡單來說就是OO的多型。

LSP (Liskov substitution principle)
LSP有點抽象不好參透,想像在設計API時,輸入參數的型別定義為類別T,但是真正使用這個API時,輸入參數的型別可以置換為T的子類別S,這樣的置換可以成立的條件為,輸入類別為S的參數不會改變原本函式的行為與目的。

ISP (interface segregation principle)
ISP提醒我們在設計類別的結構時,不要做多餘的繼承或實作,以減少模組之間的相依性。例如有一個類別Door,擁有Lock()及Open()兩個函式,當需要新增一個新的類別TimedDoor,並增加一個新函式LockTimedOut(),經過一段時間後自動上鎖。假設已經有一個計時器的類別Timer,較好的設計會是TimedDoor同時繼承或實作Door以及Timer,而不會讓TimedDoor繼承Door,Door再繼承Timer。後者的缺點讓只需使用Door功能的程式,也必須依賴Timer,縱使完全不會用到,如此增添了多餘的相依性。

DIP (dependency inversion principle)
DIP為依賴倒轉原則。一般的設計是將架構分成low-level及high-level,low-level與high-level是相對的。例如設計一個MP3 player讀取USB上的檔案來播放音樂,會有一個專門從USB讀取檔案內容的USBReader (low-level),然後有另一個處理檔案內容的MP3Processor (high-level),MP3Processor::process() --> USBReader::read(),這是非常直觀的設計,MP3Processor depends on USBReader (high-level depends on low-level)。這種設計的問題在於,如果要增加讀取音樂檔案的來源,例如想要有一個SDReader來讀取SD card上的檔案,這樣除了新增SDReader外還必須修改MP3Processor。比較好的做法是Both high-level and low-level depend on abstraction,先建立一個抽象的interface叫IStorageReader,然後USBReader及SDReader分別實作IStorageReader的方法,而MP3Processor針對IStorageReader撰碼,如此一來USBReader depends on IStorageReader, SDReader depends on IStorageReader and MP3Processor depends on IStorageReader,這就是DIP。

[1] http://www.objectmentor.com/resources/articles/srp.pdf
[2] http://www.oodesign.com