Polar靶场-做题笔记
这个靶场挺好的,比较基础
后缀未做出的我都会标记
后续会补上
Polar-Pwn
overload1
2024.9.25
日常检查
就是一个常规的覆盖溢出
但是就是要记住gets函数溢出的栈的长度
ida反编译的不太对
1 |
|
Easy_ShellCode
日常检查
1 | bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/Easy_ShellCode$ checksec 1111 |
丢进ida里面看看
1 | ssize_t Start() |
怎么说呢?
str在bss段上
buf在栈上
没有后门
在bss段上写shellcode?
在buf栈上执行??????
1 | from pwn import* |
yes,是这样的
简单题是这样的
要是所有的都这样就好了
Easy_Text+Fmt
2024.9.25
1 | bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/Easy_Text+Fmt$ checksec 1111 |
日常检查
丢进ida里面
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
简单的格式化字符串,
简单的找一下偏移
偏移为7
1 | from pwn import * |
操了
还有个后门啊
1 | from pwn import * |
好题啊好题
小狗汪汪汪
2024.9.25
日常检查
1 | bbq@ubuntu:~/桌面/pwn/小狗汪汪汪$ checksec 1111 |
看着还行
ida里面看看
后门
1 | from pwn import* |
小猫喵喵喵
2024.8.25
日常检查
1 | bbq@ubuntu:~小猫喵喵喵$ checksec 1111 |
看着不难应该
自己写个shell吗?
套公式吧
1 | from pwn import * |
歪日
这个get是用不了
我嘞个豆
看一眼wp,这个scanf是直接当gets用的
format_ret2libc
2024.9.25
1 | bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/format_ret2libc$ checksec 1111 |
日常检查
盲猜一手
格式化字符串泄露canary地址
然后找libc基址
canary有一个,基址有一个
先找一手偏移
1 | bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/format_ret2libc$ ./1111 |
偏移为6
然后就是看一下canary的位置
1 | .text:0000000000400888 mov rax, [rbp+var_8] |
在rbp上面8位
1 | +-----------------+ |
看一下主函数
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
大概也知道了
第一次read函数进行泄露canary地址
第二次泄露进行泄露puts函数的基址
首先泄露canary地址吧
接收一下
1 | gdb 111 |
可以看见
1 | 0xddc8-0xdcc0=0x108 |
可以看见偏移为33
33加上6总共为39
1 | from pwn import * |
后面接着puts函数进行泄露libc版本就行了
1 | from pwn import * |
libc版本一直试不对
so,本来都想放弃了
但是想起来有个onegadget来着
就试了试成了
脚本试AI改的
1 | one_gadget ./libc6_2.23-0ubuntu11.2_amd64.so |
1 | from pwn import * |
最终得到flag
没人能拒绝猫猫
日常检查
1 | bbq@ubuntu:~/桌面/啊布拉布拉/Polar/pwn/没人能拒绝猫猫$ checksec cat |
开了 个canary
丢进ida里面看看
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
简单看一下s2也在栈上
一个简单的覆盖
1 |
|
sandbox
一个简单的沙箱,
1 | $0绕过 |
easypwn2
1 | bbq@ubuntu:~$ checksec easypwn |
ida看一眼,满足条件就行
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
找一下atoi函数的漏洞。
what’s your name
2024.11.2
还是比较简单的
应该只是一个覆盖问题
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
1 | llq@llq-virtual-machine:~$ ./pwn2 |
应该还有个小段序的问题,这里直接搓脚本吧
1 | from pwn import * |
getshell
2024.11.2
1 | llq@llq-virtual-machine:~$ checksec pwn2 |
有后门说是
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
啥意思呢?
直接打了栈的地址?
1 | from pwn import * |
应该不是这样做的吧
谁道呢?
Game-找不到libc版本
2024.11.2
嘶!
1 | llq@llq-virtual-machine:~$ checksec 1111 |
看着还是挺正常的
漏洞gets函数
前面有几个绕过
但是没有后门??
傻逼了,泄露libc基址
1 | from pwn import* |
找不到libc版本,就这样吧
test_format
ida打开
1 | unsigned int Input() |
格式化字符串,确定一下偏移就行
1 | llq@llq-virtual-machine:~$ ./test_format |
看见偏移为6也是拿下了
1 | from pwn import* |
wsfw
03ret2syscall_32
1 | llq@llq-virtual-machine:~$ checksec 1111 |
这会包是ret2syscall了
1 | from pwn import* |
有bin/sh哇
1 | from pwn import* |
easyrop
ida看一眼
有system函数和sh
大概是64位ROP
1 | from pwn import* |
try_sandbox
2024.11.2
日常检查一下
1 | bbq@ubuntu:~$ checksec pwn1 |
ida里面看看
1 | __int64 __fastcall main(__int64 a1, char **a2, char **a3) |
有沙箱,看一下过滤
1 | seccomp-tools dump ./pwn |
没啥用感觉
就像是ret2libc
1 | from pwn import* |
我说他开头说啥呢?
原来是
1 | from pwn import * |
8字节能干什么
2024.11.3
看名字就知道是栈迁移了
1 | int vuln() |
显而易见了
日常检查一下
1 | llq@llq-virtual-machine:~$ checksec pwn |
这里没有/bin/sh
应该还是迁移到栈上
找一下buf栈顶到ebp的距离
1 | Python>0xffab8268-0xffab8228 |
1 | from pwn import* |
choose-找不到libc版本
2024.11.4
日常检查一下
1 | bbq@ubuntu:~$ checksec pwn2 |
丢进ida里面看看
1 | int __fastcall __noreturn main(int argc, const char **argv, const char **envp) |
看也看出来了
选择一泄露canary,选择2泄露libc基址,选择三正常打栈溢出
1 | from pwn import* |
可以看出偏移为6这回我们可以泄露一下canary的值了
fmt泄露canary
每次做题都得翻一下笔记,so准备详细记一下
第一步:确定偏移
知道偏移是六。
第二步:确认canary距离我们输入rsp的距离
gdb运行
1 | gdb pwn2 |
地址减一下
1 | Python>0x7fffffffde48-0x7fffffffde20 |
但这里我想直接在ida里面看一下会更简单
首先看一下汇编代码找到canary的位置
在看一下栈的位置
最后:确定最终字节
除以8字节,为5,得到5+6=11
然后就可以正常泄露了
1 | from pwn import* |
不到为什么,还是打不通了
格式化
2024.11.5
简单检查一下
1 | bbq@ubuntu:~$ checksec 1111 |
看着不难
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
看着不难
应该就是第一个gets泄露canary第二个gets打栈溢出
首先找一下偏移
知道偏移为6后
找一下canary距离栈的位置就行
确定为25+6=31
1 | from pwn import* |
ret2libc-找不到libc版本
2024.11.6
1 | bbq@ubuntu:~$ checksec ret2libc |
丢进ida里面看看
很基础哈
没啥说的
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
1 | from pwn import* |
本地能打通,远程通不了,基址也是对的,环境问题吧
跟上面那道差不多一个问题
Choice
没啥说的简单的后门
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
选三就行,正常的栈溢出
1 | from pwn import* |
x64
日常检查
1 | bbq@ubuntu:~$ checksec x64 |
没啥说的,直接ROP链
1 | from pwn import * |
你是大佬还是菜鸡
日常检查
1 | bbq@ubuntu:~$ checksec pwn |
一样
1 | from pwn import * |
play
2024.11.6
日常检查
1 | bbq@ubuntu:~$ checksec play |
看了一眼主函数
1 | __int64 play() |
前面的buf实在bss段上的,so就是shellcode的无疑了
1 | from pwn import * |
name4
日常检查
1 | bbq@ubuntu:~$ checksec name4 |
1 | int Start() |
看着if条件语句是一个绕过
我们用空字符绕过一下
1 | from pwn import * |
md,这个libcsearch没找到,得自己找
sleep-找不到libc版本
跟上面做法差不多
直接贴脚本
1 | from pwn import * |
远程环境的问题
stack_pivotingx86
栈迁移
日常检查一下
1 | bbq@ubuntu:~$ checksec 1111 |
1 | ssize_t vuln() |
就是不到为什么会有两次read
题目system和/bin/sh地址都在
不用泄露基址哇
因为我们不知道栈顶的位置
so我们要通过第一个read策一下距离
x/5xw $esp
查看寄存器值
1 | from pwn import* |
踩坑点:注意esp距离ebp的长度
相减得到0x38
夕阳下的舞者-未做出
日常检查
1 | bbq@ubuntu:~$ checksec 1111 |
感觉是上难度了
嘶
果然是堆题
这回是直接干
看一眼题wp说是有个换libc环境
1
2 patchelf --replace-needed libc.so.6 ./libc-2.23.so ./562+5Liq5Yiw
patchelf --set-interpreter ./ld-2.23.so ./562+5Liq5Yiw但是我是直接跑起来了
1 |
heap_Easy_Uaf
2024.11.12
既然是堆题,并且连漏洞都告诉你了
就好好找一下吧
1 | bbq@ubuntu:~$ checksec 1111 |
其实说实话,如果说是堆题的话,这个保护机制还有利用的必要吗???
先找一下漏洞吧
既然是UAF漏洞
uaf漏洞通常就是内存块被释放后,其对应的指针没有被置为NUL
1 | from pwn import* |
05ret2libc_64
2024.11.12
不用看了直接写吧
1 | from pwn import* |
做不出来的最大问题就是libc环境问题
1 | from pwn import * |
格式化字符串劫持got
日常检查一下
1 | bq@ubuntu:~$ checksec pwn1 |
ida打开看一下
1 | int come_on() |
看着还是比较基础的
思路:第一个泄露地址,然后got改写
这种先找一下偏移
知道偏移为7
1 | from pwn import* |
format_ropx86
2024.11.14
1 | bbq@ubuntu:~$ checksec 1111 |
ida打开就是一个格式化字符串加一个ROP链
1 | from pwn import* |
来东北看雪
2024.11.14
1 | int fun() |
看着像shellcode
1 | from pwn import* |
cardlibc
2024.11.14
1 | bbq@ubuntu:~$ checksec cardlibc |
没啥意思了
1 | from pwn import* |
中间有个整数溢出
shellcode1-未做出
2024.11.16
1 | bbq@ubuntu:~$ checksec shellcode1 |
ida里面看看
shellcode没啥说的
1 | from pwn import* |
sys
2024.11.16
后门
1 | from pwn import * |
巴啦啦亮吗-为做出
2024.11.16
1 | bbq@ubuntu:~$ checksec pwn1 |
ida打开
sys504505
2024.11.18
日常检查一下
1 | bbq@ubuntu:~$ checksec sys504505 |
全开,ida打开
1 | __int64 __fastcall main(int a1, char **a2, char **a3) |
打开也是看见了system函数,猜测就是要构造/bin/sh
但是这个command是我们要自己输入得到的
大概就两步
for循环构造/bin/sh
if绕过退出
1 | from pwn import * |
friend-找不到libc版本
栈题能做
1 | bbq@ubuntu:~$ checksec friend |
丢进ida里面看看
1 | int Start() |
1 | from pwn import* |
就这样吧
like_it
怎么说呢是道堆题
早做晚做都得做,而且现在也不早了
还是那个问题
堆题还有必要看保护机制吗?
1 | bbq@ubuntu:~$ checksec like_it |
因为没开地址随机化的问题
我们是可以利用这个后门的应该是
我们看一眼主函数
确实看上去还是比较熟悉的堆题的模板
然后呢
函数开始之前有个def函数
我还以为要有个绕过呢!
1 | unsigned __int64 def() |
但是我发现最后输入什么都可以绕过,so暂时不管他
找一下堆题的漏洞
感觉就是UAF漏洞哈
SO正常申请堆块后释放就行了是吧
1 | from pwn import* |
easychunk-未做出
日常检查
fate
2024.11.18
日常检查
1 | bbq@ubuntu:~$ checksec fate |
后门
1 | from pwn import * |
look
没啥说的
1 | #32位 |
worker
先日常检查一下
1 | bbq@ubuntu:~/tools/LibcSearcher$ checksec worker |
看着像是堆题
但是ida看一眼
1 | void __fastcall __noreturn main(__int64 a1, char **a2, char **a3) |
但是有个shell,也不知道是假的还是作为一个后门
既然是堆题看看能不能先找到漏洞再说
ezUAF
既然给出了漏洞,那就直接看
模板题型啥也不说了
1 | from pwn import* |
ezuaf
1 | bbq@ubuntu:~/tools/LibcSearcher$ checksec ezuaf |
看着开了随机化,应该是有后门的吧
结果不是我想的UAF函数
ida打开看看
1 | int __fastcall __noreturn main(int argc, const char **argv, const char **envp) |
看一下菜单
1 | int mulu() |
一读取、二申请堆块、三打印堆块
在read里面我们也是看见了UAF函数
然后我们就可以继续利用这个漏洞了
EXP:
1 | from pwn import* |
怎么说呢看一眼wp。看看malloc之前的堆块长什么样。看看申请之后是什么样
申请后
1 | from pwn import* |
music
没啥说的
1 | from pwn import* |
txxxt
后门啥也不说了
1 | from pwn import * |
shellcode分割
既然说是shellcode了
那就写shellcode喽
1 | bbq@ubuntu:~/tools/LibcSearcher$ checksec 1111 |
这里没有特别好的思路直接看wp了
这里直接贴EXP了
1 |
|
这里其实不用直接返回main函数,直接返回到shellcode函数地址就行了
本地没打通先放着看看
find
后门没啥说的
1 | from pwn import * |
travel
格式化字符串-基本题型
偏移为6
1 | from pwn import* |
heap_Double_Free-未做出
2024.11.20
既然给了漏洞就简单看一下
1 | bbq@ubuntu:~/tools/LibcSearcher$ checksec 1111 |
堆这块是一点思路没有,准备在看看前置知识
Polar-Reverse
shell
先查一下壳
有一个upx1的壳,拖一下壳,这里我用的脱壳机和upx都试了一下,看一下有啥不一样
显而易见后者跟好一些
签到题也是很明显的
flag{crack_is_funny}
JunkCode
查壳
32位,丢进ida里面
是到花指令的题,这里我是直接动调出的
直接跳到最后的判定条件
flag{junk_code_is_funny}
怎么说呢!
静态应该也能看
这里倒腾半天好像不行,最简单的犯法就是在常规地方nop一手直接进行动调,在下一个最后的断点,直接f9进行步过
看见判断条件就可以直接看见flag。
PE结构
看到题目直接010打开,看下文件头
没啥说的,改回来就行
flag{66987add03c98a8f0cac71e4cafc2a6a}
拼接
打开解压即可
白给flag{03ff6cf238c5cd8e7b4ee1e9567ad5a4}
加加减减
打开ida分析一手
1 |
|
康师傅
1 |
|
另辟蹊径
打开是没见过的
直接看wp,下载Cheat Engine
Cheat Engine安装&汉化教程 - 哔哩哔哩 (bilibili.com)
完成汉化后
CE加载一下这个程序
然后继续运行程序
得到flag
flag{60983973c2ab87436914d71000e4b4e4}
老八小冒险*
2024.12.18
jbkjckjsdsfdsfjbkjckj
60b6cd0848639100c68c04d4884db1e8
RevMethod
那道题目之后,先跑了一遍findcrypt,看见了好多flag
看一下主函数
1 | int sub_1F1990() |
怎么说呢!还是比较容易理解的,大概就是随机生成了100个随机生成的32位flag,给了我们符合条件的语句就得到flag
这里我开始以为是要进行爆破得到flag。倒腾一会发现
这几个数都未免也太大了一些,仔细看了一下这个判断条件
1 | *(&byte_1FA000 + 2566) |
这里其实是一个指针,指向的是距离byte_1FA000地址偏移为2566距离的值,地址也告诉你了0x1fa000
看一下地址偏移的值
得到flag
唉
flag{cdb10e38735935eae8a6989e372bd598}
use_jadx_open_it
2024.12.19
根据题目提示
找到main函数,直接能看见flag
1 | flag{go_to_study_android} |
re2
flag{e10adc3949ba59abbe56e057f20f883e}
layout
安卓题
jadx打开
资源文件 >>layout>>activity main.xml
逆一下子
打开不知道是干啥的
ida反编译之后,finger一下(也没啥用),那会想着好找一些main函数
然后把这个后面的-去掉就行了
flag{c68dd2625b9125411ba71f3d810341c4}
但是正常的解法是应该用Resource Hacker 打开
去除后面的禁止调用,然后正常点击编译后就可以看见我们的flag
可以点击了
没啥用我感觉!!!!
可以为师
flag{a5dd39834f606a4c00cc83d507c5e599}
一样做法
逢七必变
2024.12.19
日常查壳
丢进ida里面看看
说是话这是有壳的,看了半天没感觉出来
又解压了一遍看了一下,嘶
行吧,找一下oep
怎么说呢?
找半天,具体就是
先F9走到主函数
在ret下断点
在步过一下
然后就行了
脱完壳,拖进ida里面
插件找一手就行了,看见主要逻辑
1 |
|
高卢战记
2024.12.21
直接ida打开看见密文
然后在高卢战记的提示下是证明是凯撒加密
1 | src='6f759f8f7:deg::796486<8<8edf9:73' |
1 | flag{3c426c5c47abd774631539595bac6740} |
Why32
2024.12.22
点进去找到主要加密逻辑就完事了
1 |
|
啥意思给了一半是吧
找半天,原来是只解了一半,在解一个md5就行了哇
F1laig
这是flag
套个壳子就行了
左右为难
2024.12.22
没啥说的,迷宫解密
然后md5加密就行了
找一下迷宫的长宽,16*8
1 | 0000000000000000 |
动态酷
2024.12.22
这里直接给了个dll文件
打开找到catflag
提取一下
flag{84649ac8ca256511a52fc9359fa367a1}
?64
2024.12.22
打开找逻辑
1 |
|
我以为都结束了,为什么后面还塞了个md5加密哇
5d15777a411724ee5d029caca1ca7298
Java_Tools
jadx打开
明显的主函数可以看见
1 | package main.java; |
很明显的三个加密函数,然后我们就可以进行逆向解密就行
主要逻辑在下面
1 | package main.java; |
judge函数判断密文应该就是$gourZroohK
,然后就进行Re和add_1就行了,add_1看代码就是一个凯撒加密,Re就是一个反转操作
因为这里还有应该异或操作,因为没有调用,所以不管
1 | src=[0x24,0x67,0x6F,0x75,0x72,0x5A,0x72,0x6F,0x6F,0x68,0x4B] |
其实到HelloWorld!就差不多了,不过我md5了一下。32小写
06e0e6637d27b2622ab52022db713ce2
就对了
混淆Code?
2024.12.22
ida打开康康
动调半天,怎么说呢!
前面的限制字符串我以为是37!但是我们发现是可以不到37的,so我在尝试了一手输入我们的密文
1 | `lfgc-y`b}v! |
到X函数这里的时候我们会发现
我们的密文被转换为了
因为是异或我们正常把hello world!输入回去同样能得到密文
1 | `lfgc-y`b}v! |
然后我们在check着就可以看见我们的检查字符串就对了
然后进行md5加密就行了
flag{fc3ff98e8c6a0d3087d515c0473f8677}
Android*
2024.12.23
jadx打开找到主要加密逻辑,丢给gpt
1 | package com.example.myapplication; |
拆包,点进.so
文件康康,找到主要加密逻辑
1 | int __cdecl sub_650(int *a1, int a2, int a3) |
思路:
- 取出
a3p
数组;char a3p[50] = {0x33,0x50,0xef,0x85,0x20,0xd6,0x9d,0x8f,0x92,0xce,0x5a,0xf9,0x40,0x8f,0x91,0xcf,0x20,0x40,0xb6,0xfe};
- 循环遍历
a3p
数组,当下标i
满足5 * (i/ 5) + 4 == i
时,将对应下标的值加一;- 然后再根据
a3p
数组中的值去找byte_8F8
对应值的下标。
1 |
|
Sign Up
2024.24
64位无壳
打开之后看一眼主要逻辑
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
找一下账号密码
比较明显的。点进去就可以看见了
只不过我们输入的时候要注意有个等式的条件,我们输入的是前面的,进行相应的变换就行了喔
192168109–>>>081057009
root–>>>pmmr
081057009pmmr—>>>flag{aa07caa2ff9e5b774bfca3b1f20c3ea0}
最短路
2024.12.24
怎么说呢?
感谢GPT
flag{4991ce1781b53409a7a84e2baf9431d6}
easyre1
直接ida打开康康
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
两层加密应该是直接逆即可
1 | int enkey() |
但是逆向的话,得先进reduce、enkey
直接贴exp了
1 | key='5055045045055045055045055045055' |
babyRE
2024.12.25
64位,无壳
1 | a='asdfgcvbnmjgtlop' |
PY_RE
2024.12.26
打开是两个py文件
分别分析一下
1 | #Test.py |
1 | #start |
看上面的那个就很明显了,先初始化字典,得到26字母的转义字符后,在进行验证即可,这里验证的是flag的后半段。
这里直接打印字典即可得到转义后的字符
一一对应即可 11(P), 2(Y), 7(T),19(H), 12(O),13(N)
HELLO__PYTHON
之后md5加密即可
二层防御
2024.12.26
看名字就是脱壳的呗
upx脱一层
没啥说的,脱完了?就直接?
ida打开康康。找到加密逻辑,看到密文
其实动调跑完一遍就知道他说的二层防御其实就是对密文进行了两次加密,而不是指加壳。
看一下主体逻辑:
最主要的加密
1 | __int64 __fastcall sub122(int a1) |
卡半天,发现这里是不对a和n进行变换的
1 | flag = "llo_PWN " |
a)GPYhxeen
md5加密即可