N1nEmAn-2023集训wp
阅读原文时间:2023年08月15日阅读:1

week1

2022-12-28 WP

0x00 T1 reverse3

前几天没注意到要发wp,现在补一下。最近在学汇编,pwn题没做新的了。想到之前了解到hws的pwn会考花指令,听hjx他们说那是re的内容,就特意去做了点re。

题目来源是buuctf的reverse3。

0x01 wp

没壳,32位,准备丢ida

观察到想要输入的数据和flag一样,注意27-28行代码,需要把第j个数据+j完成变换才行。也就是说我们要将结果的j位-j获得flag。

应该就是这个str2的内容。

不过寻找的时候注意到如下内容:

看到字符串应该确定就是base64了,让赛博大厨搞定他(不是)

python能力逐渐退化了hhhhhhhhhhhh

运行得到

得到flag

week2

2023-01-10 WP

前些日子学汇编+阳了,请假后睡了一个星期过来,现在非常高兴终于能和大家一起打比赛一起写wp啦~

0x00 T1 hello_pwn

0x01 题目来源

题目来自攻防世界pwn栏目第二题:hello_pwn

一道栈溢出的基础题目。

0x02 题解

第一步:checksec 文件名

拖入ida静态分析

我们刚才已经知道此文件是64位,我们把它拖入ida64即可。

可以看出,只要让dword_60106C的值等于1853186401就可以运行下面那个函数,即得到flag

第一步:怎么完成?

db即define bytes,意思是定义一个字节,我们所需要修改的数值是下面的dword_60106C,故填充四个bytes的数据并覆盖dword_60106C为所需值即可。

第二步:正式写exp

以上就是我们写好的exp脚本,接下来就是运行啦!

第三步:运行exp!

可以看到得到flag~

2023-01-10 WP

0x00 T2 level_0

0x01 题目来源

题目来自攻防世界的引导模式pwn栏目第三题level_0

一道栈溢出的基础题目。

0x02 题解

第一步:checksec 文件名

第一步:ida静态分析

可见这是一个read函数,可以实现栈溢出。

第二步:发现后门

发现后门函数,还是ret2text'的打法

第一步:注入多少数据?

可计算得到,需要覆盖(0x80+0x08)的数据

第二步:正式写exp

第三步:运行exp!

拿到shell

2023-01-11 WP

0x00 T3 CGfsb

有错误的地方欢迎指教!有不明白的也可以提问,欢迎大家一起讨论~

题目来源是攻防世界引导模式的第五题,CGfsb。

初探格式化字符串漏洞。

0x01 wp

除了没开随机地址什么都开了,32位

可以看到需要输入两次东西,并且会打印出来,其中的printf(&s)就是格式化字符串漏洞。

这个漏洞,在于printf(&s),前面的fgets让你自己输入东西进入s以后,你就可以控制printf()里面的内容,达到查看内存和修改内存的目的。

(%p是打印地址)

比如你输入aaaa-%p,那么printf(&s)就相当于,

printf("aaaa-%p")

可是正常来写我们都知道,我们是这么写的:

printf("aaaa-%p", a) //就是说,在“……”之后,会有一个参数。

那么没有参数怎么办?直接从栈里面找,其实还是隐性的有后面的参数,只不过直接从栈中索引了。

查看内存使用%s、%c、%p之类的,写入内存使用%n或者%i$n,其中 i 代表一个变量。

其中这个 i 代表着往下索引第几个参数,然后%i$n就代表着向第 i 个参数写入成功打印的个数(比方说打印了‘aaaa’,那么就会写入4)。

如前面所说,直接从栈中索引,这个%i$n也是直接从栈往下索引参数,这么说太抽象,我们看例子。

可以看出他就是把下一个参数的内容作为地址打印出来了

我们根据ida的伪代码分析到,需要把pwnme的内容修改为8,这样就能cat flag。那么我们要充分利用%i$n写入成功打印字数的功能,成功打印八个字数然后写入pwnme的地址。

这是pwnme的地址,因为没开随即地址,它不会被改变

我们通过输入“aaaa%p-%p……”这一串内容来确认我们第一次输入的前四个字节属于第几个参数。我们可以看到aaaa被转为ascii码被当作三十二位地址打印出来了,就是0x61616161。所以我们可以数一下,我们第一次输入的内容是在第十个参数。

也就是说,我们只需要输入四个字节,再输入pwnme的地址(占四个字节),总共八个字节,就会在pwnme写入8。我们可以开始写exp了。

aaaa是第十个参数,所以我们的地址是第十一个参数,所以写入%11$n

注意一开始还要输入一个东西,随便写一下就好。

2023-01-12 WP

0x00 T4 easyasm

0x01 题目来源

题目来自hgame比赛week1的reverse,非常简单的汇编逆向,甚至连汇编知识都不怎么需要。

0x02 题解

1.看看txt

按照我的理解这个程序就是跳来跳去,最后就是对他需要的一个内容进行xor运算,其他代码可能是混淆之类的。所以只需要把下面加密的结果和0x33进行异或就可以获得flag。

2.解密

先试一下第一个元素异或的结果。

hgame的flag格式都是hgame{……}可以确定我们做题方向没有问题

随后构建完整的数组进行for循环异或就可以得到最终的flag。

0x00 T5 easy_overflow

0x01 题目来源

题目来自hgame的week1的pwn第二题。

比赛仍然进行,网址:https://hgame.vidar.club/contest/2

0x02 题解

第一步:checksec 文件名

我们继续使用checksec看看这个文件的保护情况。

可见是64位的。

第一步:拖入ida静态分析

我们刚才已经知道此文件是64位,我们把它拖入ida64即可。

第二步:跟进main函数

跟进后发现都是这些玩意,估计就是动态链接才能看出来是用什么函数。我们需要自己运行和动态分析一下。

第一步:先运行

可见功能就是使用了read或者get函数之类的,然后就结束。我们可以进一步去gdb看看。

如果有read函数之类的,就可以实行栈溢出攻击,我们还需要确定栈的大小。

第二步:gdb动态分析

猜测后门就是system()函数,可以试试设断点显示地址。

我们可以看到基本对上了。

现在就差确定栈的大小。其中注意到这里运行了一个close函数,应该就是刚才那个函数上面的函数,这个函数会让shell无法正常回显。具体请看下面的参考文章。

参考文章

从0x……130开始存到0x……148ret,可知栈大小为(0x148-0x130)

后门的地址如上。

运行完得到shell。

最后的小插曲

由于前面close()函数,不能直接获得flag。

经过欧阳学长的提示,找到了一个命令“sh”,不过也可以按照上述的参考文章进行cat flag。以下是两个解决方法。

week3

2023-01-19 WP

0x00 T1 [第五空间2019 决赛]PWN5

第三周提交wp辽。

题目来源是buuctf pwn的第7题,[第五空间2019 决赛]PWN5。

再探格式化字符串漏洞。

0x01 wp

还是除了没开随机地址什么都开了,32位

第一次看到这个题我还以为要用canary泄露什么的,然后觉得很麻烦就没做下去,结果发现是格式化字符串哈哈哈哈哈哈哈哈哈又有信心了。

详细原理请看楼上初探格式化字符串,这次偏巩固所以就不细说原理了。

和上一个格式化字符串的题差不多,基本思路就是确定偏移量,用%n写入数据,并在最后输入写入的数据拿到权限。

需要把数据写入这个地址。

偏移还是10.

写入地址长度,并用%n修改相应数据,32位数据是四个字节,故最后输入4拿到权限。

2023-01-21 WP

0x00 T2 ciscn_2019_n_8

祝大家除夕快乐!

题目来源是buuctf pwn的第9题,ciscn_2019_n_8。

0x01 wp

非常可怕!32位,什么都开了,一开始还以为要寄了,结果发现其实并没有那么难

可以看出利用的是格式化字符串的漏洞,需要我们修改var地址往下数第十四个,类似是数组的结构到var[13]为17,并且为LL就是long long int八个字节,,相当于64位的数据'\x11\x00\x00\x00\x00\x00\x00\x00'。

var数组可以看做是一个int型的数组,先用aaaa填充前面的数据,最后写入64位形式的17。

2023-01-21 WP

0x00 T3 jarvisoj_level2

大家除夕快乐哇,最近打算就是跟进一下刷题量多点经验积累。

(misc真的…唉不说了,打了两场比赛都没什么产出,感觉很多靠经验,太缺乏了这方面)

给自己找的借口:都在做pwn还有学汇编(然后发现学的汇编好像没派上什么用场,只是了解了很多名词)

0x01 题目来源

题目来自buuctf pwn的第十题,一道简单的ret2sys,然而我居然弄错了bin/sh的地址…然后查了wp才做出来,我一开始甚至蠢到用ret2libc【…】

0x02 题解

1.checksec

32位,无canary和随机地址。

2.静态分析

#第一步,跟进可以发现存在read函数可以实现栈溢出。

第二步,计算出栈偏移量为0x88+0x04。

3.找到关键函数和字符串“/bin/sh”

俩地址都有了!写exp吧!

4.写exp,运行拿flag~

0x00 T4 easy_overflow

0x01 题目来源

题目来自buuctf pwn的第十一题,突然发现后面的题目比前面的简单??

利用ret2text。

0x02 题解

第一步:checksec 文件名

我们用checksec看看这个文件的保护情况。

64位嗷

第一步:拖入ida静态分析

此程序即一开始设定read函数接收数据的长度,然后就可以利用read实现栈溢出。

后门函数,地址为0x4006E6

第二步:看看栈的偏移量

可见偏移量为(0x10+0x08)

#ret2text,并且设定接收数据为66长度。

运行得到flag

2023-01-22 WP

0x00 T5 get_started_3dsctf_2016

buuctf的pwn栏目的第十二题。

0x01 wp

很平常,32位

#看main函数。
#发现有get函数,可以实现栈溢出。

#发现get_flag函数
#只要a1,a2参数分别等于相应的值就可以获得flag

#计算到返回地址的偏移量
#为0x38

#get_flag函数的地址
#exit函数的地址(返回到exit使得程序正常退出,得到回显。)

根据以上写exp即可获得flag。

比较需要注意的是,32位函数调用时是从栈里取参数,需要在调用的函数地址后面,填入返回地址、参数1、参数2……

感谢wp:https://www.cnblogs.com/zhuangzhouQAQ/p/15036343.html

week4

2023-01-29 WP

0x00 T1 [OGeek2019]babyrop

第四周~进了华为冬令营,我还以为是线下的夏令营hhh。

题目来源是buuctf pwn的第13题,[OGeek2019]babyrop。

ret2libc,32位+一点点逆向

0x01 wp

32位

#8-10:首先程序读取一个四字节的无符号数进入buf
#11: 将buf作为一个参数,传入804871F函数。如下

#11:函数参数以long int形式读入s
#12:调用函数read,v6的值为输入的字节数,方便下一行代码实现
#13:将最后一位设为0
#14:设置v1大小,为了绕过比较,strncmp第三个参数为比较的最大字符数,我们让v1=0
strlen截断于\0,所以我们让buf第一个字节为'\x00'即可。
函数返回值v5如下。

//返回到下面这个函数,可见
//如果要实现栈溢出只要他为最大的'/xff'

最后打ret2libc即可。

#注意这题给了so文件,从里面找偏移需要使用libc.sym['xxx'],
#字符串用ROPgadget找。(由于在线查查不准卡了很久)。
#泄漏的地址可以选择write,read都可以。

0x00 T2 jarvisoj_level2_x64

0x01 wp

#直接栈溢出,打ret2sys,64位
#以下为查偏移量和找寄存器,找字符串/bin/sh

偏移量为0x88

这里选择pop rdi; ret那个

/bin/sh地址

32位和64位调用函数方式不一样,这个做题多了熟悉就好了。一个是参数跟后面一个是用寄存器。

不过32位参数大于等于3也需要用寄存器的方式调用~

0x00 T3 [HarekazeCTF2019]baby_rop

0x01 题目来源

buuctf pwn的第十五题。

0x02 题解

1.checksec

64位

2.静态分析

#用scanf读取字符串,直接栈溢出

有现成的system函数和'/bin/sh'字符串,ret2sys,64位

栈偏移直接看ida就好了,是0x18

4.写exp,运行拿flag~

flag呢?找找找……

在这儿~

0x00 T4 ciscn_2019_en_2

0x01 题目来源

题目来自buuctf pwn的第十六题,和前面某题目一模一样,简单说一下吧~

0x02 题解

第一步:checksec 文件名

我们用checksec看看这个文件的保护情况。

64位

第一步:拖入ida静态分析

首先填入1然后再在加密函数里进行栈溢出,
并且注意绕过strlen的判断所以get函数的s第一个要用\x00填充。

第二步:看看栈的偏移量

可见偏移量为(0x50+0x08)

ret2libc 64位打法。

运行得到flag

0x00 T5 not_the_same_3dsctf_2016

buuctf的pwn栏目的第十七题。

0x01 wp

![](https://article.cdnof.com/2308/97ffc3d1-0e6f-487f-bfda-8a0c1a2fa1f1.png) 32位

#看main函数。
#上来就有get函数,可以实现栈溢出。

#发现get_secret函数
#可见函数是,向&fl4g中写入flag。


#计算到返回地址的偏移量
#为0x38

并且这道题发现有mprotect函数,那么有两个打法。

第一个打法,用write函数将&fl4g打印出来

0x80489A0就是get_secret函数的地址

运行结果直接得到flag。

第二个打法,用mprotect函数

这个方法就是直接改写一个内存页的权限,然后打ret2shellcode

需要用到三个寄存器,选择这个

修改这个内存页,由于修改权限是要整个内存页(4k大小,即0x1000),所以从这里开始。

> 32位,三个参数用寄存器。先溢出到mprotect,
> 返回地址,
> 填入三个参数,
> 然后返回到read,写入shellcode。分别构成了:
> mprotect(_4kadd, 0x100, 0x7)
> //其中0x7代表rwx,可读可写可执行
> //注意第二个参数需要是页大小的倍数(0x1000的倍数)
> //虽然这次写了0x100但是最好还是写0x1000及其倍数
后续:欧阳学长查了源码,写0x100是会被直接改为0x1000对齐的

运行结果:

week5

2023-02-04 WP

0x00 T1 others_shellcode

第五周提交wp辽,祝福大家元宵快乐,幸福安康。

题目来源是buuctf pwn的第五行第三个题,others_shellcode。

一道送分题,但是需要好好理解题意。

0x01 wp

虽然全开保护了,但是不用慌张!

跟进看一下函数"getshell"如下。

不明白,我们具体看看汇编如下,具体注释如下,文章不赘述。

从上述得知,"getshell()"直接运行了execve("/bin/sh",0,0)
#如注释有问题欢迎指出!!
故直接nc获得flag。
之所以叫"others_shellcode",大概意思是之前用的都是
system("/bin/sh")
#所以这次想给我们看点不一样的吧~

题目看似简单但是暗藏玄机,不能轻易错过哦~

0x00 T2 ciscn_2019_ne_5

是下一题。

0x01 wp

只看这里还不明白,看看别的函数。

发现"Addlog(int a1)"函数可以录入128字节的数据,而在"GetFlag(char *src)"中,
将src作为指针传入字符串,且实行'strcpy'将src复制到dest,
dest长度只有48,而可以复制128过去,则可以在这里实现溢出。

我们看到有现成的"system"函数,所以在需要"/bin/sh"就行了。
根据wp,只有"sh",也是可以的!(新知识点!)
所以构造
system("sh")
即可!

exp思路便是,先输入正确的密码,然后传入1,运行'Addlog'函数,再传入我们的payload,
最后运行'getflag'函数,拿到权限。

0x00 T3 铁人三项(第五赛区)_2018_rop

下一题

0x01 题解

1.checksec

这次直接运行看看,就是read函数应该吗,然后打印个你好世界。

2.静态分析

果然,这题没后门函数,有read,那就泄露read打ret2libc即可。

4.写exp并且运行拿flag

先泄露一下地址。ok,去查好地址写好 exp如下。

拿flag。

这题就是很传统的ret2libc了,64位的。

0x00 T4 bjdctf_2020_babyrop

0x01 题目来源

下一题捏。

0x02 题解

第一步:checksec 文件名

用checksec看看这个文件的保护情况。

64位,无pie和canary,安心

第一步:拖入ida静态分析

有点中二但是我喜欢。和上一题差不多看起来。

第二步:看看栈的偏移量

可见偏移量为(0x20+0x08)
那还等啥,直接ret2libc!

泄露得到地址。

但是由于puts 690的libc太过古早,搜索半天没搜到,libcsearcher又用不了,卡了很久,最后被群里一位大哥解救,远程感谢一下Byron~

我当时找了下puts 690的libc搜到了这个wp。

并且在网站都找不到这个libc,于是Byron为我提供了下面这些信息。

这是他给我提供的,但是这个libcbase引起了我的兴趣。

最后问题解决,拿到flag。

因为这个卡了一晚上也是够蠢的……

0x00 T5 bjdctf_2020_babystack2

依然是下一题!

0x01 wp

看到if(xxxx>xxxx)基本可以知道是整数溢出了,且下面有read,
显然此题思路就是绕过if判断并且read足够多的数据达成一处运行后门。

后门函数

关于整数溢出,就是指大到最大以后他会变到最小的数(这和二进制溢出有关系,比如1111最大了,1111+1就会变成10000,但是人家只会存后四位,所以右边为了0000,不管多大字节的都同理)

由于输入时是signed,使用时是unsigned,这个漏洞就可以利用了。因为signed的负数(如1111是-1),在unsigned是很大的数字(如1111是15),字节越多越大。

由于发现存放的int是四个字节,定为long int,故传入singed最大值加一,达到整数溢出的效果,随后即是ret2text

拿下flag。

刚才提到'libc-database'吸引到了我,于是安装了一波!方法如下,大家一起看看


1. git clone https://github.com/niklasb/libc-database
2. cd libc-database
3. ./get

使用方法:

参考原文点击这里!

安装好了,我们试试看吧!

不过原本那个查不到,可能真的太老了,没办法啦~

格式化字符串那里要改成printf("aaaa-%p",&a)