PHP_encrypt_1(ISCCCTF)
打开后源码如下:<?php
function encrypt($data,$key)
{
$key = md5('ISCC');
$x = 0;
$len = strlen($data);
$klen = strlen($key);
for ($i=0; $i < $len; $i++) {
if ($x == $klen)
{
$x = 0;
}
$char .= $key[$x];
$x+=1;
}
for ($i=0; $i < $len; $i++) {
$str .= chr((ord($data[$i]) + ord($char[$i])) % 128);
}
return base64_encode($str);
}
?>
写解密为:
<?php
$flag="fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=";
$str=base64_decode($flag);
$str1="";
echo $str;
$key = md5('ISCC');
$klen=strlen($key);
echo "key";
echo $key;
$x=0;
for($i=0;$i<strlen($str);$i++)
{
if ($x == $klen)
{
$x = 0;
}
$char .= $key[$x];
$x+=1;
}
echo $char;
$data1="";
for ($j=0; $j < strlen($str); $j++)
{
$data1.= chr((ord($str[$j]) + 128-ord($char[$j]))%128);
}
echo $data1;
?>
解密算法中有两点值得注意,一是:
chr((ord($str[$j]) + 128-ord($char[$j]))%128)
根据取余来求原数,值得注意的是128%128=0;
二是:
for($i=0;$i<strlen($str);$i++)
{
if ($x == $klen)
{
$x = 0;
}
$char .= $key[$x];
$x+=1;
}
key的长度和base64解密后的明文长度不一样,将key的值赋给char时,当key的长度不够时就继续从key的第一个字符开始赋值;
即:key=729623334f0aa2784a1599fd374c120d(32位)
而char=729623334f0aa2784a1599fd374c120d729623(38位)
login(sql约束攻击)
首先先了解一下sql约束攻击:https://www.php.cn/blog/detail/3861.html
假如一个char字段,它只允许输入25个(var(25))
正常用户名为admin
攻击使用用户名为admin[多个空格];
那么在select的时候就会变成admin,
因此,这道题可以使用sql约束攻击
注册admin (这里有多个空格),密码随意
然后用此密码去登录,得到flag
BK:江湖魔头
这道题其实挺有意思的:
进去是这个页面,源码没什么好看的,进入江湖吧,进去之后源码有script.js,base64.js,md5.js
script.js:
eval(function(p,a,c,k,e,r){e=function(c){return(c<62?'':e(parseInt(c/62)))+((c=c%62)>35?String.fromCharCode(c+29):c.toString(36))};if('0'.replace(0,e)==0){while(c--)r[e(c)]=k[c];k=[function(e){return r[e]||e}];e=function(){return'[57-9abd-hj-zAB]'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('7 s(t){5 m=t+"=";5 8=9.cookie.n(\';\');o(5 i=0;i<8.d;i++){5 c=8[i].trim();u(c.v(m)==0)p c.substring(m.d,c.d)}p""}7 w(a){5 x=new Base64();5 q=x.decode(a);5 r="";o(i=0;i<q.d;i++){5 b=q[i].charCodeAt();b=b^i;b=b-((i%10)+2);r+=String.fromCharCode(b)}p r}7 ertqwe(){5 y="user";5 a=s(y);a=decodeURIComponent(a);5 z=w(a);5 8=z.n(\';\');5 e="";o(i=0;i<8.d;i++){u(-1<8[i].v("A")){e=8[i+1].n(":")[2]}}e=e.B(\'"\',"").B(\'"\',"");9.write(\'<img id="f-1" g="h/1-1.k">\');j(7(){9.l("f-1").g="h/1-2.k"},1000);j(7(){9.l("f-1").g="h/1-3.k"},2000);j(7(){9.l("f-1").g="h/1-4.k"},3000);j(7(){9.l("f-1").g="h/6.png"},4000);j(7(){alert("你使用如来神掌打败了蒙老魔,但不知道是真身还是假身,提交试一下吧!A{"+md5(e)+"}")},5000)}',[],38,'|||||var||function|ca|document|temp|num||length|key|attack|src|image||setTimeout|jpg|getElementById|name|split|for|return|result|result3|getCookie|cname|if|indexOf|decode_create|base|temp_name|mingwen|flag|replace'.split('|'),0,{}))
eval是执行函数,所以我们将去除eval的代码拿到控制台跑一遍:
得到:
整理一下:
function getCookie(cname)
{
var name=cname+\"=\";//对输入进行控制
var ca=document.cookie.split(';');//以;分片
for(var i=0;i<ca.length;i++)
{
var c=ca[i].trim();
if(c.indexOf(name)==0)
return c.substring(name.length,c.length)
}
return\"\"
}
function decode_create(temp)//解密
{
var base=new Base64();
var result=base.decode(temp);//先进行base64解密
var result3=\"\";
for(i=0;i<result.length;i++)
{
var num=result[i].charCodeAt();
num=num^i;
num=num-((i%10)+2);
result3+=String.fromCharCode(num)}//与i的乘方的值-(i取余10+2)
return result3
}
function ertqwe()
{
var temp_name=\"user\";
var temp=getCookie(temp_name);//获得cookie并赋值给temp
temp=decodeURIComponent(temp);//temp进行url解密
var mingwen=decode_create(temp);//再对temp进行解密
var ca=mingwen.split(';');
var key=\"\";
for(i=0;i<ca.length;i++)
{
if(-1<ca[i].indexOf(\"flag\"))
{
key=ca[ia+1].split(\":\")[2]}}key=key.replace('\"',\"\").replace('\"',\"\");
document.write('<img id=\"attack-1\" src=\"image/1-1.jpg\">');
setTimeout(function()
{
document.getElementById(\"attack-1\").src=\"image/1-2.jpg\"},1000);
setTimeout(
function()
{
document.getElementById(\"attack-1\").src=\"image/1-3.jpg\"},2000);
setTimeout(function(){document.getElementById(\"attack-1\").src=\"image/1-4.jpg\"},3000);
setTimeout(function(){document.getElementById(\"attack-1\").src=\"image/6.png\"},4000);
setTimeout(function(){
alert(\"你使用如来神掌打败了蒙老魔,但不知道是真身还是假身,提交试一下吧!flag{\"+md5(key)+\"}\")},5000)
}
从源码可以看到,有两个解密函数:decode_create(temp)和decodeURIComponent,并且是先进行decodeURIComponent解密再进行decode_create解密
我们去控制台跑一遍:
得到:
"O:5:\"human\":10:{s:8:\"xueliang\";i:565;s:5:\"neili\";i:966;s:5:\"lidao\";i:50;s:6:\"dingli\";i:59;s:7:\"waigong\";i:0;s:7:\"neigong\";i:0;s:7:\"jingyan\";i:0;s:6:\"yelian\";i:0;s:5:\"money\";i:0;s:4:\"flag\";s:1:\"0\";}"
可以看见我们的金钱值为0,所以我们要去伪造cookie,将金钱值该为100000去商店买技能
加密函数如下:
function encode_create(data)
{
var s="";
for(i=0;i<data.length;i++)
{
var num=data.charCodeAt(i);
num=num+((i%10)+2);
num=num^i;
s+=String.fromCharCode(num);
}
var base=new Base64();
s=base.encode(s);
return s;
}
加密出来的cookie直接修改cookie会被清空;
原因是在base64.js里面:
output被注释掉了,所以输出的cookie就变成了空;
因此我们可以通过:
document.cookie="user=UTw7PCxqe3FjcC42OThOwo1rUlBWMG5vfWppc2xtMCNzHhseH2dZYmcUDFhBQ15fBHVFDg8ODndNegd"
来给cookie赋值
之后再商店去买技能,讨伐就可得到flag;