君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

bashで特定の文字列を含むファイルの名前を、一括置換する

f:id:karoten512:20180220003702j:plain

bashである文字列を含むファイルについて、一括置換したかった

カレントディレクトリにあるファイルのうち、

無題を含むものをmudaiに変える、みたいなことがしたかった。

結論

解説

まず、以下のようにファイルを準備します。

$ touch hogeA hogeB fugaC

これらのファイルのうち、以下の2つのファイル名を

hogeA -> ho:)geA
hogeB -> ho:)geB

と変更することにします。

for文

こう書けば、カレントディレクトリのファイルについて

ループ処理をすることが出来ます。

# run.sh
for file in *
do
  echo ${file}
done
$ sh run.sh
fugaC
hogeA
hogeB

sed

新しいファイル名を生成する際、正規表現を使うことがあります。

そのときはこのsedを使いましょう。

以下のように使うことが出来ます。

$ echo hogeA | sed -E 's/(ho)(ge)/\1:)\2/g'
ho:)geA

-E オプション

正規表現が使えます。

's/(ho)(ge)/\1:)\2/g' について

ho, geという文字をかっこでくくることにより、キャプチャを撮っています。

そして、\1, \2で再度アクセスしてます。

\1, \2の間にhappy simbolをいれてます。

mv

forとsedを組み合わせて、

sedで新しいファイル名を生成しつつ、

mvでその新しいファイル名に変更していきます。

for file in *
do
    after_file=`echo ${file} | sed -E 's/(ho)(ge)/\1:)\2/g'`
    mv -i "${file}" "${after_file}"
done

まとめ

sedコマンド、とても便利。

とくにキャプチャを取り始めるとその便利さに驚く。

今回、xargsなどを用いるともっと簡単にかけるかもしれないが、

可読性のためにココらへんでとどめておくことにした。

またチャレンジしたい。

bashは最強のポータビリティ言語。

MySQLにて、特定のカラムに日本語が含まれているかどうかを抽出

あるカラムに日本語が含まれていることを検出したい

結論

あるカラムに対して、

LENGTH

CHARACTER_LENGTH

の値が異なることを利用する。

SQLの例

SELECT
  *
FROM
  table_name
WHERE
  LENGTH(column_name) != CHARACTER_LENGTH(column_name);

解説

LENGTHは「バイト」数

LENGTH:文字列のバイト数を調べる

CHAR_LENGTHは「文字」数

なるほどねぇ。

oshiete.goo.ne.jp

sshのセキュリティ設定で、なぜポートを22から変えるとよいのか〜サーバとポートと/etc/ssh/sshd_configと〜

f:id:karoten512:20180211233659j:plain

サーバのsshdプロセスに対して、1日900回以上の不正アクセスがあった

詳しくはこの記事。

karoten512.hatenablog.com

対応方法の一つ

/etc/ssh/sshd_configを編集し、

sshdがlistenしているポートを22→10022に変える。

そもそもポートとは

サーバでは、いろんなアプリケーションが動いている

f:id:karoten512:20180211231522p:plain

nginx、sshd、mysqld、telnetdなど、

いろんなアプリケーションが動いている。

サーバを利用するときは、このアプリケーションと通信することになる。

nginxアプリケーションと通信したい時

f:id:karoten512:20180211231612p:plain

webサイトを見る場合は、この場合nginxと通信することになる。

ipアドレスによって、サーバにはたどり着くが、

これだけではnginxと通信することが出来ない。

「nginxというアプリケーションと通信したいです、とお願いすればよいのでは?」

と思うかもしれないが、ユーザ側からはサーバの中が見れないので、

webサーバがnginxなのかapacheなのか、

はたまたIISなのかはわからない。

実際は

実際、アプリケーションは「ポート」という部屋のようなものの中にいる。

(正確にはポートをlistenしている、というがわかりやすさのため部屋にいる、とした)

サーバにはポートという部屋がある

f:id:karoten512:20180211232126p:plain

サーバには、

1〜65535の番号が振られた、ポートという部屋を持っている。

それぞれの部屋にはアプリケーションが住んでいる

f:id:karoten512:20180211232310p:plain

上記のように、22番にはsshd、80番にはnginx、、、というように、

部屋の中にはアプリケーションが住んでいる。

通信するときは部屋番号を指定して通信している

f:id:karoten512:20180211232422p:plain

httpアクセスが送られる時、

サーバのipアドレス: ポート番号

という形で送られている。

これで、通信したいアプリケーションと通信ができる。

これは、マンションのある部屋に郵便物をおくるイメージと似ている。

通信は、コンピュータからコンピュータではなく、

ポートからポート、と覚えておくと良い。

アプリケーションには定められた部屋番号がある

22番にはsshd、80番にはnginxというように、

色んな人が使う可能性が高いアプリケーションは、予め決められた部屋番号がある。

これにより、

サーバの中でどんなアプリケーションが動いているかは分かんないけど、

80番ポートにアクセスしたらwebサイトみれるんじゃね?

くらいの知識でwebサービスが使える。

使う側は、ipとポートさえわかっていればよい。

「アプリケーションには定められた部屋番号がある」が逆手に取られることがある

今回、sshdに向けて不正アクセスが大量にあったのは、

f:id:karoten512:20180211233104p:plain

ハッカー「22番ポートにはsshdがすんでるハズだから、鬼ノックしてやろ!!!!」

と思った人がいたからである。

対策としては、sshdのお引っ越し

f:id:karoten512:20180211233215p:plain

こんな感じでsshdを10022番に引越ししてもらう。

(/etc/ssh/sshd_configの設定を変える)

そうすると、

ハッカーは空部屋を鬼ノックし続けるという悲しいことになる。

これでsshdへの不正アクセスがぐんと減るのだ。

まとめ

  • みんなが使うアプリケーションは、予め定められたポート番号に住まわせる

  • 他の人に使ってほしくないアプリケーションは、自分だけが知っていればよいポート番号に住まわせる

とすればよいはず。

今回ポート周りの知識が整理されたので良かった。

user「PPAP」からの不正アクセスを検出しました〜sshdのログ(/var/log/secure)から不正ユーザの名前を取り出し、セキュアじゃないユーザ名について考えてみた〜

f:id:karoten512:20180210130018j:plain

存在しないユーザからのアクセスがあった

Failed password for invalid user *** from ...

これは、

linux上で登録されていないユーザ *** からのアクセスがありました」

ということ。

今回、攻撃者がどんな名前を用いてアクセスしてくるのか

探ってみる。

手順

ログからinvalid userだけ取り出す

awkを使おう。

cat /var/log/secure | awk -F' ' '/Invalid/{print$ 8}' | sort | uniq
0
1
1111
111111
123123
1234
12345
123456
123456789
12345qwert
1234qwer
12qwaszx
1q2w3e4r
1q2w3e4r5t
1qaz2wsx
1qaz@WSX

出てきた。

ついでに集計もしてみる。

cat secure | awk -F' ' '/Invalid/{print$ 8}' | awk '{count[$0]++}END{for(i in count)print count[i], i}' | sort -nr
15 minecraft
14 www
14 user1
14 steam
14 server
14 debian

出てきた。

不正アクセス者ランキング

5位

centos: 1023件

なお、ubuntuは63件でした。

なぜubuntuじゃなくてcentosなのか。

単純にサーバとしてよく使われているから・・・?

それともnmapでOSがわかるから・・・?

(自分のサーバにnmapしてみましたが、unixという情報しか出てきませんでした)

4位

guest: 1096件

ありがち。

3位

user: 1126件

これもありがち。

2位

test: 1178件

これすごくありがち。

1位

admin: 1300件

これやったことあるな。

これからは安易に使わないようにしよう。。。

なお、6位から20位はこんな感じ。

順位回数/monthユーザ名
6112oracle
798nagios
890git
963ubuntu
1054hadoop
1152pi
1246ftpuser
1343teamspeak
1441zabbix
1541vagrant
1637vnc
1737ubnt
1835support
1931ts
2030ts3

上位5位が圧倒的すぎる。

分類

数字 + ランダムアルファベット系

0
1
1111
111111
123123
1234
12345
123456
123456789

管理者系

ADMIN
Admin123
Administrator
admin
admin1
admin123
admin2
administrador
administrator

有名人系

adam
eva

特定のクラウドサービスを狙ったもの

ec2-user

人名系

外国人

alberto
aleksei
alessandro
alex
alfresco
ali
alice
alicia
allison
ally
alma

日本人

dai
daichi
daiki
daisuke
hideaki
hideki
hideo
hikaru
hiro
hiroaki
hiroki
hiroshi
hiroyuki

ソフトウェア名

nagios
git
hadoop
nginx
nodejs
redis
vagrant

デプロイ用ユーザを狙ったと思われる系

deploy1
deploy123
deploy1234
deploy12345
deploy123456
deploy2
deploy3
deploy4
deploy5

明らかに悪意がある系

exploit

番外編

PPAP

これで日本人だと特定できたかなと思ったのもつかの間、

これ世界的に流行ったやつだからどこからアクセスされてもおかしくねえぞ。

まとめ

user名で避けるべき名前

  • admin
  • test
  • user
  • guest
  • centos

よく使われているからこそ、狙われる。

感想

割と日本人の名前が多い。

どこまで考えて攻撃しているのかはしらないけど、

安易に自分の名前をユーザ名にするのは良くないと感じた。

せめて記号や数値と織り交ぜたい。

また、ソフトウェア名も良くない。

僕が借りているサーバが、世界各国から「1日900回」不正アクセスされている話〜/var/log/secureからみえる攻撃者の影〜

f:id:karoten512:20180210104805p:plain

私用で使っているサーバの/var/log/secureをみてみた

f:id:karoten512:20180210112501p:plain

見に覚えのないアクセスが大量にある。。。

しかもuserはrootだったりadminだったり。。。

これ、不正アクセスってやつか?

1日どれくらい不正アクセスを試みられているのか

2/4の不正アクセス回数を、すごい雑な方法だけどしらべてみた。

$ cat /var/log/secure | awk '/Feb  4/ && /Failed/' | wc -l
943

わお。943回。どこから不正アクセスされているんだろ。

いったんipだけ抽出して、

どこの国から狙われているか調査してみた。

使用unixコマンド

ここらへんを知っておくとログ調査に便利。

調査手順

ipアドレスのみ抽出

$ grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /var/log/secure > ips.txt

-Eオプションで正規表現が使えます

40.69.203.57
40.69.203.57
40.69.203.57
172.31.32.142
94.183.180.86
94.183.180.86
94.183.180.86
...

※ 念のためipアドレスは編集しております

ipの重複をなくす

sort ips.txt | uniq > unique_ips.txt

sortしてuniqして、ipをuniqueにします。

101.78.196.27
103.16.142.208
103.20.251.158
103.213.115.45
103.216.205.51
103.22.171.1
...

ipがユニークになった。

ipジオロケーションサービスに投げる

$ curl http://api.hostip.info/get_html.php\?ip=40.69.203.57

これを投げると、

Country: UNITED STATES (US)
City: (Unknown city)
IP: 40.69.203.57

いい感じにデータが返ってきます。

#!/bin/bash
while read ip
do
  curl http://api.hostip.info/get_html.php\?ip=$ip\&position=true
done < unique_ips.txt

run.shという名前で保存して、

$ sh run.sh > countries.txt

こんな感じで走らせ、結果をテキストファイルに保存します。

awkコマンドで国だけ抽出

$ cat countries.txt | awk '/Country/' | sort | uniq

とすると、先ほどの結果の「Country」だけ抽出できます。

結果

Country: (Private Address) (XX)
Country: (Unknown Country?) (XX)
Country: AUSTRALIA (AU)
Country: AUSTRIA (AT)
Country: BRAZIL (BR)
Country: BULGARIA (BG)
Country: CANADA (CA)
Country: CHILE (CL)
Country: CHINA (CN)
Country: COLOMBIA (CO)
Country: CROATIA (HR)
Country: DENMARK (DK)
Country: EUROPEAN UNION (EU)
Country: FRANCE (FR)
Country: GERMANY (DE)
Country: HONG KONG (HK)
Country: HUNGARY (HU)
Country: INDIA (IN)
Country: INDONESIA (ID)
Country: IRELAND (IE)
Country: ISRAEL (IL)
Country: ITALY (IT)
Country: JAPAN (JP)
Country: KOREA, REPUBLIC OF (KR)
Country: MALAYSIA (MY)
Country: MEXICO (MX)
Country: NETHERLANDS (NL)
Country: NORWAY (NO)
Country: PAKISTAN (PK)
Country: PERU (PE)
Country: PHILIPPINES (PH)
Country: POLAND (PL)
Country: RUSSIAN FEDERATION (RU)
Country: SENEGAL (SN)
Country: SLOVENIA (SI)
Country: SPAIN (ES)
Country: SWITZERLAND (CH)
Country: TAIWAN (TW)
Country: THAILAND (TH)
Country: UKRAINE (UA)
Country: UNITED KINGDOM (GB)
Country: UNITED STATES (US)
Country: VIET NAM (VN)

おおー。

世界各国から狙われている笑

攻撃元を特定するのは難しい

ただ、これだけだと発信元を特定するのは難しい。

攻撃者はいくつもの踏み台サーバを使って攻撃することにより、

自分の発信元を特定しにくくしているから。

なので、世界各国からアクセスされているからと言って、

本当に世界各国の人が狙っているかどうかはわからない。

攻撃を回避するには

色んな方法があるが、

今回はポート番号を変えてみた(次回)

puttyからsshでログインしようとした時に、Disconnected: No supported authentication methods availableと言われてしまった

f:id:karoten512:20180210003701p:plain

puttyを使ってsshでパスワード認証を使ってログインしようとした

こんなエラーが表示されました。

Disconnected: No supported authentication methods available

とりあえずサーバに入り、/etc/ssh/sshd_configをみてみる

いろいろな原因が考えられるが、とりあえずサーバの設定ファイルをみてみた。

PasswordAuthentication no

パスワード認証が使えないように設定されている。

だいぶ前にいじったから忘れてた。

セキュアじゃなくなるけど

一旦

PasswordAuthentication yes

とした。そうしたらログインできるようになった。

その後、すぐにnoに戻した。

duコマンドを使って、現在いるディレクトリにあるファイルの合計サイズを出したい

f:id:karoten512:20180209233955p:plain

現在いるディレクトリにあるファイルの合計サイズを出したい

$ du -sh .

解説

sオプションについて

sオプションをつけないとどうなるか

$ du -h .
1.2G    ./directoryA
1.2G    ./directoryB
 24K    ./pra

すべてのディレクトリのサイズがでてくる。

つけるとどうなるか

$ du -hs .
3.6G    .

普通に合計値が出る。

hオプションについて

つけないとどうなるか

$ du -s .
7614736 .

512バイト単位で出る。 なぜだ。

つけるとどうなるか

$ du -sh .
3.6G    .

いい感じの単位で出してくれる。