Duang~ 网络上有道常见题目:从输入 URL 到网页显示,其间发生了什么?
正好最近在整理笔记。准备从【安全】技术角度梳理 URL 相关知识
仅仅记录自己所知,如果有错误,请指出
更细节的东西请各位大佬自行处理
域名这种东西放在平时都是挑自己喜欢的去买就好
如果放在安全领域,需要考虑的就是域名生成算法
DGA
(domain generate algorithm)是一种伪随机域名生成算法,可批量生成大量的伪随机域名,作为C&C
(command and control server)域名。
域名生成算法经常被用作恶意软件连接 C2
中控。恶意软件定期使用 DGA
算法生成为随机域名,有效绕过黑名单检测,尝试连接,寻找 C2
中控。
通常域名生成算法分为四类:
比如几次恶意软件感染事件均使用了DGA域名:
传统的检测方法:黑名单库
现有的检测方法:长短期记忆网络 LSTM
参考资料:
想要访问特定资源,首先要判断相应资源所处目录(路径)、所处服务器(域名 + 端口)、通信方式(协议)
使用 urllib.parse 进行解析最为方便
URL 一般结构
scheme://netloc/path;parameters?query#fragment
本文主要考虑
域名是为了让人们更方便的记住所需要的资源位置,而便于计算机记录的是 IP 地址。这时就需要对 DNS 服务器进行访问,通过 ARP 协议获取对应 IP
参考链接:
https://blog.csdn.net/weixin_44604541/article/details/115909130?spm=1001.2014.3001.5501
TCP 会使用三次握手,这里我们只需知道三次握手在流量包中的显示特征即可
主要关注 Socket 客户端的 Java 实现
参考链接:
https://developer.android.com/reference/java/net/Socket
使用 HTTP 协议的通信量占大头
其中 HTTPS 中 TLS 会使用四次握手,这里我们只需知道四次握手在流量包中的显示特征即可
客户端传输内容主要使用系统内置 API 和 HTTP 框架
HTTPClient
Apache-HttpClient
OkHttp
Retrofit
参考链接:
https://www.twilio.com/blog/5-ways-to-make-http-requests-in-java
举个 okkttp 验证服务器证书的调用栈
参考链接:
https://developer.android.com/training/articles/security-ssl?hl=zh-cn
https://www.huaweicloud.com/articles/35fe55ce37013d706188fadb8644ef73.html
下载流程一般使用 Requests
库
进行一般过滤的单线程 demo
使用 wget
实现多层级网页内容爬取
仅爬取一层的 demo
使用 Selenium WebDriver 实现网页截图
基于 Chrome 的 demo
参考资源:
在移动应用分析过程中,往往都是脱壳抓包分析一条龙,抓包是必不可少的内容
可用工具:
一般网页流量均可以使用这些工具,主要讨论移动端应用,原理基本可以理解为中间人攻击
以下统称为代理
根据通信方式
HTTPS 认证
仅服务器端证书校验
将代理的根证书置于手机中,便可以正常抓包
注:根据系统版本的不同可能需要将证书置于用户层或系统层
客户端服务器双向认证
获取 App 客户端证书,导入代理中,便可正常使用
其他用处
我们平时用到域名和端口的机会还是很多的,不提一般资源的获取,平时远程访问也会用到
CTF
像在 CTF 中,有时会用到自构造 HTTP 首部,所以搞清楚常用首部内容还是可以加速解题的
举个小:
重点关注内容:Cookie & Session
常用媒体类型
内容编码类型
由于对 URL 解析之后参数格式防御不充分,则可能会使得各种姿势的 SQL 注入等攻击手段奏效
其他场景需求
单独使用 URL 分析作防御手段的场景
抱住大佬
不同的环境对应不同的需求,数据传输方式要求工具应更新换代
目前针对移动应用抓包的最好用的办法就是肉丝大佬开发的
r0capture
优点众多,我觉得比较重要的
总结
简直是妙蛙种子吃妙脆角,妙到家了
目前在学习证书格式相关内容,学完再写点小笔记
书籍:
HTTP 笔记
HTTP & HTTPS
HTTP 各版本差异
Content-Type 列表:
传输数据方式
socket/WebSocket/WebService/http/https
import
java.net.Socket;
/
/
获取 IP 端口号
mSocket
=
new Socket(mIpAddress,mClientPort);
/
/
获取输入输出流
mOutStream
=
mSocket.getOutputStream();
mInStream
=
mSocket.getInputStream();
/
/
发送获取相应信息
mOutStream.write(msg.getBytes());
mOutStream.flush();
byte[]
buffer
=
new byte[
1024
];
int
count
=
mInStream.read(
buffer
);
/
/
关闭通信连接
mOutStream.close();
mInStream.close();
mSocket.close();
import
java.net.Socket;
/
/
获取 IP 端口号
mSocket
=
new Socket(mIpAddress,mClientPort);
/
/
获取输入输出流
mOutStream
=
mSocket.getOutputStream();
mInStream
=
mSocket.getInputStream();
/
/
发送获取相应信息
mOutStream.write(msg.getBytes());
mOutStream.flush();
byte[]
buffer
=
new byte[
1024
];
int
count
=
mInStream.read(
buffer
);
/
/
关闭通信连接
mOutStream.close();
mInStream.close();
mSocket.close();
/
/
Create a neat value
object
to hold the URL
URL url
=
new URL(
"https://bbs.pediy.com"
);
HttpURLConnection connection
=
(HttpURLConnection) url.openConnection();
connection.setRequestProperty(
"accept"
,
"application/json"
);
InputStream responseStream
=
connection.getInputStream();
ObjectMapper mapper
=
new ObjectMapper();
APOD apod
=
mapper.readValue(responseStream, APOD.
class
);
System.out.println(apod.title);
/
/
Create a neat value
object
to hold the URL
URL url
=
new URL(
"https://bbs.pediy.com"
);
HttpURLConnection connection
=
(HttpURLConnection) url.openConnection();
connection.setRequestProperty(
"accept"
,
"application/json"
);
InputStream responseStream
=
connection.getInputStream();
ObjectMapper mapper
=
new ObjectMapper();
APOD apod
=
mapper.readValue(responseStream, APOD.
class
);
System.out.println(apod.title);
var client
=
HttpClient.newHttpClient();
var request
=
HttpRequest.newBuilder(
URI.create(
"https://bbs.pediy.com"
))
.header(
"accept"
,
"application/json"
)
.build();
var response
=
client.send(request, new JsonBodyHandler<>(APOD.
class
));
System.out.println(response.body().get().title);
var client
=
HttpClient.newHttpClient();
var request
=
HttpRequest.newBuilder(
URI.create(
"https://bbs.pediy.com"
))
.header(
"accept"
,
"application/json"
)
.build();
var response
=
client.send(request, new JsonBodyHandler<>(APOD.
class
));
System.out.println(response.body().get().title);
ObjectMapper mapper
=
new ObjectMapper();
try
(CloseableHttpClient client
=
HttpClients.createDefault()) {
HttpGet request
=
new HttpGet(
"https://bbs.pediy.com"
);
APOD response
=
client.execute(request, httpResponse
-
>
mapper.readValue(httpResponse.getEntity().getContent(), APOD.
class
));
System.out.println(response.title);
}
ObjectMapper mapper
=
new ObjectMapper();
try
(CloseableHttpClient client
=
HttpClients.createDefault()) {
HttpGet request
=
new HttpGet(
"https://bbs.pediy.com"
);
APOD response
=
client.execute(request, httpResponse
-
>
mapper.readValue(httpResponse.getEntity().getContent(), APOD.
class
));
System.out.println(response.title);
}
ObjectMapper mapper
=
new ObjectMapper();
OkHttpClient client
=
new OkHttpClient();
Request request
=
new Request.Builder()
.url(
"https://bbs.pediy.com"
)
.build();
Response response
=
client.newCall(request).execute();
APOD apod
=
mapper.readValue(response.body().byteStream(), APOD.
class
);
System.out.println(apod.title);
ObjectMapper mapper
=
new ObjectMapper();
OkHttpClient client
=
new OkHttpClient();
Request request
=
new Request.Builder()
.url(
"https://bbs.pediy.com"
)
.build();
Response response
=
client.newCall(request).execute();
APOD apod
=
mapper.readValue(response.body().byteStream(), APOD.
class
);
System.out.println(apod.title);
Retrofit retrofit
=
new Retrofit.Builder()
.baseUrl(
"https://bbs.pediy.com"
)
.addConverterFactory(JacksonConverterFactory.create())
.build();
APODClient apodClient
=
retrofit.create(APODClient.
class
);
CompletableFuture<APOD> response
=
apodClient.getApod(
"DEMO_KEY"
);
APOD apod
=
response.get();
System.out.println(apod.title);
Retrofit retrofit
=
new Retrofit.Builder()
.baseUrl(
"https://bbs.pediy.com"
)
.addConverterFactory(JacksonConverterFactory.create())
.build();
APODClient apodClient
=
retrofit.create(APODClient.
class
);
CompletableFuture<APOD> response
=
apodClient.getApod(
"DEMO_KEY"
);
APOD apod
=
response.get();
System.out.println(apod.title);
com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted()
android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted()
android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted()
android.security.net.config.RootTrustManager.checkServerTrusted()
com.android.org.conscrypt.Platform.checkServerTrusted()
com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain()
com.android.org.conscrypt.NativeCrypto.SSL_do_handshake()
com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake()
com.android.okhttp.Connection.connectTls()
com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted()
android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted()
android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted()
android.security.net.config.RootTrustManager.checkServerTrusted()
com.android.org.conscrypt.Platform.checkServerTrusted()
com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain()
com.android.org.conscrypt.NativeCrypto.SSL_do_handshake()
com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake()
com.android.okhttp.Connection.connectTls()
def
downloadTask(url):
log.info(
"{}/processing: {}"
.
format
(url))
try
:
r
=
requests.get(url
=
url, verify
=
False
, stream
=
True
)
except
:
log.error(
"[0] requests.get error: {}"
.
format
(url))
return
try
:
if
int
(r.headers[
'Content-length'
]) >
1024
*
1024
*
2
:
log.info(
"[1] exceeding quota: {}"
.
format
(url))
return
except
:
pass
if
r.status_code !
=
200
:
log.error(
"[2] status error: {}"
.
format
(url))
return
return
def
downloadTask(url):
log.info(
"{}/processing: {}"
.
format
(url))
try
:
r
=
requests.get(url
=
url, verify
=
False
, stream
=
True
)
except
:
log.error(
"[0] requests.get error: {}"
.
format
(url))
return
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)