<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    原文地址:http://drops.wooyun.org/%e8%bf%90%e7%bb%b4%e5%ae%89%e5%85%a8/4151

                    0x00 系統效果


                    此DDOS應用層防御系統已經部署在了http://www.yfdc.org網站上(如果訪問失敗,請直接訪問位于國內的服務器http://121.42.45.55進行在線測試)。

                    此防御系統位于應用層,可以有效防止非法用戶對服務器資源的濫用:

                    只要是發送高頻率地、應用層請求以實現大量消耗系統資源的攻擊方式,皆可有效防御。
                    

                    其實現的基本思想是:

                    定期分析所有訪問用戶在過去各個時間段內的請求頻率,將頻率高于指定閾值的用戶判定為資源濫用者,將其封殺一段時間,時效過后,防御系統自動將其解封。
                    

                    在線效果測試:

                    進入http://www.yfdc.org -> 點擊右上側在線查詢,此時將會進入/shell/yf域內,/shell/yf是一個用bash scripts寫的動態web-cgi程序,用戶每一次提交信息,此程序將會執行一些服務器端的查詢操作,然后將數據處理后返回到客戶端。

                    為了防止非法用戶高頻率地訪問這個程序,而影響到其他正常用戶的訪問,故需要進行一些保護措施。

                    最終效果:

                    enter image description here

                    被封信息頁面

                    在/shell/yf域內,按住F5不放,一直刷新,幾秒后松開,就能看到被封信息和解封時間。
                    只要某個用戶對/shell/yf的訪問超過了正常的頻率,服務將會對這個用戶關閉一段時間,期滿后自動解封。
                    

                    0x01 系統原理


                    操作系統: CentOS 6.5 x86_64 開發語言: Bash Shell Scripts Web服務器: Apache Httpd

                    enter image description here

                    (此圖為系統結構的鳥瞰圖 可存至本地后放大查看)

                    2.1 自定義日志:/etc/httpd/logs/yfddos_log


                    enter image description here

                    (自定義日志文件的格式)

                    在httpd.conf的日志參數中,加入如下兩行:

                    LogFormat "%a \"%U\" %{local}p %D %{%s}t " yfddos
                    CustomLog logs/yfddos_log yfddos
                    

                    我們接下來重點分析日志文件/etc/httpd/logs/yfddos_log.

                    LogFormat "%a \"%U\" %{local}p %D %{%s}t " yfddos

                    解釋:

                    %a -> 用戶的IP
                    %U -> 請求的URL地址,但并不包含query string(The URL path requested, not including any query string.)
                    %{local}p -> 用戶請求的服務器端口(一般為80)
                    %D -> 這個請求共消耗了服務器多少微秒(The time taken to serve the request, in microseconds.)
                    %{%s}t -> 服務器收到這個請求時,時間戳的值(seconds since 1970-01-01 00:00:00 UTC)
                    

                    例子:

                    192.168.31.1 "/shell/yf" 80 118231 1417164313
                    

                    譯為:IP為192.168.31.1的主機,在時間戳為1417164313的時候,訪問了/shell/yf,并由服務器的80端口向其提供服務,共耗時118231微秒

                    或為:IP為192.168.31.1的主機,在2014-11-28 16:45:13的時候,訪問了/shell/yf,并由服務器的80端口向其提供服務,共耗時0.118231秒

                    至于為什么不使用httpd.conf中官方定義的日志,原因如下:

                    - 用戶訪問日志的一條記錄可大約控制在60Bytes以內,數據量小,便于后期分析,官方定義的日志太過臃腫,影響分析速度
                    - 使用時間戳標志時間,便于后期分析,官方定義的日志時間參數為常規的表達方式,不便于直接進行處理
                    - httpd的日志系統本身就是從舊到新進行排序記錄的,所以/etc/httpd/logs/yfddos_log日志條目的時間戳,亦為從小到大進行排序的,數據記錄更加鮮明
                    

                    2.2 yfddosd黑名單文件格式


                    enter image description here

                    黑名單文件格式

                    yfddosd黑名單文件/etc/yfddos/web-yf-search.b格式如下:

                    # ip    add-stamp  rmv-stamp
                    1.2.3.4 1416046335 1416046395
                    1.2.3.5 1416046336 1416046396
                    1.2.3.6 1416046339 1416046399
                    

                    每一行為一個黑名單條目,上面第一個條目的意義為:

                    IP地址  :1.2.3.4
                    開始時間:時間戳1416046335,即 2014-11-15 18:12:15
                    終止時間:時間戳1416046395,即 2014-11-15 18:13:15
                    

                    直觀意義為:

                    IP地址:1.2.3.4,從2014-11-15 18:12:15開始,被封殺1分鐘,在2014-11-15 18:13:15時自動解封。

                    這個文件將由駐留在系統中的daemon守護進程yfddosd進行維護更新。

                    2.3 守護進程yfddosd:防御系統的邏輯核心


                    enter image description here

                    守護進程的原理圖

                    守護進程yfddosd是整個CC防御系統的核心,而function analyze_and_insert_black()則是yfddosd的核心。

                    yfddosd的配置參數:

                    yfddos_blackfilePath='/etc/yfddos/web-yf-search.b'
                    yfddos_accesslogPath='/etc/httpd/logs/yfddos_log'
                    
                    function analyze_and_insert_black() { 
                      # analyze_and_insert_black() :
                      #   $1:max frequency(seems as abuse if above that) $2:blackip-ttl,time to live,unit is seconds (s) 
                      #   $3:the access log ${3} seconds before will be analyzed to generate the abuse ip lists that we will block
                      # example : analyze_and_insert_black "limit" "ttl" "time"
                      # example : analyze_and_insert_black "4" "10" "5"
                      # 分析在過去5s內的用戶訪問日志 如果有人在這5s內訪問量>=4 系統將視其為資源濫用者 將其加入服務黑名單
                      # 一條黑名單的作用時間為10s 即在10s之后 系統自動刪除此黑名單條目 服務則繼續向其開放
                      # global vars:
                      # stamp logtmpfile yfddos_blackfilePath
                      # ......
                    }
                    

                    函數analyze_and_insert_black有三個輸入參數:

                    例子: analyze_and_insert_black "4" "10" "5"

                    解釋: 分析日志文件/etc/httpd/logs/yfddos_log中,在過去5s內的用戶訪問日志,如果有IP在這5s內訪問量>=4,守護進程yfddosd將視其為資源濫用者,
                        然后將這個IP加入到黑名單文件/etc/yfddos/web-yf-search.b中,此條黑名單的作用時間為10s,在10s之后,守護進程yfddosd將刪除此黑名單條目。
                    

                    例子: analyze_and_insert_black "150" "2700" "905"

                    解釋: 分析日志文件/etc/httpd/logs/yfddos_log中,在過去905s內的用戶訪問日志,如果有IP在這905s內訪問量>=150,守護進程yfddosd將視其為資源濫用者,
                        然后將這個IP加入到黑名單文件/etc/yfddos/web-yf-search.b中,此條黑名單的作用時間為2700s,在2700s之后,守護進程yfddosd將刪除此黑名單條目。
                    

                    簡記為: analyze_and_insert_black "limit" "ttl" "time"

                    解釋: 分析日志文件/etc/httpd/logs/yfddos_log中,在過去(time)s內的用戶訪問日志,如果有IP在這(time)s內訪問量>=limit,守護進程yfddosd將視其為資源濫用者,
                        然后此IP將會被加入到黑名單文件/etc/yfddos/web-yf-search.b中,作用時間為(ttl)s,在(ttl)s之后,守護進程yfddosd將自動刪除此條目。
                    

                    從上述中可看出,守護進程yfddosd至少需要完成如下三個任務:

                    守護進程yfddosd是如何實現上面三個邏輯的:

                    下面是守護進程yfddosd狀態機的偽代碼:(略去了一些處理細節)

                    #init and FSM start work...
                    counter=0
                    while true
                    do
                      sleep 5
                      counter=counter+1
                      delete obsolete items #將/etc/yfddos/web-yf-search.b中已經過期的條目全部刪除
                      if # every 5 seconds : 5s
                      then
                        analyze_and_insert_black "6" "10" "5"
                        # 分析在過去5s內訪問的用戶 如果有人其訪問量大于等于6 系統將視其為資源濫用者 
                        # 遂將其加入服務黑名單 其作用時間為10s 在10s之后 daemon進程自動刪除這個ip黑名單條目
                      fi
                      if #every 5*3 seconds : 15s 
                      then
                        analyze_and_insert_black "14" "45" "15"
                      fi
                      if #every 5*3*4+5 seconds : 65s
                      then
                        analyze_and_insert_black "40" "840" "65"
                      fi
                      if #every 5*3*4*3*5+5 seconds : 905s : 15min
                      then
                        analyze_and_insert_black "150" "2700" "905"
                      fi
                      if #every 5*3*4*3*5*4+5 seconds : 3605s : 1h
                      then
                        analyze_and_insert_black "300" "7200" "3605"
                      fi
                      if #every 5*3*4*3*5*4*3+5 seconds : 10805s : 3h
                      then
                        analyze_and_insert_black "400" "21600" "10805"
                        if #在每天的00:01-04:59時間區間 一天僅執行一次
                        then
                            #備份日志 
                        fi
                      fi
                    done
                    

                    防御者應斟酌調整每個檢測時間點的參數值(封殺時間ttl與判定閾值limit),以調節系統應對CC攻擊到來時的反應時間。

                    0x02 源代碼


                    #!bash
                    ##################################### vim /usr/local/bin/yfddosd.sh :
                    ##################################### nohup bash /usr/local/bin/yfddosd.sh &>"/etc/yfddos/""yfddosd-log-`date +%Y-%m-%d`" & 
                    ##################################### yfddos daemon
                    mkdir /etc/yfddos
                    yfddos_blackfilePath='/etc/yfddos/web-yf-search.b'
                    yfddos_accesslogPath='/etc/httpd/logs/yfddos_log'
                    
                    ### refresh tll
                    logtmpfile=`mktemp`
                    stamp=`date +%s`
                    touch "$yfddos_blackfilePath"
                    if grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$yfddos_blackfilePath" &>/dev/null
                    then
                      cat "$yfddos_blackfilePath" | while read i
                      do
                        deadstamp=`echo "$i" | grep -Po '[0-9]+$'` 
                        if [ "$stamp" -le "$deadstamp" ]
                        then
                          echo "$i" >>"$logtmpfile"
                        fi
                      done
                    fi
                    chmod o+r "$logtmpfile"
                    mv -f "$logtmpfile" "$yfddos_blackfilePath"
                    if ! grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$yfddos_blackfilePath" &>/dev/null
                    then
                      echo '255.255.255.255 0 0' >> "$yfddos_blackfilePath"
                    fi
                    
                    function analyze_and_insert_black() { 
                      # analyze_and_insert_black() :
                      #   $1:max frequency(seems as abuse if above that) $2:blackip-ttl,time to live,unit is seconds (s) 
                      #   $3:the access log ${3} seconds before will be analyzed to generate the abuse ip lists that we will block
                      # example : analyze_and_insert_black "limit" "ttl" "time"
                      # example : analyze_and_insert_black "4" "10" "5"
                      # 分析在過去5s內的用戶訪問日志 如果有人在這5s內訪問量>=4 系統將視其為資源濫用者 將其加入服務黑名單
                      # 一條黑名單的作用時間為10s 即在10s之后 系統自動刪除此黑名單條目 服務則繼續向其開放
                      # global vars:
                      # stamp logtmpfile yfddos_blackfilePath
                      local threshold="$1"
                      local ttl="$2"
                      local stamp_pre="$3"
                      local i=0
                      local num=""
                      local fre=0
                      local ip=0
                      local localbuf=0
                      local linenum=0
                      local deadstamp=0
                      stamp_pre="$((stamp-stamp_pre))"
                    
                      #二分查找初始化
                      local temp=0
                      local yf_x='1'
                      local yf_y=`cat "$logtmpfile" | wc -l`
                      if [ "$yf_y" -le "1" ]
                      then 
                        yf_y=1
                      fi
                      local yf_I=$(((yf_x+yf_y)/2))
                    
                      temp=`cat "$logtmpfile" | wc -l`
                      if [ "$temp" -gt "0" ]
                      then
                        temp=`sed -n '$p' "$logtmpfile" | grep -Po '[0-9]+ $'`
                        if [ "$temp" -lt "$stamp_pre" ]
                        then
                          num=""
                        else  
                          while true #使用二分查找的方法 快速地分析訪問日志
                          do
                            temp=`sed -n "${yf_x}p" "$logtmpfile" | grep -Po '[0-9]+ $'`
                            if [ "$temp" -ge "$stamp_pre" ]
                            then
                              break
                            fi
                            if [ "$((yf_y-yf_x))" -le "1" ]
                            then
                              yf_x="$yf_y"
                              break
                            fi
                            temp=`sed -n "${yf_I}p" "$logtmpfile" | grep -Po '[0-9]+ $'`
                            if [ "$temp" -lt "$stamp_pre" ]
                            then
                              yf_x="$yf_I"
                              yf_y="$yf_y"
                              yf_I="$(((yf_x+yf_y)/2))"
                              continue
                            fi
                            yf_x="$yf_x"
                            yf_y="$yf_I"
                            yf_I="$(((yf_x+yf_y)/2))"  
                            continue
                          done
                          temp=`sed -n "${yf_x}p" "$logtmpfile" | grep -Po '[0-9]+ $'`
                          if [ "$temp" -ge "$stamp_pre" ]
                          then
                            num="$yf_x"
                          else
                            num=""
                          fi
                        fi  
                    
                        if [ -n "$num" ]
                        then
                          sed -n "${num},\$p" "$logtmpfile" | grep -Po '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | sort -n | uniq -c | sort -rn | while read i
                          do
                            fre=`echo "$i" | grep -Po '[0-9]+' | head -1`
                            ip=`echo "$i" | grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' `
                            if [ "$fre" -ge "$threshold" ]
                            then #insert illegal ips : cat "$yfddos_blackfilePath"
                              # ip    add-stamp  rmv-stamp
                              #1.2.3.4 1416046335 1416046395
                              temp=`grep -Pn "${ip//./\\.} " "$yfddos_blackfilePath"`
                              if [ -n "$temp" ]
                              then
                                linenum=`echo "$temp" | grep -Po '^[0-9]+' | head -1`
                                deadstamp=`echo "$temp" | grep -Po '[0-9]+$' | sort -rn | head -1 `  
                                if [ "$((stamp+ttl))" -gt "$deadstamp" ]
                                then
                                  sed -i "${linenum}s/.*/${ip} ${stamp} $((stamp+ttl))/g" "$yfddos_blackfilePath"
                                fi
                              else
                                sed -i "\$a ${ip} ${stamp} $((stamp+ttl))" "$yfddos_blackfilePath"
                              fi 
                            else
                              break
                            fi
                          done
                        fi
                    
                      fi
                    }
                    
                    #init and yfddosd's FSM start work...
                    counter=0
                    
                    while true
                    do
                      sleep 5
                      counter=$((counter+1))
                      echo -n `date +%Y-%m-%d\ %H:%M:%S`" ""counter ${counter}:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
                      echo -n "refresh tll:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
                      ### refresh tll
                        #refresh ttl: analyze file: "$yfddos_blackfilePath" if some items'ttl has been reach the date , we will remove it and open service to the ip had been banned before.
                          #insert illegal ips : cat "$yfddos_blackfilePath"
                          # ip    add-stamp  rmv-stamp
                          #1.2.3.4 1416046335 1416046395
                        #sed -i "/^.* $((stamp-5))$/d;/^.* $((stamp-4))$/d;/^.* $((stamp-3))$/d;/^.* $((stamp-2))$/d;/^.* $((stamp-1))$/d;/^.* $((stamp))$/d;/^$/d" "$yfddos_blackfilePath"  
                      logtmpfile=`mktemp`
                      stamp=`date +%s`
                      touch "$yfddos_blackfilePath"
                      if grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$yfddos_blackfilePath" &>/dev/null
                      then
                        cat "$yfddos_blackfilePath" | while read i
                        do
                          deadstamp=`echo "$i" | grep -Po '[0-9]+$'` 
                          if [ "$stamp" -le "$deadstamp" ]
                          then
                            echo "$i" >>"$logtmpfile"
                          fi
                        done
                      fi
                      chmod o+r "$logtmpfile"
                      mv -f "$logtmpfile" "$yfddos_blackfilePath"
                      if ! grep -Po '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$yfddos_blackfilePath" &>/dev/null
                      then
                        echo '255.255.255.255 0 0' >> "$yfddos_blackfilePath"
                      fi
                    
                      logtmpfile=`mktemp`
                      stamp=`date +%s`
                      cat "$yfddos_accesslogPath" | grep -P ' "/shell/yf" ' >"$logtmpfile"
                      if true # every 5 seconds : 5s
                      then
                        echo -n "analyze_and_insert_black 6 10 5:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
                        #analyze yfddos log : analyze_and_insert_black() $1:max frequency(seems as abuse if above that) $2:blackip-ttl $3:the access log ${3} seconds before will be analyzed to generate the abuse ips that we will block
                        analyze_and_insert_black "6" "10" "5"
                        # 分析在過去5s內訪問的用戶 如果有人其訪問量大于等于6 系統將視其為資源濫用者 遂將其加入服務黑名單 其作用時間為10s 在10s之后 daemon進程自動刪除這個ip黑名單條目
                      fi
                      if [ "$((counter%(3)))" -eq "0" ] #every 5*3 seconds : 15s 
                      then
                        echo -n "analyze_and_insert_black 14 45 15:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "    
                      # example : analyze_and_insert_black "limit" "ttl" "time"
                        analyze_and_insert_black "10" "45" "15"
                      fi
                      if [ "$((counter%(3*4+1)))" -eq "0" ] #every 5*3*4+5 seconds : 65s
                      then
                        echo -n "analyze_and_insert_black 40 840 65:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
                      # example : analyze_and_insert_black "limit" "ttl" "time"
                        analyze_and_insert_black "25" "840" "65"
                      fi
                      if [ "$((counter%(3*4*3*5+1)))" -eq "0" ] #every 5*3*4*3*5+5 seconds : 905s : 15min
                      then
                        echo -n "analyze_and_insert_black 150 2700 905:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
                      # example : analyze_and_insert_black "limit" "ttl" "time"
                        analyze_and_insert_black "150" "2700" "905"
                      fi
                      if [ "$((counter%(3*4*3*5*4+1)))" -eq "0" ] #every 5*3*4*3*5*4+5 seconds : 3605s : 1h
                      then
                        echo -n "analyze_and_insert_black 300 7200 3605:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
                      # example : analyze_and_insert_black "limit" "ttl" "time"
                        analyze_and_insert_black "300" "7200" "3605"
                      fi
                      if [ "$((counter%(3*4*3*5*4*3+1)))" -eq "0" ] #every 5*3*4*3*5*4*3+5 seconds : 10805s : 3h
                      then
                        echo -n "analyze_and_insert_black 400 21600 10805:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
                      # example : analyze_and_insert_black "limit" "ttl" "time"
                        analyze_and_insert_black "400" "21600" "10805"
                        #### "${yfddos_accesslogPath}" backup : 在每天的00:01-04:59時間區間內 備份日志一次
                        if [ "`date +%H`" -le "5" ] && ! [ -f "${yfddos_accesslogPath}-`date +%Y-%m-%d`" ]
                        then
                          service httpd stop
                          mv "${yfddos_accesslogPath}" "${yfddos_accesslogPath}-`date +%Y-%m-%d`"
                          service httpd start
                        fi
                      fi
                      rm -fr "$logtmpfile"
                      echo "sleep:"`cat /proc/uptime | grep -Po '[0-9\.]+' | head -1`"  "
                    done
                    

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频