From 2f8fc8b9a1b6617ed03072d8a0f0028d823d6d49 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Mon, 26 Sep 2016 22:31:16 +0200 Subject: Add uftp-multicast + sinkdo/sinkcat + bug hunting. Problem leaved : uftpd listens on IPv4 only. Net conf only done in IPv6. --- make-boot-image.sh | 229 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 188 insertions(+), 41 deletions(-) diff --git a/make-boot-image.sh b/make-boot-image.sh index c6728cf..25301c2 100755 --- a/make-boot-image.sh +++ b/make-boot-image.sh @@ -1,18 +1,21 @@ #!/bin/bash -xe +PS4='+ ($LINENO) ' + # Config # ########## WORKDIR=./work DLDIR=./downloads OUTDIR=./out -OUTUSB=/dev/sdb1 +#OUTUSB=/dev/sdb1 KERNEL_TOOLS=y RUN_QEMU=y ROOTCMD=sudo -WGET="wget --no-check-certificate" +WGET="wget" #"wget --no-check-certificate" KERNEL_TARBALL_URL=https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.6.tar.xz KCONFIGLIB_MAIN_URL=https://raw.githubusercontent.com/ulfalizer/Kconfiglib/7eace27993ad3aa1d6911866d9c60a11f32d36d9/kconfiglib.py KCONFIGLIB_PATCH_URL=https://raw.githubusercontent.com/ulfalizer/Kconfiglib/7eace27993ad3aa1d6911866d9c60a11f32d36d9/makefile.patch NIC_FIRMWARE_URL=http://fr.archive.ubuntu.com/ubuntu/pool/main/l/linux-firmware/nic-firmware_1.157_all.udeb +UFTP_TARBALL_URL=http://downloads.sourceforge.net/project/uftp-multicast/source-tar/uftp-4.9.2.tar.gz BUSYBOX_BIN_URL=https://busybox.net/downloads/binaries/busybox-x86_64 PCI_IDS_URL=https://pci-ids.ucw.cz/v2.2/pci.ids USB_IDS_URL=https://usb-ids.gowdy.us/usb.ids @@ -69,7 +72,7 @@ fi if [ ! -e "$WORKDIR/apt-done" ] then $ROOTCMD apt-get update # Dependencies of this script (assuming default debian install or live) - $ROOTCMD apt-get install wget libncurses5-dev + $ROOTCMD apt-get install wget libncurses5-dev coreutils # Dependencies for kernel building $ROOTCMD apt-get build-dep linux-source # Dependancies for kernel tools @@ -183,13 +186,30 @@ chmod +x "$WORKDIR/kernel/scripts/Kconfiglib/customize.py" fi ) -if [ "x$KERNEL_TOOLS" == "xy" ] +p="$WORKDIR/kernel/tools/perf/perf" +if [ "x$KERNEL_TOOLS" == "xy" -a ! -f "$p" ] then ( cd "$WORKDIR/kernel" make tools/perf ) fi +# Build additionnal tools from source # +####################################### +uftp_tarball=$DLDIR/$(basename "$UFTP_TARBALL_URL") +[ -f "$uftp_tarball" ] || $WGET -O "$uftp_tarball" "$UFTP_TARBALL_URL" +if [ ! -d "$WORKDIR/uftp" ] +then mkdir "$WORKDIR/uftp" + tar xf "$uftp_tarball" --strip-components=1 -C "$WORKDIR/uftp" +fi + +if [ ! -f "$WORKDIR/uftp/uftpd" ] +then ( + cd "$WORKDIR/uftp/" + make NO_ENCRYPTION=1 + ) +fi + # Initial Ram Disk building (embed in kernel) # ############################################### if [ ! -d "$WORKDIR/initrd" ] @@ -207,28 +227,24 @@ then [ -f "$DLDIR/busybox" ] || $WGET -O "$DLDIR/busybox" "$BUSYBOX_BIN_URL" fi if [ ! -f "$WORKDIR/initrd/etc/keys.bmap" ] -then $ROOTCMD dumpkeys | $ROOTCMD loadkeys -b > "$WORKDIR/initrd/etc/keys.bmap" +then # When using sudo with password auth, ask and cache pass first + $ROOTCMD true + # The following compound command will suck at asking pass + $ROOTCMD dumpkeys | $ROOTCMD loadkeys -b > "$WORKDIR/initrd/etc/keys.bmap" fi -( - set +x - PATH="$WORKDIR/kernel/tools/perf:/usr/sbin:/usr/bin:/sbin:/bin" - # Diagnostic tools - mkchroot "$WORKDIR/initrd" dmidecode iftop iostat lshw lspci lsusb mpstat tcpdump - # Manpage display - mkchroot "$WORKDIR/initrd" strace groff nroff troff grotty gtbl - # Cloning tools - mkchroot "$WORKDIR/initrd" /usr/sbin/partclone* efibootmgr gdisk udp-receiver - # Some dyn-loaded libraries (ldd will not display them) - mkchroot "$WORKDIR/initrd" /lib/x86_64-linux-gnu/libusb-1.0.so.0 -) - -if [ "x$KERNEL_TOOLS" == "xy" ] +if [ ! -f "$WORKDIR/initrd/partclone-restore" ] then ( - p="$WORKDIR/kernel/tools/perf/perf" - cp -a "$p" "$WORKDIR/initrd/sbin/" set +x - mkchroot "$WORKDIR/initrd" $(ldd "$p" | egrep -o '/.* ') + PATH="/usr/sbin:/usr/bin:/sbin:/bin" + # Diagnostic tools + mkchroot "$WORKDIR/initrd" dmidecode iftop iostat lshw lspci lsusb mpstat tcpdump + # Manpage display + mkchroot "$WORKDIR/initrd" strace groff nroff troff grotty gtbl + # Cloning tools + mkchroot "$WORKDIR/initrd" /usr/sbin/partclone* efibootmgr gdisk udp-receiver + # Some dyn-loaded libraries (ldd will not display them) + mkchroot "$WORKDIR/initrd" /lib/x86_64-linux-gnu/libusb-1.0.so.0 ) fi @@ -241,6 +257,27 @@ then mkdir -p "$WORKDIR"/initrd/usr/man/man{1,8} "$WORKDIR"/initrd/usr/share/gro cp /etc/groff/man.local "$WORKDIR/initrd/usr/share/groff/1.22.2/" fi +p="$WORKDIR/initrd/bin/uftp" +if [ ! -f "$p" ] +then ( + cd "$WORKDIR/uftp/" + make DESTDIR="../initrd" install + ) + ( + set +x + mkchroot "$WORKDIR/initrd" $(ldd "$p" | egrep -o '/.* ') + ) +fi + +p="$WORKDIR/kernel/tools/perf/perf" +if [ "x$KERNEL_TOOLS" == "xy" -a ! -f "$p" ] +then ( + cp -a "$p" "$WORKDIR/initrd/sbin/" + set +x + mkchroot "$WORKDIR/initrd" $(ldd "$p" | egrep -o '/.* ') + ) +fi + if [ ! -d "$WORKDIR/initrd/var/lib" ] then [ -f "$DLDIR/pci.ids" ] || $WGET -O "$DLDIR/pci.ids" "$PCI_IDS_URL" [ -f "$DLDIR/usb.ids" ] || $WGET -O "$DLDIR/usb.ids" "$USB_IDS_URL" @@ -255,7 +292,7 @@ then [ -f "$DLDIR/nic-firmware.deb" ] || $WGET -O "$DLDIR/nic-firmware.deb" "$NI find "$WORKDIR/initrd/lib/firmware/" \( -name 'ipw*' -o -name 'brcmfmac*' -o -name '*wifi*' \) -print0 | xargs -r0 rm -v fi -cat > "$WORKDIR/initrd/funcs" <<"EOT" +cat > "$WORKDIR/initrd/funcs" <<"EOF" rescue_shell() { echo "Something went wrong. Dropping to a shell." setsid cttyhack sh @@ -268,8 +305,8 @@ tty_prog() { tty=/dev/tty$1; shift while true do - echo "(re)spawning $@ on $tty" >$tty - setsid sh -c "exec $@ <$tty >$tty 2>&1" + echo "(re)spawning $* on $tty" >$tty + setsid sh -c "exec $* <$tty >$tty 2>&1" sleep 2 done } @@ -280,6 +317,7 @@ network_up() { echo ip link set dev $iface up ip link set dev $iface up done + sleep 8 # PHY link det. + IPv6 DAD & Autoconf } machine_info() { @@ -294,9 +332,17 @@ machine_info() { ip -o l | sed -ne 's/[0-9]*: \([^:]*\):[^\\]*\\\s*link\/ether\s/network-mac-\1: /p' lsusb 2>/dev/null | grep -vE hub$ | cut -d: -f2- | sed 's/^ ID/usb-device:/' } -EOT -cat > "$WORKDIR/initrd/init" <<"EOT" +network_show() { + ip -o addr show | sed -ne 's/[0-9]*:\s*\(\S*\)\s*inet6*\s\(\S*\)\s.*$/\1: \2/p' +} +start_uftpd() { + uftpd -q -B 2097152 -x2 -F /run/uftpd.csv -L /run/uftpd.log -T /tmp -D /run/uftpd # -M ff02::1:2:3 -P ff02::4:5:6 Marche pas ??? + [ $? -eq 0 ] && netstat -nlu | grep -q ':1044 ' && echo -e '\033[42m' ----- UFTPD ready ----- '\033[40m' +} +EOF + +cat > "$WORKDIR/initrd/init" <<"EOF" #!/bin/busybox sh echo "Initrd started" # Load helper functions @@ -310,32 +356,133 @@ set -v # Mount pseudo-filesystems mount -t proc none /proc || rescue_shell mount -t sysfs none /sys || rescue_shell -mount -t devtmpfs none /dev || rescue_shell +mount -t devtmpfs -o size=1m none /dev || rescue_shell + +# Allow using most of the RAM for rootfs +mount -o remount -o size=80% / # Load keyboard map loadkmap < /etc/keys.bmap || rescue_shell +# Starting sinkdo trojan on tty2 (feed data to uploaded scripts via uftp) +mkdir /run/uftpd && tty_prog 2 sinkdo /run/uftpd /run/sink & + # Start some debug shells (background) -for i in 2 3 4 5 6; do tty_prog $i sh & done +for i in 3 4 5 6; do tty_prog $i sh & done -# Activate networking interfaces network_up -sleep 8 # PHY link detection + IPv6 Duplicate Address Detection & Autoconf - -# Dump EFIvars if available efibootmgr -v - -# Machine basic informations machine_info - -# You could press Alt+F2 to have a shell. Remote control on telnet port (TCP 23) +network_show +start_uftpd +# Remote control on telnet port (23). You could press Alt+F3 to have a shell. nc -ll -p 23 -e /bin/sh -i +EOF +chmod +x "$WORKDIR/initrd/init" -# Network IP adresses -ip -o addr show | sed -ne 's/[0-9]*:\s*\(\S*\)\s*inet6*\s\(\S*\)\s.*$/\1: \2/p' +cat > "$WORKDIR/initrd/bin/sinkcat" <<"EOF" +#!/bin/busybox sh +if [ $# -ne 1 ] +then cat < + Concatenate then delete files as soon they appear in sink-dir to stdout. + If multiple files are found in sink, the first in alphabetical order is choosen. + must not exists, this program must create it (avoiding mistakes). + Dropping an empty file in dir-sink will clean exit this program. EOT -chmod +x "$WORKDIR/initrd/init" + exit 1 +fi + +SINKDIR=$1 +mkdir "$SINKDIR" && cd "$SINKDIR" +if [ $? -ne 0 ] +then echo "Cannot mkdir/chdir to '$SINKDIR'" >&2 + exit 2 +fi + +while true +do + f=$(ls | head -n1) + if [ -n "$f" ] + then if [ -f "$f" -a -r "$f" ] + then size=$(stat -c'%s' -- "$f") + # Do the actual work on the following line + cat -- "$f" && rm -v -- "$f" >&2 + # Normal exit condition + if [ $size -eq 0 ] + then cd / && rmdir -v -- "$SINKDIR" >&2 + exit 0 + fi + else echo "'$SINKDIR/$f' is not a readable file" >&2 + exit 3 + fi + fi + sleep 1 +done +EOF +chmod +x "$WORKDIR/initrd/bin/sinkcat" + +cat > "$WORKDIR/initrd/bin/sinkdo" <<"EOF" +#!/bin/busybox sh + +if [ $# -ne 2 ] +then cat < +EOT + exit 1 +fi + +LANDDIR=$1 +SINKDIR=$2 +cd "$LANDDIR" || exit 2 + +curtask="(start)" +while true +do + f=$(ls | head -n1) + if [ -z "$f" ] + then sleep 1 + continue + fi + if [ ! -f "$f" -o ! -r "$f" ] + then echo "'$LANDDIR/$f' is not a readable file" >&2 + exit 2 + fi + size=$(stat -c'%s' -- "$f") + task=${f:0:2} + if [ "$curtask" == "$task" ] + then # Next file of an already started task + mv "$f" "$SINKDIR/" + else # Switch to the next task + if [ -d "$SINKDIR" ] + then # Inform sinkcat about end-of-data + touch -- "$SINKDIR/zz" + wait + # sinkcat always rmdir "$SINKDIR" on normal exit + if [ -d "$SINKDIR" ] + then echo "Task $task has ran into troubles" >&2 + exit 3 + fi + fi + echo "Switching from task $curtask to $task" >&2 + curtask=$task + if [ "$task" == "99" ] + then # Normal exit condition + rm -v "$f" >&2 + # reset # Usefull if ncurses on bg, anoying when destroying useful messages + echo "All task completed sucessfully" >&2 + exit 0 + else # Start a new task + chmod +x -- "$f" # XXX Checks on $f (is a script ?) + sinkcat $SINKDIR | "./$f" & + while [ ! -d "$SINKDIR" ]; do sleep 1; done + rm -v "$f" >&2 + fi + fi +done +EOF +chmod +x "$WORKDIR/initrd/bin/sinkdo" # Kernel build (with embed initramfs) # ####################################### @@ -343,7 +490,7 @@ chmod +x "$WORKDIR/initrd/init" cd "$WORKDIR/kernel" # Workaround : some kernel version forget to update embed initramfs in certain cases [ -f usr/initramfs_data.cpio.gz ] && rm usr/initramfs_data.cpio.gz - make + make -j $(($(nproc)+1)) ) # Copy / run result EFI file # -- cgit v1.2.3 From 38f5f6389a0d7c17c0f11cc7927625012ae90888 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 2 Oct 2016 13:12:23 +0200 Subject: Failed bug fix for partial write (uftp choosen as temporary mcastseed remplacement) --- mcastseed/src/Makefile.am | 4 +-- mcastseed/src/dgrambuf.c | 86 ++++++++++++++++++++++++---------------------- mcastseed/src/mcastleech.c | 4 +-- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/mcastseed/src/Makefile.am b/mcastseed/src/Makefile.am index c49cf70..2f2a735 100644 --- a/mcastseed/src/Makefile.am +++ b/mcastseed/src/Makefile.am @@ -5,9 +5,7 @@ AM_CFLAGS =\ -Wall \ -Wextra \ -pedantic \ - -Wno-format\ - -O0\ - -g + -Wno-format bin_PROGRAMS = mcastseed mcastleech random_speed_dd diff --git a/mcastseed/src/dgrambuf.c b/mcastseed/src/dgrambuf.c index b440390..5d4c302 100644 --- a/mcastseed/src/dgrambuf.c +++ b/mcastseed/src/dgrambuf.c @@ -237,7 +237,7 @@ int dgrambuf_have_data_ready_to_write(dgrambuf_t dbuf) { unsigned int next_dgram_seq; /* Last write was partial, so there is more to write */ - if ( dbuf->partial_write_remaining_bytes > 0 ) { + if ( dbuf->partial_write_remaining_bytes ) { return 1; } @@ -248,7 +248,7 @@ int dgrambuf_have_data_ready_to_write(dgrambuf_t dbuf) { /* Nothing to write if next dgram is not in buffer at all */ next_dgram_seq = ((struct indexed_uint *) gl_list_get_at(dbuf->dgram_used_slots, 0))->value; - fprintf(stderr, "DEBUG : dgram_seq_base==%u next_dgram_seq == %u\n", dbuf->dgram_seq_base, next_dgram_seq); + /*fprintf(stderr, "DEBUG : dgram_seq_base==%u next_dgram_seq == %u\n", dbuf->dgram_seq_base, next_dgram_seq);*/ if ( next_dgram_seq != dbuf->dgram_seq_base ) { return 0; } @@ -262,9 +262,9 @@ int dgrambuf_have_received_everything(dgrambuf_t dbuf) { } ssize_t dgrambuf_write(dgrambuf_t dbuf, int fd, int *info) { - size_t dgram_index, i, vlen, used_count; + size_t dgram_index, i, vlen, total, len, remain, used_count; unsigned int curr_seq, prev_seq, dgram_len; - ssize_t nwrite, total, remain, len; + ssize_t nwrite; struct iovec *iov; struct indexed_uint *active_slot; bool pos; @@ -272,7 +272,7 @@ ssize_t dgrambuf_write(dgrambuf_t dbuf, int fd, int *info) { /* FIXME Info ptr is mandatory */ *info = 0; - if ( dbuf->partial_write_remaining_bytes > 0 ) { + if ( dbuf->partial_write_remaining_bytes ) { /* Previous writev() was partial, continue it */ iov = dbuf->partial_write_iov; vlen = dbuf->partial_write_remaining_iovcnt; @@ -364,49 +364,53 @@ ssize_t dgrambuf_write(dgrambuf_t dbuf, int fd, int *info) { return -1; } + dbuf->partial_write_remaining_bytes = total - nwrite; if ( nwrite > 0 ) { dbuf->stats.write_byte += nwrite; *info |= DGRAMBUF_WRITE_SUCCESS; - } - /* Check if the write was partially done */ - dbuf->partial_write_remaining_bytes = total - nwrite; - if ( dbuf->partial_write_remaining_bytes > 0 ) { - *info |= DGRAMBUF_WRITE_PARTIAL; - dbuf->stats.write_partial++; - /* Find the partially written iov and update it */ - remain = nwrite; - for (i=0; iiov_write[i].iov_len; - if ( remain < len ) { - dbuf->partial_write_remaining_iovcnt = vlen - i; - dbuf->partial_write_iov = dbuf->iov_write + i; - - dbuf->iov_write[i].iov_base = - (uint8_t *) dbuf->iov_write[i].iov_base + remain; - dbuf->iov_write[i].iov_len -= remain; - break; + if ( dbuf->partial_write_remaining_bytes ) { + /* If the write was partially done */ + *info |= DGRAMBUF_WRITE_PARTIAL; + dbuf->stats.write_partial++; + /* Find the partially written iov and update it */ + remain = nwrite; + for (i=0; iiov_write[i].iov_len; + if ( remain < len ) { + dbuf->partial_write_remaining_iovcnt = vlen - i; + if ( dbuf->partial_write_iov ) { + dbuf->partial_write_iov += i; + } else { + dbuf->partial_write_iov = dbuf->iov_write + i; + } + + dbuf->iov_write[i].iov_base = + (uint8_t *) dbuf->iov_write[i].iov_base + remain; + dbuf->iov_write[i].iov_len -= remain; + break; + } + remain -= len; + } + if ( i == vlen ) { + fprintf(stderr, "Fatal : failed to find partial iov after partial write\n"); + return -3; } - remain -= len; - } - if ( i == vlen ) { - fprintf(stderr, "Fatal : failed to find partial iov after partial write\n"); - return -3; - } - } else { - /* Full write has happened */ - for (i=0; idgram_write_active_slots_count; i++) { - active_slot = (struct indexed_uint *) dbuf->dgram_write_active_slots[i]; - active_slot->value = 0; - pos = gl_sortedlist_nx_add(dbuf->dgram_empty_slots, _compare_indexed_uint, active_slot); - if ( !pos ) /*TODO: better oom handling */ - return -4; + } else { + /* Full write has happened */ + for (i=0; idgram_write_active_slots_count; i++) { + active_slot = (struct indexed_uint *) dbuf->dgram_write_active_slots[i]; + active_slot->value = 0; + pos = gl_sortedlist_nx_add(dbuf->dgram_empty_slots, _compare_indexed_uint, active_slot); + if ( !pos ) /*TODO: better oom handling ? */ + return -4; + } + dbuf->dgram_write_active_slots_count = 0; + /* Wipe outdated partial_* values */ + dbuf->partial_write_iov = NULL; + dbuf->partial_write_remaining_iovcnt = 0; } - dbuf->dgram_write_active_slots_count = 0; - /* Wipe outdated partial_* values for clarity in debug mode (only _bytes is use on branching) */ - dbuf->partial_write_iov = NULL; - dbuf->partial_write_remaining_iovcnt = 0; } return nwrite; diff --git a/mcastseed/src/mcastleech.c b/mcastseed/src/mcastleech.c index 76e1e79..3345665 100644 --- a/mcastseed/src/mcastleech.c +++ b/mcastseed/src/mcastleech.c @@ -218,10 +218,10 @@ int receive_data() { return nwrite; } - fprintf(stderr, "receive_data(): nread == %zi, nwrite == %zi\n", nread, nwrite); + /*fprintf(stderr, "receive_data(): nread == %zi, nwrite == %zi\n", nread, nwrite);*/ /* XXX Crapy dead state detection */ - if ( nread == 0 && nwrite == 0 ) { + if ( nread == 0 /* TEST && nwrite == 0 */ ) { if ( noop_calls_count > 10 ) { return 0; } -- cgit v1.2.3 From 47ed8eb365a5aa12592e0626da33d36b35638963 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 2 Oct 2016 13:13:32 +0200 Subject: make-boot-image.sh : Minor cosmetics --- make-boot-image.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/make-boot-image.sh b/make-boot-image.sh index 25301c2..ccba121 100755 --- a/make-boot-image.sh +++ b/make-boot-image.sh @@ -44,7 +44,7 @@ function mkchroot d=$(echo "$p" | grep -o '.*/') && mkdir -p "$dest/$d" && # Copy file - echo ${PS4}cp --dereference --preserve=mode "$p" "$dest/$p" && + echo + cp --dereference --preserve=mode "$p" "$dest/$p" && cp --dereference --preserve=mode "$p" "$dest/$p" && # Recursively copy shared libraries' shared libraries. mkchroot "$dest" $(ldd "$p" | egrep -o '/.* ') || return $? @@ -229,7 +229,7 @@ fi if [ ! -f "$WORKDIR/initrd/etc/keys.bmap" ] then # When using sudo with password auth, ask and cache pass first $ROOTCMD true - # The following compound command will suck at asking pass + # The following compound command will suck at asking pass $ROOTCMD dumpkeys | $ROOTCMD loadkeys -b > "$WORKDIR/initrd/etc/keys.bmap" fi -- cgit v1.2.3