安全矩阵

 找回密码
 立即注册
搜索
楼主: pukr

陈艺琳的学习日记

[复制链接]

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2020-7-20 09:16:58 | 显示全部楼层
https://xz.aliyun.com/t/3357      XXE分析

回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2020-7-20 09:44:04 | 显示全部楼层

程序员含义是,用get传入参数ac,fn extract()会直接生成一个ac变量,如果不为空再将fn传入的文件名的文件的内容作为字符串并且去除两边的空格返回给$f,当ac传入的变量和f传入的文件内容完全相等的时候(注意)这里是完全相等,就会返回flag.
本题已经知道目录下有一个flag.txt文件内容是flags
所以在url里面构造index.php?ac=flags&fn=flag.txt 可以解决
后来发现了另一道题
如下图:

这道题传入的参数是空,全部是空,回去试一下那道题居然不行,很奇怪,看看题目有什么不同,看到了== 和===一个是松散比较一个是严格比较,但是第一道题如果是空和空也会返回真啊,一脸懵逼,后来又发现第一道题对第一个参数的判断条件是empty() 第二个题目是isset(),其实这就是问题所在empty()和isset()究竟有什么区别?
查查资料




自己也写了一个简单的函数测试一下

返回you





返回kong





返回kong





返回kong






总结一下
empty 不仅仅检查变量是不是存在,还会检查变量的值。变量不存在,或者变量存在但是值为’假’,就认为是空。
isset 只会检查变量是不是存在,变量不存在也就是NULL才认为是空,哪怕是“”也会认为存在。

回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2020-7-20 10:09:16 | 显示全部楼层
Iscc 2017 ctf web Simple sqli 详细分析
概述
这道题目的解法并不唯一,但我个人感觉这种方法感觉是最触及核心的,也是见多识广的人应该了解的方法。
开始实践,细细琢磨
首先看到的就是这个验证码,
substr(md5(captcha), 0, 3)=9ef

关键在于他真的很’智能’真的是每次都变,不是闹着玩的
大概的意思是他会把captcha这个数据md5,然后取前3位,和等于号后面的值比较,相等就行了,然后好奇capcha到底怎么获得,看了一下元素,发现他是真的有这个参数的
不管那么多只能写一个脚本爆破md5的值,毕竟不能逆推只能比对,脚本如下:
  1. import hashlib
  2. for i in xrange(100000):
  3.     if hashlib.md5(str(i)).hexdigest().startswith('efd'):
  4.         print i
复制代码
开始注入:
首先我们尝试最一般的 username=admin&password=admin&captcha=8029
报 password error
说明似乎用户名被蒙对了
换一个随便的用户名 username=a&password=admin&captcha=9612
报 username error
说明登录验证是分两步进行的,首先是检验用户名是否正确,如果用户名正确那么验证密码正确与否,密码正确那么登陆成功,密码错误登录失败。但是用户名不正确,就不会检验密码,直接登录失败。
补充1
php常见的登录验证方式就是两种
1.select from foobar where username=’’ and password=’’
查寻语句为真就登陆成功否则登录失败
2.select password from foobar where username=’’(这个username就是我们输
入的值)
如果找不到那么用户名错误
否则
如果查到的密码和输入的password/或者是输入的经过md5加密后的值相等那么登陆成功
否则输出密码错误
我们可以去验证一下是不是属于第二种情况(依据是他是否只select password还是select
这里面会报两个password error 因为union select @@version 也在查询到的数据中,他是对查询到的数据一条一条和密码去匹配,结果发现我们的两条数据和输入的密码都不一样,所以会报两个password error
我们来本机测试一下
两条数据清晰可见,union select 很多时候就是用来填充或者引入别的数据到同一个表里
那么我们只要用union select 去构造一个数据在存放查询得到的password 的那个表中,也就是上图的5.6.17的位置,再输入我们设定好的password,那样依赖他循环遍历对比的特点,就可以绕过密码登陆成功,我们试一下:
咦,怎么回事呢,因为他验证用的是我上面说的另一种方法,把我们输入的值得md5的结果和数据库中的对比,也就是说数据库中存储的全都是md5的值,因此我们修改一下我们的payload
完全符合我们的猜想,第一个用户名admin的真实密码无法和我们构造的假密码去匹配,所以第一个是错的,然后第二个恰恰使我们构造的假密码,绕过成功!!
补充2
登录验证类似于这样
  1. <?php
  2. $servername = "localhost";
  3. $username = "php";
  4. $password = "##############";
  5. $database = "php";

  6. if($_POST[user] && $_POST[pass]) {
  7.     $conn = mysqli_connect($servername, $username, $password, $database);
  8.     if ($conn->connect_error) {
  9.         die("Connection failed: " . mysqli_error($conn));
  10. }
  11. $user = $_POST[user];
  12. $pass = md5($_POST[pass]);

  13. $sql = "select pw from php where user='$user'";
  14. $query = mysqli_query($conn,$sql);
  15. if (!$query) {
  16.     printf("Error: %s\n", mysqli_error($conn));
  17.     exit();
  18. }
  19. $row = mysqli_fetch_array($query);
  20. //echo $row["pw"];
  21. if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) {
  22.     echo "<p>Logged in! Key: ################################ </p>";
  23. }
  24. else {
  25.     echo("<p>Log in failure!</p>");

  26.   }
  27. }

  28. ?>
复制代码
总结
这种类型的绕过应该算是比较常见的绕过方式的一种,平时应该多积累,这样才能有所突破,运用起来也会游刃有余。


回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2020-7-22 14:30:06 | 显示全部楼层
https://blog.csdn.net/whatday/article/details/90674449#comments      python线程池及其原理和使用
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2020-7-24 10:09:33 | 显示全部楼层
NSE脚本编写

NES是nmap的脚本,在nmap/scripts文件夹下,语言为lua。这篇只记录我如何初识nse scripts,目前程序基础没跟上,后续还会再次学习,深入编写。



点开一个看看结构:
  1. local brute = require "brute"
  2. local creds = require "creds"
  3. local shortport = require "shortport"
  4. local stdnse = require "stdnse"
  5. local ftp = require "ftp"

  6. description = [[
  7. Performs brute force password auditing against FTP servers.

  8. Based on old ftp-brute.nse script by Diman Todorov, Vlatko Kosturjak and Ron Bowes.
  9. ]]

  10. ---
  11. -- @see ftp-anon.nse
  12. --
  13. -- @usage
  14. -- nmap --script ftp-brute -p 21 <host>
  15. --
  16. -- This script uses brute library to perform password
  17. -- guessing.
  18. --
  19. -- @output
  20. -- PORT   STATE SERVICE
  21. -- 21/tcp open  ftp
  22. -- | ftp-brute:
  23. -- |   Accounts
  24. -- |     root:root - Valid credentials
  25. -- |   Statistics
  26. -- |_    Performed 510 guesses in 610 seconds, average tps: 0
  27. --
  28. -- @args ftp-brute.timeout the amount of time to wait for a response on the socket.
  29. --       Lowering this value may result in a higher throughput for servers
  30. --       having a delayed response on incorrect login attempts. (default: 5s)

  31. -- 06.08.16 - Modified by Sergey Khegay to support new brute.lua adaptability mechanism.
  32. author = "Aleksandar Nikolic"
  33. license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
  34. categories = {"intrusive", "brute"}

  35. portrule = shortport.port_or_service(21, "ftp")

  36. local arg_timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout"))
  37. arg_timeout = (arg_timeout or 5) * 1000

  38. Driver = {

  39.   new = function(self, host, port)
  40.     local o = {}
  41.     setmetatable(o, self)
  42.     self.__index = self
  43.     o.host = host
  44.     o.port = port
  45.     return o
  46.   end,

  47.   connect = function( self )
  48.     self.socket = brute.new_socket()
  49.     -- discard buffer, we'll create a new one over the BruteSocket later
  50.     local realsocket, code, message, buffer = ftp.connect(self.host, self.port, {request_timeout=arg_timeout})
  51.     if not realsocket then
  52.       return false, brute.Error:new( "Couldn't connect to host: " .. (code or message) )
  53.     end
  54.     self.socket.socket = realsocket
  55.     return true
  56.   end,

  57.   login = function (self, user, pass)
  58.     local buffer = stdnse.make_buffer(self.socket, "\r?\n")
  59.     local status, code, message = ftp.auth(self.socket, buffer, user, pass)

  60.     if not status then
  61.       if not code then
  62.         return false, brute.Error:new("socket error during login: " .. message)
  63.       elseif code == 530 then
  64.         return false, brute.Error:new( "Incorrect password" )
  65.       elseif code == 421 then
  66.         local err = brute.Error:new("Too many connections")
  67.         err:setReduce(true)
  68.         return false, err
  69.       else
  70.         stdnse.debug1("WARNING: Unhandled response: %d %s", code, message)
  71.         local err = brute.Error:new("Unhandled response")
  72.         err:setRetry(true)
  73.         return false, err
  74.       end
  75.     end

  76.     stdnse.debug1("Successful login: %s/%s", user, pass)
  77.     return true, creds.Account:new( user, pass, creds.State.VALID)
  78.   end,

  79.   disconnect = function( self )
  80.     ftp.close(self.socket)
  81.     return true
  82.   end
  83. }

  84. action = function( host, port )
  85.   local status, result
  86.   local engine = brute.Engine:new(Driver, host, port)
  87.   engine.options.script_name = SCRIPT_NAME

  88.   status, result = engine:start()
  89.   return result
  90. end
复制代码


接下来去看一看文档,指路:文档指路

脚本分类
nmap脚本大概分为下列类别
NSE scripts define a list of categories they belong to. Currently defined categories are auth, broadcast, brute, default. discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version, and vuln. Category names are not case sensitive. The following list describes each category.
NSE脚本定义了它们所属的类别的列表。当前定义的类别 auth, broadcast, brute, default。 discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version,和 vuln。类别名称不区分大小写。以下列表描述了每个类别。

Auth:负责处理鉴权证书(绕过鉴权)
Broadcast:在局域网内探测更多服务的开启情况,如DHCP/DNS/SQLServer等。
Brute:针对常见的应用提供暴力破解方式,如HTTP/SMTP等。
Default:使用-sC或者-A选项扫描时默认的脚本,提供基本的脚本扫描能力。
Discovery:对网络进行更多信息的搜集,如SMB枚举,SNMP查询等。
DOS:用于拒绝服务攻击。
Exploit:利用已知的漏洞入侵系统。
External:利用第三方的数据库或者资源,如进行whois解析。
Fuzzer:模糊测试脚本,发送异常的包到目标机,探测潜在漏洞。
Intrusive:入侵性脚本,此类脚本可能引起对方IDS/IPS的记录或者屏蔽。
Malware:探测目标机是否感染了病毒、开启后门等信息。
Safe:与Intrusive相反,属于安全性脚本。
Version:负责增强服务与版本扫描功能。
Vuln:负责检测目标机是否有常见漏洞。
运行规则
脚本运行在nmap扫描中的哪一阶段
Prerule scripts:包含一个prerule()函数,且prerule()函数不接受参数。
在扫描开始前,prerule()函数执行一次,并且整个流程只执行一次。
These scripts run before any of Nmap’s scan phases, so Nmap has not collected any information about its targets yet. They can be useful for tasks which don’t depend on specific scan targets, such as performing network broadcast requests to query DHCP and DNS SD servers. Some of these scripts can generate new targets for Nmap to scan (only if you specify the newtargets NSE argument). For example, dns-zone-transfer can obtain a list of IPs in a domain using a zone transfer request and then automatically add them to Nmap’s scan target list.
它们对于不依赖于特定扫描目标的任务很有用,例如执行网络广播请求以查询DHCP和DNS SD服务器。其中一些脚本可以为Nmap生成新目标进行扫描(仅当您指定newtargets NSE参数时)。例如,dns-zone-transfer 可以使用区域传输请求获取域中IP的列表,然后将其自动添加到Nmap的扫描目标列表中。

Host scripts:包含一个hostrule(host)函数。扫描完一个host目标执行一次,N个host执行N次。
Scripts in this phase run during Nmap’s normal scanning process after Nmap has performed host discovery, port scanning, version detection, and OS detection against the target host. This type of script is invoked once against each target host which matches its hostrule function. Examples are whois-ip, which looks up ownership information for a target IP, and path-mtu which tries to determine the maximum IP packet size which can reach the target without requiring fragmentation.
在此阶段的脚本在Nmap对目标主机执行了主机发现,端口扫描,版本检测和OS检测之后,在Nmap的正常扫描过程中运行。对与它的hostrule功能匹配的每个目标主机调用一次这种脚本。例子有whois-ip,它查找目标IP的所有权信息,而path-mtu 试图确定无需分段即可达到目标的最大IP数据包大小。

Service scripts:包含一个portrule(host, port)函数,扫描完一个主机的一个端口后执行一次,N个端口执行N次。
These scripts run against specific services listening on a target host. For example, Nmap includes more than 15 http service scripts to run against web servers. If a host has web servers running on multiple ports, those scripts may run multiple times (one for each port). These are the most commong Nmap script type, and they are distinguished by containing a portrule function for deciding which detected services a script should run against.
这些脚本针对在目标主机上侦听的特定服务运行。例如,Nmap包含超过15种针对Web服务器运行的http服务脚本。如果主机的Web服务器在多个端口上运行,则这些脚本可能会运行多次(每个端口一个)。这些是最常见的Nmap脚本类型,它们的区别在于包含portrule用于确定脚本应针对哪些检测到的服务运行的函数。

Postrule:包含一个postrule()函数,且postrule()函数不接受参数。全部扫描完之后运行一次,整个流程只执行一次。
These scripts run after Nmap has scanned all of its targets. They can be useful for formatting and presenting Nmap output. For example, ssh-hostkey is best known for its service (portrule) script which connects to SSH servers, discovers their public keys, and prints them. But it also includes a postrule which checks for duplicate keys amongst all of the hosts scanned, then prints any that are found. Another potential use for a postrule script is printing a reverse-index of the Nmap output—showing which hosts run a particular service rather than just listing the services on each host.
这些脚本在Nmap扫描完所有目标之后运行。它们对于格式化和显示Nmap输出很有用。例如,ssh- hostkey脚本连接到SSH服务器,发现其公共密钥并输出它们。但是它还包括一个规则,该规则检查所有扫描的主机中是否有重复的密钥,然后打印找到的所有密钥。postrule的另一个潜在用途是Nmap输出的反向索引-显示哪些主机在运行特定服务,而不仅仅是在每个主机上列出服务。

脚本格式
description:描述了脚本要测试的内容以及用户应注意的任何重要说明。根据脚本的复杂程度,描述的长度可能从几句话到几段不等。
categories:定义了脚本所属的一个或多个类别,见上面脚本分类。类别不区分大小写,可以按任何顺序指定,以数组形式列出。
author:作者信息。
license:许可信息。一般格式为:
license = "Same as Nmap--See https://nmap.org/book/man-legal.html
license = "Simplified (2-clause) BSD license--See https://nmap.org/svn/docs/licenses/BSD-simplified
dependencies:元素是脚本名的数组,内部元素在这个脚本之前执行。如果省略该字段,则NSE将假定脚本没有依赖性。
rules:见上面的规则。
action:规则执行时的指令。Lua函数,它接受与规则相同的参数。

Environment Variables
示例
local shortport = require "shortport"
description = [[a http server detected test demo]]

author = "reborn"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
portrule = function(host,port)
    return port.protocol == "tcp" and port.number == 80 and port.service == "http" and port.state == "open"
end

action = function(host,port)
    return "this is a web server"
end

放到/usr/share/nmap/scripts/nselib下,更新一下脚本库。
  1. nmap --script-updatedb
复制代码
执行:
  1. nmap --script sample.nse  192.168.10.179
复制代码


类库

脚本通过包含类库,起到python类似import的作用。
试写一个库:

  1. function PortTest(port)
  2.     return string.format("Port '%s' is open",port)
  3. end
复制代码
更新执行:


defcon2018上开发小哥写的探测动态ip摄像头的脚本:



  1. description = [[
  2. finds a webcam.
  3. ]]

  4. categories = {"safe", "discovery"}

  5. require("http")

  6. function portrule(host,port)
  7.     return port.number == 80
  8. end

  9. function action(host,port)
  10.         local response
  11.         
  12.         response = http.get(host,port,"/cam.jpg")
  13.     if response.status and response.status ~= 404 and response.header["server"] and string.match(response.header["server"],"^thttpd") then
  14.         return "webcam founnd."
  15.     end
  16. end
复制代码
  1. nmap -n -Pn -p 80 --open --script http-webcam 66.7.171.- -oN webcam.nmap -d
复制代码



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2020-7-25 10:20:02 | 显示全部楼层
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2020-7-25 11:11:01 | 显示全部楼层
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2020-7-28 10:45:10 | 显示全部楼层
选择排序算法sql server 存储过程1. 输入字符串,插入数据
  1. IF OBJECT_ID('f_splite') IS NOT NULL
  2.         DROP PROC f_splite
  3. GO
  4. CREATE PROC f_splite
  5.         @s VARCHAR(100),
  6.         @split VARCHAR(10)
  7. AS
  8.         BEGIN
  9.                 DECLARE @splitlen INT
  10.                 DECLARE @i INT = 1
  11.                 SET @splitlen = LEN(@split + 'a') - 2
  12.                 WHILE CHARINDEX(@split, @s) > 0
  13.                         BEGIN
  14.                                 INSERT INTO dbo.num_order
  15.                                 VALUES ( @i,LEFT(@s, CHARINDEX(@split, @s) - 1) )
  16.                                 SET @s = STUFF(@s, 1, CHARINDEX(@split, @s) + @splitlen, '')
  17.                                         SET @i = @i +1
  18.                         END
  19.                 --INSERT into dbo.num_order
  20.                 --VALUES (@i,@s)
  21.         END
  22. GO
复制代码
2. 执行排序
  1. /*选择排序法*/
  2. IF OBJECT_ID('paixu') IS NOT NULL
  3.         DROP PROC paixu
  4. GO
  5. CREATE PROC paixu
  6.          @id int=1
  7. AS
  8.         BEGIN
  9.                 DECLARE @len int
  10.                 SET @len = (select count(1) from  dbo.num_order)
  11.                 DECLARE @i int = 1 --外层循环体
  12.                 DECLARE @min_index int --最小值索引
  13.                 DECLARE @current_num int --当前的最小值
  14.                 DECLARE @next_num int  --与当前值比较的值

  15.                 WHILE(@i<@len-1)
  16.                         BEGIN
  17.                                 --print '1i的值是'+convert(varchar,@i)
  18.                                 SET @min_index = @i
  19.                                 DECLARE @j int = @i+1
  20.                                 --print '1j的值是'+convert(varchar,@j)
  21.                                 WHILE(@j<=@len)
  22.                                         BEGIN
  23.                                                 SET @current_num = ( SELECT num FROM dbo.num_order WHERE id=@min_index)
  24.                                                 --print '@current_num的值是'+convert(varchar,@current_num)
  25.                                                 SET @next_num = (SELECT num FROM dbo.num_order WHERE id=@j)
  26.                                                 --print '@next_num的值是'+convert(varchar,@next_num)
  27.                                                 if(@current_num>@next_num)
  28.                                                         BEGIN
  29.                                                                 SET @min_index = @j
  30.                                                         END
  31.                                                 set @j+=1
  32.                                                 --print '2j的值是'+convert(varchar,@j)
  33.                                         END
  34.                                         ;with x as (select id,num from num_order where id=@i),y as (select id,num from num_order where id=@min_index) update num_order set num=z.num from (select x.num,y.id from x,y union all select y.num,x.id from x,y)z where num_order.id=z.id
  35.                                         --select * from dbo.num_order
  36.                                         set @i+=1
  37.                                         --print '2i的值是'+convert(varchar,@i)
  38.                         END
  39.         END
复制代码
3.运行
  1. delete from num_order
  2. DECLARE @str NVARCHAR(200)='5,4,3,2,1,'
  3. exec f_splite @s = @str,@split=','
  4. select * from num_order
  5. exec paixu
  6. select * from num_order
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2020-7-31 08:59:42 | 显示全部楼层




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2020-9-4 11:04:31 | 显示全部楼层
本帖最后由 pukr 于 2020-9-4 11:06 编辑

今日web题学到了一种php构造字符串的方法:
  1. <?php
  2. $f = $_POST['flag'];
  3. $f = str_replace(array('`', '美元符号', '*', '#', ':', '\\', '"', "'", '(', ')', '.', '>'), '', $f);
  4. if((strlen($f) > 13) || (false !== stripos($f, 'return'))){
  5.         die('wowwwwwwwwwwwwwwwwwwwwwwwww');
  6. }
  7. try{
  8.          eval("\$spaceone = $f");
  9. }
  10. catch (Exception $e){
  11.         return false;
  12. }
  13. if ($spaceone === 'flag'){
  14.     echo file_get_contents("helloctf.php");
  15. }
  16. ?>
复制代码

大概意思就是,flag页面,接收一个flag参数,先进行str_replace,将一些字符替换为空,长度不能大于13。然后测试传进来的flag参数的值是否为flag。

但是eval函数做了异常处理,直接提交flag=flag会产生异常,而提交flag='flag'或flag="flag",引号会被过滤,用PHP字符串的表示方法,叫做Heredoc。

百度到的:
php定界符

不包含引号,于是构造flag参数如图,因为包含换行,所以需要url编码





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-3-29 18:11 , Processed in 0.046804 second(s), 17 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表