反编译C#代码
首先这里写了一小段C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Cs
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("this is relaysec");
Console.WriteLine("Relaysec Security");
}
}
}
使用csc.exe编译为dotnet程序。
csc.exe Program.cs
将dotnet程序拉入dnspy中,然后选择ProgramNamepache即可查看源码。
我们可以尝试更改代码,选择编译类。
我们将这输出更改为Hello World,然后点击编译即可。
最后选择文件->全部保存。
然后我们尝试运行,已经变成了Hello World。
反编译Java代码
这里我们会生成jd-JUI工具来进行反编译Java jar包文件。
首先创建一个测试的java文件.
xxxxxxxxxx import java.util.*;public class HelloWorld { public static void main(String[] args) { }}
首先使用javac进行编译,这里我使用的是jdk1.8。
javac source.java
创建一个清单文件,清单文件通常以MF后缀。
最终打包成Jar包文件:
jar cmvf META-INF/MANIFEST.MF test.jar Source.class
这里需要使用JD-GUI进行反编译JAR包。
下载地址:
https://java-decompiler.github.io/
将jar文件拖进去即可。
与dnspy中是类似的,我们也可以去搜索任意方法以及变量等等。
代码审计之前的准备
在代码审计之前我们需要准备,因为现今的Web应用程序已经加入了大量的框架进行管理,比如SpringBoot,Shiro,Spring Security等等,所以我们需要花一些时间用来浏览网页,看看它的请求路由,配合Burp Suite来进行分析。
在Web应用程序正常试用期间生成的HTTP请求和响应,这让我们可以更好的了解路径以及请求方式,方便接下来我们的代码审计。
一个应用程序的攻击面取决于很多因素,比如一个Web应用程序可能比其他有更多的XSS漏洞,编程语言和框架也影响应用程序中可能存在的漏洞,比如说在Java中如果SQL语句使用预编译,那么就不会造成SQL注入攻击。
源码分析的方式
在我们分析Web应用程序源码的时候,我们需要注意数据从哪里传递进去的,是通过GET方式还是通过POST方式,如何在URL中进行体现出来,接收到的数据是否有过滤等等。
比如说我们现在有一个登录框,登录框肯定是有账号和密码的,当我们前端填写账号和密码之后请求发送到后端,后端接收到数据进行处理,需要注意的是后端是如何接收的数据。
例1-登录框
当我们遇到一个登录框之后我们应该去如何审计,首先我们肯定是需要查看JS中是否包含客户端校验的逻辑,或者密码泄露等问题。
这种问题的话我们可以直接使用IDEA全局搜索功能,直接搜索PASSWORD即可。
并且我们可以过滤.Java文件。
如果我们想看这个类或者这个方法在哪里调用了我们可以选中方法名或者类名,选择Find Usages。
常见的HTTP路由模式
Apache
比如说我们在Ubuntu上部署了一个web应用程序,HTTP服务器使用了/var/www/html作为默认的web目录,那么当我们去访问www.xxx.com/的时候其实就是访问到了/var/www/html目录。
那么如果我们想去访问relaysec.html这个资源的话,如果html目录中不存在这个资源的话,那么就会报404错误。
Servlet映射
现在很多的Javaweb应用程序都是通过web.xml进行映射。
例如如下xml配置:
这里的意思就是当我们去访问/servletContextDemo URL的时候,那么就会访问到com.itheima.Servlet.ServletContextDemo类中,由这个类的doGet或者doPost方法进行处理。
<servlet>
<servlet-name>servletContextDemo</servlet-name>
<servlet-class>com.itheima.Servlet.ServletContextDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletContextDemo</servlet-name>
<url-pattern>/servletContextDemo</url-pattern>
</servlet-mapping>
但是如今原生的项目也很少的,除了维护一些老的项目可能会使用到,现在使用最多的还是通过SprintBoot注解进行映射。
Express JS映射
眨眼一看有点像AJAX请求,其实都是大差不差,这里请求的login,也就是www.xxx.com/login。
xxxxxxxxxx var express = require('express'); var router = express.Router();...router.get('/login', function(req, res, next) { res.render('login', { title: 'Login' });});
发送到后端之后可能会由SpringBoot进行处理。
SpringBoot/SpringMvc映射
SpringBoot和SpringMvc映射是非常简单的。
如下代码:
"/admin/users"}) ({
public String getUsersPage(HttpServletRequest req, Model model,
HttpServletResponse res) {
...
}
这里代码的意思就是如果通过GET请求路径为/admin/users 那么就会走到这个方法中,由这个方法进行处理这个请求。
如上就是基本的路径请求方式。
分析源码方式方法
没有工具可以代替人工进行代码审计,因为工具通常会遗漏掉很多细节,但是为什么我们还需要工具呢?这是因为我们需要工具为我们找到一些危险函数,我们再去人工审查这样的话就会节约很多时间。
与大多数安全测试一样,我们的目标是付出时间而收获等价的结果,而黑盒测试的话,我们并不会知道应用程序使用了那些组件,比如FastJson,Shiro,Log4j等等,正因为这些外部引入的组件导致相关的安全问题。
我们主要关注如下几点(不全待补充):
-
经过身份验证之后可能存在的问题或者没有经过身份验证。
-
用户输入的地方是需要注意的,是否有漏洞 ?是否有过滤?是否可以绕过?
-
这个Web应用程序使用了那个数据库框架以及那个数据库,这个数据库框架是否有漏洞,是否可以绕过?
-
账户注册,是否存在任意用户注册,账户登录是否可以任意登录,修改密码,是否可以修改他人密码等等。
-
是否使用了威胁函数,比如Runtime.getTuntime.exec,是否可控?
-
引入外部的组件是否有漏洞?漏洞点是否可控?是否有过滤?是否可以绕过?
本地调试
理解Web应用程序最直接方式就是下断点然后去调试,一个一个代码区跟看这个功能到底传递了什么参数,是否有过滤,是否有校验等等,我们不仅可以本地调试,也可以远程调试,比如Weblogic。
使用如下程序调试(OSWE文档中的程序):
import java.util.Random;
import java.util.Scanner;
public class debugTest {
private static Random random = new Random();
public static void main(String[] args){
int num = generateRandomNumber();
Scanner scanner = new Scanner(System.in);
System.out.println("Guess a number between 1 and 100.");
try{
int answer = scanner.nextInt();
scanner.close();
System.out.println("Your guess was: " +
answer); if(answer == num) {
System.out.println("You are correct!");
} else {
System.out.println("Incorrect. The answer was " + num);
}
} catch(Exception e) {
System.out.println("That's not a number.");
} finally {
scanner.close();
}
System.exit(0);
}
public static int generateRandomNumber()
{ return random.nextInt(100)+1;
}
}
首先在Main方法这里下一个断点。
右键Debug运行即可。当我们不知道这个方法是做什么的时候,我们可以按住ctrl键然后点击该方法即可。
可以看到他就会跳转到这个方法中。
这里其实就是通过random来生成随机数。
然后我们按下F8执行下一行代码。
如果我们想进入到方法中的话,可以按下F7来进入方法。
如上就是本地调试。远程调试后面会说到。
记得转发噢 你的转发就是我更新的动力!!!!
原文始发于微信公众号(Relay学安全):OSWE笔记(1)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论