HTTPプロトコル(302ステータス)
友達から質問を受けて少し勉強しました。ソケット通信は最近あんまりつかってなかったので再度勉強した。
ソケット通信でサーバ側でやることは
- ソケットの生成
- bind
- listen
- acept
- 送受信処理
です。
こんな感じのソース書いた。
#-*- coding: utf-8 -*- import socket import threading class ClientThread(threading.Thread): def __init__(self, soc): super(ClientThread, self).__init__() self.soc = soc def run(self): self.recv() self.response() ################################### # 受信データを切れ目まで読み飛ばす def recv(self): while True: data = self.soc.recv(1024) if ((data == '\r\n') or (data == '\n)')): break; if ('\r\n\r\n' in data): break # print "server:receive '%s'" % data ################################### # 302レスポンスをかえす def response(self): self.soc.send("HTTP/1.1 302 Found" + "\r\n") self.soc.send("Location: http://www.google.co.jp/" + "\r\n") self.soc.send("\r\n") class Server(object): def __init__(self, host, port): self.host = host self.port = port def createServerSocket(self): self.server_soc = socket.socket( socket.AF_INET, socket.SOCK_STREAM) self.server_soc.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server_soc.bind((self.host, self.port)) print(u"Bind %s:%d" %(self.host, self.port)) def acceptLoop(self): self.server_soc.listen(5) (client_soc, client_address) = self.server_soc.accept() clientThread = ClientThread(client_soc) clientThread.start() if __name__ == '__main__': server = Server('localhost', 60000) server.createServerSocket() server.acceptLoop()
もう少しちゃんと改造すれば、簡易HTTPサーバとかにできるかも。
D_FORTIFY_SOURCEを使う
これもバッファーオーバーフロー検出に関するお話。
gcc4からの機能です。
使い方 (o1以上の最適化オプションをつける)
gcc -O1 -D_FORTIFY_SOURCE=1 foo.c
検出時は、下記のいずれか
- コンパイル時
- 実行時
これの機能のすごいとこは、リリースビルドで使えるということ。
- gオプションがいらないので、リリースするモジュールにも積極的に使えるということ。
#include <string.h> static char buf[6]; int main(int argc, char** argv) { strcpy(buf, argv[1]); return 0; }
こんなソースを実行すると下記の感じになる。
======= Memory map: ======== 08048000-08049000 r-xp 00000000 08:01 10888991 /home/hidekazu/src/c/tmp/a.out 08049000-0804a000 rw-p 00000000 08:01 10888991 /home/hidekazu/src/c/tmp/a.out 08d3a000-08d5b000 rw-p 00000000 00:00 0 [heap] 46e97000-46eb6000 r-xp 00000000 08:01 9179830 /usr/lib/ld-2.15.so 46eb6000-46eb7000 r--p 0001e000 08:01 9179830 /usr/lib/ld-2.15.so 46eb7000-46eb8000 rw-p 0001f000 08:01 9179830 /usr/lib/ld-2.15.so 46eba000-47065000 r-xp 00000000 08:01 9179839 /usr/lib/libc-2.15.so 47065000-47066000 ---p 001ab000 08:01 9179839 /usr/lib/libc-2.15.so 47066000-47068000 r--p 001ab000 08:01 9179839 /usr/lib/libc-2.15.so 47068000-47069000 rw-p 001ad000 08:01 9179839 /usr/lib/libc-2.15.so 47069000-4706c000 rw-p 00000000 00:00 0 47582000-4759e000 r-xp 00000000 08:01 9180054 /usr/lib/libgcc_s-4.7.2-20120921.so.1 4759e000-4759f000 rw-p 0001b000 08:01 9180054 /usr/lib/libgcc_s-4.7.2-20120921.so.1 b7769000-b776a000 rw-p 00000000 00:00 0 b7781000-b7783000 rw-p 00000000 00:00 0 b7783000-b7784000 r-xp 00000000 00:00 0 [vdso] bffb8000-bffd9000 rw-p 00000000 00:00 0 [stack] 中止 (コアダンプ)
コアダンプするので、ulimited -c unlimitedとかしてcoreファイルを
はけばgdbでバックトレースできるよ。
Mudflapを使う
gcc4から使える機能です。バッファーオーバーフロー検出ツールです。
メモリの割り当てとして、ヒープ領域、bss領域、stack領域などがあります。このツールでは、下記のようなケースが検出されました。
/* test.c */ static char onbss[128]; int main(void) { char onstack[128] = {0}; int dummy; dummy = onbss[128]; dummy = onstack[128]; return 0; }
ビルド方法は下記になります。
gcc -g -fmudflap test.c -lmudflap
実行結果
******* mudflap violation 1 (check/read): time=1354703106.661039 ptr=0x80c9c80 size=129 pc=0xb76153ff location=`testflap.c:8:18 (main)' /lib/libmudflap.so.0(__mf_check+0x3f) [0xb76153ff] ./a.out(main+0xa5) [0x8048835] /lib/libmudflap.so.0(__wrap_main+0x4b) [0xb7614b4b] Nearby object 1: checked region begins 0B into and ends 1B after mudflap object 0x901d1e8: name=`testflap.c:1:13 onbss' bounds=[0x80c9c80,0x80c9cff] size=128 area=static check=3r/0w liveness=3 alloc time=1354703106.660965 pc=0xb7614adf number of nearby objects: 1 ******* mudflap violation 2 (check/read): time=1354703106.661411 ptr=0xbf85846c size=129 pc=0xb76153ff location=`testflap.c:9:20 (main)' /lib/libmudflap.so.0(__mf_check+0x3f) [0xb76153ff] ./a.out(main+0x11a) [0x80488aa] /lib/libmudflap.so.0(__wrap_main+0x4b) [0xb7614b4b] Nearby object 1: checked region begins 0B into and ends 1B after mudflap object 0x901e790: name=`testflap.c:5:10 (main) onstack' bounds=[0xbf85846c,0xbf8584eb] size=128 area=stack check=3r/0w liveness=3 alloc time=1354703106.661027 pc=0xb7614adf number of nearby objects: 1
一応、対応するソースコードの場所が表示されますが読みにくいです。valgrindの方が見やすいですね。ただvalgrindでは、bss領域、stack領域のオーバーフローは検出できないので、その点はすごい。
参考文献
Binary Hacks――ハッカー秘伝のテクニック100選
grub2からエントリーを削除
Linuxカーネルソースをビルドしてインストールした場合、
package-cleanup --oldkernels --count=1
では削除されない。※これで削除した場合は、エントリーも削除される。
起動時には、grub2がエントリーを表示してくれるが、それを手動で削除しないといけない。
/boot/grub2/grub.cfgを直接編集した。Fedora(3.6.7)エントリを削除するには、下記のような部分を削除する。
menuentry 'Fedora (3.6.7)' --class fedora --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-1d859624-ca03-411b-b92d-4cf74d5c6be2' { load_video set gfxpayload=keep insmod gzio insmod part_msdos insmod ext2 set root='hd0,msdos1' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 1d859624-ca03-411b-b92d-4cf74d5c6be2 else search --no-floppy --fs-uuid --set=root 1d859624-ca03-411b-b92d-4cf74d5c6be2 fi echo 'Loading Fedora (3.6.7)' linux /boot/vmlinuz-3.6.7 root=UUID=1d859624-ca03-411b-b92d-4cf74d5c6be2 ro rd.md=0 rd.lvm=0 rd.dm=0 SYSFONT=False rd.luks=0 LANG=ja_JP.UTF-8 KEYTABLE=jp106 rhgb quiet echo 'Loading initial ramdisk ...' initrd /boot/initramfs-3.6.7.img }
ふつうのLinuxプログラミング
最近、仕事でLinuxで開発しています。昔買った本を引っ張り出して読み直しています。
結構内容が詰まっていていいな。この本。
ふつうのLinuxプログラミング Linuxの仕組みから学べるgccプログラミングの王道
- 作者: 青木峰郎
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2005/07/27
- メディア: 単行本
- 購入: 35人 クリック: 450回
- この商品を含むブログ (144件) を見る
リバースエンジニアリング ―Pythonによるバイナリ解析技法
前、本屋でみて気になっていたので、買いました。
リバースエンジニアリング ―Pythonによるバイナリ解析技法 (Art Of Reversing)
- 作者: Justin Seitz,安藤慶一
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/05/22
- メディア: 単行本(ソフトカバー)
- 購入: 4人 クリック: 359回
- この商品を含むブログ (29件) を見る