• ctf之WEB练习一


    一、查找备份文件

    1.通过https://github.com/maurosoria/dirsearch进行目录扫描
    python3 dirsearch.py   -u http://10.10.10.175:32770   -e   *
    2.最终获得index.php.bk备份文件,然后下载下来查看源码,即可获得flag
    flag为:Cyberpeace{855A1C4B3401294CB6604CCC98BDE334}

    二、隐藏在cookie中的flag

    1.通过抓包工具对IP访问进行抓取http头部信息,发现cookie中包含信息:
    Cookie: look-here=cookie.php
    2.然后访问网址:http://220.249.52.133:41440/cookie.php,显示文字提示See the http response,说明flag有可能在响应包中
    3.对网址http://220.249.52.133:41440/cookie.php,进行请求,查看响应包,可看到flag信息
    4.最终flag为:cyberpeace{71de0ba3c98781d7f78c4af6e5b684be}

    三、隐藏在按钮下的flag
    1.打开网址,http://220.249.52.133:52359/,发现按钮灰色,提示不能使用,这时候通过f12进行元素审核
    2.删除 disabled="" ,然后点击按钮即可获得flag
    3.最终flag为:cyberpeace{e61ed8f7f37f036a89f6d3c5622bb8e9}
    四、弱密码获得flag
    1.打开网址:

    2.输入用户名admin,123456,即可登录到系统,并获得flag
    3.最终flag为:cyberpeace{a136364c15e239b4f32b99d2d23e42ce}

    三、简单的文件包含审计获得flag
    <?php
    show_source
    (__FILE__);
    include(
    "config.php");
    $a=@$_GET['a'];
    $b=@$_GET['b'];
    if(
    $a==and $a){
        echo 
    $flag1;
    }
    if(
    is_numeric($b)){
        exit();
    }
    if(
    $b>1234){
        echo 
    $flag2;
    }
    ?>

    这段php代码的意思是,通过get方法得到a和b的值,然后如果$a==0 并且$a为真,得到flag1,如果b是整数或者数字字符串,就退出,然后如果$b>1234就得到flag2.

    基础知识:(掌握php弱类型比较)
    php中其中两种比较符号:
    ==:先将字符串类型转化成相同,再比较
    ===:先判断两种字符串的类型是否相等,再比较
    字符串和数字比较使用==时,字符串会先转换为数字类型再比较
    var_dump('a' == 0);//true,此时a字符串类型转化成数字,因为a字符串开头中没有找到数字,所以转换为0
    var_dump('123a' == 123);//true,这里'123a'会被转换为123
    var_dump('a123' == 123);//false,因为php中有这样一个规定:字符串的开始部分决定了它的值,如果该字符串以合法的数字开始,则使用该数字至和它连续的最后一个数字结束,否则其比较时整体值为0。
    var_dump('root' == 0);
    var_dump('22r22oot' == 22);  //true,先将字符串22r22oot转化成和0同等类型即数字型,因为字符串开始有合法数值,则取其连续的合法数值22,r后面的22因为与开始的合法数值不连续,所以不取它的值,22==22,所以成立。
    var_dump('root22' == 0);  //true,先将字符串root22转化成和0同等类型即数字型,因为字符串开始没有合法数值,则字符串root22转换为0,最后0==0,所以成立。
    var_dump('0e170' == '0e180');//true,因为字符串中含有e开头的值,那么php代码会将其整体看成科学记数法,最后0的170次方==0的180次方,即0==0,所以成立
    var_dump(0 === 'root');//fals,=== 在进行比较的时候,会先判断两边类型是否相等,这里数值和字符串类型明显不等,因此不成立
    var_dump ("0e830400451993494058024219903391" == "0e830400451993494058024219904444");//true,先将字符串0e830400451993494058024219903391与0e830400451993494058024219904444分别转化成数字型,因为两个字符串开始都有合法数值,则字符串0e830400451993494058024219903391转换为0,字符串0e830400451993494058024219904444转换为0,最后0==0,所以成立。
    var_dump("123.a1bc"==123);//true
    var_dump("123.2abc"==123);//false
    var_dump("123e2abc"==123);//false
    var_dump("123ea1bc"==123);//true
    开始部分存在数字,若连续的数字中包含.或e或E会干扰字符串和数字的比较,因为.就表示了浮点数,e和E表示了科学计数法,只要字符串中包含这些,上面所说的比较就不能理想地实现
    字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0

    1.打开页面,进行代码审计,发现同时满足 $a==0 和 $a 时,显示flag1。

    2.php中的弱类型比较会使’abc’ == 0为真,所以输入a=c时,可得到flag1,如图所示。(abc可换成任意字符)。

    http://220.249.52.133:53517/index.php?a=abc

    3.is_numeric() 函数会判断如果是数字和数字字符串则返回 TRUE,否则返回 FALSE,且php中弱类型比较时,会使(‘1234a’ == 1234)为真,所以当输入a=abc&b=1235a,可得到flag2,如图所示。

    入a=abc&b=1235a,可得到flag2,如图所示。

    http://220.249.52.133:53517/index.php?a=abc&b=12345f


    四、post与get方式的flag
    1.构造get方式访问
    http://220.249.52.133:48752/index.php?a=1
    2.然后按照页面提示,通过firefox中插件hackbar提交post数据,b=2,即可获得flag
    五、http头部伪绕过限制访问获得flag
    基础知识:
    xff是告诉服务器当前请求者的最终ip的http请求头字段
    通常可以直接通过修改http头中的X-Forwarded-For字段来仿造请求的最终ip
    referer就是告诉服务器当前访问者是从哪个url地址跳转到自己的,跟xff一样,referer也可直接修改
    1.打开网址http://220.249.52.133:54968/,提示必须是源ip为123.123.123.123才能访问

    2.通过抓包,在http头部添加xff伪造请求头,X-Forwarded-For: 123.123.123.123,然后访问,发现响应页面中包含,需要请求头为必须来自https://www.google.com访问,这里需要添加上,referer: https://www.google.com,然后访问可获得flag
    最终获得flag:
    cyberpeace{f116fe3f881eef96edaaf3159a3131f8}

    六、远程命令执行获取flag
    基础知识:
     windows或linux下:
        command1 && command2 先执行command1,如果为真,再执行command2。
     command1 | command2 只执行command2。
     command1 & command2 先执行command2后执行command1。
     command1 || command2 先执行command1,如果为假,再执行command2
    1.输入IP地址,这里最好127.0.0.1,如果出现回显,则存在命令执行
    2.通过在后门加上命令:127.0.0.1|  find   /  -name    flag.txt  的文件目录,其目录为:/home/flag.txt
    3.使用命令127.0.0.1| cat /home/flag.txt,查看flag.txt的flag
    最终获得flag:
    cyberpeace{400f6c86f9dd25994afb930d13cc28b8}


    JS代码获得flag

    进入环境后我们遇到了输入密码,于是我们随便输入一个密码,点击确定
    进行代码审计,发现不论输入什么都会跳到假密码,真密码位于 fromCharCode

    执行流程:

    一、首先定义了一个dechiffre函数,咱先不管,因为还没有调用

    注:先将\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30十六进制数转换成字符串,python下print即可,或网址:https://www.bejson.com/convert/ox2str/


    输出结果55,56,54,79,115,69,114,116,107,49,50

    二、执行String["fromCharCode"](dechiffre("55,56,54,79,115,69,114,116,107,49,50

    "));


    三、调用了dechiffre,执行dechiffre函数

    String["fromCharCode"](dechiffre("55,56,54,79,115,69,114,116,107,49,50

    "));

    (1)先将"55,56,54,79,115,69,114,116,107,49,50

    "带入dechiffre函数执行,即dechiffre(pass_enc)=dechiffre("55,56,54,79,115,69,114,116,107,49,50

    ")

    (2)接着我们看到了pass变量,暂时先放着

    (3)因为pass_enc="55,56,54,79,115,69,114,116,107,49,50"

    将pass_enc字符串分割成字符串数组,赋值给tab参数,所以:

    tab=[55,56,54,79,115,69,114,116,107,49,50]   注:tab此时是字符串数组!!!

    (3)随后也对pass分割

    tab2=[70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65]

    (4)变量赋值代码分析:var i,j,k,l=0,m,n,o,p = "";i = 0;j = tab.length;

    一开始i,j,k,m,n,o,没有赋值,为undefined,其它参数l=0,p="",后来i被赋值=0,j被赋值为11

    (5)第九行此时n被赋值为0,所以k=11+0+0,最后等于11    注:这里的(l)其中是英文字母l,不是数字1

    (6)第十行中,n=18

    (7)第一个for循环,精简一下代码:

    for(i = 0; i < (18); i++ )

    {o = tab[i-l];p += String.fromCharCode((o = tab2[i]));

        if(i == 5)break;}

    解释:前面的o=tab[i-1]是无用的,因为后面会被o=tab2[i]的值重新覆盖

    第一次循环:o=tab[0];p=p+String.fromCharCode((o = tab2[0])

    =>o=70;p=""+String.fromCharCode(70)=>p=英文字母F

    第二次...

    第三次...

    第四次...

    第五次...

    所以,这个for循环,最后的p为(尽管没有输出出来,这里我们知道就好)FAUX P

    (8)第二个for循环,精简一下代码:

    for(i = 0; i < 18; i++ ){

    o = tab[i-l];

        if(i > 5 && i < 17)

            p += String.fromCharCode((o = tab2[i]));

    }

    解释:这里的for循环和上面的差不多,注意这里的p值由于第一次for循环执行后现在已经是FAUX P了

    加上第一次for循环的p值,最后的p为FAUX PASSWORD HAH

    (9)p += String.fromCharCode(tab2[17]);

    因为tab2=[70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65]

    所以:p=FAUX PASSWORD HAH + A

    因此,最后的p为FAUX PASSWORD HAHA


    (10)pass = p;return pass;

     即 pass = FAUX PASSWORD HAHA;return FAUX PASSWORD HAHA;

     最后函数输出为FAUX PASSWORD HAHA

    三、dechiffre函数执行完成后,继续执行其它的代码

    h = window.prompt('Enter password');

        alert( dechiffre(h) );

    h=你输入弹框内的内容

    之后alert弹出dechiffre(h)的值,由前面所有的代码可知,代码里p的值与tab无关,因为最终都会被tab2的值替代,所以我们无论输入什么,也就是pass_enc=h,无论输入的这个h等于什么,不管tab能否被分割成字符串数组,是否存在,都只会利用到tab2。通俗点讲,有关tab的参数与值都可以视为没有,因此,pass_enc参数是什么也就没有意义了

    四、最后,结论就是,无论我们在弹框中输入什么值,都只会返回FAUX PASSWORD HAHA

    我就猜想,会不会String["fromCharCode"](dechiffre("\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30"));这个语法错误,并且没有没计算出来的是不是最后正确的值,也就是flag~

    于是,我不用它这么无论pass_enc参数输入什么都显示FAUX PASSWORD HAHA的函数,咱也抛弃它一回,自己重新写代码执行它

    <!DOCTYPE html>

    <html>

    <head>

    <meta charset="utf-8">

    </head>

    <body>

    <script>

        var n=String.fromCharCode(55,56,54,79,115,69,114,116,107,49,50);

        document.write(n);

    </script>

    </body>

    </html>

    最后结果为:786OsErtk12

    通过python脚本将十六进制转成asic编码

    a = [55,56,54,79,115,69,114,116,107,49,50]
    c = ""
    for i in a:
    b = chr(i)
    c = c + b
    print(c)

    最终获得flag:Cyberpeace{786OsErtk12}


    一、文件包含(修改全局变量)

    题目:

    <?php
    include "flag.php";
    $a = @$_REQUEST['hello'];
    if(!
    preg_match('/^\w*$/',$a )){
      die(
    'ERROR');
    }
    eval(
    "var_dump($$a);");
    show_source(__FILE__);
    ?>

    writeup:

    代码分析:

    include "flag.php";
    $a = @$_REQUEST['hello'];
    if(!preg_match('/^\w*$/',$a )){//正则表达式^匹配一行的开头,$表示结束。\w表示匹配包括下划线的任何单词字符,等价于'[A-Za-z0-9_]'。*号:匹配前面的子表达式零次或多次。
      die('ERROR');
    }
    eval("var_dump($$a);");//var_dump — 打印变量的相关信息
    show_source(__FILE__);//__FILE__当前运行文件的完整路径和文件名。
    ?>

    这个代码的作用是如果匹配正则表达式/^\w*$/,就打印变量$$a
    $a是hello,$$a是六位变量$hello
    由于$a在函数中,所以函数之外无法访问。如果要访问,将hello修改为超全局变量GLOBALS。
    在URL后加?hello=GLOBALS,将参数hello修改为Globals
    实际执行语句:
    eval("var_dump($$a);")--->eval("var_dump($hello);")--->eval("var_dump($GLOBALS);")
    $GLOBALS的作用:引用全局作用域中可用的全部变量。
    这样就会打印出当前定义的所有变量,也包括 include 的文件中的变量,flag 也存在在这些变量中。

    2.我们通过URL进行传参

    http://a7a380bd2f5c4ae3add25a7a518afc17fba46d89981f45fd.changame.ichunqiu.com/index.php?hello=GLOBALS

    最终得到flag:

    flag{146918ba-01c6-47a3-bc16-0761da476df8}

  • 相关阅读:
    代码优化
    使用python的Flask实现一个RESTful API服务器端
    数据结构与算法之排序
    Ubuntu 13.04/12.10安装Oracle 11gR2图文教程(转)
    Linux 下开启ssh服务(转)
    PLSQL Developer 9.如何设置查询返回所有纪录(转)
    linux下安装oracle11g 64位最简客户端(转)
    Linux下关于解决JavaSwing中文乱码的情况(转)
    servlet(jsp)中的重定向和转发
    在用TabbarController中出现navigationController 嵌套报错
  • 原文地址:https://www.cnblogs.com/backlion/p/15693620.html
Copyright © 2020-2023  润新知