目標(biāo)機(jī)IP:10.10.10.87
信息搜集
照常進(jìn)行nmap掃描
nmap -sC -sV -A -oN 10.10.10.87.txt 10.10.10.87
發(fā)現(xiàn)80端口開放喳瓣,掃描目錄無果,進(jìn)去探測(cè)一番
Get user.txt
枚舉
點(diǎn)進(jìn)網(wǎng)站發(fā)現(xiàn)沒什么東西藻治,順手點(diǎn)開源碼發(fā)現(xiàn)list.js
有一些值得注意的內(nèi)容
function writeList(listNum, data){
var xhttp = new XMLHttpRequest();
xhttp.open("POST","fileWrite.php",false);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send('listnum=' + listNum + '&data=' + data);
if (xhttp.readyState === 4 && xhttp.status === 200) {
return xhttp.responseText;
}else{
}
}
function deleteList(listNum){
var xhttp = new XMLHttpRequest();
xhttp.open("POST","fileDelete.php",false);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send('listnum=' + listNum);
if (xhttp.readyState === 4 && xhttp.status === 200) {
listLists();
return xhttp.responseText;
}else{
}
}
function readDir(path){
var xhttp = new XMLHttpRequest();
xhttp.open("POST","dirRead.php",false);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send('path=' + path);
if (xhttp.readyState === 4 && xhttp.status === 200) {
return xhttp.responseText;
}else{
}
}
function readFile(file){
var xhttp = new XMLHttpRequest();
xhttp.open("POST","fileRead.php",false);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send('file=' + file);
if (xhttp.readyState === 4 && xhttp.status === 200) {
return xhttp.responseText;
}else{
}
}
這四個(gè)函數(shù)分別利用XHR訪問四個(gè)不同的php文件乔夯,而且貌似進(jìn)行一定程度上敏感的讀寫操作蒂培,十分值得注意搀缠。
那么現(xiàn)在就構(gòu)造出了一種攻擊思路:
將反彈webshell寫入一個(gè)php文件->對(duì)文件進(jìn)行訪問獲取shell
但是接下來進(jìn)行枚舉過程中缰泡,發(fā)現(xiàn)了一些問題:
首先讀所有的文件烧颖,把代碼讀下來:
fileRead.php
<?php
if($_SERVER['REQUEST_METHOD'] === "POST"){
$fileContent['file'] = false;
header('Content-Type: application/json');
if(isset($_POST['file'])){
header('Content-Type: application/json');
$_POST['file'] = str_replace( array("../", "..\""), "", $_POST['file']); ../ .."
if(strpos($_POST['file'], "user.txt") === false){
$file = fopen("/var/www/html/" . $_POST['file'], "r");
$fileContent['file'] = fread($file,filesize($_POST['file']));
fclose();
}
}
echo json_encode($fileContent);
}
fileWrite.php
<?php
if($_SERVER['REQUEST_METHOD'] === "POST"){
header('Content-Type: application/json');
$condition['result'] = false;
if(isset($_POST['listnum'])){
if(is_numeric($_POST['listnum'])){
$myFile = "/var/www/html/.list/list" . $_POST['listnum'];
$handle = fopen($myFile, 'w');
$data = $_POST['data'];
fwrite($handle, $data);
fclose();
$condition['result'] = true;
}
}
echo json_encode($condition);
}
fileDelete.php
<?php
if($_SERVER['REQUEST_METHOD'] === "POST"){
if(isset($_POST['listnum'])){
header('Content-Type: application/json');
if(is_numeric($_POST['listnum'])){
$myFile = "/var/www/html/.list/list" . $_POST['listnum'];
unlink($myFile);
header('Content-Type: application/json');
echo '[true]';
}else{
header('Content-Type: application/json');
echo '[false]';
}
}else{
header('Content-Type: application/json');
echo '[false]';
}
}
dirRead.php
<?php
if($_SERVER['REQUEST_METHOD'] === "POST"){
if(isset($_POST['path'])){
header('Content-type: application/json');
$_POST['path'] = str_replace( array("../", "..\""), "", $_POST['path']);
echo json_encode(scandir("/var/www/html/" . $_POST['path']));
}else{
header('Content-type: application/json');
echo '[false]';
}
}
發(fā)現(xiàn)文件寫入過程中對(duì)文件名有is_numeric
限制弱左,文件讀取和目錄讀取過程有preg_replace
進(jìn)行目錄限制。
因此沒辦法直接寫入php文件進(jìn)去炕淮,思路中斷拆火。
換個(gè)思路
preg_replace
是可以繞過的,利用重寫的方式:
..././ => ../
對(duì)各種系統(tǒng)里的文件進(jìn)行讀取后涂圆,在用戶目錄下發(fā)現(xiàn)了令人感興趣的東西:
ssh的私鑰
最終通過ssh私鑰登錄成功獲取到user.txt
Get root.txt
更換賬戶
從我的角度來講這點(diǎn)還是挺難的
最開始還是用LinEnum來進(jìn)行枚舉们镜,然而沒有發(fā)現(xiàn)任何有用的線索
一時(shí)之間卡在這里不知道該怎么處理才好
后面突然想到之前拿到的monitor私鑰在nobody賬戶,那么用nobody直接ssh連接monitor不知是否可行
嘗試后發(fā)現(xiàn)可行:
發(fā)現(xiàn)shell受限乘综,利用ssh強(qiáng)制轉(zhuǎn)換shell
ssh -i .ssh/.monitor monitor@10.10.10.87 -t sh
app-dev目錄下有個(gè)logmonitor應(yīng)用憎账,查看logmonitor.c可以看到能夠利用logMonitor監(jiān)控各種日志
/*******************************************
*
*This is an application to print out common log files
*
********************************************/
#include "logMonitor.h"
void printUsage() {
printf("Usage: %s [-aAbdDfhklmsw] [--help]\n", PROGRAMNAME);
}
int main(int argc, char** argv){
int opt = 0;
char filename[26];
{
//temporary variables for parsing
static struct option long_options[] ={
/* These options don’t set a flag.
We distinguish them by their indices. */
{"auth", no_argument, 0, 'a'},
{"alternatives", no_argument, 0, 'A'},
{"btmp", no_argument, 0, 'b'},
{"dpkg", no_argument, 0, 'd'},
{"daemon", no_argument, 0, 'D'},
{"faillog", no_argument, 0, 'f'},
{"help", no_argument, 0, 'h'},
{"kern", no_argument, 0, 'k'},
{"lastlog", no_argument, 0, 'l'},
{"messages", no_argument, 0, 'm'},
{"syslog", no_argument, 0, 's'},
{"wtmp", no_argument, 0, 'w'},
{0,0,0,0}
};
//parse the command line arguments
int option_index = 0;
while((opt = getopt_long (argc, argv, "aAbdDfhklmsw", long_options, &option_index)) != -1 ){
switch (opt) {
case 'a' :
strncpy(filename, "/var/log/auth.log", sizeof(filename));
printFile(filename);
break;
case 'A' :
strncpy(filename, "/var/log/alternatives.log", sizeof(filename));
printFile(filename);
break;
case 'b' :
strncpy(filename, "/var/log/btmp",sizeof(filename));
printFile(filename);
break;
case 'd' :
strncpy(filename, "/var/log/daemon.log",sizeof(filename));
printFile(filename);
break;
case 'D' :
strncpy(filename, "/var/log/dpkg.log",sizeof(filename));
printFile(filename);
break;
case 'f' :
strncpy(filename, "/var/log/faillog",sizeof(filename));
printFile(filename);
break;
case 'h' :
printUsage();
exit(1);
case 'k' :
strncpy(filename, "/var/log/kern.log",sizeof(filename));
printFile(filename);
break;
case 'l' :
strncpy(filename, "/var/log/lastlog",sizeof(filename));
printFile(filename);
break;
case 'm' :
strncpy(filename, "/var/log/messages",sizeof(filename));
printFile(filename);
break;
case 's' :
strncpy(filename, "/var/log/syslog",sizeof(filename));
printFile(filename);
break;
case 'w' :
strncpy(filename, "/var/log/wtmp",sizeof(filename));
printFile(filename);
break;
default:
printUsage();
exit(EXIT_FAILURE);
}
}
}
return 1;
}
但是實(shí)際運(yùn)行,并沒有足夠權(quán)限卡辰,這一點(diǎn)十分奇怪胞皱。
進(jìn)入目錄下v0.1版本,發(fā)現(xiàn)0.1版本有權(quán)限九妈,上網(wǎng)搜索一下是linux capabilities的問題反砌。
用戶sh有tac權(quán)限,直接讀取 root.txt
完事