一次php异或加密破解

542 阅读2分钟

一次php异或加密破解

首先拿到了主页面在这里插入图片描述 查看源码后发现了source.txt,这个页面给出了php的代码,简单查看后是php异或加密和解密代码,我对代码注释了一下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接着说说异或加密和解密
在这里插入图片描述

这里说几个坑的位置,首先是$key会每几秒变一次,所以不能手工获取admin的加密值然后带入代码获取flag,这个可以通过bp发包看出来。
在这里插入图片描述在这里插入图片描述

这一点是遇到最大的坑,在代码
在这里插入图片描述

这一段代码里面能获取到admin的加密值,还有一段代码也可以获取到admin的加密值
在这里插入图片描述

这两段代码都可以获取到admin的加密值,这么说在获取到第一段的key之后要使过去flag的代码执行就得在获取一个key,这个key值和session是相关的。从以下代码就可以看出
在这里插入图片描述

为了保证获取的key不变就得使得第二段代码成立并获取system的加密值

现在就开始构造脚本来完成操作,由于算计获取的key值有可能是奇怪的字符所以脚本多来几次就出来了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
成功获取flag
在这里插入图片描述
附件:

Python代码

import requests

from lxml import etree

from urllib.parse import quote,unquote

import base64

data = {

"username":"admin",

"password":"admin",

}

cookies =
"PHPSESSID=n0r1l2qb79o36a8eocjfeampr4;"\#cookie中不带user字段,使得(empty(\$user)这个weitrue从而向客户端返回admin的加密值

header = {

"Origin": "http://159.75.30.182:8001",

"Upgrade-Insecure-Requests": "1",

"cookie":cookies,

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36",

"Accept":
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,\*/\*;q=0.8,application/signed-exchange;v=b3;q=0.9",

}

re = requests.post('http://159.75.30.182:8001/\#',data=data,headers=header)

cookie = re.cookies\#获取cookie值

cookie = unquote(cookie['user'])\#url解码cookie里面的user字段

cookie =
base64.b64decode(cookie).decode("utf-8")\#base64解码cookie里面的user字段

print(cookie)

lis = []

for i in cookie:\#把user的每个字符都存入列表好进行异或运算

lis.append(i)

print(lis)

a1 = chr(ord(lis[0]) \^
ord("a"))\#这就是把获取的user的每个字符都和admin进行异或运算从而得到key,为啥要和admin运算因为从php代码来看上面获取到的就是admin的加密值

a2 = chr(ord(lis[1]) \^ ord("d"))

a3 = chr(ord(lis[2]) \^ ord("m"))

a4 = chr(ord(lis[3]) \^ ord("i"))

a5 = chr(ord(lis[4]) \^ ord("n"))

print(a1+a2+a3+a4+a5)\#组合key

b1 = chr(ord(a1) \^
ord("s"))\#这边是把key和system进行异或运算获取system的加密值,php代码里面要获取flag就是要计算得出system的加密值

b2 = chr(ord(a2) \^ ord("y"))

b3 = chr(ord(a3) \^ ord("s"))

b4 = chr(ord(a4) \^ ord("t"))

b5 = chr(ord(a5) \^ ord("e"))

b6 = chr(ord(a1) \^ ord("m"))

strs = b1 + b2 + b3 + b4 + b5 + b6\#组合system的加密值

print(strs)

strs = strs.encode("utf-8")\#转码

strs = base64.b64encode(strs).decode('utf-8')\#base64加密

print(strs)

proxies = {

"http": "http://127.0.0.1:8080",

}

dataa = {

"username":"a",

"password":"ab",

}

cookies = "PHPSESSID=n0r1l2qb79o36a8eocjfeampr4;" + "user=" + str(strs) +
"%3D"\#组合cookie

header = {

"Origin": "http://159.75.30.182:8001",

"Upgrade-Insecure-Requests": "1",

"cookie":cookies,

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36",

"Accept":
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,\*/\*;q=0.8,application/signed-exchange;v=b3;q=0.9",

}

\#re =
requests.post('http://159.75.30.182:8001',data=dataa,headers=header,proxies=proxies)

re = requests.post('http://159.75.30.182:8001',data=dataa,headers=header)

print(re.text)\#打印获取的网页内容获取flag

php代码

\<?php

session\_start();

ini\_set('display\_errors', 0);

require\_once('config.php');

if(!isset(\$\_SESSION['time']) \|\| (time() - \$\_SESSION['time'])\>2){

\$\_SESSION['time'] = time();

\$\_SESSION['key'] = md5(rand\_str());//随机去一个md5的加密字符串

}

\$key=\$\_SESSION['key'];//把加密字符串的值赋值给key,这个key就是我们要逆推的值

function encrypt(\$plain)//\$plain是传入的参数

{

global \$key;

\$r='';

for(\$i=0;\$i\<strlen(\$plain);\$i++){//获取\$plain长度

\$k = \$i %
strlen(\$key);//获取key长度\$key,经过我的验证由于i是从0开始而0-5之间与任意数字取余都是0-5

\$r.= chr(ord(\$key[\$k]) \^
ord(\$plain[\$i]));//这是\$key的每一个字符和\$plain的每一个字符进行异或运算,如果字符长度不相等就循环

}

return base64\_encode(\$r);//base64加密\$r

}

function decrypt(\$cipher)

{

global \$key;

\$cipher = base64\_decode(\$cipher);//base64解密\$cipher

\$r = '';

for(\$i=0;\$i\<strlen(\$cipher);\$i++){//获取\$cipher长度

\$k = \$i %
strlen(\$key);//获取key长度\$key,经过我的验证由于i是从0开始而0-5之间与任意数字取余都是0-5

\$r .=
chr(ord(\$key[\$k])\^ord(\$cipher[\$i]));//这是\$key的每一个字符和\$cipher的每一个字符进行异或运算,如果字符长度不相等就循环

}

return \$r;

}

if(isset(\$\_POST['login']))//判断POST传入的login是否为空

{

\$username = \$\_POST['username'];

\$password = \$\_POST['password'];

if(\$username === \$\_username and \$password === \$\_password)

{

setcookie("user",encrypt('admin'));//登录成功后给客户端传回一个cookie:user=admin加密后的值

echo "\<p\>Welcome admin\</p\>";

echo "\<p\>You are not system,I can not give you flag\</p\>";

}else{

echo '\<p\>username or password is error\</p\>';

}

}

else

{

\$user=\$\_COOKIE['user'];//接受cookie里面user的值

\$phpsession = \$\_COOKIE['PHPSESSID'];

if(empty(\$user))//判断user是否为空,为空的话就给客户端传回一个cookie:user=admin加密后的值

{

setcookie("user",encrypt('admin'));

exit(0);

}

if(empty(\$phpsession)){

die('Need PHPSESSID');

}

if(decrypt(\$user)==='system'){//客户端发回的cookie里面user的值解密后全等于system就返回flag

echo "\<p\>welcome system, the flag is ".\$flag."\</p\>";

}

else{

echo '\<p\>Not authorized ! Please login\</p\>';

}

}

?\>

\<?php

\$string="asd";

\$key="1234567890";

\$result1=\$string\^\$key;

\$result2=\$result1\^\$key;

echo \$result1\^\$string;//获取\$key值

?\>
stem就返回flag

echo "\<p\>welcome system, the flag is ".\$flag."\</p\>";

}

else{

echo '\<p\>Not authorized ! Please login\</p\>';

}

}

?\>

\<?php

\$string="asd";

\$key="1234567890";

\$result1=\$string\^\$key;

\$result2=\$result1\^\$key;

echo \$result1\^\$string;//获取\$key值

?\>