HOW TO APT-GET FROM THE INTERNAL NETWORKREMOTE SSHDWITH KNEESOCKS 
2014/09/14 
すみだセキュリティ勉強会2014#3 
@inaz2
About me 
•@inaz2 
•Security engineer & Python programmer 
•Girls Idol Freak 
•ももいろテクノロジー 
•http://inaz2.hatenablog.com/ 
2
ONE DAY
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
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 update 
Err http://security.ubuntu.com precise-security Release.gpg 
Temporary failure resolving 'security.ubuntu.com' 
5
THE NEXT DAY
I used HTTP Proxy 
LAN: 
192.168.0.0/24 
Internal: 
10.0.0.0/24 
.1 
.2 
.2 .3 
router 
sv1 sv2 
HTTP Proxy 
Internet 
7
I used HTTP Proxy 
LAN: 
192.168.0.0/24 
Internal: 
10.0.0.0/24 
.1 
.2 
.2 .3 
router 
sv1 sv2 
HTTP Proxy 
Internet 
$ sudo http_proxy=http://10.0.0.2:8080/ apt-get update 
Get:1 http://jp.archive.ubuntu.com precise Release.gpg [198 
B] 
8
HTTP Proxy worked, but … 
•別のマシンにProxyサーバを立てる必要がある 
•http_proxy環境変数を読まないコマンドもある 
•HTTP以外のプロトコルには使えない 
9
HTTP Proxy worked, but … 
•別のマシンにProxyサーバを立てる必要がある 
•http_proxy環境変数を読まないコマンドもある 
•HTTP以外のプロトコルには使えない 
10 
汎用性低い
OpenSSHDynamic Port Forwarding 
•ssh-D 1080 user@sv1 
•localhost:1080 を指定することで、sv1をSOCKS Proxyとして 使うことができる 
•HTTPに限らず、あらゆるTCP/UDPプロトコルに使える 
•OpenSSHはほとんどのサーバで動いている 
11
OpenSSHDynamic Port Forwarding 
•ssh-D 1080 user@sv1 
•localhost:1080 を指定することで、sv1をSOCKS Proxyとして 使うことができる 
•HTTPに限らず、あらゆるTCP/UDPプロトコルに使える 
•OpenSSHはほとんどのサーバに入っている 
汎用性高い 
12
SOCKSIFY(1) 
•DanteというSOCKS Proxy実装に含まれるコマンド 
•https://www.inet.no/dante/ 
•sudoapt-get install dante-client 
•ライブラリ関数をフックすることで、任意のコマンドを SOCKS Proxyに対応させることができる 
•このようなプログラムはProxifierと呼ばれる 
•http://en.wikipedia.org/wiki/Comparison_of_proxifiers 
13
SOCKSIFY(1) 
•DanteというSOCKS Proxy実装に含まれるコマンド 
•https://www.inet.no/dante/ 
•sudoapt-get install dante-client 
•ライブラリ関数をフックすることで、任意のコマンドを SOCKS Proxyに対応させることができる 
•このようなプログラムはProxifierと呼ばれる 
•http://en.wikipedia.org/wiki/Comparison_of_proxifiers 
$ SOCKS_PROXY=localhost:1080 socksifycurl http://www.example.com/ 
14
SOCKSIFY(1) 
•DanteというSOCKS Proxy実装に含まれるコマンド 
•https://www.inet.no/dante/ 
•sudoapt-get install dante-client 
•ライブラリ関数をフックすることで、任意のコマンドを SOCKS Proxyに対応させることができる 
•このようなプログラムはProxifierと呼ばれる 
•http://en.wikipedia.org/wiki/Comparison_of_proxifiers 
$ SOCKS_PROXY=localhost:1080 socksifycurl http://www.example.com/ 
curl: (7) Failed to connect to 0.0.0.1: Network is unreachable 
15 
( ꒪⌓꒪)
OpenSSHsource code 
•channels.c: channel_decode_socks5() 
•https://github.com/openssh/openssh-portable/blob/master/channels.c 
16
OpenSSHsource code 
•channels.c: channel_decode_socks5() 
•https://github.com/openssh/openssh-portable/blob/master/channels.c 
UDP非対応 
17
socksify+ openssh= FAIL 
•socksifyがDNS問い合わせをProxy経由で行おうとする 
•DNS問い合わせはUDPなので、OpenSSHはエラーを返す 
•即ち死 
18
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
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 
微妙…
SOCKS5 proxy-end DNS resolution 
•SOCKS5ではDNS名前解決をProxy側で行うようにできる 
•requestする側がDNSサーバのアドレスを知らなくても大丈夫 
•とりあえずDNSはなんとかできる 
•DNS以外のUDPは依然としてダメだが、問題になることは少ない 
21
SOCKS5 proxy-end DNS resolution 
•SOCKS5ではDNS名前解決をProxy側で行うようにできる 
•requestする側がDNSサーバのアドレスを知らなくても大丈夫 
•とりあえずDNSはなんとかできる 
•DNS以外のUDPは依然としてダメだが、問題になることは少ない 
22 
いい感じ
proxychains-ng 
•https://github.com/rofl0r/proxychains-ng 
•proxy-end DNS resolution対応 
•認証付きProxy対応 
•HTTP、SOCKS4、SOCKS5混在の多段Proxy接続可能 
23
proxychains-ng 
•https://github.com/rofl0r/proxychains-ng 
•proxy-end DNS resolution対応 
•認証付きProxy対応 
•HTTP、SOCKS4、SOCKS5混在の多段Proxy接続可能 
$ proxychains4 curl http://www.example.com/ 
[proxychains] configfile found: /etc/proxychains.conf 
[proxychains] preloading /usr/lib/libproxychains4.so 
<!doctypehtml> 
... 
24
proxychains-ng works, but … 
•設定ファイルの書き換えが必須 
•環境変数から設定できるようにしたい 
•デバッグ出力を完全に消せない 
•明示的に指定しない限り、入出力に触れないでほしい 
•多機能すぎてオーバーヘッド大きそう 
•せっかくならオーバーヘッドを最小化したい 
•認証も多段接続もいらない 
25
KNEESOCKS
kneesocksgithub 
27
kneesocksgithub 
28
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
Typical code for TCP connect 
30
Typical code for TCP connect 
31
Hooking libcfunctions 
•libkneesocks.so 
•改変したconnect, getaddrinfo(+ gethostbyname) を実装した共有ラ イブラリ 
•kneesocks[command] 
•LD_PRELOAD=libkneesocks.so [command] するだけのシェルスク リプト 
•libkneesocks.soを優先的に読ませる 
32
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
Hooking DNS lookup 
•ドメイン名からIPアドレスへの変換は getaddrinfo(or gethostbyname) で行われる 
•getaddrinfoをフックして、常に0.0.0.1を返すようにする 
•SOCKS4aの仕様にならう 
•このとき、ドメイン名をThread Local Storageに記憶 
•0.0.0.1へのconnectが来たら、記憶したドメイン名をProxyに 投げて解決させる 
34
Request with domain name 
•RFC 1928 -SOCKS Protocol Version 5 
•http://tools.ietf.org/html/rfc1928 
35
Request with domain name 
•RFC 1928 -SOCKS Protocol Version 5 
•http://tools.ietf.org/html/rfc1928 
36
Request with domain name 
•RFC 1928 -SOCKS Protocol Version 5 
•http://tools.ietf.org/html/rfc1928 
37 
¥x0fwww.example.com
Typical code for TCP connect 
saved_node= “www.example.com” 
return orig_getaddrinfo(“0.0.0.1”, ...) 
orig_connect(s, {“127.0.0.1”, 1080}, ...) 
if dstaddris “0.0.0.1”: 
establish SOCKS5 connection to saved_node(=“www.example.com”) 
return s 
38
Install, setup proxy and run 
•sudoapt-get install build-essential 
•git clone https://github.com/inaz2/kneesocks.git 
•cd kneesocks 
•make 
•sudomake install 
•ssh-D 1080 user@sv1 -f sleep 3600 
•kneesockscurl http://www.example.com/ 
•sudokneesocksapt-get update 
•kneesocksgit clone https://github.com/rapid7/metasploit-framework.git 
•kneesocksbundle install 
backgroundで1時間接続 
39
Configuration via envvariables 
•socks_proxy=localhost:1080 kneesocks[command] 
•localhost:1080 の部分を変える(上記はデフォルト値) 
•DEBUG=1 kneesocks[command] 
•標準エラー出力にデバッグログを吐かせる 
$ DEBUG=1 kneesockscurl 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 
<!doctypehtml> 
... 
40
WONTFIX 
•gethostbyname2, gethostbyname_r, gethostbyname2_r 
•GNU拡張(IPv6対応版とreentrant版) 
•gethostbyname系関数はすでにobsoleteなので放置 
•getaddrinfoを使わず、直接DNSrequestを投げるプログラム 
•dig, nslookup 
•libcをstatic linkしているプログラム 
•connectの前にgetaddrinfoを2連続で呼ぶプログラム 
•よく使うものであったら教えてください 
41
Pros and cons 
•Pros 
•SSHサーバさえ立っていれば、あとはローカルで完結 
•DNSサーバのアドレスを知らなくてもよい 
•任意のプログラムに統一的なインタフェースで使える 
•オーバーヘッド最小 
•Cons 
•Linuxでしか使えない 
•事前にコンパイルとインストールが必要 
42
Recap 
•Proxyプロトコルは楽しい 
•標準Cライブラリ関数のフックは楽しい 
•kneesocksお手軽便利 
•「kneesocksを履かせる」という言い回し推奨 
43
References 
•ssh-Linux SOCKS5 tunneling not working with udptraffic -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 
•mallocfailure (その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
THANK YOU! 
@inaz2

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

  • 1.
    HOW TO APT-GETFROM THE INTERNAL NETWORKREMOTE SSHDWITH KNEESOCKS 2014/09/14 すみだセキュリティ勉強会2014#3 @inaz2
  • 2.
    About me •@inaz2 •Security engineer & Python programmer •Girls Idol Freak •ももいろテクノロジー •http://inaz2.hatenablog.com/ 2
  • 3.
  • 4.
    I wanted toapt-get from sv2 LAN: 192.168.0.0/24 Internal: 10.0.0.0/24 .1 .2 .2 .3 router sv1 sv2 Internet 4
  • 5.
    I wanted toapt-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 update Err http://security.ubuntu.com precise-security Release.gpg Temporary failure resolving 'security.ubuntu.com' 5
  • 6.
  • 7.
    I used HTTPProxy LAN: 192.168.0.0/24 Internal: 10.0.0.0/24 .1 .2 .2 .3 router sv1 sv2 HTTP Proxy Internet 7
  • 8.
    I used HTTPProxy LAN: 192.168.0.0/24 Internal: 10.0.0.0/24 .1 .2 .2 .3 router sv1 sv2 HTTP Proxy Internet $ sudo http_proxy=http://10.0.0.2:8080/ apt-get update Get:1 http://jp.archive.ubuntu.com precise Release.gpg [198 B] 8
  • 9.
    HTTP Proxy worked,but … •別のマシンにProxyサーバを立てる必要がある •http_proxy環境変数を読まないコマンドもある •HTTP以外のプロトコルには使えない 9
  • 10.
    HTTP Proxy worked,but … •別のマシンにProxyサーバを立てる必要がある •http_proxy環境変数を読まないコマンドもある •HTTP以外のプロトコルには使えない 10 汎用性低い
  • 11.
    OpenSSHDynamic Port Forwarding •ssh-D 1080 user@sv1 •localhost:1080 を指定することで、sv1をSOCKS Proxyとして 使うことができる •HTTPに限らず、あらゆるTCP/UDPプロトコルに使える •OpenSSHはほとんどのサーバで動いている 11
  • 12.
    OpenSSHDynamic Port Forwarding •ssh-D 1080 user@sv1 •localhost:1080 を指定することで、sv1をSOCKS Proxyとして 使うことができる •HTTPに限らず、あらゆるTCP/UDPプロトコルに使える •OpenSSHはほとんどのサーバに入っている 汎用性高い 12
  • 13.
    SOCKSIFY(1) •DanteというSOCKS Proxy実装に含まれるコマンド •https://www.inet.no/dante/ •sudoapt-get install dante-client •ライブラリ関数をフックすることで、任意のコマンドを SOCKS Proxyに対応させることができる •このようなプログラムはProxifierと呼ばれる •http://en.wikipedia.org/wiki/Comparison_of_proxifiers 13
  • 14.
    SOCKSIFY(1) •DanteというSOCKS Proxy実装に含まれるコマンド •https://www.inet.no/dante/ •sudoapt-get install dante-client •ライブラリ関数をフックすることで、任意のコマンドを SOCKS Proxyに対応させることができる •このようなプログラムはProxifierと呼ばれる •http://en.wikipedia.org/wiki/Comparison_of_proxifiers $ SOCKS_PROXY=localhost:1080 socksifycurl http://www.example.com/ 14
  • 15.
    SOCKSIFY(1) •DanteというSOCKS Proxy実装に含まれるコマンド •https://www.inet.no/dante/ •sudoapt-get install dante-client •ライブラリ関数をフックすることで、任意のコマンドを SOCKS Proxyに対応させることができる •このようなプログラムはProxifierと呼ばれる •http://en.wikipedia.org/wiki/Comparison_of_proxifiers $ SOCKS_PROXY=localhost:1080 socksifycurl http://www.example.com/ curl: (7) Failed to connect to 0.0.0.1: Network is unreachable 15 ( ꒪⌓꒪)
  • 16.
    OpenSSHsource code •channels.c:channel_decode_socks5() •https://github.com/openssh/openssh-portable/blob/master/channels.c 16
  • 17.
    OpenSSHsource code •channels.c:channel_decode_socks5() •https://github.com/openssh/openssh-portable/blob/master/channels.c UDP非対応 17
  • 18.
    socksify+ openssh= FAIL •socksifyがDNS問い合わせをProxy経由で行おうとする •DNS問い合わせはUDPなので、OpenSSHはエラーを返す •即ち死 18
  • 19.
    Force TCP DNSrequest •tsocks •http://sourceforge.net/projects/tsocks/ •res_init(3) をフックして、TCP問い合わせを有効にする •redsocks •http://darkk.net.ru/redsocks/ •DNS requestをキャッチしたら、truncatedフラグ付きの偽応答を返 し、TCPで再度requestさせる •どちらにしても、requestする側が外側のDNSサーバのアドレ スを知っていなければならない 19
  • 20.
    Force TCP DNSrequest •tsocks •http://sourceforge.net/projects/tsocks/ •res_init(3) をフックして、TCP問い合わせを有効にする •redsocks •http://darkk.net.ru/redsocks/ •DNS requestをキャッチしたら、truncatedフラグ付きの偽応答を返 し、TCPで再度requestさせる •どちらにしても、requestする側が外側のDNSサーバのアドレ スを知っていなければならない 20 微妙…
  • 21.
    SOCKS5 proxy-end DNSresolution •SOCKS5ではDNS名前解決をProxy側で行うようにできる •requestする側がDNSサーバのアドレスを知らなくても大丈夫 •とりあえずDNSはなんとかできる •DNS以外のUDPは依然としてダメだが、問題になることは少ない 21
  • 22.
    SOCKS5 proxy-end DNSresolution •SOCKS5ではDNS名前解決をProxy側で行うようにできる •requestする側がDNSサーバのアドレスを知らなくても大丈夫 •とりあえずDNSはなんとかできる •DNS以外のUDPは依然としてダメだが、問題になることは少ない 22 いい感じ
  • 23.
    proxychains-ng •https://github.com/rofl0r/proxychains-ng •proxy-endDNS resolution対応 •認証付きProxy対応 •HTTP、SOCKS4、SOCKS5混在の多段Proxy接続可能 23
  • 24.
    proxychains-ng •https://github.com/rofl0r/proxychains-ng •proxy-endDNS resolution対応 •認証付きProxy対応 •HTTP、SOCKS4、SOCKS5混在の多段Proxy接続可能 $ proxychains4 curl http://www.example.com/ [proxychains] configfile found: /etc/proxychains.conf [proxychains] preloading /usr/lib/libproxychains4.so <!doctypehtml> ... 24
  • 25.
    proxychains-ng works, but… •設定ファイルの書き換えが必須 •環境変数から設定できるようにしたい •デバッグ出力を完全に消せない •明示的に指定しない限り、入出力に触れないでほしい •多機能すぎてオーバーヘッド大きそう •せっかくならオーバーヘッドを最小化したい •認証も多段接続もいらない 25
  • 26.
  • 27.
  • 28.
  • 29.
    SOCKS5 protocol in1 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
  • 30.
    Typical code forTCP connect 30
  • 31.
    Typical code forTCP connect 31
  • 32.
    Hooking libcfunctions •libkneesocks.so •改変したconnect, getaddrinfo(+ gethostbyname) を実装した共有ラ イブラリ •kneesocks[command] •LD_PRELOAD=libkneesocks.so [command] するだけのシェルスク リプト •libkneesocks.soを優先的に読ませる 32
  • 33.
    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
  • 34.
    Hooking DNS lookup •ドメイン名からIPアドレスへの変換は getaddrinfo(or gethostbyname) で行われる •getaddrinfoをフックして、常に0.0.0.1を返すようにする •SOCKS4aの仕様にならう •このとき、ドメイン名をThread Local Storageに記憶 •0.0.0.1へのconnectが来たら、記憶したドメイン名をProxyに 投げて解決させる 34
  • 35.
    Request with domainname •RFC 1928 -SOCKS Protocol Version 5 •http://tools.ietf.org/html/rfc1928 35
  • 36.
    Request with domainname •RFC 1928 -SOCKS Protocol Version 5 •http://tools.ietf.org/html/rfc1928 36
  • 37.
    Request with domainname •RFC 1928 -SOCKS Protocol Version 5 •http://tools.ietf.org/html/rfc1928 37 ¥x0fwww.example.com
  • 38.
    Typical code forTCP connect saved_node= “www.example.com” return orig_getaddrinfo(“0.0.0.1”, ...) orig_connect(s, {“127.0.0.1”, 1080}, ...) if dstaddris “0.0.0.1”: establish SOCKS5 connection to saved_node(=“www.example.com”) return s 38
  • 39.
    Install, setup proxyand run •sudoapt-get install build-essential •git clone https://github.com/inaz2/kneesocks.git •cd kneesocks •make •sudomake install •ssh-D 1080 user@sv1 -f sleep 3600 •kneesockscurl http://www.example.com/ •sudokneesocksapt-get update •kneesocksgit clone https://github.com/rapid7/metasploit-framework.git •kneesocksbundle install backgroundで1時間接続 39
  • 40.
    Configuration via envvariables •socks_proxy=localhost:1080 kneesocks[command] •localhost:1080 の部分を変える(上記はデフォルト値) •DEBUG=1 kneesocks[command] •標準エラー出力にデバッグログを吐かせる $ DEBUG=1 kneesockscurl 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 <!doctypehtml> ... 40
  • 41.
    WONTFIX •gethostbyname2, gethostbyname_r,gethostbyname2_r •GNU拡張(IPv6対応版とreentrant版) •gethostbyname系関数はすでにobsoleteなので放置 •getaddrinfoを使わず、直接DNSrequestを投げるプログラム •dig, nslookup •libcをstatic linkしているプログラム •connectの前にgetaddrinfoを2連続で呼ぶプログラム •よく使うものであったら教えてください 41
  • 42.
    Pros and cons •Pros •SSHサーバさえ立っていれば、あとはローカルで完結 •DNSサーバのアドレスを知らなくてもよい •任意のプログラムに統一的なインタフェースで使える •オーバーヘッド最小 •Cons •Linuxでしか使えない •事前にコンパイルとインストールが必要 42
  • 43.
    Recap •Proxyプロトコルは楽しい •標準Cライブラリ関数のフックは楽しい •kneesocksお手軽便利 •「kneesocksを履かせる」という言い回し推奨 43
  • 44.
    References •ssh-Linux SOCKS5tunneling not working with udptraffic -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 •mallocfailure (その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
  • 45.