强网杯2019
babymimic
拟态防御…惊了
程序提供了两个EFL文件:
32位: https://github.com/Inv0k3r/pwnable_files/raw/master/_stkof
64位: https://github.com/Inv0k3r/pwnable_files/raw/master/__stkof
漏洞点都很明显, 都是简单的栈溢出
32位:
64位:
检查保护, 虽然开了canary, 但是栈溢出的那个函数并没有check, 猜测应该是出题人手动把check nop了
后续测试中, 发现无法leak任何内容, 猜测服务器对返回的内容进行了检测, 由于程序是静态编译的, 所以我们可以尝试构造ROP链来getshell
这里使用ROPGenerator, 生成ROP chain以后, 溢出到返回地址即可getshell
但是打服务器的时候打不下来, 因为服务器用的拟态防御, 我们无法知道交互的是32位程序还是64位程序
当然我们可以通过不断运行两个架构的攻击脚本来尝试爆破, 但是服务器设置了爆破限制, 随机8位的字符, 然后sha256加密, 给出5位,我们需要爆破另外3位, 这样就降低了爆破成功的可能性(我爆了一天没成功
所以我们需要一个payload, 来同时对64和32进行攻击
经过分析可知, 32位程序的返回地址偏移是272, 而64位是280
所以我们可以利用中间这8个字节, 来判断服务器是32位还是64位
32位程序使用4字节作为一个地址, 所以8字节可以让我们写两条gadget
由于无法leak任何地址(带出来数据就会触发服务器的check导致连接关闭), 所以我们不知道栈地址, 没法直接跳转
所以我们可以通过修改栈顶指针寄存器, 来让程序跳转到栈上的另外一个位置
尝试找一下gadget:
可以写add esp 0xc进去, 那么栈顶将被修改到当前栈地址+ 0xc
这样一来, 针对32位程序的payload可以写成:
payload = 272 * 'a' + p32(add_esp_0xc) + 0xc* 'a' + ROP链
其中的0x10字节, 我们可以用来写64位程序的ROP链
我们用ROPGenerator生成的ROP chain:
32位:
64位:
生成的rop链中, 32位的长度为92字节, 64位的长度为112字节
而我们的payload
payload = 272 * 'a' + p32(add_esp_0xc) + 0xc * 'a' + 32位ROP链
中, 有8字节可用, 所以我们可以写一个add rsp 0x??; ret
的方式来进行跳转, 跳到32位ROP链之后, 找一下64位程序的gadget:
各种长度都有,很舒服
我们32位程序的ROP链, 长度是92字节, 所以我们的64位程序跳转的时候要留给32位ROP链足够空间
这里选择0x68这个gadget
那么payload=272 * 'a' + p32(add_esp_0xc) + 'b' * 4 + p64(add_rsp_0x68) + 92字节的32位程序的ROP + 112字节的64位程序的ROP
后续测试发现ROPGenerator生成的32位ROP链无法getshell…最后换了ROPgadget生成:
ROPgadget --binary "_stkof" --ropchain
长度是136字节, 所以对上面payload进行修改, 64位的gadget需要跳到更远, 所以选择了0xd8这个gadget:
payload=272*'a' + p32(add_esp_0xc) + 'b' * 4 + p64(add_rsp_0xd8) + 136字节的32位程序的ROP + (0xd8 - 136) * 'c' + 112字节的64位程序的ROP
成功getshell:
最终脚本:
import hashlib |
justre
定位到check函数, 发现很多xmm指令…
调试一下看看结果
前面的部分是确定输入是否在0-9A-F之间, 并把前8个字符转成16进制形式, 第九个字符存入一个变量
输入1A2B3C4D5F6A7B8C9D0E
xmmword_405018 + 0x10 = (0x10 + 0x1A2B3C4D) ^ (0x1010101 * 0x5F + xmmword_405018 + v20)
上面的操作, 经过8轮运算以后, 和96字节的字符比较:
55 8B EC 83 E4 F0 81 EC 78 02 00 00 A1 04 50 40 00 33 C4 89 84 24 74 02 00 00 0F 10 05 A8 41 40 00 A0 C0 41 40 00 56 0F 11 44 24 2C 57 F3 0F 7E 05 B8 41 40 00 66 0F D6 44 24 40 0F 10 41 0A 6A 40 88 44 24 4C 8D 84 24 FC 01 00 00 6A 00 50 0F 11 44 24 1C E8 58 0F 00 00 6A 40 8D 84 24 48 02
xmmword_405018 = 416214C801120DF0ED93C08B7EB6971B
xmmword_405028 = 41537868F119106CFF3DF4E788CDFF6A
xmmword_405038 = 5B19BFC22CEE54810A6010AF40D2706E
xmmword_405048 = 671C51850A51F4B0B31932734153886F
from struct import Dword |
得到: 0x10 0x13242298
接下来是DES加密
crypto
[++++++++++++++++]proof completed[++++++++++++++++]
[+]Generating challenge 1
[+]n=0x381c2a94ae89869e563b600b4b9cce988197a565e027fd923bee484664d33f1a10037857ce9e0c49422470536cef963e540ab1bffbd6fe3dfda54ac04fae790c99568fe064a77d57ea17609f45d5d0f984bd4235f54b4c8b069ceac1220e743e0fcd420a5302eda89dc58497e94a01281849c0134c88d543adda2d423c3af7fL
[+]e=3
[+]m=random.getrandbits(512)
[+]c=pow(m,e,n)=0x1da185826272d2d806f3b8e036fbe2b27320defe9892175f9e18a60c39348fa2b631d386edeb98f37f18e8059360e827cea76363a3e1aaae46aef40ac0c6621576e41ab644c704a9c662c998618c7d48e17542001142d768fce50d778c3555fd3d795a7b23d72c65f6a96fd4e1e438bcca7dc963adf0baf3b135de994662b82L
[+]((m>>72)<<72)=0xfabc61918e517c9bf73b2bf5d91f30a80c19de72a995e1c47de8f9be1bb4006b6dd10a11adb95ce73613e6236aa4e91db6d5c8f07dac16000000000000000000L
[-]long_to_bytes(m).encode('hex')=
e = 3, 给了部分明文, 使用CoppersmithAttack
n=0x381c2a94ae89869e563b600b4b9cce988197a565e027fd923bee484664d33f1a10037857ce9e0c49422470536cef963e540ab1bffbd6fe3dfda54ac04fae790c99568fe064a77d57ea17609f45d5d0f984bd4235f54b4c8b069ceac1220e743e0fcd420a5302eda89dc58497e94a01281849c0134c88d543adda2d423c3af7f |
丢到在线网站: https://sagecell.sagemath.org/
得到13132102744876364837010657674093125827216092673699264307134817022461255433729251935499820467653979827420832582244375851850135494237158389876362816492294802
转hex提交
[++++++++++++++++]challenge 1 completed[++++++++++++++++]
[+]Generating challenge 2
[+]n=0x62645f7122276f971d8be2c280c50af2a4d24f64c66d887a63412eca8318139b63d3a208bea26c760f9da2a4a5532193120ef2741863e506ef56f972afbf88072de0626af4a7f119342e524c3467f2a0b593127646a08dd9edeb94772d844847a0e4adbba021ff157a1c41393840d32966ca4b425be64c5cd7be71f15f1c0c0fL
[+]e=65537
[+]m=random.getrandbits(512)
[+]c=pow(m,e,n)=0x2ea82d02c8405c04606f471756806a9d17cd0d9bedc636f7d884244745e086dbef806e4cfa440780f93abb33d5d295227df4cca71783f6693a6ea7c7775188f8cd814fadaec1a67087e5b6e1d3f51985243f057f667c663f59fbf638ea745b7aa6f57deff8da242b18086c2e8dba028613f01d100269d3342f0094e9c91eddL
[+]((p>>128)<<128)=0xa19bcc2975554445de9f02e634661d4f6a665336a0af5c6a6f93758a8d23dfec8b258004a431974f371132c3ca7696ef00000000000000000000000000000000L
[-]long_to_bytes(m).encode('hex')=$
n=0x62645f7122276f971d8be2c280c50af2a4d24f64c66d887a63412eca8318139b63d3a208bea26c760f9da2a4a5532193120ef2741863e506ef56f972afbf88072de0626af4a7f119342e524c3467f2a0b593127646a08dd9edeb94772d844847a0e4adbba021ff157a1c41393840d32966ca4b425be64c5cd7be71f15f1c0c0f |
求得p=8464128337073235841306774067889692521235027856600640285732672852346488815451647340168593969676910111879627488847926492818393003168975897246870844426887263
q=n/p=8163069655763991394338137148931618671791210480216681019589422494491872929647892079092083346702116373697540683755495323751341124306366881478618522649358929
def egcd(a, b): |
d=modinv(e,(p-1)*(q-1))
求得d解密
d0579143a455d3b10f0c0e69ce45f26e4b39207ef640afc1bc89a3dd2797fd11990efeeeb3c9beb8780ab9e201c89aca59a82dc82d22a6832f8e12b9ae451612
[++++++++++++++++]challenge 2 completed[++++++++++++++++]
[+]Generating challenge 3
[+]n=0x7792e8692d355b543bd466603bf0d63e9f80c178695c5fdf8781a7718422f3df04de72ad0d8758274108d6e5b9fae9fe548c218589da15e5bcdd3c4d64d881e0ee1437a5280b16d127b85773ee4b662d8c032ccf08bb9cd270cc03e12b8884bc22439ef833cbaffc629f1e5022fd200eb7ae459104b19efa8a1d7dfe5fcb52cdL
[+]e=3
[+]m=random.getrandbits(512)
[+]c=pow(m,e,n)=0x72920d5cc7aef95112d4800535f2e479a10d4901af657ff06dbc105ef4e9a7bec7fb86e3af7ea3e393d919ba21464f90af9781acad2c2ca8041282c7a0e03267fe62ddf57d7ace68a7f55f8aa1e45f312ea9a1cbbb5cc1a4172aec0ef12b3c853a915573864545ce9c03cb8b50bc1cb241a6221495a9d78e472afda50d9b2174L
[+]d=invmod(e,(p-1)*(q-1))
[+]d&((1<<512)-1)=0xb51c0c25d4b249e9a2c8d3daf342136c05e3c2ab32fea94033e4cb01d553ac0770c32884556eee08d3a61cde383c2caa7ea68fb7367f88a0312e948c4c4ac293L
[-]long_to_bytes(m).encode('hex')=$
def partial_p(p0, kbits, n): |
后面不会了, 鸽了
贴一个Chamd5的wp: https://mp.weixin.qq.com/s/Rcm4qaELX0wl8IULApujuw
签到
flag{welcome_to_qwb_2019}
鲲or鳗orGame
选游戏, js里找到var romPath = "rom/game.gb";
下载下来, 用GameBoy模拟器打开, 金手指启动, 把最高纪录改到0xff
即可得到flag:
flag{PS03R49UE576R421RE8}
强网先锋-AD
IDA反编译以后可以看到程序读入了一段字节
动态调试一下, 在内存里dump出来:
0072| 0x7fffffffdc28 —> 0x7fffffffdc60 (“ZmxhZ3ttYWZha3VhaWxhaXFpYW5kYW9ifQ==”)
解base64即可:flag{mafakuailaiqiandaob}
强网先锋-辅助
给了两组rsa:
c1 = 2482083893746618248544426737023750400124543452082436334398504986023501710639402060949106693279462896968839029712099336235976221571564642900240827774719199533124053953157919850838214021934907480633441577316263853011232518392904983028052155862154264401108124968404098823946691811798952747194237290581323868666637357604693015079007555594974245559555518819140844020498487432684946922741232053249894575417796067090655122702306134848220257943297645461477488086804856018323986796999103385565540496534422406390355987976815450744535949785073009043007159496929187184338592859040917546122343981520508220332785862546608841127597
e = 65537
n1 = 14967030059975114950295399874185047053736587880127990542035765201425779342430662517765063258784685868107066789475747180244711352646469776732938544641583842313791872986357504462184924075227433498631423289187988351475666785190854210389587594975456064984611990461126684301086241532915267311675164190213474245311019623654865937851653532870965423474555348239858021551589650169602439423841160698793338115204238140085738680883313433574060243600028500600824624358473403059597593891412179399165813622512901263380299561019624741488779367019389775786547292065352885007224239581776975892385364446446185642939137287519945974807727
c2 = 3829060039572042737496679186881067950328956133163629908872348108160129550437697677150599483923925798224328175594483217938833520220087230303470138525970468915511111320396185482564783975435346354440035776909781158407636044986403819840648379609630039348895415045723208843631191252142600667607807479954194447237061080618370787672720344741413537975922184859333432197766580150534457001196765621678659952108010596273244230812327182786329760844037149719587269632133595149294067490955644893402708720284179715002149224068928828656515326446881791228638008572889331511945042911372915003805505412099102954073299010951896955362470
e = 65537
n2 = 14624662628725820618622370803948630854094687814338334827462870357582795291844925274690253604919535785934208081825425541536057550227048399837243392490762167733083030368221240764693694321150104306044125934201699430146970466657410999261630825931178731857267599750324918610790098952520113593130245010530961350592735239454337631927669542026935873535964487595433984902529960726655481696404006628917922241666148082741874033756970724357470539589848548704573091633917869387239324447730587545472564561496724882799495186768858324490838169123077051890332313671220385830444331578674338014080959653201802476516237464651809255679979
题目脚本可知
n1 = p1 q1
n2 = p2 q1
求n1和n2的最大公约数即可分解n, 然后算私钥解密即可:
|
flag{i_am_very_sad_233333333333}
强网先锋-AP
修改堆块的时候没检查大小, 导致堆溢出
思路就是先leak libc, 然后用sh和system覆盖堆里的地址然后调用open操作即可
- 创建4个ticket
- 修改第三个ticket, 越界写到第四个ticket的puts地址那里
- 用open操作打印ticket3, 得到puts的地址
- 得到libc版本, 找到system地址和
/bin/sh
地址 - 修改第一个ticket, 覆盖到第二个ticket的两个地址
- 调用第二个ticket的open, getshell
脚本:
from pwn import * |