kaistshadow / blockchain-sim

Scalable blockchain simulator/emulator running on shadow simulator
MIT License
9 stars 1 forks source link

Add `shadow node` and `fake addr` supports for Monero Sybil Adapter API #287

Closed ygnkim closed 3 years ago

ygnkim commented 3 years ago

Monero Adapter should support shadow node which passively receives connection request from the target Monero node.

Also, to test the shadow node, it is also nice to include fake addr message feature for Monero Adapter so that the target Monero can initiate the connection to the shadow node.

Originally posted by @ygnkim in https://github.com/kaistshadow/blockchain-sim/issues/275#issuecomment-813191175

ygnkim commented 3 years ago

The fake addr can be implemented by adding peerlist_entry in the response of the TIMED_SYNC message.

After the insertion of IP address '3.0.0.1:28080', the target Monero prints the following logs.

2020-01-01 00:01:04.400 I [3.0.0.1:28080 OUT] 243 bytes sent for category command-1001 initiated by us
2020-01-01 00:01:04.400 T [3.0.0.1:28080 OUT] [levin_protocol] -->> start_outer_call
2020-01-01 00:01:04.400 T Moving counter buffer by 1 second 0 < 1.57784e+09 (last time 0)
2020-01-01 00:01:04.400 T Throttle throttle_speed_out: packet of ~276b  (from 276 b) Speed AVG=   0[w=1]    0[w=1] /  Limit=16 KiB/sec  [276 0 0 0 0 0 0 0 0 0 ]
2020-01-01 00:01:04.400 D do_send_chunk() NOW SENSD: packet=276 B
2020-01-01 00:01:04.400 T handler_write (direct) - before ASIO write, for packet=276 B (after sleep)
2020-01-01 00:01:04.400 T Setting 00:05:00 expiry
2020-01-01 00:01:04.400 T [3.0.0.1:28080 OUT] [sock 1313] Async send calledback 276
2020-01-01 00:01:04.400 T Moving counter buffer by 1 second 1.57784e+09 < 1.57784e+09 (last time 1.57784e+09)
2020-01-01 00:01:04.400 T Moving counter buffer by 1 second 1.57784e+09 < 1.57784e+09 (last time 1.57784e+09)
2020-01-01 00:01:04.400 T dbg >>> global-OUT: speed is A= 21.8085 vs Max=2.09715e+06  so sleep: D=-9.39988 sec E=     205 (Enow=     481) M=2.09715e+06 W=     9.4 R=1.9713e+07 Wgood      11 History: [0 0 205 0 0 0 0 0 0 0 ] m_last_sample_time=1.57784e+09
2020-01-01 00:01:04.400 T Throttle >>> global-OUT: packet of ~276b  (from 276 b) Speed AVG=   0[w=9.4]    0[w=9.4] /  Limit=2048 KiB/sec  [276 0 205 0 0 0 0 0 0 0 ]
2020-01-01 00:01:04.400 D [3.0.0.1:28080 OUT] LEVIN_PACKET_SENT. [len=243, flags1, r?=1, cmd = 1001, ver=1
2020-01-01 00:01:04.400 T [3.0.0.1:28080 OUT] [levin_protocol] -->> start_outer_call
2020-01-01 00:01:04.400 D [3.0.0.1:28080 OUT] anvoke_handler, timeout: 5000
2020-01-01 00:01:04.400 T [3.0.0.1:28080 OUT] [levin_protocol] <<-- finish_outer_call
2020-01-01 00:01:04.400 T [3.0.0.1:28080 OUT] [sock 1313] release
2020-01-01 00:01:09.500 I [3.0.0.1:28080 OUT] Timeout on invoke operation happened, command: 1001 timeout: 5000
2020-01-01 00:01:09.500 I Failed to invoke command 1001 return code -4
2020-01-01 00:01:09.500 W [3.0.0.1:28080 OUT] COMMAND_HANDSHAKE invoke failed. (-4, LEVIN_ERROR_CONNECTION_TIMEDOUT)
2020-01-01 00:01:09.500 W [3.0.0.1:28080 OUT] COMMAND_HANDSHAKE Failed
2020-01-01 00:01:09.500 I [3.0.0.1:28080 OUT] Failed to HANDSHAKE with peer 3.0.0.1:28080

The shadow node of the Monero should implement command_handshake response first.

ygnkim commented 3 years ago

Adhoc-test of handshaking to shadow node from a target Monero node is successfully done.

The fake addr injection mechanism for Monero should be implemented in scalable way.

ygnkim commented 3 years ago

EREBUS policy를 써서 에러없이 동작시키는데에는 성공함. 하지만, benign node churnout을 구현해야하고, 실제 공격과 유사하게 파라미터 설정이 필요함.

또한, 처음에 target Monero에서 NOTIFY_GET_TXPOOL_COMPLEMENT 메시지를 만들고, 전송을 못해서 한 노드와 해당 연결이 제대로 이뤄지지 않는 문제점을 발견 (실제 로컬 monero와 비교했을 때, context switching이 제대로 안되는 것 때문인지?). 일단, NOTIFY_GET_TXPOOL_COMPLEMENT 메시지가 더 안만들어져서 문제는 없어보이는데, 나중에 여유 있을 때 디버깅해보기. (shadow 관련된 이슈로 추정된다)

ygnkim commented 3 years ago

fake addr injection은 MoneroNodePrimitives.cpp 에서 _addr_ip_list 벡터를 이용해 구현함. 즉, ADDR 타이머가 호출될때마다 우선 _addr_ip_list에 target에게 보낼 ip들을 넣어줌. 그리고, attacker node가 target node와 주기적인 COMMAND_TIMED_SYNC_T 메시지를 교환할 때마다 _addr_ip_list이 비어있지 않다면 target node에게 전달함.

https://github.com/kaistshadow/blockchain-sim/blob/608e3d35644423d64e5d303ad5a532ce21915eed/BLEEPeval/sybiltest-app/monero/MoneroNodePrimitives.cpp#L231-L237

Bitcoin 같이 별도의 ADDR message를 이용한 ADDR injection mechanism이 Monero에서도 가능한지는 조사가 좀더 필요함.

ygnkim commented 3 years ago

구현한 adapter를 적용한 EREBUS policy를 동작시켰을 때, shadow node가 제대로 연결되는 것까지 확인했음.

(근데 본 이슈와는 별개로 모네로에서 최대 outgoing connection 개수만큼 연결이 맺어졌을 때에, connection이 끊어지는 로직이 있음)