david942j/one_gadget

GitHub: david942j/one_gadget

一款用于在 libc.so.6 中自动搜索单字节 RCE gadget 的 Ruby 工具,解决利用链手动查找困难的问题。

Stars: 2317 | Forks: 148

[![Downloads](https://img.shields.io/endpoint?url=https://gem-badge-h3lg.onrender.com/downloads/one_gadget)](https://rubygems.org/gems/one_gadget) [![Gem Version](https://badge.fury.io/rb/one_gadget.svg)](https://badge.fury.io/rb/one_gadget) [![Build Status](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/4418a377df000317.svg)](https://github.com/david942j/one_gadget/actions) [![Maintainability](https://qlty.sh/gh/david942j/projects/one_gadget/maintainability.svg)](https://qlty.sh/gh/david942j/projects/one_gadget) [![Code Coverage](https://qlty.sh/gh/david942j/projects/one_gadget/coverage.svg)](https://qlty.sh/gh/david942j/projects/one_gadget) [![Inline docs](https://inch-ci.org/github/david942j/one_gadget.svg?branch=master)](https://inch-ci.org/github/david942j/one_gadget) [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/github/david942j/one_gadget/) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](http://choosealicense.com/licenses/mit/) ## OneGadget 在玩 CTF PWN 挑战时,我们通常需要 one-gadget RCE(远程代码执行), 这会导致调用 `execve('/bin/sh', NULL, NULL)`。 这个 gem 提供了这样一个 gadgets 查找工具,无需每次都像个傻瓜一样使用 objdump 或 IDA-pro :wink: 要在命令行中使用此工具,请输入 `one_gadget /path/to/libc` 并享受魔法 :laughing: ## 安装 RubyGems.org 上可用! ``` $ gem install one_gadget ``` 注意:需要 Ruby 版本 >= 2.1.0,你可以使用 `ruby --version` 来检查。 ## 支持的架构 - [x] i386 - [x] amd64 (x86-64) - [x] aarch64 (ARMv8) ## 实现原理 OneGadget 使用符号执行来查找成功所需的约束条件。 介绍如何开发此工具的文章可以在 [我的博客](https://david942j.blogspot.com/2017/02/project-one-gadget-in-glibc.html) 上找到。 ## 用法 ### 命令行接口 ``` $ one_gadget # Usage: one_gadget [options] # -b, --build-id BuildID BuildID[sha1] of libc. # -f, --[no-]force-file Force search gadgets in file instead of build id first. # -l, --level OUTPUT_LEVEL The output level. # OneGadget automatically selects gadgets with higher successful probability. # Increase this level to ask OneGadget show more gadgets it found. # Default: 0 # -n, --near FUNCTIONS/FILE Order gadgets by their distance to the given functions or to the GOT functions of the given file. # -o, --output-format FORMAT Output format. FORMAT should be one of . # Default: pretty # -r, --raw Alias of -o raw. Output gadgets offset only, split with one space. # -s, --script exploit-script Run exploit script with all possible gadgets. # The script will be run as 'exploit-script $offset'. # --info BuildID Show version information given BuildID. # --base BASE_ADDRESS The base address of libc. # Default: 0 # --version Current gem version. ``` ``` $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 # 0xe3afe execve("/bin/sh", r15, r12) # constraints: # [r15] == NULL || r15 == NULL || r15 is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0xe3b01 execve("/bin/sh", r15, rdx) # constraints: # [r15] == NULL || r15 == NULL || r15 is a valid argv # [rdx] == NULL || rdx == NULL || rdx is a valid envp # # 0xe3b04 execve("/bin/sh", rsi, rdx) # constraints: # [rsi] == NULL || rsi == NULL || rsi is a valid argv # [rdx] == NULL || rdx == NULL || rdx is a valid envp ``` ![x86_64](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/8c7db8aeee000320.png) #### 给定 BuildID ``` $ one_gadget -b aad7dbe330f23ea00ca63daf793b766b51aceb5d # 0x4557a execve("/bin/sh", rsp+0x30, environ) # constraints: # [rsp+0x30] == NULL || {[rsp+0x30], [rsp+0x38], [rsp+0x40], [rsp+0x48], ...} is a valid argv # # 0xf1651 execve("/bin/sh", rsp+0x40, environ) # constraints: # [rsp+0x40] == NULL || {[rsp+0x40], [rsp+0x48], [rsp+0x50], [rsp+0x58], ...} is a valid argv # # 0xf24cb execve("/bin/sh", rsp+0x60, environ) # constraints: # [rsp+0x60] == NULL || {[rsp+0x60], [rsp+0x68], [rsp+0x70], [rsp+0x78], ...} is a valid argv ``` ![build id](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/c812ece34e000323.png) #### 靠近函数的 Gadgets ##### 为什么 考虑在利用时遇到以下场景: 1. 能够写入 GOT(全局偏移表) 2. libc 的基地址 *未知* 在这种情况下,你可以选择使用 one-gadget 的两个低字节来写入 GOT 条目中的低字节。 如果函数在 GOT 上的偏移量与 one-gadget 足够接近, 你将有至少 1/16 的成功机会。 ##### 用法 根据给定函数的距离重新排序 gadgets。 ``` $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near exit,mkdir # [OneGadget] Gadgets near exit(0x46a40): # 0xe3afe execve("/bin/sh", r15, r12) # constraints: # [r15] == NULL || r15 == NULL || r15 is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0xe3b01 execve("/bin/sh", r15, rdx) # constraints: # [r15] == NULL || r15 == NULL || r15 is a valid argv # [rdx] == NULL || rdx == NULL || rdx is a valid envp # # 0xe3b04 execve("/bin/sh", rsi, rdx) # constraints: # [rsi] == NULL || rsi == NULL || rsi is a valid argv # [rdx] == NULL || rdx == NULL || rdx is a valid envp # # [OneGadget] Gadgets near mkdir(0x10de70): # 0xe3b04 execve("/bin/sh", rsi, rdx) # constraints: # [rsi] == NULL || rsi == NULL || rsi is a valid argv # [rdx] == NULL || rdx == NULL || rdx is a valid envp # # 0xe3b01 execve("/bin/sh", r15, rdx) # constraints: # [r15] == NULL || r15 == NULL || r15 is a valid argv # [rdx] == NULL || rdx == NULL || rdx is a valid envp # # 0xe3afe execve("/bin/sh", r15, r12) # constraints: # [r15] == NULL || r15 == NULL || r15 is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # ``` ![near](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/e645a01ba2000326.png) 接受正则表达式。 ``` $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near 'write.*' --raw # [OneGadget] Gadgets near writev(0x114690): # 932612 932609 932606 # # [OneGadget] Gadgets near write(0x10e280): # 932612 932609 932606 # ``` 传递一个 ELF 文件作为参数,OneGadget 将处理所有 GOT 函数。 ``` $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near spec/data/test_near_file.elf --raw # [OneGadget] Gadgets near exit(0x46a40): # 932606 932609 932612 # # [OneGadget] Gadgets near puts(0x84420): # 932606 932609 932612 # # [OneGadget] Gadgets near printf(0x61c90): # 932606 932609 932612 # # [OneGadget] Gadgets near strlen(0x9f630): # 932606 932609 932612 # # [OneGadget] Gadgets near __cxa_finalize(0x46f10): # 932606 932609 932612 # # [OneGadget] Gadgets near __libc_start_main(0x23f90): # 932606 932609 932612 # ``` #### 显示所有 Gadgets 有时 `one_gadget` 找到的 gadgets 太多,无法一次性显示, 默认情况下会根据约束条件的难度自动过滤 gadgets。 使用选项 `--level 1` 来显示所有找到的 gadgets,而不仅仅是那些概率较高的。 ``` $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --level 1 # 0x51dfb posix_spawn(rsp+0xc, "/bin/sh", 0, rbp, rsp+0x50, environ) # constraints: # address rsp+0x60 is writable # rsp & 0xf == 0 # {"sh", "-c", rbx, NULL} is a valid argv # rbp == NULL || (u16)[rbp] == NULL # # 0x51e02 posix_spawn(rsp+0xc, "/bin/sh", 0, rbp, rsp+0x50, environ) # constraints: # address rsp+0x60 is writable # rsp & 0xf == 0 # rax == NULL || {"sh", rax, rbx, NULL} is a valid argv # rbp == NULL || (u16)[rbp] == NULL # # 0x51e09 posix_spawn(rsp+0xc, "/bin/sh", 0, rbp, rsp+0x50, environ) # constraints: # address rsp+0x60 is writable # rsp & 0xf == 0 # rcx == NULL || {rcx, rax, rbx, NULL} is a valid argv # rbp == NULL || (u16)[rbp] == NULL # # 0x51e10 posix_spawn(rsp+0xc, "/bin/sh", rdx, rbp, rsp+0x50, environ) # constraints: # address rsp+0x60 is writable # rsp & 0xf == 0 # rcx == NULL || {rcx, (u64)xmm1, rbx, NULL} is a valid argv # rdx == NULL || (s32)[rdx+0x4] <= 0 # rbp == NULL || (u16)[rbp] == NULL # # 0x51e15 posix_spawn(rsp+0xc, "/bin/sh", rdx, rbp, rsp+0x50, environ) # constraints: # address rsp+0x60 is writable # rsp & 0xf == 0 # (u64)xmm0 == NULL || {(u64)xmm0, (u64)xmm1, rbx, NULL} is a valid argv # rdx == NULL || (s32)[rdx+0x4] <= 0 # rbp == NULL || (u16)[rbp] == NULL # # 0x51e25 posix_spawn(rdi, "/bin/sh", rdx, rbp, rsp+0x50, [rax]) # constraints: # address rsp+0x60 is writable # rsp & 0xf == 0 # (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 >> 64), rbx, NULL} is a valid argv # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp # rdi == NULL || writable: rdi # rdx == NULL || (s32)[rdx+0x4] <= 0 # rbp == NULL || (u16)[rbp] == NULL # # 0x51e2a posix_spawn(rdi, "/bin/sh", rdx, rbp, r8, [rax]) # constraints: # address rsp+0x60 is writable # rsp & 0xf == 0 # [r8] == NULL || r8 is a valid argv # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp # rdi == NULL || writable: rdi # rdx == NULL || (s32)[rdx+0x4] <= 0 # rbp == NULL || (u16)[rbp] == NULL # # 0x51e2d posix_spawn(rdi, "/bin/sh", rdx, rcx, r8, [rax]) # constraints: # address rsp+0x60 is writable # rsp & 0xf == 0 # [r8] == NULL || r8 is a valid argv # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp # rdi == NULL || writable: rdi # rdx == NULL || (s32)[rdx+0x4] <= 0 # rcx == NULL || (u16)[rcx] == NULL # # 0x51e32 posix_spawn(rdi, "/bin/sh", rdx, rcx, r8, [rax]) # constraints: # address rsp+0x68 is writable # rsp & 0xf == 0 # [r8] == NULL || r8 is a valid argv # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp # rdi == NULL || writable: rdi # rdx == NULL || (s32)[rdx+0x4] <= 0 # rcx == NULL || (u16)[rcx] == NULL # # 0x84135 posix_spawn(rbx+0xe0, "/bin/sh", r12, 0, rsp+0x60, environ) # constraints: # address rsp+0x70 is writable # rsp & 0xf == 0 # {"sh", "-c", rbp, NULL} is a valid argv # rbx+0xe0 == NULL || writable: rbx+0xe0 # r12 == NULL || (s32)[r12+0x4] <= 0 # # 0x8413c posix_spawn(rbx+0xe0, "/bin/sh", r12, 0, rsp+0x60, environ) # constraints: # address rsp+0x70 is writable # rsp & 0xf == 0 # rax == NULL || {"sh", rax, rbp, NULL} is a valid argv # rbx+0xe0 == NULL || writable: rbx+0xe0 # r12 == NULL || (s32)[r12+0x4] <= 0 # # 0x84143 posix_spawn(rbx+0xe0, "/bin/sh", r12, 0, rsp+0x60, environ) # constraints: # address rsp+0x70 is writable # rsp & 0xf == 0 # rcx == NULL || {rcx, rax, rbp, NULL} is a valid argv # rbx+0xe0 == NULL || writable: rbx+0xe0 # r12 == NULL || (s32)[r12+0x4] <= 0 # # 0x84146 posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, environ) # constraints: # address rsp+0x70 is writable # rsp & 0xf == 0 # rcx == NULL || {rcx, rax, rbp, NULL} is a valid argv # rbx+0xe0 == NULL || writable: rbx+0xe0 # rdx == NULL || (s32)[rdx+0x4] <= 0 # # 0x8414b posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, environ) # constraints: # address rsp+0x78 is writable # rsp & 0xf == 0 # rcx == NULL || {rcx, rax, [rsp+0x70], NULL} is a valid argv # rbx+0xe0 == NULL || writable: rbx+0xe0 # rdx == NULL || (s32)[rdx+0x4] <= 0 # # 0x84150 posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, environ) # constraints: # address rsp+0x78 is writable # rsp & 0xf == 0 # rcx == NULL || {rcx, (u64)xmm1, [rsp+0x70], NULL} is a valid argv # rbx+0xe0 == NULL || writable: rbx+0xe0 # rdx == NULL || (s32)[rdx+0x4] <= 0 # # 0x8415c posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, [rax]) # constraints: # address rsp+0x78 is writable # rsp & 0xf == 0 # (u64)xmm0 == NULL || {(u64)xmm0, (u64)xmm1, [rsp+0x70], NULL} is a valid argv # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp # rbx+0xe0 == NULL || writable: rbx+0xe0 # rdx == NULL || (s32)[rdx+0x4] <= 0 # # 0x84162 posix_spawn(rbx+0xe0, "/bin/sh", rdx, rcx, rsp+0x60, [rax]) # constraints: # address rsp+0x78 is writable # rsp & 0xf == 0 # (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 >> 64), [rsp+0x70], NULL} is a valid argv # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp # rbx+0xe0 == NULL || writable: rbx+0xe0 # rdx == NULL || (s32)[rdx+0x4] <= 0 # rcx == NULL || (u16)[rcx] == NULL # # 0x84169 posix_spawn(rdi, "/bin/sh", rdx, rcx, rsp+0x60, [rax]) # constraints: # address rsp+0x78 is writable # rsp & 0xf == 0 # (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 >> 64), [rsp+0x70], NULL} is a valid argv # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp # rdi == NULL || writable: rdi # rdx == NULL || (s32)[rdx+0x4] <= 0 # rcx == NULL || (u16)[rcx] == NULL # # 0x84170 posix_spawn(rdi, "/bin/sh", rdx, rcx, r8, [rax]) # constraints: # address rsp+0x78 is writable # rsp & 0xf == 0 # [r8] == NULL || r8 is a valid argv # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp # rdi == NULL || writable: rdi # rdx == NULL || (s32)[rdx+0x4] <= 0 # rcx == NULL || (u16)[rcx] == NULL # # 0xe3afe execve("/bin/sh", r15, r12) # constraints: # [r15] == NULL || r15 == NULL || r15 is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0xe3b01 execve("/bin/sh", r15, rdx) # constraints: # [r15] == NULL || r15 == NULL || r15 is a valid argv # [rdx] == NULL || rdx == NULL || rdx is a valid envp # # 0xe3b04 execve("/bin/sh", rsi, rdx) # constraints: # [rsi] == NULL || rsi == NULL || rsi is a valid argv # [rdx] == NULL || rdx == NULL || rdx is a valid envp # # 0xe3cf3 execve("/bin/sh", r10, r12) # constraints: # address rbp-0x78 is writable # [r10] == NULL || r10 == NULL || r10 is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0xe3cf6 execve("/bin/sh", r10, rdx) # constraints: # address rbp-0x78 is writable # [r10] == NULL || r10 == NULL || r10 is a valid argv # [rdx] == NULL || rdx == NULL || rdx is a valid envp # # 0xe3d62 execve("/bin/sh", rbp-0x50, r12) # constraints: # address rbp-0x48 is writable # r13 == NULL || {"/bin/sh", r13, NULL} is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0xe3d69 execve("/bin/sh", rbp-0x50, r12) # constraints: # address rbp-0x48 is writable # rax == NULL || {rax, r13, NULL} is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0xe3d70 execve("/bin/sh", rbp-0x50, r12) # constraints: # address rbp-0x50 is writable # rax == NULL || {rax, [rbp-0x48], NULL} is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0xe3da7 execve("/bin/sh", rbp-0x50, r12) # constraints: # address rbp-0x50 is writable # [rbp-0x68] == NULL || {"/bin/sh", [rbp-0x68], NULL} is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0xe3db1 execve("/bin/sh", rbp-0x50, r12) # constraints: # address rbp-0x50 is writable # rax == NULL || {rax, [rbp-0x68], NULL} is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0xe3db5 execve("/bin/sh", r10, r12) # constraints: # addresses r10+0x10, rbp-0x50 are writable # [r10] == NULL || r10 == NULL || r10 is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0xe3dbd execve("/bin/sh", r10, r12) # constraints: # addresses r10+0x10, rbp-0x48 are writable # [r10] == NULL || r10 == NULL || r10 is a valid argv # [r12] == NULL || r12 == NULL || r12 is a valid envp # # 0x1077ca posix_spawn(rsp+0x64, "/bin/sh", [rsp+0x38], 0, rsp+0x70, [rsp+0xf0]) # constraints: # [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv # [[rsp+0xf0]] == NULL || [rsp+0xf0] == NULL || [rsp+0xf0] is a valid envp # [rsp+0x38] == NULL || (s32)[[rsp+0x38]+0x4] <= 0 # # 0x1077d2 posix_spawn(rsp+0x64, "/bin/sh", [rsp+0x38], 0, rsp+0x70, r9) # constraints: # [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv # [r9] == NULL || r9 == NULL || r9 is a valid envp # [rsp+0x38] == NULL || (s32)[[rsp+0x38]+0x4] <= 0 # # 0x1077d7 posix_spawn(rsp+0x64, "/bin/sh", rdx, 0, rsp+0x70, r9) # constraints: # [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv # [r9] == NULL || r9 == NULL || r9 is a valid envp # rdx == NULL || (s32)[rdx+0x4] <= 0 # # 0x1077e1 posix_spawn(rdi, "/bin/sh", rdx, 0, r8, r9) # constraints: # [r8] == NULL || r8 is a valid argv # [r9] == NULL || r9 == NULL || r9 is a valid envp # rdi == NULL || writable: rdi # rdx == NULL || (s32)[rdx+0x4] <= 0 ``` #### 其他架构 ##### i386 ``` $ one_gadget /lib32/libc.so.6 # 0xc890b execve("/bin/sh", [ebp-0x2c], esi) # constraints: # address ebp-0x20 is writable # ebx is the GOT address of libc # [[ebp-0x2c]] == NULL || [ebp-0x2c] == NULL || [ebp-0x2c] is a valid argv # [esi] == NULL || esi == NULL || esi is a valid envp # # 0x1421b3 execl("/bin/sh", eax) # constraints: # ebp is the GOT address of libc # eax == NULL # # 0x1421b4 execl("/bin/sh", [esp]) # constraints: # ebp is the GOT address of libc # [esp] == NULL ``` ![i386](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/ae5cbea4cb000329.png) ##### AArch64 ``` $ one_gadget spec/data/aarch64-libc-2.27.so # 0x3f160 execve("/bin/sh", sp+0x70, environ) # constraints: # address x20+0x338 is writable # x3 == NULL # # 0x3f184 execve("/bin/sh", sp+0x70, environ) # constraints: # addresses x19+0x4, x20+0x338 are writable # [sp+0x70] == NULL # # 0x3f1a8 execve("/bin/sh", x21, environ) # constraints: # addresses x19+0x4, x20+0x338 are writable # [x21] == NULL || x21 == NULL # # 0x63e90 execl("/bin/sh", x1) # constraints: # x1 == NULL ``` ![aarch64](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/2e0ca3ea9f000334.png) #### 与脚本结合 将你的利用脚本作为 `one_gadget` 的参数传递,它可以 逐个尝试所有 gadgets,这样你就不需要手动尝试每一个可能的 gadgets。 ![--script](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/d5e59bc956000336.png) ### 在 Ruby 脚本中 ``` require 'one_gadget' OneGadget.gadgets(file: '/lib/x86_64-linux-gnu/libc.so.6') #=> [932606, 932609, 932612] # or in shorter way one_gadget('/lib/x86_64-linux-gnu/libc.so.6', level: 1) #=> [335355, 335362, 335369, 335376, 335381, 335397, 335402, 335405, 335410, 540981, 540988, 540995, 540998, 541003, 541008, 541020, 541026, 541033, 541040, 932606, 932609, 932612, 933107, 933110, 933218, 933225, 933232, 933287, 933297, 933301, 933309, 1079242, 1079250, 1079255, 1079265] # from build id one_gadget('b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0') #=> [324286, 324293, 324386, 1090444] ``` ### Python 爱好者 ``` import subprocess def one_gadget(filename): return [int(i) for i in subprocess.check_output(['one_gadget', '--raw', filename]).decode().split(' ')] one_gadget('/lib/x86_64-linux-gnu/libc.so.6') #=> [932606, 932609, 932612] ``` ## 让 OneGadget 更好 欢迎任何建议或功能请求!随时提交拉取请求。 如果你发现某个 libc 导致 OneGadget 无法找到 gadgets,请告诉我。 另外,如果你喜欢这项工作,我很乐意被 [加星](https://github.com/david942j/one_gadget/stargazers) :grimacing:
标签:ELF, gadget查找, Hakrawler, libc.so.6, one_gadget, pwn, RCE, RubyGem, 二进制分析, 云安全监控, 云安全运维, 云资产清单, 动态链接库, 开源安全工具, 符号执行, 编程工具, 远程代码执行, 逆向工程, 逆向工程平台, 静态分析