shifeng

bugku web wp
这是半年前打的bugku的wp了,记录一下我的摸鱼之路 _(:з」∠)_
扫描右侧二维码阅读全文
25
2019/03

bugku web wp

这是半年前打的bugku的wp了,记录一下我的摸鱼之路 _(:з」∠)_

web2

摸鱼题,F12就是

web基础$_GET

读代码可知在url后加?what=flag即可

计算器

F12,把maxlength改成2就行

web基础$_POST

在hackbar里进行post what=flag即可

矛盾

审计代码,可知要利用php弱类型比较漏洞,在url后加入?num=1d

当is_num()判断时会返回false,当与1进行比较时,num的值会被转成int类型即1

web3

截断加载停止浏览器刷新,然后F12可以找到一串html的编码,用python写脚本解码

域名解析

在C:WindowsSystem32driversetc找到host文件,修改一下DNS就好

管理员系统

进去后是个登录界面,于是尝试弱密码admin和123456

提示IP被禁止于是想到用X-Forwarded-For,然后用burpsuit抓包

抓包后发现有一串base64字符串,解码的得到test123

于是尝试X-Forwarded-For:127.0.0.1且user=admin&pass=test123,成功得到flag

你必须让他停下

打开页面浏览器一直再刷新,于是打开burpsuit抓包
Go多几次后得到flag

本地包含

$_REQUESE有get和post的作用
eval()可以执行代码
show_source()将文件高亮显示
var_dump()输出

于是构造payload: ?hello=1);show_source(‘flag.php’);var_dump( 绕出并读取flag.php得到flag

变量1

审计代码,提示flag保存在某个变量中。同时由于要正则限制数据为{a-z,A-Z,0-9,_},于是不能同上题一样注入。但在var_dump()中有个可变变量,于是可以通过使用$GLOBAL变量得到所有变量

web5

F12,发现有一大串字符被注释

搞了好久才知道是jother编码
于是放到chrome的console中回车得到flag

头等舱

既然题目叫头等舱,就用burpsuit获得http头
发现flag

网站被黑

这个入坑咸鱼没实战过,就百度了一下wp学学大致的流程

首先在url尾部加上index.php,网页存在,说明后台是由php写的
于是进行端口扫描,扫到有个shell入口

最后burpsuie密码爆破,得到password为hack
输入hack得到flag

web4

既然题目让看看源代码就F12看看

打开后发现js里有两串url编码的字符串
于是在python中进行解码

得到一个js函数,读一下

易知将if()中的字符串输入提交即可获得flag

flag在index里

这道题没什么思路,点click me?no后尝试将file后改成index.php然而什么都没有,用burpsuit也是,于是查了一下,发现要利用php伪协议
构造payload:

`file=php://filter/read=convert.base64-encode/resource=index.php`

用base64编码读取的原因是如果是正常的话就直接运行,而不会显示出来
于是得到一串base64编码

用python进行解码

获得flag

还有一点

这题是因为include()这个函数才能用filter协议,一般情况下是不行的

点击一百万次

看题目就知道和js有关,F12获取js代码

可以看到,当click>=1000000时,会向服务端post一个clicks
于是我们直接用hackbar post一个click=10000001获得flag

输入密码查看flag

看到url里有个baopo,就试着打开burpsuit进行密码爆破

成功爆出密码,没想到是纯数字这么简单

备份是个好习惯

看题目想着是应该要用到备份之类的,不过小白没了解过于是选择百度
然后得知备份文件以.bak结尾于是在url后加上index.php.bak获得了备份文件
打开进行审计

脚本是说获得url在?后的部分,然后将字符串中的key删去,最后获得key1和key2两个变量。然后进行md5()后比较,key1、key2不同但md5()后相同便得flag
删key可通过双写kekeyy绕过,但对字符串的要求不会弄,继续百度得知
有两种方法通过
①md5()不处理数组,若传入数组便返回NULL,于是构造:?kekeyy1[]=fafdsa&kekeyy2[]=ndaslkdla
②当md5()出来的值是0e开头,则被认为是科学记数法,同时认为是0*10^n相等。使md5()结果为0e开头的字符串有:{QNKCDZO、240610708、s878926199a、s155964671a、s214587387a、s214587387a},选用其中两个构造语句即可

成绩单

一看就是sql注入题
尝试1’,发现没回显说明有注入点

于是开始注入
Payload:

1’ order by 4#
-1' union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database()#
-1' union select 1,2,3,group_concat(column_name) from information_schema.columns where table_name=’fl4g’#
-1' union select 1,2,3,group_concat(skctf_flag) from fl4g#

秋名山老司机

打开发现要求在2s内传值

再刷新一下,发现是要post一个value

解题方法很明确,编写一个python脚本获得flag

速度要快

看题目又是要写脚本,用burpsuit抓包发现flag

用试着base64解码了一下出来一段奇怪的字符串也不是flag很懵逼,搞了好久没出来于是百度

发现原来是要解码两次,而且不能分次手工去解码,因为解出的字符串每次都不同,只能脚本抓,很难受

cookie欺骗

看到filename的参数像base64就试着解码,解出来是keys.txt就试着输入index.php然而什么都没有,就试着改line的参数,发现line是按行返回,于是写脚本

# -*- coding:utf8 -*-  
from base64 import * 
import requests
import re

str1 = 'http://120.24.86.145:8002/web11/index.php?line='
str2 = '&filename=aW5kZXgucGhw'


for i in range(30):
    url = str1+str(i)+str2
    http = requests.get(url)
    con = http.content
    f = open('index.php','a')
    f.write(con) 
    f.close()

获得index.php源码

审计代码,发现当cookie下margin的值为margin时,便能通过filename获取keys.php源码,于是修改下脚本

获得keys.php源码

never give up

打开网页再f12发现没什么好搞的,于是burpsuit抓包发现1p.html

在网页打开跳到了一个没什么用的社区网页,于是试着用burpsuit抓包,发现host不对

于是就拿之前的request修改后来go一下

这个应该没错了,发现一大串base64编码,于是解码发现一大串url编码继续解码得到源码

读源码,下面那块水平不够不会绕,于是试着直接加f4l2a3g.txt在url后,居然直接就能进去???

不过还是想看看有没有绕过的办法,百度一下wp学到了一波操作
a因为是file_get_contents(),所以可以用a=php://input,然后用POST bugku is a nice plateform! 即可
b可以用%00截断绕过,b=%00456789
        原理好像是eregi()可以用%00截断而substr()不行
id用id=%00或id=. 或id==0绕过
        第一个时%00确实存在因而不会被过滤,但int后值却是0
        第二个.转化成int后也是0(其实只要不是数字开头就行)
        第三个因为==后不能作为布尔值

welcome to bugkuctf

打开页面F12,发现有段被注释的源码,复制下来读一下

看到file_get_contents()函数想到用php://input通过
有include()和后面注释的hint.php,就想到用php://filter获取hint.php的源码
构造payload:
?txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php
并post welcome to the bugkuctf 获得一串base64编码的字符串

接着进行解码得到源码

可以看出hint.php里面有一个flag类并提示了有flag.php,但通过同样的方法不能获得flag.php里的内容,于是继续读类。可以看到这个类定义了一个file变量,同时用了一个魔术方法。
__tostring()这个方法在将一个对象当做一个字符串来使用时,会自动调用。可以看到调用这个方法后会输出对象中file值的文件。
因为hint.php中并没有设置Flag类的对象,于是可以得知在其他php中调用了hint.php
于是用同样方法获得index.php并解码

可以看到flag被过滤掉于是不能直接查,于是只能寻其他路。发现有使用include()说明可以通过这里导入hint.php。继续看得知password参数会被反序列化后传给password变量然后echo。
到这里就很清楚了,因为echo的话若是Flag对象就会调用__tostring()方法,继而输出file值对应的文件,于是构造一个序列化后的字符串

然后构造payload

然而迷之没得到flag,用burpsuie也是,于是百度别人的wp,发现大佬们都出了???弃疗直接用flag了
flag{php_is_the_best_language}

过狗一句话

打开题目就有一串php代码,先读一波

大概就是将$poc这个字符串以#来分割成一块块数组,然后再连接起来
最后就成assert()这个函数,assert()是用执行传进函数的代码。于是这里就想到传木马进行攻击,不过第一次做这种不太会操作就百度一下wp
查到能用scandir()进行目录扫描,用print_r()将数组打印出来,于是构建payloda:?s=print_r(scandir(‘./’));

然后直接查flag就行

字符?正则?

打开有一段代码,先读一下

大概就是用id传入一个值和里面的正则匹配就行,trim函数因为没有设其他参数,于是不用考虑对两侧进行绕过
然后读正则,不怎么碰读起来很难受,边看匹配规则边读总算写出来了
大概就是:
key+任意零或多个字符+key+任意4到7个字符+key:/+一个任意字符+/+任意零或多个字符+key+一个a到z的字符+任意一个符号
然后构造payload:?id=key454545key12345key:/4/4545keya; 获得flag

前女友(SKCTF)

打开是一段令人愉快(x)的故事,看到有链接二字就去点了一下,果然有链接

读代码,有两个要绕过的地方,一个是之前见过的md5()绕过,另一个是strcmp()。一开始我还以为strcmp()相等是返回1就顺便给了个参数,没想到不行。于是百度了一下才发现是返回0
然后查了一下strcmp()有什么漏洞能利用,查到php5.3前strcmp()用于数组和字符串比较时会返回-1,不过5.3以上已改成返回0可利用,试了一下可以

login1(SKCTF)

点开发现提示sql约束攻击,于是去百度一下,大致原理是数据库的列设置了长度之后,若数据过长会自动截取设置的长度。具体操作一次

先猜测是admin账号然后开始sql约束攻击

先用 admin                                1作为用户名注册
中间一大串空格在传入数据库是会被转义成字符计入长度中,于是过长的话存在数据库里是就会被截成admin。而查询时会从上查询,于是登录时虽然使用我们的账号密码,但返回数据时则是原admin账号的数据
登录得到flag

不过我觉得这个漏洞应该是用在修改密码上的,因为大多都会用分离式登录,而且不会去取第二个数据,所以登录很难做到

你从哪里来

打开就问我是不是来自google,于是用burpsuit抓包
把referer修改成google的域名得flag

md5 collision(NUPT_CTF)

这道题没解出是由于之前0e那个没有完全理解清楚,当md5()后0e开头的都会认为是0的科学计数法,导致值为0。然后由于弱类型漏洞,导致 0==非数字开头字符串 从而绕过
给a传入个MD5后为0e开头的字符串就行

程序员本地网站

看题目还以为又是referer,但用burpsuit抓包后修改没成功。想了好久没想法于是百度,发现头协议里还有个叫X-Forwarded-For的协议
这个协议用来标记http请求端的真实ip,只有在通过代理或负载均衡服务器才会添加这个
于是添加并设为127.0.0.1获得flag

各种绕过

看题目还以为会有一堆要绕过的,但认真读一下代码,要绕的只有shal()这个函数。之前在看md5()文档时好像有看到过这个函数,于是尝试用md5()的方法来试着绕过,让两个变量都成数组

web8

这题挺简单的,读源码

大概就是传入两个参数ac存在,且等于fn对应的文件里的内容就出flag。
进题目时提示了“txt????”,于是试一下flag.txt,结果得到了里面的文本

剩下就很简单了,构造payload: ?ac=flags&fn=flag.txt 得flag

细心

打开页面没什么东西,整蛊了好久也没搞出什么,也没什么头绪就百度看看
于是又学到一个新东西,每个网站为了自己有一些地址不被网络爬虫爬到,会设置一个robots.txt。里面的 User-agent: 是用来标识哪些用户不能访问 Disallow:里的地址。每个爬虫读取这个网站前就会先读取这个txt再进行下一步。
于是打开看看

里面禁止了所有爬虫爬resusl.php,于是我们就打开这个php看看

根据下面的代码以及提示了想办法变成admin,就尝试x=admin,结果成功出flag

求getshell

打开页面是要文件上传,这块不是很会就去看看大佬们的上传姿势
操作是上传一个getshell.php,然后burpsuit抓包后吧contant-type改为可上传的image/jpg,filename中把扩展名改成php5这种非常用的扩展名,然后multipart/form-data;把m大写绕过(这里不是很懂原理),接着得flag

insert into注入

这是一个神奇的登陆框

看页面应该是一个post类型的注入,这次就学着用一下sqlmap注入看看
首先用burpsuit抓包

保存为1.txt在D盘中,然后打开sqlmap读取1.txt并获取数据库名字

接着获取表名,列名,flag

多次

打开页面,url上有id这个参数,尝试1、2、3发现显示文字改变,用0时显示error,就先确定时道sql注入题。
接着在后面加'发现出错

然后尝试#和%23,发现加%23后页面正常,于是可以开始注入

但用order by和union select时都出错了,应该是有过滤,于是用异或注入来判断。
若过滤时通过正则代替的话,那么1'^(length('union')=5)这条语句就会返回1显示正常,而1'^(length('union')=0)则返回0显示error,因为这里union被换成空字符串了。接着尝试几个会用到的order、by、union、select、gruop_concat()

order出现了和预测不一样的结果,进过几次测试后发现时过滤了or
payload:

0’ uunionion selecselectt 1,group_concat(table_name) from information_schema.tables where table_schema=database()%23
0' uunionnion selecselectt 1,group_concat(column_name) from infoorrmation_schema.columns where table_name='flag1'%23
0' uunionnion selecselectt 1,group_concat(flag1) from flag1%23

得到flag

这个不知道能不能用,但题目说有两个flag就继续找了
接着取查另一个列address,得到一个链接

进入网页同样操作试遍,发现只有union被过滤,但双写不起作用了,应该是发现非法字符直接不继续sql查询,于是试试看报错注入,结果成功
payload:

0' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),0)%23
0' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='flag2')),0)%23
0' or updatexml(1,concat(0x7e,(select group_concat(flag2) from flag2)),0)%23

PHP_encrypt_1(ISCCCTF)

题目给了一个 php,先下来读一下

是一个加密题,加密过程是先将ISCC进行md5,把字符串赋给key。然后将key的字符一个个递给char,但key字符不够用时就从头继续递,直到char和data一样长。然后在把char和data同位置上的字符串ascii码值的和与128求余,再转回字符后传给str,最终将str解码

基本上没什么难度,写个python破解出来就行

文件包含2

打开看到有?file=就尝试index.php和flag.php,但无输出。尝试../../etc/passwd、php://filter被过滤,于是F12发现upload.php

打开是个上传页面,于是构造一句话<script language=php>system("ls")</script>(其他的好像都被过滤了),保存为1.php.jpg后上传,然后打开文件所在位置获得目录下所有文件名

最后读取flag文件

flag.php

打开页面login果然不能点,然后转到flag.php什么都没用,试着post到flag.php然后设admin和hint也不行,抓包也没用,就懵逼了。查了查wp发现hint原来是当参数用的orz

然后就是读代码了,大概就是要再cookie中放一个ISecer,它的值序列化后为空。讲道理为什么这个代码不会出错啊
还有;要用url编码%3B

sql注入2

这题是真tm绝望,各种找办法绕过然而都失败了,最后无奈百度wp
然后只能说再也不信题目了,是完全没看过的源码泄漏
用ds_store_exp-master跑一下,就找到flag了

孙xx的博客

这题说是被玩烂了,等能搞了再说吧

报错注入

Trim的日记本

看题目的模样看起来是搞二次注入,但用了各种方法都不行
然后拿御剑扫一波没想到扫出了个show.php,打开就是flag,这题有点坑

里面一个ID都没有,看不懂这题啊,估计被人改了?

login2(SKCTF)

这题进去是个登录页面,整了一会没弄出什么,于是试着用burpsuit抓包

发现tip里有一串base64,解码

这里是分离式的用户密码验证,绕开md5()是重点
于是构造payload:
username = admin' union select md5(1),md5(1)#&password=1
登录成功,进去是个命令执行页面

这里尝试过反弹shell但不知道为什么没成功于是换用盲注

构造payload:

c=123;a=`ls`;b='a';if [ ${a:0:1} == $b ];then sleep 5;fi

把整个目录跑出来,得到fLag_c2Rmc2Fncn-MzRzZGZnNDc.txt
然后再构造payload:

    c=123;a=`fLag_c2Rmc2Fncn-MzRzZGZnNDc.txt\`;b='a';if [ ${a:0:1} == $b ];then sleep 5;fi

跑出flag

login3(SKCTF)

这题进去后试了几下,发现有进行过滤
于是写个脚本跑一下过滤了什么

发现空格 , union = and information被过滤

空格被过滤了用()代替,逗号尽量不用,union过滤了就不能用正常注入,不过这题没有返回什么也用不了。and被代替用or或^,这次用^来做。等号被过滤用<>代替,information被过滤就不能一步步查了,直接猜另一列位passwd或password看看,结果是password。

于是写个脚本,构造盲注语句:
admin'^(ascii(substr((password)from(m)))<>n)^0#

这里因为空格被过滤就不能用from...for,不过只用from也是可以,from会从标记的位置进行截断获取后面的字符串,而ascii()只会获取字符串第一个字符
然后跑一下出密码

(盲注还是二分法写吧,真的慢)
可以看出是个md5加密,于是找个网站解码出来是skctf123456
用这个密码登录就得到flag

文件上传2(湖湘杯)

看到文件上传的题还是没什么想法,还是查查wp看看
然后发现直接用php://filter就搞出来了,又这么坑吗orz

直接读出base64的flag,解码就是

login4

这道题和实验吧见到过很像的,基本就是一样的题,但还是搞了很久

首先第一步就没搞出来,查了才知道有.swp这种临时文件,如果不删可能导致源码泄漏,于是url后加.index.php.swp获得
然后在linux上用终端输入命令行 vim -r .index.php.swp还原得到源码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Login Form</title>
<link href="static/css/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="static/js/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    $(".username").focus(function() {
        $(".user-icon").css("left","-48px");
    });
    $(".username").blur(function() {
        $(".user-icon").css("left","0px");
    });

    $(".password").focus(function() {
        $(".pass-icon").css("left","-48px");
    });
    $(".password").blur(function() {
        $(".pass-icon").css("left","0px");
    });
});
</script>
</head>

<?php
define("SECRET_KEY", file_get_contents('/root/key'));
define("METHOD", "aes-128-cbc");
session_start();

function get_random_iv(){
    $random_iv='';
    for($i=0;$i<16;$i++){
        $random_iv.=chr(rand(1,255));
    }
    return $random_iv;
}

function login($info){
    $iv = get_random_iv();
    $plain = serialize($info);
    $cipher = openssl_encrypt($plain, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv);
    $_SESSION['username'] = $info['username'];
    setcookie("iv", base64_encode($iv));
    setcookie("cipher", base64_encode($cipher));
}

function check_login(){
    if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv'])){
        $cipher = base64_decode($_COOKIE['cipher']);
        $iv = base64_decode($_COOKIE["iv"]);
        if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)){
            $info = unserialize($plain) or die("<p>base64_decode('".base64_encode($plain)."') can't unserialize</p>");
            $_SESSION['username'] = $info['username'];
        }else{
            die("ERROR!");
        }
    }
}

function show_homepage(){
    if ($_SESSION["username"]==='admin'){
        echo '<p>Hello admin</p>';
        echo '<p>Flag is $flag</p>';
    }else{
        echo '<p>hello '.$_SESSION['username'].'</p>';
        echo '<p>Only admin can see flag</p>';
    }
    echo '<p><a href="loginout.php">Log out</a></p>';
}

if(isset($_POST['username']) && isset($_POST['password'])){
    $username = (string)$_POST['username'];
    $password = (string)$_POST['password'];
    if($username === 'admin'){
        exit('<p>admin are not allowed to login</p>');
    }else{
        $info = array('username'=>$username,'password'=>$password);
        login($info);
        show_homepage();
    }
}else{
    if(isset($_SESSION["username"])){
        check_login();
        show_homepage();
    }else{
        echo '<body class="login-body">
                <div id="wrapper">
                    <div class="user-icon"></div>
                    <div class="pass-icon"></div>
                    <form name="login-form" class="login-form" action="" method="post">
                        <div class="header">
                        <h1>Login Form</h1>
                        <span>Fill out the form below to login to my super awesome imaginary control panel.</span>
                        </div>
                        <div class="content">
                        <input name="username" type="text" class="input username" value="Username" onfocus="this.value=\'\'" />
                        <input name="password" type="password" class="input password" value="Password" onfocus="this.value=\'\'" />
                        </div>
                        <div class="footer">
                        <input type="submit" name="submit" value="Login" class="button" />
                        </div>
                    </form>
                </div>
            </body>';
    }
}
?>
</html>

这题和实验吧那题还是有些不同,不过也没什么
大概就是如果有post用户名和密码过去就查session中有没有用户名,不然就报错。当登录使用用户名为admin时会提示admin不能用,但在session中读到admin时才会给出flag。然后再看看其他部分,在用admin外的字符登录时,随机生成16位iv,再将用户名和密码序列化作为plain和iv进行cbc加密获得cipher。当刷新时会查cookie中的iv和cipher,用这两个来解密获得序列化的用户名和密码,最终取出用户名判断
接着要做什么就很明显了,就是通过修改cookie中的iv和plain把序列化出来的用户名修改成admin就行
这题最重要的地方就是cbc加密

这张图就解释了原理,先将字符串截成每16字符位一块,然后传入iv和第一块进行异或运算,得出的结果再和第二块异或,就这样把整个字符串加密
这题要用到异或的一个特点:A^B=C,C^B=A
我们可以构造数据:{'username':'2dmin','password':'22222'},然后我们会得到返回的iv和cipher。
此时反序列化的数据,在16字符分隔后为

可以看到,2在第二行第10位,于是2是由第一行第十位进行加密的
于是将cipher以16字符分隔后,我们可以用(第十位加密后的值)^2^a将2dmin修改成admin。然后修改了cipher后iv也要改,不然无法反序列化。于是将旧iv和新cipher提交,获得报错的数据
我们知道:
new_cipher^new_iv = new_data
new_cipher^old_iv = error_data
于是:
new_iv = old_iv^error_data^new_data,new_data就是新的序列化数据(就上面2改成a)
通过这个获得新iv,接着再次提交新iv和新cipher获得flag

最后修改:2019 年 03 月 25 日 06 : 37 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论