Thursday, March 21, 2013

Emacs: Flyspell-mode


最近開始拿 Emacs 編寫上課筆記,像我這種英文苦手表示悲劇,常常拼錯自,好在 Emacs 有內建的 flyspell-mode 可以幫我解決這個問題

http://www.emacswiki.org/emacs/FlySpell

在 .emacs 裡面加入  (或是用  hook 綁在某個  mode 上)這行即可

(flyspell-mode 1)

M-TAB 可以幫你 auto correct 回來,就甘心


Tuesday, March 5, 2013

Python dump skype DB

據說 Skype local 端資料也是直接用 sqlite 存的

Mac OSX
~/Library/Application Support/Skype/$account/main.db

Linux
~/.Skype/$account/main.db

所以我們可以自己寫 tools 查看自己的資料 請不要拿來查看別人的資料 >_<

剛剛初步可以 Dump 出以下XD

也許這樣學習資料庫比較有趣(?


[~/.Skype/****]-[Arch Linux] $ sqlite3 main.db
SQLite version 3.7.15.2 2013-01-09 11:53:05
sqlite> .table
Accounts        ChatMembers     Conversations   Participants    Videos
Alerts          Chats           DbMeta          SMSes           Voicemails
CallMembers     ContactGroups   LegacyMessages  Transfers
Calls           Contacts        Messages        VideoMessages
sqlite> select * from Accounts;


Sample code:
#!/usr/bin/python

import sys
import sqlite3

def printProfile(skypeDB):
    conn = sqlite3.connect(skypeDB)
    c = conn.cursor()


    print "show tables:"
    c.execute("SELECT tbl_name from sqlite_master WHERE type=='table';")
    print c.fetchall()

    c.execute("SELECT fullname, skypename, city, country, \
               datetime(profile_timestamp,'unixepoch') FROM Accounts;")


    print "Dump Account: "
    print "-" * 50
    for row in c.fetchall():
        print '[*] -- Found Account --'
        print '    [+] User: ' + row[0]
        print '    [+] Skype Username: ' + row[1]
        print '    [+] Location: ' + row[2] + ',' + row[3]
        print '    [+] Profile Date: ' + row[4]

    print "Dump Contacts: "
    print "-" * 50
    c.execute("SELECT displayname, skypename, phone_mobile, \
               birthday FROM Contacts;")

    for row in c.fetchall():
        print '[*] -- Found Account --'
        print '    [+] User: ' + (row[0])
        print '    [+] Skype Username: ' + row[1]
        print '    [+] Phone_mobile: ' + str(row[2])
        print '    [+] Birthday: ' + str(row[3])


if __name__ == "__main__":
    
    printProfile(sys.argv[1])

python nmap

Ref: http://xael.org/norman/python/python-nmap/
https://pypi.python.org/pypi/python-nmap/0.2.7


知己知彼,百戰百勝,nmap 是什麼這邊就不多作介紹了

python-nmap 是一個 nmap 的 python wrapper ,用於方便對於 namp 操作

也許今天有好多好多機器需要作測試,pyhton-nmap 這時就是我們的好工具了

高階邏輯的部份,例如決定哪些機器需要作測試、測試的 policy 、結果分析等等

這些事情可以丟給 python 解決,而不用痛苦的在  shell scripts 裡面完成這些苦工

Sample code:
#!/usr/bin/python

import nmap
nm = nmap.PortScanner()
result = []
result.append( nm.scan('127.0.0.1', ports='22-443')   )
result.append( nm.scan('127.0.0.1', arguments='-p22-443')   )
result.append( nm.scan('localhost', arguments='-sT'))
result.append( nm.scan(arguments='-p 0-1024')       )
result.append( nm.scan(arguments='-p22 -sV')        )

for r in result:
    print r
    print "=" * 50




'''                                                                              
methods:
nm.all_hosts             nm.get_nmap_last_output
nm.nmap_version          nm.scanstats nm.command_line
nm.has_host              nm.scan
nm.csv                   nm.listscan
nm.scaninfo
                                                                                 

nm.scan()
    Definition: nm.scan(self, hosts='127.0.0.1', ports=None, arguments='-sV')        
    hosts = string for hosts as nmap use it 'scanme.nmap.org' or '198.116.0-255.1-127' or '216.163.128.20/20'
    ports = string for ports as nmap use it '22,53,110,143-4564'
    arguments = string of arguments for nmap '-sU -sX -sC'


maybe need root privileges
    PortScannerError: u'You requested a scan type which requires root privileges.\nQUITTING!\n'
'''


個人認為,在 iPython 裡面用這玩意超好用的XD


同場加映 Perl 也有人作類似的 CPAN module
http://search.cpan.org/~maxschube/Nmap-Scanner-1.0/

Python image downloader

昨天下午寫出來的小玩具

BeautifulSoup 和 urllib2 的簡單練習 : )

然後我發現我還是不會用  Python 的 re .... Orz

絕對不是要拿來抓謎物喔


#!/usr/bin/python

import urllib2
import urlparse
import BeautifulSoup
import os
import time
import re
                                                                                
def find_tags(url):
    c = urllib2.urlopen(url).read()
    soup = BeautifulSoup.BeautifulSoup(c);
    return soup.findAll('img')

def get_src(url, re_):
    r = re.compile(re_)
    tags = find_tags(url)
    for tag in tags:
        img = tag['src']
        if r.search(img):
            yield img

def get_basename(url):
    return os.path.basename(urlparse.urlsplit(url)[2])

def download(url, re_=''):
    for src in get_src(url, re_):
        content = urllib2.urlopen(src).read()
        print "[+] download: " + src
        file_ = open(get_basename(src) , 'wb')
        file_.write(content)
        file_.close()
        time.sleep(1)

if __name__ == '__main__':
    download(url='http://this-plt-life.tumblr.com', re_='gif')

Monday, March 4, 2013

things from plurk error message

據說今天早上 plurk 又 504 惹...

然後某學長把 python traceback 貼出來XDrz

身為一個專業的鄉民當然要備份一下

Traceback (most recent call last):
  File "/home/plurk/plurk/git_trunk/ext/parts/web/wsgiserver/__init__.py", line 1246, in communicate
    req.respond()
  File "/home/plurk/plurk/git_trunk/ext/parts/web/wsgiserver/__init__.py", line 758, in respond
    self.server.gateway(self).respond()
  File "/home/plurk/plurk/git_trunk/ext/parts/web/wsgiserver/__init__.py", line 1949, in respond
    response = self.req.server.wsgi_app(self.env, self.start_response)
  File "/home/plurk/plurk/git_trunk/ext/werkzeug/utils.py", line 859, in __call__
    return self.app(environ, start_response)
  File "/home/plurk/plurk/git_trunk/ext/parts/web/web.py", line 295, in dispatch_request
    rv = handle_error()
  File "/home/plurk/plurk/git_trunk/ext/parts/web/web.py", line 358, in handle_error
    result = handler(e)
  File "plurk/web/error_handler.py", line 65, in error_handler
    trace_back=t_b)
  File "plurk/templates.py", line 147, in renderPlurkTemplate
    html = PlurkTemplates().addDynamicData(html, ses_user, page_user)
  File "plurk/templates.py", line 153, in addDynamicData
    'session_user': users.exposeSessionUser(ses_user),
  File "plurk/users.py", line 342, in exposeSessionUser
    session_user['notifications_count'] = Notifications().getCount(user.id)
  File "/home/plurk/plurk/git_trunk/ext/parts/cache/__init__.py", line 125, in proxy
    value = f(*args, **kwargs)
  File "plurk/models/notifications.py", line 114, in getCount
    is_email_confirmed = Users().isEmailConfirmed(uid)
  File "plurk/models/users.py", line 210, in isEmailConfirmed
    row = main_db().select('users_map', id=uid, cols='is_email_confirmed', as_one=True)
  File "/home/plurk/plurk/git_trunk/ext/parts/db/wrapper.py", line 121, in select
    with self.cursor(sql) as cursor:
  File "/home/plurk/plurk/git_trunk/ext/parts/db/wrapper.py", line 55, in cursor
    con = self.connections.getConnection(host)
  File "/home/plurk/plurk/git_trunk/ext/parts/db/wrapper.py", line 578, in getConnection
    (pprint.pformat(attempts), dbinfo, exception))
Exception: Could not create a connection on server [{'charset': 'utf8',
  'compress': False,
  'exception': 'Traceback (most recent call last):\n  File "/home/plurk/plurk/git_trunk/ext/parts/db/wrapper.py", line 557, in getConnection\n    con = MySQLdb.Connect(**conf)\n  File "/usr/lib/python2.7/dist-packages/MySQLdb/__init__.py", line 81, in Connect\n    return Connection(*args, **kwargs)\n  File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 187, in __init__\n    super(Connection, self).__init__(*args, **kwargs2)\nOperationalError: (2003, "Can\'t connect to MySQL server on \'192.168.0.211\' (99)")\n',
  'host': '192.168.0.211',
  'passwd': 'plurk',
  'port': 3306,
  'refresh': True,
  'refresh_host': '192.168.0.211',
  'use_unicode': True,
  'user': 'plurk'},
 {'charset': 'utf8',
  'compress': False,
  'exception': 'Traceback (most recent call last):\n  File "/home/plurk/plurk/git_trunk/ext/parts/db/wrapper.py", line 557, in getConnection\n    con = MySQLdb.Connect(**conf)\n  File "/usr/lib/python2.7/dist-packages/MySQLdb/__init__.py", line 81, in Connect\n    return Connection(*args, **kwargs)\n  File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 187, in __init__\n    super(Connection, self).__init__(*args, **kwargs2)\nOperationalError: (2003, "Can\'t connect to MySQL server on \'192.168.0.211\' (99)")\n',
  'host': '192.168.0.211',
  'passwd': 'plurk',
  'port': 3306,
  'refresh': True,
  'refresh_host': '192.168.0.211',
  'use_unicode': True,
  'user': 'plurk'},
 {'charset': 'utf8',
  'compress': False,
  'exception': 'Traceback (most recent call last):\n  File "/home/plurk/plurk/git_trunk/ext/parts/db/wrapper.py", line 557, in getConnection\n    con = MySQLdb.Connect(**conf)\n  File "/usr/lib/python2.7/dist-packages/MySQLdb/__init__.py", line 81, in Connect\n    return Connection(*args, **kwargs)\n  File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 187, in __init__\n    super(Connection, self).__init__(*args, **kwargs2)\nOperationalError: (2003, "Can\'t connect to MySQL server on \'192.168.0.211\' (99)")\n',
  'host': '192.168.0.211',
  'passwd': 'plurk',
  'port': 3306,
  'refresh': True,
  'refresh_host': '192.168.0.211',
  'use_unicode': True,
  'user': 'plurk'}]
.{'_rhost': '192.168.0.211', 'server_name': 'main', 'use_unicode': True, 'compress': False, 'charset': 'utf8', 'db': 'plurk_main', 'resolve_host': None, 'id': 'main', 'host': '192.168.0.211', 'user': 'plurk', 'refresh_host': <function refresh_host at 0x7f0a4cb03938>, 'password': 'plurk', 'port': 3306}
Error was 
Traceback (most recent call last):
  File "/home/plurk/plurk/git_trunk/ext/parts/db/wrapper.py", line 557, in getConnection
    con = MySQLdb.Connect(**conf)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/__init__.py", line 81, in Connect
    return Connection(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 187, in __init__
    super(Connection, self).__init__(*args, **kwargs2)
OperationalError: (2003, "Can't connect to MySQL server on '192.168.0.211' (99)")
===

從這份信息我們可以知道

plurk 跑在 wsgi 上面,有用 werkzeug

透過 git 管理代碼,server 上面的 account 叫做 plurk

內網的 192.168.0.211 跑  MySQL,port 沒換,user / passwd 都是 plurk

於是乎,只要打下一台進的了內網的機器就... (troll)


========
順便附上 Orange 大大的  slides 吧,page 26

Friday, March 1, 2013

Python decrypt tools

看了某本書的靈感,寫了找回自己密碼的小工具

full permutation generator

#!/usr/bin/python                                                               
                                                                                
import sys                                                                      
                                                                                
alpha = ""                                                                      
def f(base, l):                                                                 
    global alpha                                                                
    if l > 0:                                                                   
        ubase = base                                                            
        for i in alpha:                                                         
            base += i                                                           
            print base                                                          
            f(base, l-1)                                                        
            base = ubase
            
if __name__ == '__main__':                                                      
    if len(sys.argv) != 3:                                                      
        print "Usage: ./gen.py aAdx 10"                                         
        sys.exit(1)                                                             
    else:                                                                       
        if 'a' in sys.argv[1]: alpha += "abcdefghijklmnopqrstuvwxyz"            
        if 'A' in sys.argv[1]: alpha += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"            
        if 'd' in sys.argv[1]: alpha += "0123456789"                            
        if 'x' in sys.argv[1]: alpha += """\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ """
                                                                                
#        print "use this string: \n" + alpha + "\n"                             
#        raw_input()                                                            
                                                                                
        f("", int(sys.argv[2])) 



和基於字典檔的 decrypt tool

/usr/share/dict, 或是也可以由以上工具產生 ;-)




#!/usr/bin/python                                                               
                                                                                
import crypt                                                                    
import sys                                                                      
                                                                                
def testPass(cryptPass, dic):                                                   
    salt = cryptPass[0:2]                                                       
    dictFile = open(dic, 'r')                                                   
                                                                                
    for word in dictFile.readlines():                                           
        word = word.strip('\n')                                                 
        ced = crypt.crypt(word, salt)                                           
        if (ced == cryptPass):                                                  
            print "[+] Found Password: " + word + "\n"                          
            return                                                              
                                                                                
    print "[-] Password Not Found.\n"                                           
    return                                                                      
                                                                                
                                                                                
if __name__ == "__main__":                                                      
    if len(sys.argv) != 3:                                                      
        print 'Usage: ./crypt_crack.py "$CRYPT" "$DICT_FILE"'                   
    else:                                                                       
        testPass(sys.argv[1], sys.argv[2])