how to apt-get from the internal network: remote sshd with kneesocks

45
HOW TO APT-GET FROM THE INTERNAL NETWORK REMOTE SSHD WITH KNEESOCKS 2014/09/14 すみだセキュリティ勉強会2014#3 @inaz2

Upload: inaz2

Post on 24-May-2015

1.876 views

Category:

Technology


6 download

DESCRIPTION

2014/09/14 すみだセキュリティ勉強会2014#3

TRANSCRIPT

Page 1: How to apt-get from the internal network: remote sshd with kneesocks

HOW TO APT-GET FROM THE INTERNAL NETWORK

REMOTE SSHD WITH KNEESOCKS

2014/09/14

すみだセキュリティ勉強会2014#3

@inaz2

Page 2: How to apt-get from the internal network: remote sshd with kneesocks

About me

• @inaz2

• Security engineer & Python programmer

• Girls Idol Freak

•ももいろテクノロジー

• http://inaz2.hatenablog.com/

2

Page 3: How to apt-get from the internal network: remote sshd with kneesocks

ONE DAY

Page 4: How to apt-get from the internal network: remote sshd with kneesocks

I wanted to apt-get from sv2

LAN: 192.168.0.0/24

Internal: 10.0.0.0/24

.1

.2

.2 .3

router

sv1 sv2

Internet

4

Page 5: How to apt-get from the internal network: remote sshd with kneesocks

I wanted to apt-get from sv2

LAN: 192.168.0.0/24

Internal: 10.0.0.0/24

.1

.2

.2 .3

router

sv1 sv2

Internet

$ sudo apt-get updateErr http://security.ubuntu.com precise-security Release.gpg

Temporary failure resolving 'security.ubuntu.com'

5

Page 6: How to apt-get from the internal network: remote sshd with kneesocks

THE NEXT DAY

Page 7: How to apt-get from the internal network: remote sshd with kneesocks

I used HTTP Proxy

LAN: 192.168.0.0/24

Internal: 10.0.0.0/24

.1

.2

.2 .3

router

sv1 sv2HTTP Proxy

Internet

7

Page 8: How to apt-get from the internal network: remote sshd with kneesocks

I used HTTP Proxy

LAN: 192.168.0.0/24

Internal: 10.0.0.0/24

.1

.2

.2 .3

router

sv1 sv2HTTP Proxy

Internet

$ sudo http_proxy=http://10.0.0.2:8080/ apt-get updateGet:1 http://jp.archive.ubuntu.com precise Release.gpg [198 B]

8

Page 9: How to apt-get from the internal network: remote sshd with kneesocks

HTTP Proxy worked, but …

•別のマシンにProxyサーバを立てる必要がある

• http_proxy環境変数を読まないコマンドもある

• HTTP以外のプロトコルには使えない

9

Page 10: How to apt-get from the internal network: remote sshd with kneesocks

HTTP Proxy worked, but …

•別のマシンにProxyサーバを立てる必要がある

• http_proxy環境変数を読まないコマンドもある

• HTTP以外のプロトコルには使えない

10

汎用性低い

Page 11: How to apt-get from the internal network: remote sshd with kneesocks

OpenSSH Dynamic Port Forwarding

• ssh -D 1080 user@sv1

• localhost:1080 を指定することで、sv1をSOCKS Proxyとして使うことができる

• HTTPに限らず、あらゆるTCP/UDPプロトコルに使える

• OpenSSHはほとんどのサーバで動いている

11

Page 12: How to apt-get from the internal network: remote sshd with kneesocks

OpenSSH Dynamic Port Forwarding

• ssh -D 1080 user@sv1

• localhost:1080 を指定することで、sv1をSOCKS Proxyとして使うことができる

• HTTPに限らず、あらゆるTCP/UDPプロトコルに使える

• OpenSSHはほとんどのサーバに入っている

汎用性高い12

Page 13: How to apt-get from the internal network: remote sshd with kneesocks

SOCKSIFY(1)

• DanteというSOCKS Proxy実装に含まれるコマンド

• https://www.inet.no/dante/

• sudo apt-get install dante-client

•ライブラリ関数をフックすることで、任意のコマンドをSOCKS Proxyに対応させることができる

•このようなプログラムは Proxifierと呼ばれる

• http://en.wikipedia.org/wiki/Comparison_of_proxifiers

13

Page 14: How to apt-get from the internal network: remote sshd with kneesocks

SOCKSIFY(1)

• DanteというSOCKS Proxy実装に含まれるコマンド

• https://www.inet.no/dante/

• sudo apt-get install dante-client

•ライブラリ関数をフックすることで、任意のコマンドをSOCKS Proxyに対応させることができる

•このようなプログラムは Proxifierと呼ばれる

• http://en.wikipedia.org/wiki/Comparison_of_proxifiers

$ SOCKS_PROXY=localhost:1080 socksify curl http://www.example.com/

14

Page 15: How to apt-get from the internal network: remote sshd with kneesocks

SOCKSIFY(1)

• DanteというSOCKS Proxy実装に含まれるコマンド

• https://www.inet.no/dante/

• sudo apt-get install dante-client

•ライブラリ関数をフックすることで、任意のコマンドをSOCKS Proxyに対応させることができる

•このようなプログラムは Proxifierと呼ばれる

• http://en.wikipedia.org/wiki/Comparison_of_proxifiers

$ SOCKS_PROXY=localhost:1080 socksify curl http://www.example.com/curl: (7) Failed to connect to 0.0.0.1: Network is unreachable

15

( ꒪⌓꒪)

Page 16: How to apt-get from the internal network: remote sshd with kneesocks

OpenSSH source code

• channels.c: channel_decode_socks5()

• https://github.com/openssh/openssh-portable/blob/master/channels.c

16

Page 17: How to apt-get from the internal network: remote sshd with kneesocks

OpenSSH source code

• channels.c: channel_decode_socks5()

• https://github.com/openssh/openssh-portable/blob/master/channels.c

UDP非対応17

Page 18: How to apt-get from the internal network: remote sshd with kneesocks

socksify + openssh = FAIL

• socksifyがDNS問い合わせをProxy経由で行おうとする

• DNS問い合わせはUDPなので、OpenSSHはエラーを返す

•即ち死

18

Page 19: How to apt-get from the internal network: remote sshd with kneesocks

Force TCP DNS request

• tsocks

• http://sourceforge.net/projects/tsocks/

• res_init(3) をフックして、TCP問い合わせを有効にする

• redsocks

• http://darkk.net.ru/redsocks/

• DNS requestをキャッチしたら、truncatedフラグ付きの偽応答を返し、TCPで再度requestさせる

•どちらにしても、requestする側が外側のDNSサーバのアドレスを知っていなければならない

19

Page 20: How to apt-get from the internal network: remote sshd with kneesocks

Force TCP DNS request

• tsocks

• http://sourceforge.net/projects/tsocks/

• res_init(3) をフックして、TCP問い合わせを有効にする

• redsocks

• http://darkk.net.ru/redsocks/

• DNS requestをキャッチしたら、truncatedフラグ付きの偽応答を返し、TCPで再度requestさせる

•どちらにしても、requestする側が外側のDNSサーバのアドレスを知っていなければならない

20

微妙…

Page 21: How to apt-get from the internal network: remote sshd with kneesocks

SOCKS5 proxy-end DNS resolution

• SOCKS5ではDNS名前解決をProxy側で行うようにできる

• requestする側がDNSサーバのアドレスを知らなくても大丈夫

•とりあえずDNSはなんとかできる

• DNS以外のUDPは依然としてダメだが、問題になることは少ない

21

Page 22: How to apt-get from the internal network: remote sshd with kneesocks

SOCKS5 proxy-end DNS resolution

• SOCKS5ではDNS名前解決をProxy側で行うようにできる

• requestする側がDNSサーバのアドレスを知らなくても大丈夫

•とりあえずDNSはなんとかできる

• DNS以外のUDPは依然としてダメだが、問題になることは少ない

22

いい感じ

Page 23: How to apt-get from the internal network: remote sshd with kneesocks

proxychains-ng

• https://github.com/rofl0r/proxychains-ng

• proxy-end DNS resolution対応

•認証付きProxy対応

• HTTP、SOCKS4、SOCKS5混在の多段Proxy接続可能

23

Page 24: How to apt-get from the internal network: remote sshd with kneesocks

proxychains-ng

• https://github.com/rofl0r/proxychains-ng

• proxy-end DNS resolution対応

•認証付きProxy対応

• HTTP、SOCKS4、SOCKS5混在の多段Proxy接続可能

$ proxychains4 curl http://www.example.com/[proxychains] config file found: /etc/proxychains.conf[proxychains] preloading /usr/lib/libproxychains4.so<!doctype html>...

24

Page 25: How to apt-get from the internal network: remote sshd with kneesocks

proxychains-ng works, but …

•設定ファイルの書き換えが必須

•環境変数から設定できるようにしたい

•デバッグ出力を完全に消せない

•明示的に指定しない限り、入出力に触れないでほしい

•多機能すぎてオーバーヘッド大きそう

•せっかくならオーバーヘッドを最小化したい

•認証も多段接続もいらない

25

Page 26: How to apt-get from the internal network: remote sshd with kneesocks

KNEESOCKS

Page 27: How to apt-get from the internal network: remote sshd with kneesocks

kneesocks github

27

Page 28: How to apt-get from the internal network: remote sshd with kneesocks

kneesocks github

28

Page 29: How to apt-get from the internal network: remote sshd with kneesocks

SOCKS5 protocol in 1 minute

client proxy

1. support only NO-AUTH

2. ok, go with NO-AUTH

3. please connect to 203.0.113.1:80

4. succeeded

GET / HTTP/1.1

HTTP/1.1 200 OK

usual payload 203.0.113.1

29

Page 30: How to apt-get from the internal network: remote sshd with kneesocks

Typical code for TCP connect

30

Page 31: How to apt-get from the internal network: remote sshd with kneesocks

Typical code for TCP connect

31

Page 32: How to apt-get from the internal network: remote sshd with kneesocks

Hooking libc functions

• libkneesocks.so

•改変したconnect, getaddrinfo (+ gethostbyname) を実装した共有ライブラリ

• kneesocks [command]

• LD_PRELOAD=libkneesocks.so [command] するだけのシェルスクリプト

• libkneesocks.soを優先的に読ませる

32

Page 33: How to apt-get from the internal network: remote sshd with kneesocks

Outline of libkneesocks.so

• init()

• orig_connect = dlsym(RTLD_NEXT, “connect”)

• connect(s, {“203.0.113.1”, 80}, ...)

• connect_proxy(s, {“203.0.113.1”, 80}, ...)

• unset non-blocking flag

• orig_connect(s, {“127.0.0.1”, 1080}, ...)

• establish SOCKS connection for {“203.0.113.1”, 80}

• restore non-blocking flag

• return s

33

Page 34: How to apt-get from the internal network: remote sshd with kneesocks

Hooking DNS lookup

•ドメイン名からIPアドレスへの変換はgetaddrinfo (or gethostbyname) で行われる

• getaddrinfoをフックして、常に0.0.0.1を返すようにする

• SOCKS4aの仕様にならう

•このとき、ドメイン名をThread Local Storageに記憶

• 0.0.0.1へのconnectが来たら、記憶したドメイン名をProxyに投げて解決させる

34

Page 35: How to apt-get from the internal network: remote sshd with kneesocks

Request with domain name

• RFC 1928 - SOCKS Protocol Version 5

• http://tools.ietf.org/html/rfc1928

35

Page 36: How to apt-get from the internal network: remote sshd with kneesocks

Request with domain name

• RFC 1928 - SOCKS Protocol Version 5

• http://tools.ietf.org/html/rfc1928

36

Page 37: How to apt-get from the internal network: remote sshd with kneesocks

Request with domain name

• RFC 1928 - SOCKS Protocol Version 5

• http://tools.ietf.org/html/rfc1928

37

¥x0fwww.example.com

Page 38: How to apt-get from the internal network: remote sshd with kneesocks

Typical code for TCP connectsaved_node = “www.example.com”return orig_getaddrinfo(“0.0.0.1”, ...)

orig_connect(s, {“127.0.0.1”, 1080}, ...)if dst addr is “0.0.0.1”:

establish SOCKS5 connection to saved_node (=“www.example.com”)

return s

38

Page 39: How to apt-get from the internal network: remote sshd with kneesocks

Install, setup proxy and run

• sudo apt-get install build-essential

• git clone https://github.com/inaz2/kneesocks.git

• cd kneesocks

• make

• sudo make install

• ssh -D 1080 user@sv1 -f sleep 3600

• kneesocks curl http://www.example.com/

• sudo kneesocks apt-get update

• kneesocks git clone https://github.com/rapid7/metasploit-framework.git

• kneesocks bundle install

backgroundで1時間接続

39

Page 40: How to apt-get from the internal network: remote sshd with kneesocks

Configuration via env variables

• socks_proxy=localhost:1080 kneesocks [command]

• localhost:1080 の部分を変える(上記はデフォルト値)

• DEBUG=1 kneesocks [command]

•標準エラー出力にデバッグログを吐かせる

$ DEBUG=1 kneesocks curl http://www.example.com/[kneesocks] getaddrinfo: node=www.example.com, service=80[kneesocks] connect: type=stream, family=2, address=0.0.0.1, port=80[kneesocks] connect_proxy: saved_node=www.example.com<!doctype html>...

40

Page 41: How to apt-get from the internal network: remote sshd with kneesocks

WONTFIX

• gethostbyname2, gethostbyname_r, gethostbyname2_r

• GNU拡張(IPv6対応版とreentrant版)

• gethostbyname系関数はすでにobsoleteなので放置

• getaddrinfoを使わず、直接DNS requestを投げるプログラム

• dig, nslookup

• libcをstatic linkしているプログラム

• connectの前にgetaddrinfoを2連続で呼ぶプログラム

•よく使うものであったら教えてください

41

Page 42: How to apt-get from the internal network: remote sshd with kneesocks

Pros and cons

• Pros

• SSHサーバさえ立っていれば、あとはローカルで完結

• DNSサーバのアドレスを知らなくてもよい

•任意のプログラムに統一的なインタフェースで使える

•オーバーヘッド最小

• Cons

• Linuxでしか使えない

•事前にコンパイルとインストールが必要

42

Page 43: How to apt-get from the internal network: remote sshd with kneesocks

Recap

• Proxyプロトコルは楽しい

•標準Cライブラリ関数のフックは楽しい

• kneesocksお手軽便利

•「kneesocksを履かせる」という言い回し推奨

43

Page 44: How to apt-get from the internal network: remote sshd with kneesocks

References

• ssh - Linux SOCKS5 tunneling not working with udp traffic - Super User

• http://superuser.com/questions/639425/linux-socks5-tunneling-not-working-with-udp-traffic

• How Socks 5 Works

• http://samsclass.info/122/proj/how-socks5-works.html

• malloc failure (その4) - Wataru's memo

• http://memo.wnishida.com/?date=20060730

• スレッドローカルストレージ(TLS) - Linuxの備忘録とか・・・

• http://wiki.bit-hive.com/north/pg/%A5%B9%A5%EC%A5%C3%A5%C9%A5%ED%A1%BC%A5%AB%A5%EB%A5%B9%A5%C8%A5%EC%A1%BC%A5%B8%28TLS%29

• opensshとproxychains-ngによるSOCKS Proxy経由のインターネット接続 -ももいろテクノロジー

• http://inaz2.hatenablog.com/entry/2014/08/20/004106

44

Page 45: How to apt-get from the internal network: remote sshd with kneesocks

THANK YOU!@inaz2