【逆向学习】分析MIPS下蠕虫木马学习笔记

前言

在扫网站的时候不小心下了两个文件下来,火绒反手杀了,正好我是做木马分析的,这能放过?直接开逆。

前置知识:

  • python
  • upx壳
  • ida por
  • 远程gdb调试
  • qemu 模拟器

要的知识点蛮多,那开始罢,因为是用户现场的,无法提供文件ψ(._. )>

一、信息收集

img

下了两个,实际上是同一个,无脑沙箱

img

沙箱报毒,是elf文件,但是行为分析失败
https://s.threatbook.com/report/file/f6c97b1e2ed02578ca1066c8235ba4f991e645f89012406c639dbccc6582eec8

看起来直接运行失败了,不是常规的反沙箱
image

看看加壳?
image

一眼upx,哎呀这不upx吗,几天没见了,这么拉了,丢kali脱壳

image

脱不了一点?是不是假的壳,直接101打开

image

发现的确是upx(ノへ ̄、),那只能跑起来看看了,pwn手照例看看文件和保护(这里方便打,改名成了elf)
image

ん?MIPS,路由器还在追我(最近分析路由器固件快疯了),那就qemu伺候

二、模拟器跑起来!

脱壳手法之一就是:跑起来,在真正进入文件逻辑前dump内存。但是由于是MIPS架构,函数跳转十分不好看,只能手动调试跟进

sudo qemu-mipsel -g 1234 ./elf

2.1 ida 能救吗?

答案是:不行
image
image

你的断点只能打到这里,然后手动跟踪,跟踪的时候还没有反编译看(直接看裸露的数据),汇编都没有,过于抽象,笔者在尝试了几次后放弃了,老老实实用pwngdb罢

image

这里是进入主循环了(上帝视角),但是里根本不知道下一步有没有跳转,真的难受。

2.2 pwngdb能救吗?

答案还是:不行

我的确尝试点到了upx加密后的跳转逻辑,当我尝试dump下来内存后发现dump下来的并不完整(也许是我的方法不对)但是试了很久都是一半损坏的

2.3 那为什么呢?

后来我发现主循环有问题,看这个函数:

void __fastcall sub_420F9C(int a1, int a2, int a3)
{
  int *v3; // $s4
  int v4; // $gp
  _DWORD *v5; // $fp
  int v6; // $s3
  int v7; // $s5
  int v8; // $a2
  int v9; // $s2
  _DWORD *v10; // $a0
  _DWORD *v11; // $s4
  int v12; // $gp
  unsigned int v13; // $gp
  int v14; // [sp+0h] [-20h] BYREF
  int v15; // [sp+8h] [-18h]
  char *v16; // [sp+Ch] [-14h]
  int v17; // [sp+10h] [-10h]
  int n4005; // [sp+14h] [-Ch]
  int v19; // [sp+18h] [-8h]
  int v20; // [sp+1Ch] [-4h]

  v17 = v4;
  __asm { syscall }
  n4005 = 4005;
  v6 = *v3;
  v7 = (int)v5 - *(v5 - 3) - 12;
  v20 = (int)v3 + *v3 - v7;
  v19 = sub_421088(0, v20, a3, 2050, v4, 4005);
  v9 = sub_421088(v19, v20 - v6 + v3[1], v8, 18, v17, n4005) - v7;
  v10 = v3 + 3;
  v11 = (int *)((char *)v3 + v9);
  v15 = ((unsigned int)v5 + v9) & v12;
  v16 = (char *)v11 + v6 - v15;
  v14 = v6;
  ((void (__fastcall *)(_DWORD *, _DWORD, _DWORD *, int *))v5)(v10, v11[1], v11, &v14);
  *v11 |= (unsigned __int16)(v13 >> 9);
  __asm { syscall }
  __asm { jr      $ra }
}

怀疑是动态加密,运行时解密,用完后马上加载回去,ida里面看到内存相同位置被反复覆写,我就怀疑真dump
下来(这里省略亿点斗智斗勇的过程)

三、不能沙箱。也没办法静态分析,还有救吗?

有的,分析木马直接抓流量也是可行的方法,要是我们可以抓到木马的行为,就可以反向找出来了

3.1 行为记录

发现了一个命令可以记录行为:

sudo qemu-mipsel -strace ./elf

开了一个socker
image
去读入了一堆东西
image
然后报错退出
image

可以看出在监听14737端口,再次运行看看?

3.2 再次运行

image
仍然绑定14737端口

开个nc看看能不能听到点什么
image

那很坏了,作者是木马退出后启动的nc,换句话说:还没启动木马

sudo fuser -k 14737/udp

image

直接杀掉,目前架构不同,暂时不用担心逃逸,下次一定要小心

3.3 叽里咕噜说啥呢?

再次监听nc
image
启动
image

发现被占用退出了,杀掉nc,在主机上监听
image

没听到啥,初步分析是被动木马

3.4 注意到!

由之前分析路由器的经历,我猜测是否要搭建一个网桥,试试看呗

sudo brctl addbr br0
sudo ifconfig br0 192.168.0.1
chmod +x ./bin/httpd
./bin/httpd

然后改用strace监视网络活动

sudo strace -e trace=network -f -o net_only.log qemu-mipsel ./elf

image
等一下,让它运行完
image

嗯,直接炸了(pwn手看到这个快心脏骤停了。。。后遗症了),去看看日志?

日志很大,也是截取一部分
开头
image
image
中间
image
最后
image

看得出来,首先先寻找常见的网络工具,然后尝试开一堆线程外连
image

那么,这个端口干什么的?

3.5 黑盒测试

既然你不外连,那我主动发包

# 强化后的 fuzzer:支持收包(回显)分析
import socket
import random
import time

TARGET_IP = "127.0.0.1"
TARGET_PORT = 14737
TIMEOUT = 0.5

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(TIMEOUT)

payloads = [
    b"ping", b"\x00"*4, b"A"*8, b"magic", b"CMD:ls", b"GET / HTTP/1.1\r\n\r\n", b"\xde\xad\xbe\xef"
]

print("[+] Fuzzing UDP target...")

for i in range(1000):
    if i < len(payloads):
        data = payloads[i]
    else:
        data = random.choice(payloads) + bytes(random.getrandbits(8) for _ in range(random.randint(2, 12)))

    try:
        sock.sendto(data, (TARGET_IP, TARGET_PORT))
        print(f"[{i:03d}] Sent: {data.hex()}")

        response, addr = sock.recvfrom(1024)
        print(f"[!!!] Got response from {addr}: {response!r}")

    except socket.timeout:
        pass
    except Exception as e:
        print(f"[ERR] {e}")

    time.sleep(0.05)

断掉网络,然后再次发包
image
image

有一点点变化,但是不多,加上网络呢?

image

有变化,只要python包不断,就能一直跑下去,也就是说的确接受回复和命令

3.6 总结

把日志喂给ai,总结出来:

这是一个具备主动通信能力的木马样本
它执行了典型的网络活动,包括 UDP 数据包广播、TCP 连接尝试以及与多个外部 IP 的通信。

  1. 监听本地端口:
    进程通过bind在本地 127.0.0.1:14737上监听了UDP通信,说明它支持本地控制(如通过反向连接的代理接入控制端)。

  2. 主动探测外部目标(典型蠕虫行为):
    多个sendto()向世界各地的 IP 地址(UDP)发送数据包,目标端口包括:

5060, 30245, 8081, 6880, 28012, 28000, 25146, 63415, 6901, 55969, 54675, 45763 等。

这是 BitTorrent DHT 协议格式的数据,例如:

d1:ad2:id20:...4:info_hash20:...4:porti6881e1:q9:announce
  1. TCP 连接尝试(C2 或感染尝试):
    多次尝试连接外部 IP 地址的 80/8080 端口,但多数失败(ECONNREFUSED)。
    典型目标如:
195.174.131.191:8080
59.124.84.190:80
166.197.71.92:80
  1. 接收响应:
    多次调用 recvfrom() 接收远程主机响应,说明通信成功,木马处于活跃通信阶段。

涉及的可疑外部 IP 样例:

1. `195.174.131.191:8080`
2. `59.124.84.190:80`
3. `3.90.90.64:6880`
4. `178.162.174.40:28012`
5. `185.209.82.75:45288`

作者去威胁情报查了,都是一片红过去

  1. 初步判断:
    使用BitTorrent协议伪装数据通信(如 d1:ad2:id20:... 是典型 DHT 报文);
    可用于C2 通信、扫描横向传播或数据渗漏通道;
    具备动态行为依赖网络连通性,在无外网时会静默或早退。

四、总结

没想到之前学的东西一个不落地用上了,知识点+1。chatgpt还是太强了,知道方向、结果,基本上可以用来快速找方法,但是不能无脑,也坑我好多次,尤其是说出一个不存在的命令...

posted @ 2025-07-03 12:27  归海言诺  阅读(69)  评论(0)    收藏  举报