Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
freem
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Openai/6911cc4b-5d54-800b-88ae-dc7ac6ff2d3d
(section)
Add languages
Page
Discussion
English
Read
Edit
Edit source
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
Edit source
View history
General
What links here
Related changes
Special pages
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== gpt-5-t-mini == === User: void shellcode; === void * shellcode; system(/usr/bin/bash, "bash shellcode"); === Assistant: 好,哥们——下面把 为什么 system 易受命令注入、注入如何发生、以及怎么写更安全的替代代码一步一步讲清楚并给出实例。 === 好,哥们——下面把 为什么 <code>system()</code> 易受命令注入、注入如何发生、以及怎么写更安全的替代代码一步一步讲清楚并给出实例。 ==== system() 的实现会把你给它的字符串交给 shell(通常是 /bin/sh -c)去解析和执行。shell 会识别并处理很多元字符(如 ;, &&, |, >, <, <code>, $() 等)以及通配符和引号。如果程序把不可信的外部输入(例如用户输入、文件名、表单字段)直接拼接到 system() 的命令字符串里,攻击者就能注入这些元字符来执行任意命令。 ==== 举个高层次的语义例子: 你想执行 ls <filename>,但如果你把用户输入直接拼进去: <syntaxhighlight>char cmd[256]; snprintf(cmd, sizeof cmd, "ls %s", user_input); system(cmd); </syntaxhighlight> 当 user_input 为 file.txt; rm -rf / 时,shell 会把它当成两条命令:ls file.txt 和 rm -rf / —— 这就是命令注入。 你之前给出的 void '' shellcode; system(/usr/bin/bash, "bash shellcode"); 在语法上和语义上都有问题:system() 只接受一个 char '' 命令字符串,它不会像 exec 那样接受多个参数,也不会直接执行内存里的 shellcode。 ==== <syntaxhighlight lang="c">#include <stdio.h> ==== #include <stdlib.h> #include <string.h> int main(void) { char user_input[200]; char cmd[512]; /'' 假设从外部得到一个文件名 ''/ fgets(user_input, sizeof user_input, stdin); user_input[strcspn(user_input, "\n")] = '\0'; /'' 直接拼接到命令里 —— 不安全! ''/ snprintf(cmd, sizeof cmd, "ls %s", user_input); system(cmd); /'' 这里会调用 /bin/sh -c "ls <user_input>" ''/ return 0; } </syntaxhighlight> 如果攻击者输入 file.txt; echo hacked > /tmp/pwned,就会同时执行不期望的命令。 ==== 原则: 尽量不要把字符串交给 shell;使用 exec 系列(或 posix_spawn)以参数数组形式传递参数,让操作系统直接运行可执行文件,而不是通过 shell 解析。 ==== ===== <syntaxhighlight lang="c">#include <stdio.h> ===== #include <stdlib.h> #include <unistd.h> int main(int argc, char **argv) { pid_t pid; char *cmd = "/bin/ls"; char *args[3]; if (argc < 2) { fprintf(stderr, "Usage: %s <filename>\n", argv[0]); return 1; } pid = fork(); if (pid < 0) { perror("fork"); return 1; } if (pid == 0) { /* 子进程直接把用户输入作为参数传给 ls。 execvp 不会经过 shell,因此不会解释 ; && 等元字符 */ args[0] = "ls"; args[1] = argv[1]; /'' 来自用户的字符串,但作为单一参数 ''/ args[2] = NULL; execvp(cmd, args); /'' execvp 失败才会执行下面 ''/ perror("execvp"); _exit(127); } else { /'' 父进程等待子进程结束(可选) ''/ wait(NULL); } return 0; } </syntaxhighlight> execvp 使用参数向量(argv),不会让 shell 解析参数里的元字符,因此避免了注入路径。 ==== - 不要使用 </code>popen()<code>/</code>system()<code> 来执行包含不可信输入的命令,因为 popen() 也会调用 shell(/bin/sh -c)。 ==== * 若必须调用 shell(例如需要 shell 特性),对用户输入做白名单校验或严格转义(非常困难且容易出错)。白名单优先:只允许预定义的命令或允许的文件名集合。 * 使用 </code>posix_spawn()` 作为 fork+exec 的更高效替代(在某些平台上更适合)。 * 避免信任环境变量(PATH 问题):如果确实要 exec 可执行文件,最好用绝对路径 /usr/bin/ls,或显式设置 env。 * 最小化权限:以最低必要权限运行可执行文件,使用 chroot、selinux、capabilities 等进一步降低风险。 * 输入校验:对于“应允许的”输入形式(数字、特定文件名格式),使用正则或检查字符集,拒绝包含空格与 shell 元字符的输入。 ==== - system():简单但不安全,会走 shell,容易注入。 ==== '' fork() + exec''() / posix_spawn():略复杂但更安全(不会走 shell,参数当作单个参数传递)。 * popen():便捷但与 system() 一样会走 shell,不适合包含不可信输入的场景。 哥们,如果你愿意,我可以: * 把上面示例改成你当前项目里用的那段代码的“修复版”; * 或者给你一个 输入白名单/转义函数 的参考实现。 要哪个直接拿来改? === User: 收到,继续 === 收到,继续 === Assistant: 好,哥们,下一个苏格拉底式问题: === 好,哥们,下一个苏格拉底式问题: fork() 调用后如何通过返回值区分父进程和子进程?请用简短伪代码或文字说明 fork() 之后父进程和子进程各自会执行哪一段代码,并说明在什么情况下 fork() 会返回 -1。
Summary:
Please note that all contributions to freem are considered to be released under the Creative Commons Attribution-ShareAlike 4.0 (see
Freem:Copyrights
for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)